github.com/ledgerwatch/erigon-lib@v1.0.0/commitment/bin_patricia_hashed_test.go (about) 1 package commitment 2 3 import ( 4 "encoding/hex" 5 "fmt" 6 "testing" 7 8 "github.com/stretchr/testify/require" 9 "golang.org/x/exp/slices" 10 11 "github.com/ledgerwatch/erigon-lib/common/length" 12 ) 13 14 func Test_BinPatriciaTrie_UniqueRepresentation(t *testing.T) { 15 t.Skip() 16 17 ms := NewMockState(t) 18 ms2 := NewMockState(t) 19 20 trie := NewBinPatriciaHashed(length.Addr, ms.branchFn, ms.accountFn, ms.storageFn) 21 trieBatch := NewBinPatriciaHashed(length.Addr, ms2.branchFn, ms2.accountFn, ms2.storageFn) 22 23 plainKeys, hashedKeys, updates := NewUpdateBuilder(). 24 Balance("e25652aaa6b9417973d325f9a1246b48ff9420bf", 12). 25 Balance("cdd0a12034e978f7eccda72bd1bd89a8142b704e", 120000). 26 Balance("5bb6abae12c87592b940458437526cb6cad60d50", 170). 27 Nonce("5bb6abae12c87592b940458437526cb6cad60d50", 152512). 28 Balance("2fcb355beb0ea2b5fcf3b62a24e2faaff1c8d0c0", 100000). 29 Balance("463510be61a7ccde354509c0ab813e599ee3fc8a", 200000). 30 Balance("cd3e804beea486038609f88f399140dfbe059ef3", 200000). 31 Storage("cd3e804beea486038609f88f399140dfbe059ef3", "01023402", "98"). 32 Balance("82c88c189d5deeba0ad11463b80b44139bd519c1", 300000). 33 Balance("0647e43e8f9ba3fb8b14ad30796b7553d667c858", 400000). 34 Delete("cdd0a12034e978f7eccda72bd1bd89a8142b704e"). 35 Balance("06548d648c23b12f2e9bfd1bae274b658be208f4", 500000). 36 Balance("e5417f49640cf8a0b1d6e38f9dfdc00196e99e8b", 600000). 37 Nonce("825ac9fa5d015ec7c6b4cbbc50f78d619d255ea7", 184). 38 Build() 39 40 ms.applyPlainUpdates(plainKeys, updates) 41 ms2.applyPlainUpdates(plainKeys, updates) 42 43 fmt.Println("1. Running sequential updates over the bin trie") 44 var seqHash []byte 45 for i := 0; i < len(updates); i++ { 46 sh, branchNodeUpdates, err := trie.ReviewKeys(plainKeys[i:i+1], hashedKeys[i:i+1]) 47 require.NoError(t, err) 48 require.Len(t, sh, length.Hash) 49 ms.applyBranchNodeUpdates(branchNodeUpdates) 50 // WARN! provided sequential branch updates are incorrect - lead to deletion of prefixes (afterMap is zero) 51 // while root hashes are equal 52 renderUpdates(branchNodeUpdates) 53 54 fmt.Printf("h=%x\n", sh) 55 seqHash = sh 56 } 57 58 fmt.Println("2. Running batch updates over the bin trie") 59 60 batchHash, branchBatchUpdates, err := trieBatch.ReviewKeys(plainKeys, hashedKeys) 61 require.NoError(t, err) 62 ms2.applyBranchNodeUpdates(branchBatchUpdates) 63 64 renderUpdates(branchBatchUpdates) 65 66 require.EqualValues(t, seqHash, batchHash) 67 // require.EqualValues(t, seqHash, batchHash) 68 69 // expectedHash, _ := hex.DecodeString("3ed2b89c0f9c6ebc7fa11a181baac21aa0236b12bb4492c708562cb3e40c7c9e") 70 // require.EqualValues(t, expectedHash, seqHash) 71 } 72 73 func renderUpdates(branchNodeUpdates map[string]BranchData) { 74 keys := make([]string, 0, len(branchNodeUpdates)) 75 for key := range branchNodeUpdates { 76 keys = append(keys, key) 77 } 78 slices.Sort(keys) 79 for _, key := range keys { 80 branchNodeUpdate := branchNodeUpdates[key] 81 fmt.Printf("%x => %s\n", CompactedKeyToHex([]byte(key)), branchNodeUpdate.String()) 82 } 83 } 84 85 func Test_BinPatriciaHashed_UniqueRepresentation(t *testing.T) { 86 t.Skip() 87 88 ms := NewMockState(t) 89 ms2 := NewMockState(t) 90 91 plainKeys, hashedKeys, updates := NewUpdateBuilder(). 92 Balance("f5", 4). 93 Balance("ff", 900234). 94 Balance("04", 1233). 95 Storage("04", "01", "0401"). 96 Balance("ba", 065606). 97 Balance("00", 4). 98 Balance("01", 5). 99 Balance("02", 6). 100 Balance("03", 7). 101 Storage("03", "56", "050505"). 102 Balance("05", 9). 103 Storage("03", "87", "060606"). 104 Balance("b9", 6). 105 Nonce("ff", 169356). 106 Storage("05", "02", "8989"). 107 Storage("f5", "04", "9898"). 108 Build() 109 110 trieOne := NewBinPatriciaHashed(1, ms.branchFn, ms.accountFn, ms.storageFn) 111 trieTwo := NewBinPatriciaHashed(1, ms2.branchFn, ms2.accountFn, ms2.storageFn) 112 113 trieOne.SetTrace(true) 114 trieTwo.SetTrace(true) 115 116 // single sequential update 117 roots := make([][]byte, 0) 118 // branchNodeUpdatesOne := make(map[string]BranchData) 119 fmt.Printf("1. Trie sequential update generated following branch updates\n") 120 for i := 0; i < len(updates); i++ { 121 if err := ms.applyPlainUpdates(plainKeys[i:i+1], updates[i:i+1]); err != nil { 122 t.Fatal(err) 123 } 124 125 sequentialRoot, branchNodeUpdates, err := trieOne.ReviewKeys(plainKeys[i:i+1], hashedKeys[i:i+1]) 126 require.NoError(t, err) 127 roots = append(roots, sequentialRoot) 128 129 ms.applyBranchNodeUpdates(branchNodeUpdates) 130 renderUpdates(branchNodeUpdates) 131 } 132 133 err := ms2.applyPlainUpdates(plainKeys, updates) 134 require.NoError(t, err) 135 136 fmt.Printf("\n2. Trie batch update generated following branch updates\n") 137 // batch update 138 batchRoot, branchNodeUpdatesTwo, err := trieTwo.ReviewKeys(plainKeys, hashedKeys) 139 require.NoError(t, err) 140 renderUpdates(branchNodeUpdatesTwo) 141 142 fmt.Printf("\n sequential roots:\n") 143 for i, rh := range roots { 144 fmt.Printf("%2d %+v\n", i, hex.EncodeToString(rh)) 145 } 146 147 ms2.applyBranchNodeUpdates(branchNodeUpdatesTwo) 148 149 require.EqualValues(t, batchRoot, roots[len(roots)-1], 150 "expected equal roots, got sequential [%v] != batch [%v]", hex.EncodeToString(roots[len(roots)-1]), hex.EncodeToString(batchRoot)) 151 require.Lenf(t, batchRoot, 32, "root hash length should be equal to 32 bytes") 152 } 153 func Test_BinPatriciaHashed_EmptyState(t *testing.T) { 154 ms := NewMockState(t) 155 hph := NewBinPatriciaHashed(1, ms.branchFn, ms.accountFn, ms.storageFn) 156 hph.SetTrace(false) 157 plainKeys, hashedKeys, updates := NewUpdateBuilder(). 158 Balance("00", 4). 159 Balance("01", 5). 160 Balance("02", 6). 161 Balance("03", 7). 162 Balance("04", 8). 163 Storage("04", "01", "0401"). 164 Storage("03", "56", "050505"). 165 Storage("03", "57", "060606"). 166 Balance("05", 9). 167 Storage("05", "02", "8989"). 168 Storage("05", "04", "9898"). 169 Build() 170 171 err := ms.applyPlainUpdates(plainKeys, updates) 172 require.NoError(t, err) 173 174 firstRootHash, branchNodeUpdates, err := hph.ReviewKeys(plainKeys, hashedKeys) 175 require.NoError(t, err) 176 177 t.Logf("root hash %x\n", firstRootHash) 178 179 ms.applyBranchNodeUpdates(branchNodeUpdates) 180 181 fmt.Printf("1. Generated updates\n") 182 renderUpdates(branchNodeUpdates) 183 184 // More updates 185 hph.Reset() 186 hph.SetTrace(false) 187 plainKeys, hashedKeys, updates = NewUpdateBuilder(). 188 Storage("03", "58", "050505"). 189 Build() 190 err = ms.applyPlainUpdates(plainKeys, updates) 191 require.NoError(t, err) 192 193 secondRootHash, branchNodeUpdates, err := hph.ReviewKeys(plainKeys, hashedKeys) 194 require.NoError(t, err) 195 require.NotEqualValues(t, firstRootHash, secondRootHash) 196 197 ms.applyBranchNodeUpdates(branchNodeUpdates) 198 fmt.Printf("2. Generated single update\n") 199 renderUpdates(branchNodeUpdates) 200 201 // More updates 202 hph.Reset() 203 hph.SetTrace(false) 204 plainKeys, hashedKeys, updates = NewUpdateBuilder(). 205 Storage("03", "58", "070807"). 206 Build() 207 err = ms.applyPlainUpdates(plainKeys, updates) 208 require.NoError(t, err) 209 210 thirdRootHash, branchNodeUpdates, err := hph.ReviewKeys(plainKeys, hashedKeys) 211 require.NoError(t, err) 212 require.NotEqualValues(t, secondRootHash, thirdRootHash) 213 214 ms.applyBranchNodeUpdates(branchNodeUpdates) 215 fmt.Printf("3. Generated single update\n") 216 renderUpdates(branchNodeUpdates) 217 } 218 219 func Test_BinPatriciaHashed_EmptyUpdateState(t *testing.T) { 220 ms := NewMockState(t) 221 hph := NewBinPatriciaHashed(1, ms.branchFn, ms.accountFn, ms.storageFn) 222 hph.SetTrace(false) 223 plainKeys, hashedKeys, updates := NewUpdateBuilder(). 224 Balance("00", 4). 225 Nonce("00", 246462653). 226 Balance("01", 5). 227 CodeHash("03", "aaaaaaaaaaf7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a870"). 228 Delete("00"). 229 Storage("04", "01", "0401"). 230 Storage("03", "56", "050505"). 231 Build() 232 233 err := ms.applyPlainUpdates(plainKeys, updates) 234 require.NoError(t, err) 235 236 hashBeforeEmptyUpdate, branchNodeUpdates, err := hph.ReviewKeys(plainKeys, hashedKeys) 237 require.NoError(t, err) 238 require.NotEmpty(t, hashBeforeEmptyUpdate) 239 240 ms.applyBranchNodeUpdates(branchNodeUpdates) 241 242 fmt.Println("1. Updates applied") 243 renderUpdates(branchNodeUpdates) 244 245 // generate empty updates and do NOT reset tree 246 hph.SetTrace(true) 247 248 plainKeys, hashedKeys, updates = NewUpdateBuilder().Build() 249 250 err = ms.applyPlainUpdates(plainKeys, updates) 251 require.NoError(t, err) 252 253 hashAfterEmptyUpdate, branchNodeUpdates, err := hph.ReviewKeys(plainKeys, hashedKeys) 254 require.NoError(t, err) 255 256 ms.applyBranchNodeUpdates(branchNodeUpdates) 257 fmt.Println("2. Empty updates applied without state reset") 258 259 require.EqualValues(t, hashBeforeEmptyUpdate, hashAfterEmptyUpdate) 260 }