diff --git a/vms/platformvm/block/executor/acceptor.go b/vms/platformvm/block/executor/acceptor.go index ff5542f65157..af26c931d088 100644 --- a/vms/platformvm/block/executor/acceptor.go +++ b/vms/platformvm/block/executor/acceptor.go @@ -172,6 +172,16 @@ func (a *acceptor) optionBlock(b, parent block.Block, blockType string) error { return err } + parentState, ok := a.blkIDToState[parentID] + if !ok { + return fmt.Errorf("%w %s", errMissingBlockState, parentID) + } + if parentState.onDecisionState != nil { + if err := parentState.onDecisionState.Apply(a.state); err != nil { + return err + } + } + blkState, ok := a.blkIDToState[blkID] if !ok { return fmt.Errorf("%w %s", errMissingBlockState, blkID) @@ -191,11 +201,11 @@ func (a *acceptor) optionBlock(b, parent block.Block, blockType string) error { } // Note that this method writes [batch] to the database. - if err := a.ctx.SharedMemory.Apply(blkState.atomicRequests, batch); err != nil { + if err := a.ctx.SharedMemory.Apply(parentState.atomicRequests, batch); err != nil { return fmt.Errorf("failed to apply vm's state to shared memory: %w", err) } - if onAcceptFunc := blkState.onAcceptFunc; onAcceptFunc != nil { + if onAcceptFunc := parentState.onAcceptFunc; onAcceptFunc != nil { onAcceptFunc() } diff --git a/vms/platformvm/block/executor/backend.go b/vms/platformvm/block/executor/backend.go index 94b301c89ddb..4d915047f560 100644 --- a/vms/platformvm/block/executor/backend.go +++ b/vms/platformvm/block/executor/backend.go @@ -51,20 +51,20 @@ func (b *backend) GetState(blkID ids.ID) (state.Chain, bool) { return b.state, blkID == b.state.GetLastAccepted() } -func (b *backend) getBlkWithOnAbortState(blkID ids.ID) (*blockState, bool) { +func (b *backend) getOnAbortState(blkID ids.ID) (state.Diff, bool) { state, ok := b.blkIDToState[blkID] if !ok || state.onAbortState == nil { return nil, false } - return state, true + return state.onAbortState, true } -func (b *backend) getBlkWithOnCommitState(blkID ids.ID) (*blockState, bool) { +func (b *backend) getOnCommitState(blkID ids.ID) (state.Diff, bool) { state, ok := b.blkIDToState[blkID] if !ok || state.onCommitState == nil { return nil, false } - return state, true + return state.onCommitState, true } func (b *backend) GetBlock(blkID ids.ID) (block.Block, error) { diff --git a/vms/platformvm/block/executor/block_state.go b/vms/platformvm/block/executor/block_state.go index 11b6b0823bd0..abec214ae244 100644 --- a/vms/platformvm/block/executor/block_state.go +++ b/vms/platformvm/block/executor/block_state.go @@ -15,9 +15,9 @@ import ( type proposalBlockState struct { initiallyPreferCommit bool + onDecisionState state.Diff onCommitState state.Diff onAbortState state.Diff - onDecisionState state.Diff } // The state of a block. diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index 107e3a39bec0..b05627f31b6d 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -59,11 +59,7 @@ func (v *verifier) BanffProposalBlock(b *block.BanffProposalBlock) error { } parentID := b.Parent() - onCommitState, err := state.NewDiff(parentID, v.backend) - if err != nil { - return err - } - onAbortState, err := state.NewDiff(parentID, v.backend) + onDecisionState, err := state.NewDiff(parentID, v.backend) if err != nil { return err } @@ -72,36 +68,40 @@ func (v *verifier) BanffProposalBlock(b *block.BanffProposalBlock) error { nextChainTime := b.Timestamp() changes, err := executor.AdvanceTimeTo( v.txExecutorBackend, - onCommitState, + onDecisionState, nextChainTime, ) if err != nil { return err } - onCommitState.SetTimestamp(nextChainTime) - changes.Apply(onCommitState) + onDecisionState.SetTimestamp(nextChainTime) + changes.Apply(onDecisionState) - onAbortState.SetTimestamp(nextChainTime) - changes.Apply(onAbortState) + inputs, atomicRequests, onAcceptFunc, err := v.processStandardTxs(b.Transactions, onDecisionState, b.Parent()) + if err != nil { + return err + } - // Apply the changes, if any, from processing the decision txs. - // [onCommitState] = [onAbortState] here, either one can be used. It is - // only used to ensure that [onDecisionState] contains only the change diff - // of all the standard txs *after* the timestamp advancement changes are - // applied. [onDecisionState] will be applied to [onCommitState] or - // [onAbortState] depending on if the proposal is committed or aborted. - onDecisionState, err := wrapState(onCommitState) + onCommitState, err := wrapState(onDecisionState) if err != nil { return err } - inputs, atomicRequests, onAcceptFunc, err := v.processStandardTxs(b.Transactions, onDecisionState, b.Parent()) + onAbortState, err := wrapState(onDecisionState) if err != nil { return err } - return v.proposalBlock(&b.ApricotProposalBlock, onDecisionState, onCommitState, onAbortState, inputs, atomicRequests, onAcceptFunc) + return v.proposalBlock( + &b.ApricotProposalBlock, + onDecisionState, + onCommitState, + onAbortState, + inputs, + atomicRequests, + onAcceptFunc, + ) } func (v *verifier) BanffStandardBlock(b *block.BanffStandardBlock) error { @@ -335,25 +335,16 @@ func (v *verifier) commonBlock(b block.Block) error { // abortBlock populates the state of this block if [nil] is returned func (v *verifier) abortBlock(b block.Block) error { parentID := b.Parent() - parentState, ok := v.getBlkWithOnAbortState(parentID) + onAbortState, ok := v.getOnAbortState(parentID) if !ok { return fmt.Errorf("%w: %s", state.ErrMissingParentState, parentID) } - if err := parentState.onDecisionState.Apply(parentState.onAbortState); err != nil { - return err - } - blkID := b.ID() v.blkIDToState[blkID] = &blockState{ statelessBlock: b, - - onAcceptState: parentState.onAbortState, - onAcceptFunc: parentState.onAcceptFunc, - - inputs: parentState.inputs, - timestamp: parentState.onAbortState.GetTimestamp(), - atomicRequests: parentState.atomicRequests, + onAcceptState: onAbortState, + timestamp: onAbortState.GetTimestamp(), } return nil } @@ -361,25 +352,16 @@ func (v *verifier) abortBlock(b block.Block) error { // commitBlock populates the state of this block if [nil] is returned func (v *verifier) commitBlock(b block.Block) error { parentID := b.Parent() - parentState, ok := v.getBlkWithOnCommitState(parentID) + onCommitState, ok := v.getOnCommitState(parentID) if !ok { return fmt.Errorf("%w: %s", state.ErrMissingParentState, parentID) } - if err := parentState.onDecisionState.Apply(parentState.onCommitState); err != nil { - return err - } - blkID := b.ID() v.blkIDToState[blkID] = &blockState{ statelessBlock: b, - - onAcceptState: parentState.onCommitState, - onAcceptFunc: parentState.onAcceptFunc, - - inputs: parentState.inputs, - timestamp: parentState.onCommitState.GetTimestamp(), - atomicRequests: parentState.atomicRequests, + onAcceptState: onCommitState, + timestamp: onCommitState.GetTimestamp(), } return nil } diff --git a/vms/platformvm/block/executor/verifier_test.go b/vms/platformvm/block/executor/verifier_test.go index 6e03f3fe4eb3..6d4e32e0bee5 100644 --- a/vms/platformvm/block/executor/verifier_test.go +++ b/vms/platformvm/block/executor/verifier_test.go @@ -356,7 +356,6 @@ func TestVerifierVisitCommitBlock(t *testing.T) { timestamp := time.Now() gomock.InOrder( parentStatelessBlk.EXPECT().Height().Return(uint64(1)).Times(1), - parentOnDecisionState.EXPECT().Apply(parentOnCommitState).Return(nil), parentOnCommitState.EXPECT().GetTimestamp().Return(timestamp).Times(1), ) @@ -428,7 +427,6 @@ func TestVerifierVisitAbortBlock(t *testing.T) { timestamp := time.Now() gomock.InOrder( parentStatelessBlk.EXPECT().Height().Return(uint64(1)).Times(1), - parentOnDecisionState.EXPECT().Apply(parentOnAbortState).Return(nil), parentOnAbortState.EXPECT().GetTimestamp().Return(timestamp).Times(1), )