@@ -871,137 +871,140 @@ func (branchData BranchData) String() string {
871871 return sb .String ()
872872}
873873
874- // if fn returns nil, the original key will be copied from branchData
875- func (branchData BranchData ) ReplacePlainKeys (newData []byte , fn func (key []byte , isStorage bool ) (newKey []byte , err error )) (BranchData , error ) {
874+ // if fn returns nil, the original key will be copied from branchData.
875+ // Returns (result, buf, err): result may point into mmap when returned unchanged;
876+ // buf is always the heap scratch buffer (grown from the input buf), safe to retain
877+ // across calls. Callers that need a heap-owned copy of result should bytes.Clone(result).
878+ func (branchData BranchData ) ReplacePlainKeys (buf []byte , fn func (key []byte , isStorage bool ) (newKey []byte , err error )) (BranchData , []byte , error ) {
876879 if len (branchData ) < 4 {
877- return branchData , nil
880+ return branchData , buf , nil
878881 }
879882
880883 var numBuf [binary .MaxVarintLen64 ]byte
881884 touchMap := binary .BigEndian .Uint16 (branchData [0 :])
882885 afterMap := binary .BigEndian .Uint16 (branchData [2 :])
883886 if touchMap & afterMap == 0 {
884- return branchData , nil
887+ return branchData , buf , nil
885888 }
886889 pos := 4
887- newData = append (newData [:0 ], branchData [:4 ]... )
890+ buf = append (buf [:0 ], branchData [:4 ]... )
888891 for bitset , j := touchMap & afterMap , 0 ; bitset != 0 ; j ++ {
889892 bit := bitset & - bitset
890893 fields := cellFields (branchData [pos ])
891- newData = append (newData , byte (fields ))
894+ buf = append (buf , byte (fields ))
892895 pos ++
893896 if fields & fieldExtension != 0 {
894897 l , n := binary .Uvarint (branchData [pos :])
895898 if n == 0 {
896- return nil , errors .New ("replacePlainKeys buffer too small for hashedKey len" )
899+ return nil , buf , errors .New ("replacePlainKeys buffer too small for hashedKey len" )
897900 } else if n < 0 {
898- return nil , errors .New ("replacePlainKeys value overflow for hashedKey len" )
901+ return nil , buf , errors .New ("replacePlainKeys value overflow for hashedKey len" )
899902 }
900- newData = append (newData , branchData [pos :pos + n ]... )
903+ buf = append (buf , branchData [pos :pos + n ]... )
901904 pos += n
902905 if len (branchData ) < pos + int (l ) {
903- return nil , fmt .Errorf ("replacePlainKeys buffer too small for hashedKey: expected %d got %d" , pos + int (l ), len (branchData ))
906+ return nil , buf , fmt .Errorf ("replacePlainKeys buffer too small for hashedKey: expected %d got %d" , pos + int (l ), len (branchData ))
904907 }
905908 if l > 0 {
906- newData = append (newData , branchData [pos :pos + int (l )]... )
909+ buf = append (buf , branchData [pos :pos + int (l )]... )
907910 pos += int (l )
908911 }
909912 }
910913 if fields & fieldAccountAddr != 0 {
911914 l , n := binary .Uvarint (branchData [pos :])
912915 if n == 0 {
913- return nil , errors .New ("replacePlainKeys buffer too small for accountAddr len" )
916+ return nil , buf , errors .New ("replacePlainKeys buffer too small for accountAddr len" )
914917 } else if n < 0 {
915- return nil , errors .New ("replacePlainKeys value overflow for accountAddr len" )
918+ return nil , buf , errors .New ("replacePlainKeys value overflow for accountAddr len" )
916919 }
917920 pos += n
918921 if len (branchData ) < pos + int (l ) {
919- return nil , fmt .Errorf ("replacePlainKeys buffer too small for accountAddr: expected %d got %d" , pos + int (l ), len (branchData ))
922+ return nil , buf , fmt .Errorf ("replacePlainKeys buffer too small for accountAddr: expected %d got %d" , pos + int (l ), len (branchData ))
920923 }
921924 if l > 0 {
922925 pos += int (l )
923926 }
924927 newKey , err := fn (branchData [pos - int (l ):pos ], false )
925928 if err != nil {
926- return nil , err
929+ return nil , buf , err
927930 }
928931 if newKey == nil {
929932 // invariant: fn returns nil (keep original) only for plain addr keys (length.Addr bytes)
930- newData = append (newData , branchData [pos - int (l )- n :pos ]... )
933+ buf = append (buf , branchData [pos - int (l )- n :pos ]... )
931934 } else {
932935 // invariant: newKey is a short reference (≤8 bytes) or full plain addr (length.Addr bytes)
933936 n = binary .PutUvarint (numBuf [:], uint64 (len (newKey )))
934- newData = append (newData , numBuf [:n ]... )
935- newData = append (newData , newKey ... )
937+ buf = append (buf , numBuf [:n ]... )
938+ buf = append (buf , newKey ... )
936939 }
937940 }
938941 if fields & fieldStorageAddr != 0 {
939942 l , n := binary .Uvarint (branchData [pos :])
940943 if n == 0 {
941- return nil , errors .New ("replacePlainKeys buffer too small for storageAddr len" )
944+ return nil , buf , errors .New ("replacePlainKeys buffer too small for storageAddr len" )
942945 } else if n < 0 {
943- return nil , errors .New ("replacePlainKeys value overflow for storageAddr len" )
946+ return nil , buf , errors .New ("replacePlainKeys value overflow for storageAddr len" )
944947 }
945948 pos += n
946949 if len (branchData ) < pos + int (l ) {
947- return nil , fmt .Errorf ("replacePlainKeys buffer too small for storageAddr: expected %d got %d" , pos + int (l ), len (branchData ))
950+ return nil , buf , fmt .Errorf ("replacePlainKeys buffer too small for storageAddr: expected %d got %d" , pos + int (l ), len (branchData ))
948951 }
949952 if l > 0 {
950953 pos += int (l )
951954 }
952955 newKey , err := fn (branchData [pos - int (l ):pos ], true )
953956 if err != nil {
954- return nil , err
957+ return nil , buf , err
955958 }
956959 if newKey == nil {
957960 // invariant: fn returns nil (keep original) only for plain storage keys (length.Addr+length.Hash bytes)
958- newData = append (newData , branchData [pos - int (l )- n :pos ]... ) // -n to include length
961+ buf = append (buf , branchData [pos - int (l )- n :pos ]... ) // -n to include length
959962 } else {
960963 // invariant: newKey is a short reference (≤8 bytes) or full plain storage key (length.Addr+length.Hash bytes)
961964 n = binary .PutUvarint (numBuf [:], uint64 (len (newKey )))
962- newData = append (newData , numBuf [:n ]... )
963- newData = append (newData , newKey ... )
965+ buf = append (buf , numBuf [:n ]... )
966+ buf = append (buf , newKey ... )
964967 }
965968 }
966969 if fields & fieldHash != 0 {
967970 l , n := binary .Uvarint (branchData [pos :])
968971 if n == 0 {
969- return nil , errors .New ("replacePlainKeys buffer too small for hash len" )
972+ return nil , buf , errors .New ("replacePlainKeys buffer too small for hash len" )
970973 } else if n < 0 {
971- return nil , errors .New ("replacePlainKeys value overflow for hash len" )
974+ return nil , buf , errors .New ("replacePlainKeys value overflow for hash len" )
972975 }
973- newData = append (newData , branchData [pos :pos + n ]... )
976+ buf = append (buf , branchData [pos :pos + n ]... )
974977 pos += n
975978 if len (branchData ) < pos + int (l ) {
976- return nil , fmt .Errorf ("replacePlainKeys buffer too small for hash: expected %d got %d" , pos + int (l ), len (branchData ))
979+ return nil , buf , fmt .Errorf ("replacePlainKeys buffer too small for hash: expected %d got %d" , pos + int (l ), len (branchData ))
977980 }
978981 if l > 0 {
979- newData = append (newData , branchData [pos :pos + int (l )]... )
982+ buf = append (buf , branchData [pos :pos + int (l )]... )
980983 pos += int (l )
981984 }
982985 }
983986 if fields & fieldStateHash != 0 {
984987 l , n := binary .Uvarint (branchData [pos :])
985988 if n == 0 {
986- return nil , errors .New ("replacePlainKeys buffer too small for acLeaf hash len" )
989+ return nil , buf , errors .New ("replacePlainKeys buffer too small for acLeaf hash len" )
987990 } else if n < 0 {
988- return nil , errors .New ("replacePlainKeys value overflow for acLeafhash len" )
991+ return nil , buf , errors .New ("replacePlainKeys value overflow for acLeafhash len" )
989992 }
990- newData = append (newData , branchData [pos :pos + n ]... )
993+ buf = append (buf , branchData [pos :pos + n ]... )
991994 pos += n
992995 if len (branchData ) < pos + int (l ) {
993- return nil , fmt .Errorf ("replacePlainKeys buffer too small for LeafHash: expected %d got %d" , pos + int (l ), len (branchData ))
996+ return nil , buf , fmt .Errorf ("replacePlainKeys buffer too small for LeafHash: expected %d got %d" , pos + int (l ), len (branchData ))
994997 }
995998 if l > 0 {
996- newData = append (newData , branchData [pos :pos + int (l )]... )
999+ buf = append (buf , branchData [pos :pos + int (l )]... )
9971000 pos += int (l )
9981001 }
9991002 }
10001003
10011004 bitset ^= bit
10021005 }
10031006
1004- return newData , nil
1007+ return bytes . Clone ( buf ), buf , nil
10051008}
10061009
10071010// IsComplete determines whether given branch data is complete, meaning that all information about all the children is present
@@ -1286,8 +1289,8 @@ func (m *BranchMerger) Merge(branch1 BranchData, branch2 BranchData) (BranchData
12861289 }
12871290 pos1 += n
12881291 if len (branch1 ) < pos1 + int (l ) {
1289- fmt .Printf ("b1: %x %v\n " , branch1 , branch1 )
1290- fmt .Printf ("b2: %x\n " , branch2 )
1292+ // fmt.Printf("b1: %x %v\n", branch1, branch1)
1293+ // fmt.Printf("b2: %x\n", branch2)
12911294 return nil , fmt .Errorf ("MergeHexBranches branch1 is too small: expected at least %d got %d bytes" , pos1 + int (l ), len (branch1 ))
12921295 }
12931296 if l > 0 {
0 commit comments