diff --git a/go/database/mpt/forest.go b/go/database/mpt/forest.go index bf3142084..d0db34400 100644 --- a/go/database/mpt/forest.go +++ b/go/database/mpt/forest.go @@ -911,7 +911,7 @@ func (s *Forest) createAccount() (NodeReference, shared.WriteHandle[Node], error instance, present := s.addToCache(&ref, shared.MakeShared[Node](node)) if present { write := instance.GetWriteHandle() - *write.Get().(*AccountNode) = *node + write.Get().Reset() write.Release() } return ref, instance.GetWriteHandle(), err @@ -927,7 +927,7 @@ func (s *Forest) createBranch() (NodeReference, shared.WriteHandle[Node], error) instance, present := s.addToCache(&ref, shared.MakeShared[Node](node)) if present { write := instance.GetWriteHandle() - *write.Get().(*BranchNode) = *node + write.Get().Reset() write.Release() } return ref, instance.GetWriteHandle(), err @@ -943,7 +943,7 @@ func (s *Forest) createExtension() (NodeReference, shared.WriteHandle[Node], err instance, present := s.addToCache(&ref, shared.MakeShared[Node](node)) if present { write := instance.GetWriteHandle() - *write.Get().(*ExtensionNode) = *node + write.Get().Reset() write.Release() } return ref, instance.GetWriteHandle(), err @@ -959,7 +959,7 @@ func (s *Forest) createValue() (NodeReference, shared.WriteHandle[Node], error) instance, present := s.addToCache(&ref, shared.MakeShared[Node](node)) if present { write := instance.GetWriteHandle() - *write.Get().(*ValueNode) = *node + write.Get().Reset() write.Release() } return ref, instance.GetWriteHandle(), err diff --git a/go/database/mpt/nodes.go b/go/database/mpt/nodes.go index 76b248aae..c9561b630 100644 --- a/go/database/mpt/nodes.go +++ b/go/database/mpt/nodes.go @@ -173,6 +173,9 @@ type Node interface { // rooted by this node. Only non-frozen nodes can be released. Release(manager NodeManager, thisRef *NodeReference, this shared.WriteHandle[Node]) error + // Reset resets the node to its zero state. + Reset() + // IsDirty returns whether this node's state is different in memory than it // is on disk. All nodes are created dirty and may only be cleaned by marking // them as such. @@ -554,6 +557,12 @@ func (n *nodeBase) Release() { n.hashStatus = hashStatusClean } +func (n *nodeBase) reset() { + n.markDirty() + n.hashStatus = hashStatusDirty + n.frozen = false +} + func (n *nodeBase) check(thisRef *NodeReference) error { var errs []error if !n.IsDirty() && n.hashStatus == hashStatusDirty { @@ -636,6 +645,10 @@ func (e EmptyNode) Release(NodeManager, *NodeReference, shared.WriteHandle[Node] return nil } +func (e EmptyNode) Reset() { + // nothing to do +} + func (e EmptyNode) IsDirty() bool { return false } @@ -929,6 +942,14 @@ func (n *BranchNode) Release(manager NodeManager, thisRef *NodeReference, this s return manager.release(thisRef) } +func (n *BranchNode) Reset() { + n.nodeBase.reset() + n.children = [16]NodeReference{} + n.dirtyHashes = 0 + n.embeddedChildren = 0 + n.frozenChildren = 0 +} + func (n *BranchNode) MarkFrozen() { n.nodeBase.MarkFrozen() n.frozenChildren = ^uint16(0) @@ -1404,6 +1425,14 @@ func (n *ExtensionNode) Release(manager NodeManager, thisRef *NodeReference, thi return manager.release(thisRef) } +func (n *ExtensionNode) Reset() { + n.nodeBase.reset() + n.path = Path{} + n.next = NodeReference{} + n.nextHashDirty = true + n.nextIsEmbedded = false +} + func (n *ExtensionNode) Freeze(manager NodeManager, this shared.WriteHandle[Node]) error { if n.IsFrozen() { return nil @@ -1802,6 +1831,15 @@ func (n *AccountNode) Release(manager NodeManager, thisRef *NodeReference, this return manager.release(thisRef) } +func (n *AccountNode) Reset() { + n.nodeBase.reset() + n.address = common.Address{} + n.info = AccountInfo{} + n.storage = NodeReference{} + n.storageHashDirty = true + n.pathLength = 0 +} + func (n *AccountNode) setPathLength(manager NodeManager, thisRef *NodeReference, this shared.WriteHandle[Node], length byte) (NodeReference, bool, error) { if n.pathLength == length { return *thisRef, false, nil @@ -2041,6 +2079,13 @@ func (n *ValueNode) Release(manager NodeManager, thisRef *NodeReference, this sh return manager.release(thisRef) } +func (n *ValueNode) Reset() { + n.nodeBase.reset() + n.key = common.Key{} + n.value = common.Value{} + n.pathLength = 0 +} + func (n *ValueNode) setPathLength(manager NodeManager, thisRef *NodeReference, this shared.WriteHandle[Node], length byte) (NodeReference, bool, error) { if n.pathLength == length { return *thisRef, false, nil diff --git a/go/database/mpt/nodes_mocks.go b/go/database/mpt/nodes_mocks.go index 714a1db64..4e227f687 100644 --- a/go/database/mpt/nodes_mocks.go +++ b/go/database/mpt/nodes_mocks.go @@ -237,6 +237,18 @@ func (mr *MockNodeMockRecorder) Release(manager, thisRef, this any) *gomock.Call return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Release", reflect.TypeOf((*MockNode)(nil).Release), manager, thisRef, this) } +// Reset mocks base method. +func (m *MockNode) Reset() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Reset") +} + +// Reset indicates an expected call of Reset. +func (mr *MockNodeMockRecorder) Reset() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reset", reflect.TypeOf((*MockNode)(nil).Reset)) +} + // SetAccount mocks base method. func (m *MockNode) SetAccount(manager NodeManager, thisRef *NodeReference, this shared.WriteHandle[Node], address common.Address, path []Nibble, info AccountInfo) (NodeReference, bool, error) { m.ctrl.T.Helper() @@ -862,6 +874,18 @@ func (mr *MockleafNodeMockRecorder) Release(manager, thisRef, this any) *gomock. return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Release", reflect.TypeOf((*MockleafNode)(nil).Release), manager, thisRef, this) } +// Reset mocks base method. +func (m *MockleafNode) Reset() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Reset") +} + +// Reset indicates an expected call of Reset. +func (mr *MockleafNodeMockRecorder) Reset() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reset", reflect.TypeOf((*MockleafNode)(nil).Reset)) +} + // SetAccount mocks base method. func (m *MockleafNode) SetAccount(manager NodeManager, thisRef *NodeReference, this shared.WriteHandle[Node], address common.Address, path []Nibble, info AccountInfo) (NodeReference, bool, error) { m.ctrl.T.Helper()