mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 10:22:23 +00:00
trie: polish the code
This commit is contained in:
parent
2ed07c7ae8
commit
9d6877b26e
2 changed files with 14 additions and 24 deletions
|
|
@ -202,58 +202,48 @@ func (t *VerkleTrie) DeleteAccount(addr common.Address) error {
|
||||||
// RollBackAccount removes the account info + code from the tree, unlike DeleteAccount
|
// RollBackAccount removes the account info + code from the tree, unlike DeleteAccount
|
||||||
// that will overwrite it with 0s. The first 64 storage slots are also removed.
|
// that will overwrite it with 0s. The first 64 storage slots are also removed.
|
||||||
func (t *VerkleTrie) RollBackAccount(addr common.Address) error {
|
func (t *VerkleTrie) RollBackAccount(addr common.Address) error {
|
||||||
evaluatedAddr := t.cache.Get(addr.Bytes())
|
var (
|
||||||
codesizekey := utils.CodeSizeKeyWithEvaluatedAddress(evaluatedAddr)
|
evaluatedAddr = t.cache.Get(addr.Bytes())
|
||||||
codesizeBytes, err := t.root.Get(codesizekey, t.nodeResolver)
|
codeSizeKey = utils.CodeSizeKeyWithEvaluatedAddress(evaluatedAddr)
|
||||||
|
)
|
||||||
|
codeSizeBytes, err := t.root.Get(codeSizeKey, t.nodeResolver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("rollback: error finding code size: %w", err)
|
return fmt.Errorf("rollback: error finding code size: %w", err)
|
||||||
}
|
}
|
||||||
codesize := binary.LittleEndian.Uint64(codesizeBytes)
|
codeSize := binary.LittleEndian.Uint64(codeSizeBytes)
|
||||||
|
|
||||||
// Delete the account header + first 64 slots + first 128 code chunks
|
// Delete the account header + first 64 slots + first 128 code chunks
|
||||||
|
key := common.CopyBytes(codeSizeKey)
|
||||||
for i := 0; i < verkle.NodeWidth; i++ {
|
for i := 0; i < verkle.NodeWidth; i++ {
|
||||||
codesizekey[31] = byte(i)
|
key[31] = byte(i)
|
||||||
|
|
||||||
// this is a workaround to avoid deleting nil leaves, the lib needs to be
|
// this is a workaround to avoid deleting nil leaves, the lib needs to be
|
||||||
// fixed to be able to handle that
|
// fixed to be able to handle that
|
||||||
v, err := t.root.Get(codesizekey, t.nodeResolver)
|
v, err := t.root.Get(key, t.nodeResolver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error rolling back account header: %w", err)
|
return fmt.Errorf("error rolling back account header: %w", err)
|
||||||
}
|
}
|
||||||
if len(v) == 0 {
|
if len(v) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
_, err = t.root.Delete(key, t.nodeResolver)
|
||||||
_, err = t.root.Delete(codesizekey, t.nodeResolver)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error rolling back account header: %w", err)
|
return fmt.Errorf("error rolling back account header: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var root *verkle.InternalNode
|
|
||||||
switch r := t.root.(type) {
|
|
||||||
case *verkle.InternalNode:
|
|
||||||
root = r
|
|
||||||
default:
|
|
||||||
return errInvalidRootType
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete all further code
|
// Delete all further code
|
||||||
var key []byte
|
for i, chunknr := uint64(32*128), uint64(128); i < codeSize; i, chunknr = i+32, chunknr+1 {
|
||||||
for i, chunknr := uint64(32*128), uint64(128); i < codesize; i, chunknr = i+32, chunknr+1 {
|
|
||||||
// evaluate group key at the start of a new group
|
// evaluate group key at the start of a new group
|
||||||
groupOffset := (chunknr + 128) % 256
|
groupOffset := (chunknr + 128) % 256
|
||||||
if groupOffset == 0 {
|
if groupOffset == 0 {
|
||||||
key = utils.CodeChunkKeyWithEvaluatedAddress(evaluatedAddr, uint256.NewInt(chunknr))
|
key = utils.CodeChunkKeyWithEvaluatedAddress(evaluatedAddr, uint256.NewInt(chunknr))
|
||||||
}
|
}
|
||||||
|
|
||||||
key[31] = byte(groupOffset)
|
key[31] = byte(groupOffset)
|
||||||
_, err = root.Delete(key[:], t.nodeResolver)
|
_, err = t.root.Delete(key[:], t.nodeResolver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("RollbackContractCode (addr=%x) error: %w", addr[:], err)
|
return fmt.Errorf("error deleting code chunk (addr=%x) error: %w", addr[:], err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,6 @@ func TestVerkleRollBack(t *testing.T) {
|
||||||
t.Fatalf("Failed to update account, %v", err)
|
t.Fatalf("Failed to update account, %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create more than 128 chunks of code
|
// create more than 128 chunks of code
|
||||||
code := make([]byte, 129*32)
|
code := make([]byte, 129*32)
|
||||||
for i := 0; i < len(code); i += 2 {
|
for i := 0; i < len(code); i += 2 {
|
||||||
|
|
@ -113,6 +112,7 @@ func TestVerkleRollBack(t *testing.T) {
|
||||||
}
|
}
|
||||||
hash := crypto.Keccak256Hash(code)
|
hash := crypto.Keccak256Hash(code)
|
||||||
if err := tr.UpdateContractCode(addr, hash, code); err != nil {
|
if err := tr.UpdateContractCode(addr, hash, code); err != nil {
|
||||||
|
t.Fatalf("Failed to update contract, %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue