@@ -22,6 +22,7 @@ import (
2222 "github.com/holiman/uint256"
2323 "github.com/ledgerwatch/erigon-lib/kv"
2424 "github.com/ledgerwatch/erigon-lib/kv/mdbx"
25+ "github.com/ledgerwatch/erigon-lib/recsplit"
2526 "github.com/ledgerwatch/erigon/consensus/ethash"
2627 "github.com/ledgerwatch/erigon/consensus/misc"
2728 "github.com/ledgerwatch/erigon/core"
@@ -887,19 +888,6 @@ func validateTxLookups2(db kv.RwDB, startBlock uint64, interruptCh chan bool) {
887888 }
888889}
889890
890- func getModifiedAccounts (chaindata string ) {
891- // TODO(tjayrush): The call to GetModifiedAccounts needs a database tx
892- fmt .Println ("hack - getModiiedAccounts is temporarily disabled." )
893- db := mdbx .MustOpen (chaindata )
894- defer db .Close ()
895- tool .Check (db .View (context .Background (), func (tx kv.Tx ) error {
896- addrs , err := changeset .GetModifiedAccounts (tx , 49300 , 49400 )
897- tool .Check (err )
898- fmt .Printf ("Len(addrs)=%d\n " , len (addrs ))
899- return nil
900- }))
901- }
902-
903891type Receiver struct {
904892 defaultReceiver * trie.RootHashAggregator
905893 accountMap map [string ]* accounts.Account
@@ -1011,52 +999,44 @@ func testGetProof(chaindata string, address common.Address, rewind int, regen bo
1011999 log .Info ("GetProof" , "address" , address , "storage keys" , len (storageKeys ), "head" , * headNumber , "block" , block ,
10121000 "alloc" , common .StorageSize (m .Alloc ), "sys" , common .StorageSize (m .Sys ))
10131001
1014- ts := dbutils .EncodeBlockNumber (block + 1 )
10151002 accountMap := make (map [string ]* accounts.Account )
10161003
1017- if err := changeset .Walk (tx , kv .AccountChangeSet , ts , 0 , func (blockN uint64 , address , v []byte ) (bool , error ) {
1018- if blockN > * headNumber {
1019- return false , nil
1020- }
1021-
1004+ if err := changeset .ForRange (tx , kv .AccountChangeSet , block + 1 , * headNumber + 1 , func (blockN uint64 , address , v []byte ) error {
10221005 var addrHash , err = common .HashData (address )
10231006 if err != nil {
1024- return false , err
1007+ return err
10251008 }
10261009 k := addrHash [:]
10271010
10281011 if _ , ok := accountMap [string (k )]; ! ok {
10291012 if len (v ) > 0 {
10301013 var a accounts.Account
10311014 if innerErr := a .DecodeForStorage (v ); innerErr != nil {
1032- return false , innerErr
1015+ return innerErr
10331016 }
10341017 accountMap [string (k )] = & a
10351018 } else {
10361019 accountMap [string (k )] = nil
10371020 }
10381021 }
1039- return true , nil
1022+ return nil
10401023 }); err != nil {
10411024 return err
10421025 }
10431026 runtime .ReadMemStats (& m )
10441027 log .Info ("Constructed account map" , "size" , len (accountMap ),
10451028 "alloc" , common .StorageSize (m .Alloc ), "sys" , common .StorageSize (m .Sys ))
10461029 storageMap := make (map [string ][]byte )
1047- if err := changeset .Walk (tx , kv .StorageChangeSet , ts , 0 , func (blockN uint64 , address , v []byte ) (bool , error ) {
1048- if blockN > * headNumber {
1049- return false , nil
1050- }
1030+ if err := changeset .ForRange (tx , kv .StorageChangeSet , block + 1 , * headNumber + 1 , func (blockN uint64 , address , v []byte ) error {
10511031 var addrHash , err = common .HashData (address )
10521032 if err != nil {
1053- return false , err
1033+ return err
10541034 }
10551035 k := addrHash [:]
10561036 if _ , ok := storageMap [string (k )]; ! ok {
10571037 storageMap [string (k )] = v
10581038 }
1059- return true , nil
1039+ return nil
10601040 }); err != nil {
10611041 return err
10621042 }
@@ -1137,7 +1117,7 @@ func testGetProof(chaindata string, address common.Address, rewind int, regen bo
11371117 return nil
11381118}
11391119
1140- func dumpState (chaindata string ) error {
1120+ func dumpState (chaindata string , block uint64 ) error {
11411121 db := mdbx .MustOpen (chaindata )
11421122 defer db .Close ()
11431123 f , err := os .Create ("statedump" )
@@ -1149,39 +1129,91 @@ func dumpState(chaindata string) error {
11491129 defer w .Flush ()
11501130 stAccounts := 0
11511131 stStorage := 0
1152- var varintBuf [ 10 ] byte // Buffer for varint number
1132+ var rs * recsplit. RecSplit
11531133 if err := db .View (context .Background (), func (tx kv.Tx ) error {
11541134 c , err := tx .Cursor (kv .PlainState )
11551135 if err != nil {
11561136 return err
11571137 }
1158- k , v , e := c .First ()
1159- for ; k != nil && e == nil ; k , v , e = c .Next () {
1160- keyLen := binary .PutUvarint (varintBuf [:], uint64 (len (k )))
1161- if _ , err = w .Write (varintBuf [:keyLen ]); err != nil {
1138+ var count uint64
1139+ if count , err = c .Count (); err != nil {
1140+ return err
1141+ }
1142+ if block > 1 {
1143+ count = block
1144+ }
1145+ if rs , err = recsplit .NewRecSplit (recsplit.RecSplitArgs {
1146+ KeyCount : int (count ),
1147+ BucketSize : 2000 ,
1148+ Salt : 0 ,
1149+ LeafSize : 8 ,
1150+ TmpDir : "" ,
1151+ StartSeed : []uint64 {0x106393c187cae21a , 0x6453cec3f7376937 , 0x643e521ddbd2be98 , 0x3740c6412f6572cb , 0x717d47562f1ce470 , 0x4cd6eb4c63befb7c , 0x9bfd8c5e18c8da73 ,
1152+ 0x082f20e10092a9a3 , 0x2ada2ce68d21defc , 0xe33cb4f3e7c6466b , 0x3980be458c509c59 , 0xc466fd9584828e8c , 0x45f0aabe1a61ede6 , 0xf6e7b8b33ad9b98d ,
1153+ 0x4ef95e25f4b4983d , 0x81175195173b92d3 , 0x4e50927d8dd15978 , 0x1ea2099d1fafae7f , 0x425c8a06fbaaa815 , 0xcd4216006c74052a },
1154+ }); err != nil {
1155+ return err
1156+ }
1157+ k , _ , e := c .First ()
1158+ i := 0
1159+ for ; k != nil && e == nil ; k , _ , e = c .Next () {
1160+ if err := rs .AddKey (k ); err != nil {
11621161 return err
11631162 }
1164- if _ , err = w .Write ([]byte (k )); err != nil {
1165- return err
1163+ i ++
1164+ if i == int (count ) {
1165+ break
11661166 }
1167- valLen := binary .PutUvarint (varintBuf [:], uint64 (len (v )))
1168- if _ , err = w .Write (varintBuf [:valLen ]); err != nil {
1169- return err
1167+ if i % 1_000_000 == 0 {
1168+ log .Info ("Added" , "keys" , i )
11701169 }
1171- if len (v ) > 0 {
1172- if _ , err = w .Write (v ); err != nil {
1173- return err
1170+ }
1171+ if e != nil {
1172+ return e
1173+ }
1174+ start := time .Now ()
1175+ log .Info ("Building recsplit..." )
1176+ if err = rs .Build (); err != nil {
1177+ return err
1178+ }
1179+ s1 , s2 := rs .Stats ()
1180+ log .Info ("Done" , "time" , time .Since (start ), "s1" , s1 , "s2" , s2 )
1181+ log .Info ("Testing bijection" )
1182+ bitCount := (count + 63 ) / 64
1183+ bits := make ([]uint64 , bitCount )
1184+ k , _ , e = c .First ()
1185+ i = 0
1186+ var collisionMap map [int ]string
1187+ if count < 1000000 {
1188+ collisionMap = make (map [int ]string )
1189+ }
1190+ var lookupTime time.Duration
1191+ for ; k != nil && e == nil ; k , _ , e = c .Next () {
1192+ start := time .Now ()
1193+ idx := rs .Lookup (k , false /* trace */ )
1194+ lookupTime += time .Since (start )
1195+ if idx >= int (count ) {
1196+ return fmt .Errorf ("idx %d >= count %d" , idx , count )
1197+ }
1198+ mask := uint64 (1 ) << (idx & 63 )
1199+ if bits [idx >> 6 ]& mask != 0 {
1200+ if collisionMap != nil {
1201+ fmt .Printf ("Key %x collided with key %x\n " , k , collisionMap [idx ])
11741202 }
1203+ rs .Lookup ([]byte (collisionMap [idx ]), true )
1204+ rs .Lookup (k , true )
1205+ return fmt .Errorf ("no bijection key idx=%d, lookup up idx = %d" , i , idx )
11751206 }
1176- if len (k ) > 28 {
1177- stStorage ++
1178- } else {
1179- stAccounts ++
1207+ if collisionMap != nil {
1208+ collisionMap [idx ] = string (k )
11801209 }
1181- if (stStorage + stAccounts )% 100000 == 0 {
1182- fmt .Printf ("State records: %d\n " , stStorage + stAccounts )
1210+ bits [idx >> 6 ] |= mask
1211+ i ++
1212+ if i == int (count ) {
1213+ break
11831214 }
11841215 }
1216+ log .Info ("Average lookup time" , "per key" , time .Duration (uint64 (lookupTime )/ count ))
11851217 return e
11861218 }); err != nil {
11871219 return err
@@ -1225,29 +1257,23 @@ func changeSetStats(chaindata string, block1, block2 uint64) error {
12251257 return err1
12261258 }
12271259 defer tx .Rollback ()
1228- if err := changeset .Walk (tx , kv .AccountChangeSet , dbutils .EncodeBlockNumber (block1 ), 0 , func (blockN uint64 , k , v []byte ) (bool , error ) {
1229- if blockN >= block2 {
1230- return false , nil
1231- }
1260+ if err := changeset .ForRange (tx , kv .AccountChangeSet , block1 , block2 , func (blockN uint64 , k , v []byte ) error {
12321261 if (blockN - block1 )% 100000 == 0 {
12331262 fmt .Printf ("at the block %d for accounts, booster size: %d\n " , blockN , len (accounts ))
12341263 }
12351264 accounts [string (common .CopyBytes (k ))] = struct {}{}
1236- return true , nil
1265+ return nil
12371266 }); err != nil {
12381267 return err
12391268 }
12401269
12411270 storage := make (map [string ]struct {})
1242- if err := changeset .Walk (tx , kv .StorageChangeSet , dbutils .EncodeBlockNumber (block1 ), 0 , func (blockN uint64 , k , v []byte ) (bool , error ) {
1243- if blockN >= block2 {
1244- return false , nil
1245- }
1271+ if err := changeset .ForRange (tx , kv .StorageChangeSet , block1 , block2 , func (blockN uint64 , k , v []byte ) error {
12461272 if (blockN - block1 )% 100000 == 0 {
12471273 fmt .Printf ("at the block %d for accounts, booster size: %d\n " , blockN , len (accounts ))
12481274 }
12491275 storage [string (common .CopyBytes (k ))] = struct {}{}
1250- return true , nil
1276+ return nil
12511277 }); err != nil {
12521278 return err
12531279 }
@@ -1266,11 +1292,11 @@ func searchChangeSet(chaindata string, key []byte, block uint64) error {
12661292 }
12671293 defer tx .Rollback ()
12681294
1269- if err := changeset .Walk (tx , kv .AccountChangeSet , dbutils .EncodeBlockNumber (block ), 0 , func (blockN uint64 , k , v []byte ) ( bool , error ) {
1295+ if err := changeset .ForEach (tx , kv .AccountChangeSet , dbutils .EncodeBlockNumber (block ), func (blockN uint64 , k , v []byte ) error {
12701296 if bytes .Equal (k , key ) {
12711297 fmt .Printf ("Found in block %d with value %x\n " , blockN , v )
12721298 }
1273- return true , nil
1299+ return nil
12741300 }); err != nil {
12751301 return err
12761302 }
@@ -1286,11 +1312,11 @@ func searchStorageChangeSet(chaindata string, key []byte, block uint64) error {
12861312 return err1
12871313 }
12881314 defer tx .Rollback ()
1289- if err := changeset .Walk (tx , kv .StorageChangeSet , dbutils .EncodeBlockNumber (block ), 0 , func (blockN uint64 , k , v []byte ) ( bool , error ) {
1315+ if err := changeset .ForEach (tx , kv .StorageChangeSet , dbutils .EncodeBlockNumber (block ), func (blockN uint64 , k , v []byte ) error {
12901316 if bytes .Equal (k , key ) {
12911317 fmt .Printf ("Found in block %d with value %x\n " , blockN , v )
12921318 }
1293- return true , nil
1319+ return nil
12941320 }); err != nil {
12951321 return err
12961322 }
@@ -2267,7 +2293,7 @@ func devTx(chaindata string) error {
22672293 tool .Check (err )
22682294 cc , err := rawdb .ReadChainConfig (tx , b .Hash ())
22692295 tool .Check (err )
2270- txn := types .NewTransaction (1 , common.Address {}, uint256 .NewInt (100 ), 100_000 , uint256 .NewInt (1 ), []byte {1 })
2296+ txn := types .NewTransaction (2 , common.Address {}, uint256 .NewInt (100 ), 100_000 , uint256 .NewInt (1 ), []byte {1 })
22712297 signedTx , err := types .SignTx (txn , * types .LatestSigner (cc ), core .DevnetSignPrivateKey )
22722298 tool .Check (err )
22732299 buf := bytes .NewBuffer (nil )
@@ -2331,9 +2357,6 @@ func main() {
23312357 case "val-tx-lookup-2" :
23322358 ValidateTxLookups2 (* chaindata )
23332359
2334- case "modiAccounts" :
2335- getModifiedAccounts (* chaindata )
2336-
23372360 case "slice" :
23382361 dbSlice (* chaindata , * bucket , common .FromHex (* hash ))
23392362
@@ -2404,7 +2427,7 @@ func main() {
24042427 err = snapSizes (* chaindata )
24052428
24062429 case "dumpState" :
2407- err = dumpState (* chaindata )
2430+ err = dumpState (* chaindata , uint64 ( * block ) )
24082431
24092432 case "readCallTraces" :
24102433 err = readCallTraces (* chaindata , uint64 (* block ))
0 commit comments