diff --git a/rskj-core/src/test/java/co/rsk/vm/opcode/MCopyDslTest.java b/rskj-core/src/test/java/co/rsk/vm/opcode/MCopyDslTest.java index 154bfe436b..0c5695de79 100644 --- a/rskj-core/src/test/java/co/rsk/vm/opcode/MCopyDslTest.java +++ b/rskj-core/src/test/java/co/rsk/vm/opcode/MCopyDslTest.java @@ -414,4 +414,438 @@ void testMCOPY_fullMemoryClean_behaveAsExpected() throws FileNotFoundException, } + @Test + void testMCOPY_fullMemoryCopy_behaveAsExpected() throws FileNotFoundException, DslProcessorException { + + DslParser parser = DslParser.fromResource("dsl/opcode/mcopy/testFullMemoryCopy.txt"); + World world = new World(); + WorldDslProcessor processor = new WorldDslProcessor(world); + processor.processCommands(parser); + + // Assertions + + // There's one block (b01) containing only 1 transaction + Block block1 = world.getBlockByName("b01"); + Assertions.assertNotNull(block1); + Assertions.assertEquals(1, block1.getTransactionsList().size()); + + // There's a transaction called txTestMCopy + Transaction txTestMCopy = world.getTransactionByName("txTestMCopy"); + Assertions.assertNotNull(txTestMCopy); + + // Transaction txTestMCopy has a transaction receipt + TransactionReceipt txTestMCopyReceipt = world.getTransactionReceiptByName("txTestMCopy"); + Assertions.assertNotNull(txTestMCopyReceipt); + + // Transaction txTestMCopy has been processed correctly + byte[] creationStatus = txTestMCopyReceipt.getStatus(); + Assertions.assertNotNull(creationStatus); + Assertions.assertEquals(1, creationStatus.length); + Assertions.assertEquals(1, creationStatus[0]); + + // There's one block (b02) containing only 1 transaction + Block block2 = world.getBlockByName("b02"); + Assertions.assertNotNull(block2); + Assertions.assertEquals(1, block2.getTransactionsList().size()); + + // There's a transaction called txTestMCopyOKCall + Transaction txTestMCopyOKCall = world.getTransactionByName("txTestMCopyOKCall"); + Assertions.assertNotNull(txTestMCopyOKCall); + + // Transaction txTestMCopyOKCall has a transaction receipt + TransactionReceipt txTestMCopyOKCallReceipt = world.getTransactionReceiptByName("txTestMCopyOKCall"); + Assertions.assertNotNull(txTestMCopyOKCallReceipt); + + // Transaction txTestMCopyOKCall has been processed correctly + byte[] txTestMCopyOKCallCreationStatus = txTestMCopyOKCallReceipt.getStatus(); + Assertions.assertNotNull(txTestMCopyOKCallCreationStatus); + Assertions.assertEquals(1, txTestMCopyOKCallCreationStatus.length); + Assertions.assertEquals(1, txTestMCopyOKCallCreationStatus[0]); + + // Check events + Assertions.assertEquals(1, TransactionReceiptUtil.getEventCount(txTestMCopyOKCallReceipt, "OK", null)); + Assertions.assertEquals(0, TransactionReceiptUtil.getEventCount(txTestMCopyOKCallReceipt, "ERROR", null)); + + } + + @Test + void testMCOPY_fullMemoryCopyOffset_behaveAsExpected() throws FileNotFoundException, DslProcessorException { + + DslParser parser = DslParser.fromResource("dsl/opcode/mcopy/testFullMemoryCopyOffset.txt"); + World world = new World(); + WorldDslProcessor processor = new WorldDslProcessor(world); + processor.processCommands(parser); + + // Assertions + + // There's one block (b01) containing only 1 transaction + Block block1 = world.getBlockByName("b01"); + Assertions.assertNotNull(block1); + Assertions.assertEquals(1, block1.getTransactionsList().size()); + + // There's a transaction called txTestMCopy + Transaction txTestMCopy = world.getTransactionByName("txTestMCopy"); + Assertions.assertNotNull(txTestMCopy); + + // Transaction txTestMCopy has a transaction receipt + TransactionReceipt txTestMCopyReceipt = world.getTransactionReceiptByName("txTestMCopy"); + Assertions.assertNotNull(txTestMCopyReceipt); + + // Transaction txTestMCopy has been processed correctly + byte[] creationStatus = txTestMCopyReceipt.getStatus(); + Assertions.assertNotNull(creationStatus); + Assertions.assertEquals(1, creationStatus.length); + Assertions.assertEquals(1, creationStatus[0]); + + // There's one block (b02) containing only 1 transaction + Block block2 = world.getBlockByName("b02"); + Assertions.assertNotNull(block2); + Assertions.assertEquals(1, block2.getTransactionsList().size()); + + // There's a transaction called txTestMCopyOKCall + Transaction txTestMCopyOKCall = world.getTransactionByName("txTestMCopyOKCall"); + Assertions.assertNotNull(txTestMCopyOKCall); + + // Transaction txTestMCopyOKCall has a transaction receipt + TransactionReceipt txTestMCopyOKCallReceipt = world.getTransactionReceiptByName("txTestMCopyOKCall"); + Assertions.assertNotNull(txTestMCopyOKCallReceipt); + + // Transaction txTestMCopyOKCall has been processed correctly + byte[] txTestMCopyOKCallCreationStatus = txTestMCopyOKCallReceipt.getStatus(); + Assertions.assertNotNull(txTestMCopyOKCallCreationStatus); + Assertions.assertEquals(1, txTestMCopyOKCallCreationStatus.length); + Assertions.assertEquals(1, txTestMCopyOKCallCreationStatus[0]); + + // Check events + Assertions.assertEquals(1, TransactionReceiptUtil.getEventCount(txTestMCopyOKCallReceipt, "OK", null)); + Assertions.assertEquals(0, TransactionReceiptUtil.getEventCount(txTestMCopyOKCallReceipt, "ERROR", null)); + + } + + @Test + void testMCOPY_fullMemoryRewrite_behaveAsExpected() throws FileNotFoundException, DslProcessorException { + + DslParser parser = DslParser.fromResource("dsl/opcode/mcopy/testFullMemoryRewrite.txt"); + World world = new World(); + WorldDslProcessor processor = new WorldDslProcessor(world); + processor.processCommands(parser); + + // Assertions + + // There's one block (b01) containing only 1 transaction + Block block1 = world.getBlockByName("b01"); + Assertions.assertNotNull(block1); + Assertions.assertEquals(1, block1.getTransactionsList().size()); + + // There's a transaction called txTestMCopy + Transaction txTestMCopy = world.getTransactionByName("txTestMCopy"); + Assertions.assertNotNull(txTestMCopy); + + // Transaction txTestMCopy has a transaction receipt + TransactionReceipt txTestMCopyReceipt = world.getTransactionReceiptByName("txTestMCopy"); + Assertions.assertNotNull(txTestMCopyReceipt); + + // Transaction txTestMCopy has been processed correctly + byte[] creationStatus = txTestMCopyReceipt.getStatus(); + Assertions.assertNotNull(creationStatus); + Assertions.assertEquals(1, creationStatus.length); + Assertions.assertEquals(1, creationStatus[0]); + + // There's one block (b02) containing only 1 transaction + Block block2 = world.getBlockByName("b02"); + Assertions.assertNotNull(block2); + Assertions.assertEquals(1, block2.getTransactionsList().size()); + + // There's a transaction called txTestMCopyOKCall + Transaction txTestMCopyOKCall = world.getTransactionByName("txTestMCopyOKCall"); + Assertions.assertNotNull(txTestMCopyOKCall); + + // Transaction txTestMCopyOKCall has a transaction receipt + TransactionReceipt txTestMCopyOKCallReceipt = world.getTransactionReceiptByName("txTestMCopyOKCall"); + Assertions.assertNotNull(txTestMCopyOKCallReceipt); + + // Transaction txTestMCopyOKCall has been processed correctly + byte[] txTestMCopyOKCallCreationStatus = txTestMCopyOKCallReceipt.getStatus(); + Assertions.assertNotNull(txTestMCopyOKCallCreationStatus); + Assertions.assertEquals(1, txTestMCopyOKCallCreationStatus.length); + Assertions.assertEquals(1, txTestMCopyOKCallCreationStatus[0]); + + // Check events + Assertions.assertEquals(1, TransactionReceiptUtil.getEventCount(txTestMCopyOKCallReceipt, "OK", null)); + Assertions.assertEquals(0, TransactionReceiptUtil.getEventCount(txTestMCopyOKCallReceipt, "ERROR", null)); + + } + + // Memory Extension Tests + + @Test + void testMCOPY_outOfBoundsMemoryExtension_behaveAsExpected() throws FileNotFoundException, DslProcessorException { + + DslParser parser = DslParser.fromResource("dsl/opcode/mcopy/testOutOfBoundsMemoryExtension.txt"); + World world = new World(); + WorldDslProcessor processor = new WorldDslProcessor(world); + processor.processCommands(parser); + + // Assertions + + // There's one block (b01) containing only 1 transaction + Block block1 = world.getBlockByName("b01"); + Assertions.assertNotNull(block1); + Assertions.assertEquals(1, block1.getTransactionsList().size()); + + // There's a transaction called txTestMCopy + Transaction txTestMCopy = world.getTransactionByName("txTestMCopy"); + Assertions.assertNotNull(txTestMCopy); + + // Transaction txTestMCopy has a transaction receipt + TransactionReceipt txTestMCopyReceipt = world.getTransactionReceiptByName("txTestMCopy"); + Assertions.assertNotNull(txTestMCopyReceipt); + + // Transaction txTestMCopy has been processed correctly + byte[] creationStatus = txTestMCopyReceipt.getStatus(); + Assertions.assertNotNull(creationStatus); + Assertions.assertEquals(1, creationStatus.length); + Assertions.assertEquals(1, creationStatus[0]); + + // There's one block (b02) containing only 1 transaction + Block block2 = world.getBlockByName("b02"); + Assertions.assertNotNull(block2); + Assertions.assertEquals(1, block2.getTransactionsList().size()); + + // There's a transaction called txTestMCopyOKCall + Transaction txTestMCopyOKCall = world.getTransactionByName("txTestMCopyOKCall"); + Assertions.assertNotNull(txTestMCopyOKCall); + + // Transaction txTestMCopyOKCall has a transaction receipt + TransactionReceipt txTestMCopyOKCallReceipt = world.getTransactionReceiptByName("txTestMCopyOKCall"); + Assertions.assertNotNull(txTestMCopyOKCallReceipt); + + // Transaction txTestMCopyOKCall has been processed correctly + byte[] txTestMCopyOKCallCreationStatus = txTestMCopyOKCallReceipt.getStatus(); + Assertions.assertNotNull(txTestMCopyOKCallCreationStatus); + Assertions.assertEquals(1, txTestMCopyOKCallCreationStatus.length); + Assertions.assertEquals(1, txTestMCopyOKCallCreationStatus[0]); + + // Check events + Assertions.assertEquals(1, TransactionReceiptUtil.getEventCount(txTestMCopyOKCallReceipt, "OK", null)); + Assertions.assertEquals(0, TransactionReceiptUtil.getEventCount(txTestMCopyOKCallReceipt, "ERROR", null)); + + } + + @Test + void testMCOPY_singleByteMemoryExtension_behaveAsExpected() throws FileNotFoundException, DslProcessorException { + + DslParser parser = DslParser.fromResource("dsl/opcode/mcopy/testSingleByteMemoryExtension.txt"); + World world = new World(); + WorldDslProcessor processor = new WorldDslProcessor(world); + processor.processCommands(parser); + + // Assertions + + // There's one block (b01) containing only 1 transaction + Block block1 = world.getBlockByName("b01"); + Assertions.assertNotNull(block1); + Assertions.assertEquals(1, block1.getTransactionsList().size()); + + // There's a transaction called txTestMCopy + Transaction txTestMCopy = world.getTransactionByName("txTestMCopy"); + Assertions.assertNotNull(txTestMCopy); + + // Transaction txTestMCopy has a transaction receipt + TransactionReceipt txTestMCopyReceipt = world.getTransactionReceiptByName("txTestMCopy"); + Assertions.assertNotNull(txTestMCopyReceipt); + + // Transaction txTestMCopy has been processed correctly + byte[] creationStatus = txTestMCopyReceipt.getStatus(); + Assertions.assertNotNull(creationStatus); + Assertions.assertEquals(1, creationStatus.length); + Assertions.assertEquals(1, creationStatus[0]); + + // There's one block (b02) containing only 1 transaction + Block block2 = world.getBlockByName("b02"); + Assertions.assertNotNull(block2); + Assertions.assertEquals(1, block2.getTransactionsList().size()); + + // There's a transaction called txTestMCopyOKCall + Transaction txTestMCopyOKCall = world.getTransactionByName("txTestMCopyOKCall"); + Assertions.assertNotNull(txTestMCopyOKCall); + + // Transaction txTestMCopyOKCall has a transaction receipt + TransactionReceipt txTestMCopyOKCallReceipt = world.getTransactionReceiptByName("txTestMCopyOKCall"); + Assertions.assertNotNull(txTestMCopyOKCallReceipt); + + // Transaction txTestMCopyOKCall has been processed correctly + byte[] txTestMCopyOKCallCreationStatus = txTestMCopyOKCallReceipt.getStatus(); + Assertions.assertNotNull(txTestMCopyOKCallCreationStatus); + Assertions.assertEquals(1, txTestMCopyOKCallCreationStatus.length); + Assertions.assertEquals(1, txTestMCopyOKCallCreationStatus[0]); + + // Check events + Assertions.assertEquals(1, TransactionReceiptUtil.getEventCount(txTestMCopyOKCallReceipt, "OK", null)); + Assertions.assertEquals(0, TransactionReceiptUtil.getEventCount(txTestMCopyOKCallReceipt, "ERROR", null)); + + } + + @Test + void testMCOPY_singleWordMemoryExtension_behaveAsExpected() throws FileNotFoundException, DslProcessorException { + + DslParser parser = DslParser.fromResource("dsl/opcode/mcopy/testSingleWordMemoryExtension.txt"); + World world = new World(); + WorldDslProcessor processor = new WorldDslProcessor(world); + processor.processCommands(parser); + + // Assertions + + // There's one block (b01) containing only 1 transaction + Block block1 = world.getBlockByName("b01"); + Assertions.assertNotNull(block1); + Assertions.assertEquals(1, block1.getTransactionsList().size()); + + // There's a transaction called txTestMCopy + Transaction txTestMCopy = world.getTransactionByName("txTestMCopy"); + Assertions.assertNotNull(txTestMCopy); + + // Transaction txTestMCopy has a transaction receipt + TransactionReceipt txTestMCopyReceipt = world.getTransactionReceiptByName("txTestMCopy"); + Assertions.assertNotNull(txTestMCopyReceipt); + + // Transaction txTestMCopy has been processed correctly + byte[] creationStatus = txTestMCopyReceipt.getStatus(); + Assertions.assertNotNull(creationStatus); + Assertions.assertEquals(1, creationStatus.length); + Assertions.assertEquals(1, creationStatus[0]); + + // There's one block (b02) containing only 1 transaction + Block block2 = world.getBlockByName("b02"); + Assertions.assertNotNull(block2); + Assertions.assertEquals(1, block2.getTransactionsList().size()); + + // There's a transaction called txTestMCopyOKCall + Transaction txTestMCopyOKCall = world.getTransactionByName("txTestMCopyOKCall"); + Assertions.assertNotNull(txTestMCopyOKCall); + + // Transaction txTestMCopyOKCall has a transaction receipt + TransactionReceipt txTestMCopyOKCallReceipt = world.getTransactionReceiptByName("txTestMCopyOKCall"); + Assertions.assertNotNull(txTestMCopyOKCallReceipt); + + // Transaction txTestMCopyOKCall has been processed correctly + byte[] txTestMCopyOKCallCreationStatus = txTestMCopyOKCallReceipt.getStatus(); + Assertions.assertNotNull(txTestMCopyOKCallCreationStatus); + Assertions.assertEquals(1, txTestMCopyOKCallCreationStatus.length); + Assertions.assertEquals(1, txTestMCopyOKCallCreationStatus[0]); + + // Check events + Assertions.assertEquals(1, TransactionReceiptUtil.getEventCount(txTestMCopyOKCallReceipt, "OK", null)); + Assertions.assertEquals(0, TransactionReceiptUtil.getEventCount(txTestMCopyOKCallReceipt, "ERROR", null)); + + } + + @Test + void testMCOPY_singleWordMinusOneByteMemoryExtension_behaveAsExpected() throws FileNotFoundException, DslProcessorException { + + DslParser parser = DslParser.fromResource("dsl/opcode/mcopy/testSingleWordMinusOneByteMemoryExtension.txt"); + World world = new World(); + WorldDslProcessor processor = new WorldDslProcessor(world); + processor.processCommands(parser); + + // Assertions + + // There's one block (b01) containing only 1 transaction + Block block1 = world.getBlockByName("b01"); + Assertions.assertNotNull(block1); + Assertions.assertEquals(1, block1.getTransactionsList().size()); + + // There's a transaction called txTestMCopy + Transaction txTestMCopy = world.getTransactionByName("txTestMCopy"); + Assertions.assertNotNull(txTestMCopy); + + // Transaction txTestMCopy has a transaction receipt + TransactionReceipt txTestMCopyReceipt = world.getTransactionReceiptByName("txTestMCopy"); + Assertions.assertNotNull(txTestMCopyReceipt); + + // Transaction txTestMCopy has been processed correctly + byte[] creationStatus = txTestMCopyReceipt.getStatus(); + Assertions.assertNotNull(creationStatus); + Assertions.assertEquals(1, creationStatus.length); + Assertions.assertEquals(1, creationStatus[0]); + + // There's one block (b02) containing only 1 transaction + Block block2 = world.getBlockByName("b02"); + Assertions.assertNotNull(block2); + Assertions.assertEquals(1, block2.getTransactionsList().size()); + + // There's a transaction called txTestMCopyOKCall + Transaction txTestMCopyOKCall = world.getTransactionByName("txTestMCopyOKCall"); + Assertions.assertNotNull(txTestMCopyOKCall); + + // Transaction txTestMCopyOKCall has a transaction receipt + TransactionReceipt txTestMCopyOKCallReceipt = world.getTransactionReceiptByName("txTestMCopyOKCall"); + Assertions.assertNotNull(txTestMCopyOKCallReceipt); + + // Transaction txTestMCopyOKCall has been processed correctly + byte[] txTestMCopyOKCallCreationStatus = txTestMCopyOKCallReceipt.getStatus(); + Assertions.assertNotNull(txTestMCopyOKCallCreationStatus); + Assertions.assertEquals(1, txTestMCopyOKCallCreationStatus.length); + Assertions.assertEquals(1, txTestMCopyOKCallCreationStatus[0]); + + // Check events + Assertions.assertEquals(1, TransactionReceiptUtil.getEventCount(txTestMCopyOKCallReceipt, "OK", null)); + Assertions.assertEquals(0, TransactionReceiptUtil.getEventCount(txTestMCopyOKCallReceipt, "ERROR", null)); + + } + + @Test + void testMCOPY_singleWordPlusOneByteMemoryExtension_behaveAsExpected() throws FileNotFoundException, DslProcessorException { + + DslParser parser = DslParser.fromResource("dsl/opcode/mcopy/testSingleWordPlusOneByteMemoryExtension.txt"); + World world = new World(); + WorldDslProcessor processor = new WorldDslProcessor(world); + processor.processCommands(parser); + + // Assertions + + // There's one block (b01) containing only 1 transaction + Block block1 = world.getBlockByName("b01"); + Assertions.assertNotNull(block1); + Assertions.assertEquals(1, block1.getTransactionsList().size()); + + // There's a transaction called txTestMCopy + Transaction txTestMCopy = world.getTransactionByName("txTestMCopy"); + Assertions.assertNotNull(txTestMCopy); + + // Transaction txTestMCopy has a transaction receipt + TransactionReceipt txTestMCopyReceipt = world.getTransactionReceiptByName("txTestMCopy"); + Assertions.assertNotNull(txTestMCopyReceipt); + + // Transaction txTestMCopy has been processed correctly + byte[] creationStatus = txTestMCopyReceipt.getStatus(); + Assertions.assertNotNull(creationStatus); + Assertions.assertEquals(1, creationStatus.length); + Assertions.assertEquals(1, creationStatus[0]); + + // There's one block (b02) containing only 1 transaction + Block block2 = world.getBlockByName("b02"); + Assertions.assertNotNull(block2); + Assertions.assertEquals(1, block2.getTransactionsList().size()); + + // There's a transaction called txTestMCopyOKCall + Transaction txTestMCopyOKCall = world.getTransactionByName("txTestMCopyOKCall"); + Assertions.assertNotNull(txTestMCopyOKCall); + + // Transaction txTestMCopyOKCall has a transaction receipt + TransactionReceipt txTestMCopyOKCallReceipt = world.getTransactionReceiptByName("txTestMCopyOKCall"); + Assertions.assertNotNull(txTestMCopyOKCallReceipt); + + // Transaction txTestMCopyOKCall has been processed correctly + byte[] txTestMCopyOKCallCreationStatus = txTestMCopyOKCallReceipt.getStatus(); + Assertions.assertNotNull(txTestMCopyOKCallCreationStatus); + Assertions.assertEquals(1, txTestMCopyOKCallCreationStatus.length); + Assertions.assertEquals(1, txTestMCopyOKCallCreationStatus[0]); + + // Check events + Assertions.assertEquals(1, TransactionReceiptUtil.getEventCount(txTestMCopyOKCallReceipt, "OK", null)); + Assertions.assertEquals(0, TransactionReceiptUtil.getEventCount(txTestMCopyOKCallReceipt, "ERROR", null)); + + } + }