|
12 | 12 | */ |
13 | 13 | package net.consensys.shomei; |
14 | 14 |
|
15 | | -// import static net.consensys.shomei.util.TestFixtureGenerator.getContractStorageTrie; |
16 | | -// import static net.consensys.shomei.util.bytes.MimcSafeBytes.safeUInt256; |
17 | | -// import static org.assertj.core.api.Assertions.assertThat; |
18 | | -// |
19 | | -// import org.hyperledger.besu.datatypes.Hash; |
20 | | -// import org.hyperledger.besu.datatypes.StorageSlotKey; |
21 | | -// import org.hyperledger.besu.ethereum.rlp.RLP; |
22 | | -// import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; |
23 | | -// |
24 | | -// import net.consensys.shomei.exception.MissingTrieLogException; |
25 | | -// import net.consensys.shomei.storage.ZkWorldStateArchive; |
26 | | -// import net.consensys.shomei.trie.ZKTrie; |
27 | | -// import net.consensys.shomei.trielog.TrieLogLayer; |
28 | | -// import net.consensys.shomei.trielog.TrieLogLayerConverter; |
29 | | -// import net.consensys.shomei.util.TestFixtureGenerator; |
30 | | -// import net.consensys.shomei.util.bytes.MimcSafeBytes; |
31 | | -// import org.apache.tuweni.bytes.Bytes; |
32 | | -// import org.apache.tuweni.bytes.Bytes32; |
33 | | -// import org.apache.tuweni.units.bigints.UInt256; |
34 | | -// import org.junit.Test; |
35 | | - |
36 | | -@SuppressWarnings("unused") |
| 15 | +import static net.consensys.shomei.util.TestFixtureGenerator.getContractStorageTrie; |
| 16 | +import static net.consensys.shomei.util.bytes.PoseidonSafeBytesUtils.safeUInt256; |
| 17 | +import static org.assertj.core.api.Assertions.assertThat; |
| 18 | + |
| 19 | +import org.hyperledger.besu.datatypes.Hash; |
| 20 | +import org.hyperledger.besu.datatypes.StorageSlotKey; |
| 21 | +import org.hyperledger.besu.datatypes.Wei; |
| 22 | +import org.hyperledger.besu.ethereum.rlp.RLP; |
| 23 | +import org.hyperledger.besu.ethereum.trie.common.PmtStateTrieAccountValue; |
| 24 | + |
| 25 | +import net.consensys.shomei.context.ShomeiContext; |
| 26 | +import net.consensys.shomei.storage.InMemoryStorageProvider; |
| 27 | +import net.consensys.shomei.storage.StorageProvider; |
| 28 | +import net.consensys.shomei.storage.ZkWorldStateArchive; |
| 29 | +import net.consensys.shomei.storage.worldstate.InMemoryWorldStateStorage; |
| 30 | +import net.consensys.shomei.storage.worldstate.WorldStateStorage; |
| 31 | +import net.consensys.shomei.trie.ZKTrie; |
| 32 | +import net.consensys.shomei.trie.storage.InMemoryStorage; |
| 33 | +import net.consensys.shomei.trielog.TrieLogLayer; |
| 34 | +import net.consensys.shomei.trielog.TrieLogLayerConverter; |
| 35 | +import net.consensys.shomei.trielog.ZkTrieLogFactory; |
| 36 | +import net.consensys.shomei.util.TestFixtureGenerator; |
| 37 | +import net.consensys.shomei.util.bytes.PoseidonSafeBytes; |
| 38 | +import org.apache.tuweni.bytes.Bytes; |
| 39 | +import org.apache.tuweni.bytes.Bytes32; |
| 40 | +import org.apache.tuweni.units.bigints.UInt256; |
| 41 | +import org.junit.jupiter.api.Test; |
| 42 | + |
37 | 43 | public class TrieLogShippingTests { |
38 | | - /* |
39 | | - // TODO activate when ZkTrieLogFactoryImpl will be available |
40 | | - @Test |
41 | | - public void testTrielogShippingWithNewContractUpdate() throws MissingTrieLogException { |
42 | 44 |
|
43 | | - ZKTrie accountStateTrieOne = |
44 | | - ZKTrie.createTrie(new WorldStateStorageProxy(new InMemoryWorldStateStorage())); |
| 45 | + @Test |
| 46 | + public void testTrielogShippingWithNewContractUpdate() { |
| 47 | + // Initialize in-memory storage and state trie |
| 48 | + final InMemoryStorage storage = new InMemoryStorage(); |
| 49 | + ZKTrie accountStateTrie = ZKTrie.createTrie(storage); |
45 | 50 |
|
46 | | - // add contract with storage |
| 51 | + // Create a contract with initial storage |
47 | 52 | MutableZkAccount contract = TestFixtureGenerator.getAccountTwo(); |
48 | | - StorageSlotKey storageSlotKey = new StorageSlotKey(UInt256.valueOf(14)); |
49 | | - MimcSafeBytes<UInt256> slotValue = safeUInt256(UInt256.valueOf(12)); |
| 53 | + PoseidonSafeBytes<UInt256> slotKey = safeUInt256(UInt256.valueOf(14)); |
| 54 | + PoseidonSafeBytes<UInt256> slotValue = safeUInt256(UInt256.valueOf(12)); |
50 | 55 | ZKTrie contractStorageTrie = getContractStorageTrie(contract); |
51 | | - contractStorageTrie.putAndProve(storageSlotKey.slotHash(), storageSlotKey.slotKey(), slotValue); |
52 | | - contract.setStorageRoot(Hash.wrap(contractStorageTrie.getTopRootHash())); |
53 | 56 |
|
54 | | - accountStateTrieOne.putAndProve( |
| 57 | + // Update contract storage and state trie |
| 58 | + contractStorageTrie.putWithTrace(slotKey.hash(), slotKey, slotValue); |
| 59 | + contract.setStorageRoot(Hash.wrap(contractStorageTrie.getTopRootHash())); |
| 60 | + accountStateTrie.putWithTrace( |
55 | 61 | contract.getHkey(), contract.getAddress(), contract.getEncodedBytes()); |
56 | 62 |
|
57 | | - Hash topRootHashBeforeUpdate = Hash.wrap(accountStateTrieOne.getTopRootHash()); |
| 63 | + // Save the root hash before updating the storage |
| 64 | + Hash topRootHashBeforeUpdate = Hash.wrap(accountStateTrie.getTopRootHash()); |
58 | 65 |
|
59 | | - // change storage |
60 | | - final MimcSafeBytes<UInt256> newStorageValue = safeUInt256(UInt256.valueOf(22)); |
61 | | - contractStorageTrie.putAndProve( |
62 | | - storageSlotKey.slotHash(), storageSlotKey.slotKey(), newStorageValue); |
| 66 | + // Update storage with new value |
| 67 | + final PoseidonSafeBytes<UInt256> newStorageValue = safeUInt256(UInt256.valueOf(22)); |
| 68 | + contractStorageTrie.putWithTrace(slotKey.hash(), slotKey, newStorageValue); |
63 | 69 | contract.setStorageRoot(Hash.wrap(contractStorageTrie.getTopRootHash())); |
64 | | - accountStateTrieOne.putAndProve( |
| 70 | + accountStateTrie.putWithTrace( |
65 | 71 | contract.getHkey(), contract.getAddress(), contract.getEncodedBytes()); |
66 | 72 |
|
67 | | - Hash topRootHashAfterUpdate = Hash.wrap(accountStateTrieOne.getTopRootHash()); |
| 73 | + // Save the root hash after updating the storage |
| 74 | + Hash topRootHashAfterUpdate = Hash.wrap(accountStateTrie.getTopRootHash()); |
68 | 75 |
|
69 | | - // simulate trielog from Besu before update |
70 | | - org.hyperledger.besu.ethereum.bonsai.trielog.TrieLogLayer trieLogLayer = |
71 | | - new org.hyperledger.besu.ethereum.bonsai.trielog.TrieLogLayer(); |
72 | | - trieLogLayer.addAccountChange( |
| 76 | + // Simulate TrieLogLayer from Besu before the update |
| 77 | + org.hyperledger.besu.ethereum.trie.pathbased.common.trielog.TrieLogLayer trieLogLayerBefore = |
| 78 | + new org.hyperledger.besu.ethereum.trie.pathbased.common.trielog.TrieLogLayer(); |
| 79 | + trieLogLayerBefore.addAccountChange( |
73 | 80 | contract.getAddress().getOriginalUnsafeValue(), |
74 | 81 | null, |
75 | | - new StateTrieAccountValue( |
76 | | - contract.nonce.toLong(), |
77 | | - contract.balance, |
78 | | - Hash.wrap( |
79 | | - Bytes32.random()), // change storage root to simulate evm storage root sent by Besu |
| 82 | + new PmtStateTrieAccountValue( |
| 83 | + contract.nonce.getOriginalUnsafeValue().toLong(), |
| 84 | + Wei.of(contract.balance.getOriginalUnsafeValue()), |
| 85 | + Hash.wrap(Bytes32.random()), // Simulate initial storage root |
80 | 86 | Hash.wrap(contract.keccakCodeHash.getOriginalUnsafeValue()))); |
81 | | - trieLogLayer.setBlockHash(Hash.wrap(Bytes32.random())); |
82 | | - trieLogLayer.addStorageChange( |
| 87 | + trieLogLayerBefore.setBlockHash(Hash.wrap(Bytes32.random())); |
| 88 | + trieLogLayerBefore.setBlockNumber(0); |
| 89 | + trieLogLayerBefore.addStorageChange( |
83 | 90 | contract.getAddress().getOriginalUnsafeValue(), |
84 | | - new org.hyperledger.besu.ethereum.bonsai.worldview.StorageSlotKey( |
85 | | - storageSlotKey.slotKey().getOriginalUnsafeValue()), |
| 91 | + new StorageSlotKey(slotKey.getOriginalUnsafeValue()), |
86 | 92 | null, |
87 | 93 | slotValue.getOriginalUnsafeValue()); |
88 | 94 |
|
89 | | - // simulate trielog from Besu after update |
90 | | - org.hyperledger.besu.ethereum.bonsai.trielog.TrieLogLayer trieLogLayer2 = |
91 | | - new org.hyperledger.besu.ethereum.bonsai.trielog.TrieLogLayer(); |
92 | | - trieLogLayer2.addAccountChange( |
| 95 | + // Simulate TrieLogLayer from Besu after the update |
| 96 | + org.hyperledger.besu.ethereum.trie.pathbased.common.trielog.TrieLogLayer trieLogLayerAfter = |
| 97 | + new org.hyperledger.besu.ethereum.trie.pathbased.common.trielog.TrieLogLayer(); |
| 98 | + trieLogLayerAfter.addAccountChange( |
93 | 99 | contract.getAddress().getOriginalUnsafeValue(), |
94 | | - new StateTrieAccountValue( |
95 | | - contract.nonce.toLong(), |
96 | | - contract.balance, |
97 | | - Hash.wrap( |
98 | | - Bytes32.random()), // change storage root to simulate evm storage root sent by Besu |
99 | | - Hash.wrap( |
100 | | - contract.keccakCodeHash |
101 | | - .getOriginalUnsafeValue())), // get update of the first trielog |
102 | | - new StateTrieAccountValue( |
103 | | - contract.nonce.toLong(), |
104 | | - contract.balance, |
105 | | - Hash.wrap( |
106 | | - Bytes32.random()), // change storage root to simulate evm storage root sent by Besu |
| 100 | + new PmtStateTrieAccountValue( |
| 101 | + contract.nonce.getOriginalUnsafeValue().toLong(), |
| 102 | + Wei.of(contract.balance.getOriginalUnsafeValue()), |
| 103 | + Hash.wrap(Bytes32.random()), // Simulate updated storage root |
| 104 | + Hash.wrap(contract.keccakCodeHash.getOriginalUnsafeValue())), |
| 105 | + new PmtStateTrieAccountValue( |
| 106 | + contract.nonce.getOriginalUnsafeValue().toLong(), |
| 107 | + Wei.of(contract.balance.getOriginalUnsafeValue()), |
| 108 | + Hash.wrap(Bytes32.random()), // Simulate further storage root update |
107 | 109 | Hash.wrap(contract.keccakCodeHash.getOriginalUnsafeValue()))); |
108 | | - trieLogLayer2.setBlockHash(Hash.wrap(Bytes32.random())); |
109 | | - trieLogLayer2.addStorageChange( |
| 110 | + trieLogLayerAfter.setBlockHash(Hash.wrap(Bytes32.random())); |
| 111 | + trieLogLayerAfter.setBlockNumber(1); |
| 112 | + trieLogLayerAfter.addStorageChange( |
110 | 113 | contract.getAddress().getOriginalUnsafeValue(), |
111 | | - new org.hyperledger.besu.ethereum.bonsai.worldview.StorageSlotKey( |
112 | | - storageSlotKey.slotKey().getOriginalUnsafeValue()), |
| 114 | + new StorageSlotKey(slotKey.getOriginalUnsafeValue()), |
113 | 115 | slotValue.getOriginalUnsafeValue(), |
114 | 116 | newStorageValue.getOriginalUnsafeValue()); |
115 | 117 |
|
116 | | - ZkTrieLogFactoryImpl zkTrieLogFactory = new ZkTrieLogFactoryImpl(); |
117 | | -
|
118 | | - // init the worldstate entrypoint with empty worldstate |
119 | | - InMemoryWorldStateStorage storage = new InMemoryWorldStateStorage(); |
120 | | - ZkWorldStateArchive evmWorldStateEntryPoint = new ZkWorldStateArchive(storage); |
121 | | - assertThat(evmWorldStateEntryPoint.getCurrentRootHash()).isEqualTo(ZKTrie.EMPTY_TRIE_ROOT); |
122 | | -
|
123 | | - // decode trielog from Besu |
124 | | - TrieLogLayer decodedLayer = |
125 | | - new TrieLogLayerConverter(storage) |
126 | | - .decodeTrieLog(RLP.input(Bytes.wrap(zkTrieLogFactory.serialize(trieLogLayer)))); |
127 | | -
|
128 | | - // move head with the new trielog |
129 | | - evmWorldStateEntryPoint.applyTrieLog(0, decodedLayer); |
130 | | - assertThat(evmWorldStateEntryPoint.getCurrentRootHash()).isEqualTo(topRootHashBeforeUpdate); |
131 | | -
|
132 | | - // decode second trielog from Besu |
133 | | - TrieLogLayer decodedLayer2 = |
134 | | - new TrieLogLayerConverter(storage) |
135 | | - .decodeTrieLog(RLP.input(Bytes.wrap(zkTrieLogFactory.serialize(trieLogLayer2)))); |
136 | | -
|
137 | | - // move head with the second trielog |
138 | | - evmWorldStateEntryPoint.applyTrieLog(1, decodedLayer2); |
139 | | - assertThat(evmWorldStateEntryPoint.getCurrentRootHash()).isEqualTo(topRootHashAfterUpdate); |
| 118 | + // Initialize the ShomeiContext and world state entry point |
| 119 | + ZkTrieLogFactory zkTrieLogFactory = |
| 120 | + new ZkTrieLogFactory(ShomeiContext.ShomeiContextImpl.getOrCreate()); |
| 121 | + InMemoryWorldStateStorage worldStateStorage = new InMemoryWorldStateStorage(); |
| 122 | + StorageProvider inMemoryStorageProvider = |
| 123 | + new InMemoryStorageProvider() { |
| 124 | + @Override |
| 125 | + public WorldStateStorage getWorldStateStorage() { |
| 126 | + return worldStateStorage; |
| 127 | + } |
| 128 | + }; |
| 129 | + |
| 130 | + ZkWorldStateArchive worldStateArchive = new ZkWorldStateArchive(inMemoryStorageProvider); |
| 131 | + |
| 132 | + // Verify initial world state matches the default state root hash |
| 133 | + assertThat(worldStateArchive.getHeadWorldState().getStateRootHash()) |
| 134 | + .isEqualTo(ZKTrie.DEFAULT_TRIE_ROOT); |
| 135 | + |
| 136 | + // Decode and apply TrieLogLayer before the update |
| 137 | + TrieLogLayer decodedLayerBefore = |
| 138 | + new TrieLogLayerConverter(inMemoryStorageProvider.getWorldStateStorage()) |
| 139 | + .decodeTrieLog(RLP.input(Bytes.wrap(zkTrieLogFactory.serialize(trieLogLayerBefore)))); |
| 140 | + worldStateArchive.applyTrieLog(0, false, decodedLayerBefore); |
| 141 | + |
| 142 | + // Assert world state root matches before update |
| 143 | + assertThat(worldStateArchive.getHeadWorldState().getStateRootHash()) |
| 144 | + .isEqualTo(topRootHashBeforeUpdate); |
| 145 | + |
| 146 | + // Decode and apply TrieLogLayer after the update |
| 147 | + TrieLogLayer decodedLayerAfter = |
| 148 | + new TrieLogLayerConverter(inMemoryStorageProvider.getWorldStateStorage()) |
| 149 | + .decodeTrieLog(RLP.input(Bytes.wrap(zkTrieLogFactory.serialize(trieLogLayerAfter)))); |
| 150 | + worldStateArchive.applyTrieLog(1, false, decodedLayerAfter); |
| 151 | + |
| 152 | + // Assert world state root matches after update |
| 153 | + assertThat(worldStateArchive.getHeadWorldState().getStateRootHash()) |
| 154 | + .isEqualTo(topRootHashAfterUpdate); |
140 | 155 | } |
141 | | - */ |
142 | 156 | } |
0 commit comments