From 4d4e83bf5dbe8e658271c5f3dca0f3f317967a49 Mon Sep 17 00:00:00 2001 From: Herbert Jordan Date: Sat, 29 Jun 2024 17:04:59 +0200 Subject: [PATCH] Fix race condition in frozen node copy operation --- go/database/mpt/nodes.go | 45 +++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/go/database/mpt/nodes.go b/go/database/mpt/nodes.go index c9561b630..68acea163 100644 --- a/go/database/mpt/nodes.go +++ b/go/database/mpt/nodes.go @@ -950,6 +950,16 @@ func (n *BranchNode) Reset() { n.frozenChildren = 0 } +func (n *BranchNode) assign(other *BranchNode) { + n.nodeBase.markDirty() + n.nodeBase.markMutable() + n.children = other.children + n.hashes = other.hashes + n.dirtyHashes = other.dirtyHashes + n.embeddedChildren = other.embeddedChildren + n.frozenChildren = other.frozenChildren +} + func (n *BranchNode) MarkFrozen() { n.nodeBase.MarkFrozen() n.frozenChildren = ^uint16(0) @@ -1608,9 +1618,7 @@ func (n *AccountNode) SetAccount(manager NodeManager, thisRef *NodeReference, th } defer handle.Release() newNode := handle.Get().(*AccountNode) - *newNode = *n - newNode.markDirty() - newNode.markMutable() + newNode.assign(n) newNode.info = info return newRef, false, nil } @@ -1762,9 +1770,7 @@ func (n *AccountNode) SetSlot(manager NodeManager, thisRef *NodeReference, this } defer newHandle.Release() newNode := newHandle.Get().(*AccountNode) - *newNode = *n - newNode.markDirty() - newNode.markMutable() + newNode.assign(n) newNode.storage = root newNode.storageHashDirty = true return newRef, false, nil @@ -1794,9 +1800,7 @@ func (n *AccountNode) ClearStorage(manager NodeManager, thisRef *NodeReference, } defer newHandle.Release() newNode := newHandle.Get().(*AccountNode) - *newNode = *n - newNode.markDirty() - newNode.markMutable() + newNode.assign(n) newNode.storage = NewNodeReference(EmptyId()) newNode.storageHashDirty = true return newRef, false, nil @@ -1840,6 +1844,17 @@ func (n *AccountNode) Reset() { n.pathLength = 0 } +func (n *AccountNode) assign(other *AccountNode) { + n.nodeBase.markDirty() + n.nodeBase.markMutable() + n.address = other.address + n.info = other.info + n.storage = other.storage + n.storageHash = other.storageHash + n.storageHashDirty = other.storageHashDirty + n.pathLength = other.pathLength +} + 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 @@ -1851,9 +1866,7 @@ func (n *AccountNode) setPathLength(manager NodeManager, thisRef *NodeReference, } defer newHandle.Release() newNode := newHandle.Get().(*AccountNode) - *newNode = *n - newNode.markDirty() - newNode.markMutable() + newNode.assign(n) newNode.pathLength = length return newRef, false, nil } @@ -2086,6 +2099,14 @@ func (n *ValueNode) Reset() { n.pathLength = 0 } +func (n *ValueNode) assign(other *ValueNode) { + n.nodeBase.markDirty() + n.nodeBase.markMutable() + n.key = other.key + n.value = other.value + n.pathLength = other.pathLength +} + 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