package vm import ( "bytes" "strings" "testing" "github.com/ethereum/go-ethereum/common" ) func TestMemoryCopy(t *testing.T) { // Test cases from https://eips.ethereum.org/EIPS/eip-5656#test-cases for i, tc := range []struct { dst, src, len uint64 pre string want string }{ { // MCOPY 0 32 32 - copy 32 bytes from offset 32 to offset 0. 0, 32, 32, "0000000000000000000000000000000000000000000000000000000000000000 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", }, { // MCOPY 0 0 32 - copy 32 bytes from offset 0 to offset 0. 0, 0, 32, "0101010101010101010101010101010101010101010101010101010101010101", "0101010101010101010101010101010101010101010101010101010101010101", }, { // MCOPY 0 1 8 - copy 8 bytes from offset 1 to offset 0 (overlapping). 0, 1, 8, "000102030405060708 000000000000000000000000000000000000000000000000", "010203040506070808 000000000000000000000000000000000000000000000000", }, { // MCOPY 1 0 8 - copy 8 bytes from offset 0 to offset 1 (overlapping). 1, 0, 8, "000102030405060708 000000000000000000000000000000000000000000000000", "000001020304050607 000000000000000000000000000000000000000000000000", }, // Tests below are not in the EIP, but maybe should be added { // MCOPY 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF 0 - copy zero bytes from out-of-bounds index(overlapping). 0xFFFFFFFFFFFF, 0xFFFFFFFFFFFF, 0, "11", "11", }, { // MCOPY 0xFFFFFFFFFFFF 0 0 - copy zero bytes from start of mem to out-of-bounds. 0xFFFFFFFFFFFF, 0, 0, "11", "11", }, { // MCOPY 0 0xFFFFFFFFFFFF 0 - copy zero bytes from out-of-bounds to start of mem 0, 0xFFFFFFFFFFFF, 0, "11", "11", }, } { m := NewMemory() // Clean spaces data := common.FromHex(strings.ReplaceAll(tc.pre, " ", "")) // Set pre m.Resize(uint64(len(data))) m.Set(0, uint64(len(data)), data) // Do the copy m.Copy(tc.dst, tc.src, tc.len) want := common.FromHex(strings.ReplaceAll(tc.want, " ", "")) if have := m.store; !bytes.Equal(want, have) { t.Errorf("case %d: want: %#x\nhave: %#x\n", i, want, have) } } }