SparklyPower/SparklyPaper

Redstone shinanigans with non alternate-current

Quinowell opened this issue · 9 comments

Redstone lag machine randomly crashes server 🤨
Simple redstone stuff sometimes (and sometimes not?!?) crushes server with exeption:

[19:04:59 ERROR]: Encountered an unexpected exception
java.lang.RuntimeException: java.util.concurrent.ExecutionException: net.minecraft.ReportedException: Exception while updating neighbours
        at net.minecraft.server.MinecraftServer.tickChildren(MinecraftServer.java:1818) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at net.minecraft.server.dedicated.DedicatedServer.tickChildren(DedicatedServer.java:464) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at net.minecraft.server.MinecraftServer.tickServer(MinecraftServer.java:1520) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1221) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:324) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at java.lang.Thread.run(Thread.java:833) ~[?:?]
Caused by: java.util.concurrent.ExecutionException: net.minecraft.ReportedException: Exception while updating neighbours
        at java.util.concurrent.FutureTask.report(FutureTask.java:122) ~[?:?]
        at java.util.concurrent.FutureTask.get(FutureTask.java:191) ~[?:?]
        at net.minecraft.server.MinecraftServer.tickChildren(MinecraftServer.java:1815) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        ... 5 more
Caused by: net.minecraft.ReportedException: Exception while updating neighbours
        at net.minecraft.server.MinecraftServer.lambda$tickChildren$16(MinecraftServer.java:1807) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[?:?]
        at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[?:?]
        ... 1 more
Caused by: java.util.ConcurrentModificationException
        at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013) ~[?:?]
        at java.util.ArrayList$Itr.next(ArrayList.java:967) ~[?:?]
        at com.destroystokyo.paper.util.RedstoneWireTurbo.breadthFirstWalk(RedstoneWireTurbo.java:633) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at com.destroystokyo.paper.util.RedstoneWireTurbo.updateSurroundingRedstone(RedstoneWireTurbo.java:807) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at net.minecraft.world.level.block.RedStoneWireBlock.updateSurroundingRedstone(RedStoneWireBlock.java:273) ~[?:?]
        at net.minecraft.world.level.block.RedStoneWireBlock.neighborChanged(RedStoneWireBlock.java:544) ~[?:?]
        at net.minecraft.world.level.block.state.BlockBehaviour$BlockStateBase.neighborChanged(BlockBehaviour.java:1234) ~[?:?]
        at net.minecraft.world.level.redstone.NeighborUpdater.executeUpdate(NeighborUpdater.java:66) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at net.minecraft.world.level.redstone.CollectingNeighborUpdater$SimpleNeighborUpdate.runNext(CollectingNeighborUpdater.java:160) ~[?:?]
        at net.minecraft.world.level.redstone.CollectingNeighborUpdater.runUpdates(CollectingNeighborUpdater.java:79) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at net.minecraft.world.level.redstone.CollectingNeighborUpdater.addAndRun(CollectingNeighborUpdater.java:63) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at net.minecraft.world.level.redstone.CollectingNeighborUpdater.neighborChanged(CollectingNeighborUpdater.java:35) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at net.minecraft.server.level.ServerLevel.neighborChanged(ServerLevel.java:1912) ~[?:?]
        at net.minecraft.world.level.block.DiodeBlock.updateNeighborsInFront(DiodeBlock.java:198) ~[?:?]
        at net.minecraft.world.level.block.DiodeBlock.onPlace(DiodeBlock.java:183) ~[?:?]
        at net.minecraft.world.level.block.state.BlockBehaviour$BlockStateBase.onPlace(BlockBehaviour.java:1264) ~[?:?]
        at net.minecraft.world.level.chunk.LevelChunk.setBlockState(LevelChunk.java:474) ~[?:?]
        at net.minecraft.world.level.Level.setBlock(Level.java:953) ~[?:?]
        at net.minecraft.world.level.Level.setBlock(Level.java:913) ~[?:?]
        at net.minecraft.world.level.block.DiodeBlock.tick(DiodeBlock.java:72) ~[?:?]
        at net.minecraft.world.level.block.state.BlockBehaviour$BlockStateBase.tick(BlockBehaviour.java:1276) ~[?:?]
        at net.minecraft.server.level.ServerLevel.tickBlock(ServerLevel.java:1365) ~[?:?]
        at net.minecraft.world.ticks.LevelTicks.runCollectedTicks(LevelTicks.java:197) ~[?:?]
        at net.minecraft.world.ticks.LevelTicks.tick(LevelTicks.java:94) ~[?:?]
        at net.minecraft.server.level.ServerLevel.tick(ServerLevel.java:860) ~[?:?]
        at net.minecraft.server.MinecraftServer.lambda$tickChildren$16(MinecraftServer.java:1778) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[?:?]
        at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[?:?]
        ... 1 more

