gecko/vms/platformvm/abort_block.go

62 lines
1.6 KiB
Go

// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package platformvm
import (
"github.com/ava-labs/gecko/ids"
"github.com/ava-labs/gecko/vms/components/core"
)
// Abort being accepted results in the proposal of its parent (which must be a proposal block)
// being rejected.
type Abort struct {
DoubleDecisionBlock `serialize:"true"`
}
// Verify this block performs a valid state transition.
//
// The parent block must be a proposal
//
// This function also sets onAcceptDB database if the verification passes.
func (a *Abort) Verify() error {
parent, ok := a.parentBlock().(*ProposalBlock)
// Abort is a decision, so its parent must be a proposal
if !ok {
if err := a.Reject(); err == nil {
if err := a.vm.DB.Commit(); err != nil {
a.vm.Ctx.Log.Error("error committing Abort block as rejected: %s", err)
}
} else {
a.vm.DB.Abort()
}
return errInvalidBlockType
}
a.onAcceptDB, a.onAcceptFunc = parent.onAbort()
a.vm.currentBlocks[a.ID().Key()] = a
a.parentBlock().addChild(a)
return nil
}
// newAbortBlock returns a new *Abort block where the block's parent, a proposal
// block, has ID [parentID].
func (vm *VM) newAbortBlock(parentID ids.ID) *Abort {
abort := &Abort{DoubleDecisionBlock: DoubleDecisionBlock{CommonDecisionBlock: CommonDecisionBlock{CommonBlock: CommonBlock{
Block: core.NewBlock(parentID),
vm: vm,
}}}}
// We serialize this block as a Block so that it can be deserialized into a
// Block
blk := Block(abort)
bytes, err := Codec.Marshal(&blk)
if err != nil {
return nil
}
abort.Block.Initialize(bytes, vm.SnowmanVM)
return abort
}