Skip to content

Commit

Permalink
FIX: bug in TrieKeyAdaptor swapLastByte (hyperledger#13)
Browse files Browse the repository at this point in the history
swapLastByte did not take properly into account the last byte of a UInt256.
Also, the UInt256 is reversed to littleEndian as part of the routine.
More tests have been included for contract code chunking.

Signed-off-by: Thomas Zamojski <[email protected]>
Signed-off-by: Dragan Pilipovic <[email protected]>
  • Loading branch information
thomas-quadratic authored and dragan2234 committed Jan 22, 2024
1 parent 8a097ea commit 621e772
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ public TrieKeyAdapter(Hasher hasher) {
* @param subIndex The subIndex.
* @return The modified key.
*/
Bytes32 swapLastByte(Bytes32 base, Bytes subIndex) {
return (Bytes32) Bytes.concatenate(base.slice(0, 31), subIndex);
Bytes32 swapLastByte(Bytes32 base, UInt256 subIndex) {
Bytes lastByte = Bytes.of(subIndex.toBytes().reverse().get(0));
return (Bytes32) Bytes.concatenate(base.slice(0, 31), lastByte);
}

/**
Expand All @@ -77,7 +78,7 @@ public Bytes32 storageKey(Bytes address, Bytes32 storageKey) {
((index.compareTo(headerOffset) < 0) ? HEADER_STORAGE_OFFSET : MAIN_STORAGE_OFFSET);
UInt256 pos = offset.add(index);
Bytes32 base = hasher.trieKeyHash(address, pos.divide(VERKLE_NODE_WIDTH));
Bytes32 key = swapLastByte(base, pos.mod(VERKLE_NODE_WIDTH).toMinimalBytes());
Bytes32 key = swapLastByte(base, pos.mod(VERKLE_NODE_WIDTH));
return key;
}

Expand All @@ -88,7 +89,7 @@ public Bytes32 storageKey(Bytes address, Bytes32 storageKey) {
* @param chunkId The chunk ID.
* @return The generated code chunk key.
*/
public Bytes32 codeChunkKey(Bytes address, long chunkId) {
public Bytes32 codeChunkKey(Bytes address, int chunkId) {
return codeChunkKey(address, UInt256.valueOf(chunkId));
}

Expand All @@ -102,7 +103,7 @@ public Bytes32 codeChunkKey(Bytes address, long chunkId) {
public Bytes32 codeChunkKey(Bytes address, UInt256 chunkId) {
UInt256 pos = CODE_OFFSET.add(chunkId);
Bytes32 base = hasher.trieKeyHash(address, pos.divide(VERKLE_NODE_WIDTH).toBytes());
Bytes32 key = swapLastByte(base, pos.mod(VERKLE_NODE_WIDTH).toMinimalBytes());
Bytes32 key = swapLastByte(base, pos.mod(VERKLE_NODE_WIDTH));
return key;
}

Expand All @@ -115,7 +116,7 @@ public Bytes32 codeChunkKey(Bytes address, UInt256 chunkId) {
*/
Bytes32 headerKey(Bytes address, UInt256 leafKey) {
Bytes32 base = hasher.trieKeyHash(address, UInt256.valueOf(0).toBytes());
Bytes32 key = swapLastByte(base, leafKey.toBytes().slice(31));
Bytes32 key = swapLastByte(base, leafKey);
return key;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import static org.assertj.core.api.Assertions.assertThat;

import org.hyperledger.besu.ethereum.trie.verkle.adapter.TrieKeyAdapter;
import org.hyperledger.besu.ethereum.trie.verkle.hasher.SHA256Hasher;
import org.hyperledger.besu.ethereum.trie.verkle.hasher.PedersenHasher;

import java.io.IOException;
import java.io.InputStream;
Expand All @@ -36,14 +36,14 @@

public class TrieKeyAdapterTest {
Bytes address = Bytes.fromHexString("0x00112233445566778899aabbccddeeff00112233");
TrieKeyAdapter adapter = new TrieKeyAdapter(new SHA256Hasher());
TrieKeyAdapter adapter = new TrieKeyAdapter(new PedersenHasher());

@Test
public void testStorageKey() {
UInt256 storageKey = UInt256.valueOf(32);
// Need to change this once commit is fixed
Bytes32 expected =
Bytes32.fromHexString("0x1719aec0fd8358bc50c95799bd3cd38da48f6519f78d64ccb2546f554d80a060");
Bytes32.fromHexString("0xc224b9edaff18b27ce2604ad0f33a162d19840fd25290436dedcce42ad15d260");
assertThat(adapter.storageKey(address, storageKey)).isEqualTo(expected);
}

Expand All @@ -52,65 +52,75 @@ public void testCodeChunkKey() {
UInt256 chunkId = UInt256.valueOf(24);
// Need to change this once commit is fixed
Bytes32 expected =
Bytes32.fromHexString("0x1719aec0fd8358bc50c95799bd3cd38da48f6519f78d64ccb2546f554d80a098");
Bytes32.fromHexString("0xc224b9edaff18b27ce2604ad0f33a162d19840fd25290436dedcce42ad15d298");
assertThat(adapter.codeChunkKey(address, chunkId)).isEqualTo(expected);
}

@Test
public void testCodeChunkKey2() {
Bytes addr = Bytes.fromHexString("0x6f22ffbc56eff051aecf839396dd1ed9ad6bba9d");
UInt256 chunkId =
UInt256.fromHexString("0x0000000000000000000000000000000000000000000000000000000000000080");
Bytes32 expected =
Bytes32.fromHexString("0x07361aa490296db032a91d3a5a69d3c3ef0e477baf8fced7f6775e4739614200");
assertThat(adapter.codeChunkKey(addr, chunkId)).isEqualTo(expected);
}

@Test
public void testVersionKey() {
// Need to change this once commit is fixed
Bytes32 expected =
Bytes32.fromHexString("0x1719aec0fd8358bc50c95799bd3cd38da48f6519f78d64ccb2546f554d80a000");
Bytes32.fromHexString("0xc224b9edaff18b27ce2604ad0f33a162d19840fd25290436dedcce42ad15d200");
assertThat(adapter.versionKey(address)).isEqualTo(expected);
}

@Test
public void testBalanceKey() {
// Need to change this once commit is fixed
Bytes32 expected =
Bytes32.fromHexString("0x1719aec0fd8358bc50c95799bd3cd38da48f6519f78d64ccb2546f554d80a001");
Bytes32.fromHexString("0xc224b9edaff18b27ce2604ad0f33a162d19840fd25290436dedcce42ad15d201");
assertThat(adapter.balanceKey(address)).isEqualTo(expected);
}

@Test
public void testNonceKey() {
// Need to change this once commit is fixed
Bytes32 expected =
Bytes32.fromHexString("0x1719aec0fd8358bc50c95799bd3cd38da48f6519f78d64ccb2546f554d80a002");
Bytes32.fromHexString("0xc224b9edaff18b27ce2604ad0f33a162d19840fd25290436dedcce42ad15d202");
assertThat(adapter.nonceKey(address)).isEqualTo(expected);
}

@Test
public void testCodeKeccakKey() {
// Need to change this once commit is fixed
Bytes32 expected =
Bytes32.fromHexString("0x1719aec0fd8358bc50c95799bd3cd38da48f6519f78d64ccb2546f554d80a003");
Bytes32.fromHexString("0xc224b9edaff18b27ce2604ad0f33a162d19840fd25290436dedcce42ad15d203");
assertThat(adapter.codeKeccakKey(address)).isEqualTo(expected);
}

@Test
public void testCodeSizeKey() {
// Need to change this once commit is fixed
Bytes32 expected =
Bytes32.fromHexString("0x1719aec0fd8358bc50c95799bd3cd38da48f6519f78d64ccb2546f554d80a004");
Bytes32.fromHexString("0xc224b9edaff18b27ce2604ad0f33a162d19840fd25290436dedcce42ad15d204");
assertThat(adapter.codeSizeKey(address)).isEqualTo(expected);
}

private static final ObjectMapper objectMapper = new ObjectMapper();

public static List<TestData> JsonData() throws IOException {
InputStream inputStream = TrieKeyAdapterTest.class.getResourceAsStream("/erc20CodeChunks.json");
return objectMapper.readValue(inputStream, new TypeReference<List<TestData>>() {});
public static List<TestChunkifyData> JsonChunkifyData() throws IOException {
InputStream inputStream = TrieKeyAdapterTest.class.getResourceAsStream("/chunkifyCode.json");
return objectMapper.readValue(inputStream, new TypeReference<List<TestChunkifyData>>() {});
}

static class TestData {
static class TestChunkifyData {
public String bytecode;
public ArrayList<String> chunks;
}

@ParameterizedTest
@MethodSource("JsonData")
public void TestChunkifyCode(TestData testData) {
@MethodSource("JsonChunkifyData")
public void TestChunkifyCode(TestChunkifyData testData) {
Bytes bytecode = Bytes.fromHexString(testData.bytecode);
List<Bytes32> result = adapter.chunkifyCode(bytecode);
assertThat(testData.chunks.size()).isEqualTo(result.size());
Expand All @@ -123,4 +133,37 @@ public void TestChunkifyCode(TestData testData) {
// expected.add(value);
}
}

static class KeyValueData {
public String key;
public String value;
}

static class TestCodeData {
public String address;
public String bytecode;
public ArrayList<KeyValueData> chunks;
}

public static List<TestCodeData> JsonContractCodeData() throws IOException {
InputStream inputStream = TrieKeyAdapterTest.class.getResourceAsStream("/contractCode.json");
return objectMapper.readValue(inputStream, new TypeReference<List<TestCodeData>>() {});
}

@ParameterizedTest
@MethodSource("JsonContractCodeData")
public void TestContractCode(TestCodeData testData) {
Bytes addr = Bytes.fromHexString(testData.address);
Bytes bytecode = Bytes.fromHexString(testData.bytecode);
List<Bytes32> chunks = adapter.chunkifyCode(bytecode);
assertThat(chunks.size()).as("Same number of chunks").isEqualTo(testData.chunks.size());
for (int i = 0; i < chunks.size(); ++i) {
Bytes32 key = adapter.codeChunkKey(addr, UInt256.valueOf(i));
Bytes32 expectedKey = Bytes32.fromHexString(testData.chunks.get(i).key);
assertThat(key).as(String.format("Key %s", i)).isEqualTo(expectedKey);
Bytes32 value = chunks.get(i);
Bytes32 expectedValue = Bytes32.fromHexString(testData.chunks.get(i).value);
assertThat(value).as(String.format("Value %s", i)).isEqualTo(expectedValue);
}
}
}
File renamed without changes.
53 changes: 53 additions & 0 deletions src/test/resources/contractCode.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
[
{
"address": "0x2a97e18168654393a573599759104efdfec6d8bd",
"bytecode": "0x608060405234801561000f575f80fd5b5060043610610034575f3560e01c80632e64cec1146100385780636057361d14610056575b5f80fd5b610040610072565b60405161004d919061029a565b60405180910390f35b610070600480360381019061006b91906102e1565b61019c565b005b5f8060405161008090610275565b604051809103905ff080158015610099573d5f803e3d5ffd5b5090505f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632e64cec16040518163ffffffff1660e01b8152600401602060405180830381865afa158015610107573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061012b9190610320565b90508173ffffffffffffffffffffffffffffffffffffffff16636057361d826040518263ffffffff1660e01b8152600401610166919061029a565b5f604051808303815f87803b15801561017d575f80fd5b505af115801561018f573d5f803e3d5ffd5b505050505f549250505090565b805f819055505f6040516101af90610275565b604051809103905ff0801580156101c8573d5f803e3d5ffd5b5090508073ffffffffffffffffffffffffffffffffffffffff16636057361d836040518263ffffffff1660e01b8152600401610204919061029a565b5f604051808303815f87803b15801561021b575f80fd5b505af115801561022d573d5f803e3d5ffd5b505050508060015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6101e38061034c83390190565b5f819050919050565b61029481610282565b82525050565b5f6020820190506102ad5f83018461028b565b92915050565b5f80fd5b6102c081610282565b81146102ca575f80fd5b50565b5f813590506102db816102b7565b92915050565b5f602082840312156102f6576102f56102b3565b5b5f610303848285016102cd565b91505092915050565b5f8151905061031a816102b7565b92915050565b5f60208284031215610335576103346102b3565b5b5f6103428482850161030c565b9150509291505056fe608060405234801561000f575f80fd5b506101c68061001d5f395ff3fe60806040526004361061003e575f3560e01c80632711432d146100425780632e64cec11461006c5780636057361d14610096578063d64c8ca4146100be575b5f80fd5b34801561004d575f80fd5b506100566100c8565b604051610063919061011e565b60405180910390f35b348015610077575f80fd5b506100806100d1565b60405161008d919061011e565b60405180910390f35b3480156100a1575f80fd5b506100bc60048036038101906100b79190610165565b6100d9565b005b6100c66100e9565b005b5f600154905090565b5f8054905090565b805f819055508060018190555050565b5f3390508073ffffffffffffffffffffffffffffffffffffffff16ff5b5f819050919050565b61011881610106565b82525050565b5f6020820190506101315f83018461010f565b92915050565b5f80fd5b61014481610106565b811461014e575f80fd5b50565b5f8135905061015f8161013b565b92915050565b5f6020828403121561017a57610179610137565b5b5f61018784828501610151565b9150509291505056fea2646970667358221220dc349a9524617af5742ac60346440c0d09b175e4d9c4d95e378a9652cb9acbb064736f6c63430008160033a264697066735822122079744fe4f745783dffcec2415a6b99b8b7b340bcf4a768d5563f00d2ec1f916b64736f6c63430008160033",
"chunks": [
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b80", "value":"0x00608060405234801561000f575f80fd5b5060043610610034575f3560e01c80"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b81", "value":"0x00632e64cec1146100385780636057361d14610056575b5f80fd5b6100406100"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b82", "value":"0x0172565b60405161004d919061029a565b60405180910390f35b610070600480"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b83", "value":"0x00360381019061006b91906102e1565b61019c565b005b5f8060405161008090"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b84", "value":"0x00610275565b604051809103905ff080158015610099573d5f803e3d5ffd5b50"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b85", "value":"0x0090505f60015f9054906101000a900473ffffffffffffffffffffffffffffff"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b86", "value":"0x05ffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632e64"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b87", "value":"0x02cec16040518163ffffffff1660e01b8152600401602060405180830381865a"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b88", "value":"0x00fa158015610107573d5f803e3d5ffd5b505050506040513d601f19601f8201"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b89", "value":"0x00168201806040525081019061012b9190610320565b90508173ffffffffffff"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b8a", "value":"0x0effffffffffffffffffffffffffff16636057361d826040518263ffffffff16"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b8b", "value":"0x0060e01b8152600401610166919061029a565b5f604051808303815f87803b15"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b8c", "value":"0x00801561017d575f80fd5b505af115801561018f573d5f803e3d5ffd5b505050"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b8d", "value":"0x00505f549250505090565b805f819055505f6040516101af90610275565b6040"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b8e", "value":"0x0051809103905ff0801580156101c8573d5f803e3d5ffd5b5090508073ffffff"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b8f", "value":"0x11ffffffffffffffffffffffffffffffffff16636057361d836040518263ffff"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b90", "value":"0x02ffff1660e01b8152600401610204919061029a565b5f604051808303815f87"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b91", "value":"0x00803b15801561021b575f80fd5b505af115801561022d573d5f803e3d5ffd5b"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b92", "value":"0x00505050508060015f6101000a81548173ffffffffffffffffffffffffffffff"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b93", "value":"0x05ffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b94", "value":"0x001602179055505050565b6101e38061034c83390190565b5f81905091905056"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b95", "value":"0x005b61029481610282565b82525050565b5f6020820190506102ad5f83018461"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b96", "value":"0x02028b565b92915050565b5f80fd5b6102c081610282565b81146102ca575f80"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b97", "value":"0x00fd5b50565b5f813590506102db816102b7565b92915050565b5f6020828403"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b98", "value":"0x0012156102f6576102f56102b3565b5b5f610303848285016102cd565b915050"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b99", "value":"0x0092915050565b5f8151905061031a816102b7565b92915050565b5f60208284"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b9a", "value":"0x00031215610335576103346102b3565b5b5f6103428482850161030c565b9150"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b9b", "value":"0x00509291505056fe608060405234801561000f575f80fd5b506101c68061001d"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b9c", "value":"0x005f395ff3fe60806040526004361061003e575f3560e01c80632711432d1461"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b9d", "value":"0x0200425780632e64cec11461006c5780636057361d14610096578063d64c8ca4"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b9e", "value":"0x00146100be575b5f80fd5b34801561004d575f80fd5b506100566100c8565b60"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b9f", "value":"0x014051610063919061011e565b60405180910390f35b348015610077575f80fd"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09ba0", "value":"0x005b506100806100d1565b60405161008d919061011e565b60405180910390f3"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09ba1", "value":"0x005b3480156100a1575f80fd5b506100bc60048036038101906100b791906101"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09ba2", "value":"0x0165565b6100d9565b005b6100c66100e9565b005b5f600154905090565b5f80"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09ba3", "value":"0x0054905090565b805f819055508060018190555050565b5f3390508073ffffff"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09ba4", "value":"0x11ffffffffffffffffffffffffffffffffff16ff5b5f819050919050565b6101"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09ba5", "value":"0x011881610106565b82525050565b5f6020820190506101315f83018461010f56"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09ba6", "value":"0x005b92915050565b5f80fd5b61014481610106565b811461014e575f80fd5b50"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09ba7", "value":"0x00565b5f8135905061015f8161013b565b92915050565b5f6020828403121561"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09ba8", "value":"0x02017a57610179610137565b5b5f61018784828501610151565b915050929150"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09ba9", "value":"0x005056fea2646970667358221220dc349a9524617af5742ac60346440c0d09b1"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09baa", "value":"0x0c75e4d9c4d95e378a9652cb9acbb064736f6c63430008160033a26469706673"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09bab", "value":"0x015822122079744fe4f745783dffcec2415a6b99b8b7b340bcf4a768d5563f00"},
{"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09bac", "value":"0x00d2ec1f916b64736f6c63430008160033000000000000000000000000000000"}
]
}
]

0 comments on commit 621e772

Please sign in to comment.