or sometimes

[19:14:19 ERROR]: Encountered an unexpected exception
java.lang.RuntimeException: java.util.concurrent.ExecutionException: net.minecraft.ReportedException: Exception while updating neighbours
        at net.minecraft.server.MinecraftServer.tickChildren(MinecraftServer.java:1818) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at net.minecraft.server.dedicated.DedicatedServer.tickChildren(DedicatedServer.java:464) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at net.minecraft.server.MinecraftServer.tickServer(MinecraftServer.java:1520) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1221) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:324) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at java.lang.Thread.run(Thread.java:833) ~[?:?]
Caused by: java.util.concurrent.ExecutionException: net.minecraft.ReportedException: Exception while updating neighbours
        at java.util.concurrent.FutureTask.report(FutureTask.java:122) ~[?:?]
        at java.util.concurrent.FutureTask.get(FutureTask.java:191) ~[?:?]
        at net.minecraft.server.MinecraftServer.tickChildren(MinecraftServer.java:1815) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        ... 5 more
Caused by: net.minecraft.ReportedException: Exception while updating neighbours
        at net.minecraft.server.MinecraftServer.lambda$tickChildren$16(MinecraftServer.java:1807) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[?:?]
        at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[?:?]
        ... 1 more
Caused by: java.lang.NullPointerException: Cannot read field "currentState" because "center_up" is null
        at com.destroystokyo.paper.util.RedstoneWireTurbo.calculateCurrentChanges(RedstoneWireTurbo.java:861) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at com.destroystokyo.paper.util.RedstoneWireTurbo.updateNode(RedstoneWireTurbo.java:444) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at com.destroystokyo.paper.util.RedstoneWireTurbo.breadthFirstWalk(RedstoneWireTurbo.java:638) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at com.destroystokyo.paper.util.RedstoneWireTurbo.updateSurroundingRedstone(RedstoneWireTurbo.java:807) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at net.minecraft.world.level.block.RedStoneWireBlock.updateSurroundingRedstone(RedStoneWireBlock.java:273) ~[?:?]
        at net.minecraft.world.level.block.RedStoneWireBlock.neighborChanged(RedStoneWireBlock.java:544) ~[?:?]
        at net.minecraft.world.level.block.state.BlockBehaviour$BlockStateBase.neighborChanged(BlockBehaviour.java:1234) ~[?:?]
        at net.minecraft.world.level.redstone.NeighborUpdater.executeUpdate(NeighborUpdater.java:66) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at net.minecraft.world.level.redstone.CollectingNeighborUpdater$SimpleNeighborUpdate.runNext(CollectingNeighborUpdater.java:160) ~[?:?]
        at net.minecraft.world.level.redstone.CollectingNeighborUpdater.runUpdates(CollectingNeighborUpdater.java:79) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at net.minecraft.world.level.redstone.CollectingNeighborUpdater.addAndRun(CollectingNeighborUpdater.java:63) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at net.minecraft.world.level.redstone.CollectingNeighborUpdater.neighborChanged(CollectingNeighborUpdater.java:35) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at net.minecraft.server.level.ServerLevel.neighborChanged(ServerLevel.java:1912) ~[?:?]
        at net.minecraft.world.level.block.DiodeBlock.updateNeighborsInFront(DiodeBlock.java:198) ~[?:?]
        at net.minecraft.world.level.block.DiodeBlock.onPlace(DiodeBlock.java:183) ~[?:?]
        at net.minecraft.world.level.block.state.BlockBehaviour$BlockStateBase.onPlace(BlockBehaviour.java:1264) ~[?:?]
        at net.minecraft.world.level.chunk.LevelChunk.setBlockState(LevelChunk.java:474) ~[?:?]
        at net.minecraft.world.level.Level.setBlock(Level.java:953) ~[?:?]
        at net.minecraft.world.level.Level.setBlock(Level.java:913) ~[?:?]
        at net.minecraft.world.level.block.DiodeBlock.tick(DiodeBlock.java:65) ~[?:?]
        at net.minecraft.world.level.block.state.BlockBehaviour$BlockStateBase.tick(BlockBehaviour.java:1276) ~[?:?]
        at net.minecraft.server.level.ServerLevel.tickBlock(ServerLevel.java:1365) ~[?:?]
        at net.minecraft.world.ticks.LevelTicks.runCollectedTicks(LevelTicks.java:197) ~[?:?]
        at net.minecraft.world.ticks.LevelTicks.tick(LevelTicks.java:94) ~[?:?]
        at net.minecraft.server.level.ServerLevel.tick(ServerLevel.java:860) ~[?:?]
        at net.minecraft.server.MinecraftServer.lambda$tickChildren$16(MinecraftServer.java:1778) ~[sparklypaper-1.20.4.jar:git-SparklyPaper-"be7e5e1"]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[?:?]
        at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[?:?]
        ... 1 more

Here is save.
archive-2024-03-10T190116Z.tar.gz

Steps to replicate (all versions with Parallel World Ticking):
0 - Set redstone implementation something that is not alternate-current
1 - Load this save
2 - Interact with machine (observers and wires)
3 - Have bad luck (sometimes it works perfectly fine)
If good luck:
3.1 - Use worldedit to copy/paste and try again

2024-03-10.22-14-13.mp4

Are you using the latest 1.20.4 version? I haven't updated my public server to 1.20.4 yet (still using SparklyPaper 1.20.2) so I haven't worked out all the issues with it.

However this is very weird, especially because that code should always be ran on the world's ticking thread, so I don't know how a CME could happen.

Now that I noticed that you said that this doesn't happen with ALTERNATE_CURRENT whoops, yeah we use ALTERNATE_CURRENT @ SparklyPower

Okay now that I took a look into the code, the reason it borks out is because RedstoneWireTurbo instance is shared between all redstone wire blocks, so the code will bork out if you have two redstone contraptions in two different worlds and they end up ticking at the same time, this will cause concurrent modification exceptions and unexpected behavior with redstone.

For now, it is better to use ALTERNATE_CURRENT instead, I may fix this issue later, but no promises, because I don't use EIGENCRAFT on my server, however it is probably not that hard to fix it, I just need to make the RedstoneWireTurbo class be unique for each world.

I fixed this, but I haven't tested it thoroughly, so bugs may still happen!

As I mentioned in first message - any system that is not alternate-current crashes game.

Vanilla one is also crashes (when restone runs more than in one world)
изображение

Have you tried that in vanilla Paper? If this happens with the vanilla redstone behavior (which is "thread-safe" all things considered) then that may be just the server locking up due to too many redstone updates (see the "The server has not responded for 15 seconds!")

Also try Eigencraft in the latest build, I have fixed the concurrent modification exception there.

EIGENCRAFT works fine now.
Just paper with vanilla works. Low tps.
изображение

I need to check that out later then, but I don't think it is a issue inherently in SparklyPaper, but I haven't tested that issue out yet

Any progress with vanilla system? I'd like to use ALTERNATE_CURRENT, but it hurts vanilla Redstoners 😔