Skip to content

Commit

Permalink
Merge pull request #433 from lochjin/main
Browse files Browse the repository at this point in the history
BUG:Inconsistent block state root
  • Loading branch information
dindinw authored May 19, 2023
2 parents 01dfeb6 + 056d2b9 commit ab2acce
Show file tree
Hide file tree
Showing 11 changed files with 69 additions and 33 deletions.
5 changes: 3 additions & 2 deletions consensus/model/vm_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import (
type VMI interface {
VerifyTx(tx Tx) (int64, error)
VerifyTxSanity(tx Tx) error
CheckConnectBlock(block *types.SerializedBlock, state BlockState) error
ConnectBlock(block *types.SerializedBlock, state BlockState) (uint64, error)
CheckConnectBlock(block *types.SerializedBlock) error
ConnectBlock(block *types.SerializedBlock) (uint64, error)
DisconnectBlock(block *types.SerializedBlock) (uint64, error)
AddTxToMempool(tx *types.Transaction, local bool) (int64, error)
RemoveTxFromMempool(tx *types.Transaction) error
Expand All @@ -31,4 +31,5 @@ type VMI interface {
RewindTo(state BlockState) error
BlockChain() *core.BlockChain
ChainDatabase() ethdb.Database
PrepareEnvironment(state BlockState) (*etypes.Header, error)
}
5 changes: 0 additions & 5 deletions consensus/vm/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ type Block struct {
Id *hash.Hash
Txs []model.Tx
Time time.Time
ParentBlockState model.BlockState
}

func (b *Block) ID() *hash.Hash {
Expand Down Expand Up @@ -70,7 +69,3 @@ func (b *Block) String() string {
func (b *Block) Transactions() []model.Tx {
return b.Txs
}

func (b *Block) ParentState() model.BlockState {
return b.ParentBlockState
}
4 changes: 2 additions & 2 deletions consensus/vm/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"github.com/Qitmeer/qng/vm/consensus"
)

func BuildEVMBlock(block *types.SerializedBlock, prevState model.BlockState) (consensus.Block, error) {
result := &Block{Id: block.Hash(), Txs: []model.Tx{}, Time: block.Block().Header.Timestamp, ParentBlockState: prevState}
func BuildEVMBlock(block *types.SerializedBlock) (consensus.Block, error) {
result := &Block{Id: block.Hash(), Txs: []model.Tx{}, Time: block.Block().Header.Timestamp}

for idx, tx := range block.Transactions() {
if idx == 0 {
Expand Down
17 changes: 16 additions & 1 deletion core/blockchain/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,14 @@ func (b *BlockChain) Start() error {
}
b.wg.Add(1)
go b.handler()

// prepare evm env
mainTip := b.bd.GetMainChainTip()
evmHead, err := b.VMService().PrepareEnvironment(mainTip.GetState())
if err != nil {
return err
}
log.Info("prepare evm environment", "mainTipOrder", mainTip.GetOrder(), "mainTipHash", mainTip.GetHash().String(), "hash", evmHead.Hash().String(), "number", evmHead.Number.Uint64(), "root", evmHead.Root.String())
return nil
}

Expand Down Expand Up @@ -718,7 +726,7 @@ func (b *BlockChain) reorganizeChain(ib meerdag.IBlock, detachNodes *list.List,
}
break
}

isEVMInit := false
for e := attachNodes.Front(); e != nil; e = e.Next() {
nodeBlock := e.Value.(meerdag.IBlock)
if nodeBlock.GetID() == ib.GetID() {
Expand All @@ -741,6 +749,13 @@ func (b *BlockChain) reorganizeChain(ib meerdag.IBlock, detachNodes *list.List,
}
continue
}
if !isEVMInit {
isEVMInit = true
err = b.prepareEVMEnvironment(nodeBlock)
if err != nil {
return err
}
}
view := utxo.NewUtxoViewpoint()
view.SetViewpoints([]*hash.Hash{nodeBlock.GetHash()})
stxos := []utxo.SpentTxOut{}
Expand Down
24 changes: 22 additions & 2 deletions core/blockchain/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ func (b *BlockChain) connectDagChain(ib meerdag.IBlock, block *types.SerializedB
}
var sb *types.SerializedBlock
var err error
isEVMInit := false
for _, nodeBlock := range newOr {
if nodeBlock.GetID() == ib.GetID() {
sb = block
Expand All @@ -354,6 +355,7 @@ func (b *BlockChain) connectDagChain(ib meerdag.IBlock, block *types.SerializedB
sb.SetOrder(uint64(nodeBlock.GetOrder()))
sb.SetHeight(nodeBlock.GetHeight())
}

if !nodeBlock.IsOrdered() {
er := b.updateDefaultBlockState(nodeBlock)
if er != nil {
Expand All @@ -364,6 +366,13 @@ func (b *BlockChain) connectDagChain(ib meerdag.IBlock, block *types.SerializedB
if sb == nil {
return false, fmt.Errorf("No block:%s,id:%d\n", nodeBlock.GetHash().String(), nodeBlock.GetID())
}
if !isEVMInit {
isEVMInit = true
err = b.prepareEVMEnvironment(nodeBlock)
if err != nil {
return false, err
}
}
view := utxo.NewUtxoViewpoint()
view.SetViewpoints([]*hash.Hash{nodeBlock.GetHash()})
stxos := []utxo.SpentTxOut{}
Expand Down Expand Up @@ -431,8 +440,7 @@ func (b *BlockChain) connectBlock(node meerdag.IBlock, block *types.SerializedBl
pkss = append(pkss, stxo.PkScript)
}
if !node.GetState().GetStatus().KnownInvalid() {
prevState := b.bd.GetBlockByOrder(node.GetOrder() - 1).GetState()
_, err := b.VMService().ConnectBlock(block, prevState)
_, err := b.VMService().ConnectBlock(block)
if err != nil {
return err
}
Expand Down Expand Up @@ -787,6 +795,18 @@ func (b *BlockChain) updateDefaultBlockState(ib meerdag.IBlock) error {
return nil
}

func (b *BlockChain) prepareEVMEnvironment(block meerdag.IBlock) error {
prev := b.bd.GetBlockByOrder(block.GetOrder() - 1)
if prev == nil {
return fmt.Errorf("No dag block:%s,id:%d\n", block.GetHash().String(), block.GetID())
}
_, err := b.VMService().PrepareEnvironment(prev.GetState())
if err != nil {
return err
}
return nil
}

type processMsg struct {
block *types.SerializedBlock
flags BehaviorFlags
Expand Down
3 changes: 1 addition & 2 deletions core/blockchain/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -941,8 +941,7 @@ func (b *BlockChain) checkConnectBlock(ib meerdag.IBlock, block *types.Serialize
if err != nil {
return err
}
prevState := b.bd.GetBlockByOrder(ib.GetOrder() - 1).GetState()
return b.VMService().CheckConnectBlock(block, prevState)
return b.VMService().CheckConnectBlock(block)
}

// consensusScriptVerifyFlags returns the script flags that must be used when
Expand Down
4 changes: 4 additions & 0 deletions meerevm/evm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,10 @@ func (vm *VM) ChainDatabase() ethdb.Database {
return vm.chain.Ether().ChainDb()
}

func (vm *VM) PrepareEnvironment(state model.BlockState) (*types.Header, error) {
return vm.mchain.PrepareEnvironment(state)
}

func New() *VM {
return &VM{}
}
22 changes: 8 additions & 14 deletions meerevm/meer/meerchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,16 @@ type MeerChain struct {
}

func (b *MeerChain) CheckConnectBlock(block qconsensus.Block) error {
parent, err := b.prepareEnvironment(block.ParentState())
if err != nil {
return err
}
_, _, _, err = b.buildBlock(parent, block.Transactions(), block.Timestamp().Unix())
parent := b.chain.Ether().BlockChain().CurrentBlock()
_, _, _, err := b.buildBlock(parent, block.Transactions(), block.Timestamp().Unix())
if err != nil {
return err
}
return nil
}

func (b *MeerChain) ConnectBlock(block qconsensus.Block) (uint64, error) {
parent, err := b.prepareEnvironment(block.ParentState())
if err != nil {
return 0, err
}
parent := b.chain.Ether().BlockChain().CurrentBlock()
mblock, _, _, err := b.buildBlock(parent, block.Transactions(), block.Timestamp().Unix())
if err != nil {
return 0, err
Expand Down Expand Up @@ -313,18 +307,14 @@ func (b *MeerChain) prepareEnvironment(state model.BlockState) (*types.Header, e
if err != nil {
return nil, getError(err.Error())
}
parentState := curBlockState
if i != len(list)-1 {
parentState = list[i+1]
}
dtxs := list[i].GetDuplicateTxs()
if len(dtxs) > 0 {
for _, index := range dtxs {
sb.Transactions()[index].IsDuplicate = true
}
}

eb, err := vm.BuildEVMBlock(sb, parentState)
eb, err := vm.BuildEVMBlock(sb)
if err != nil {
return nil, getError(err.Error())
}
Expand Down Expand Up @@ -352,6 +342,10 @@ func (b *MeerChain) prepareEnvironment(state model.BlockState) (*types.Header, e
return nil, getError("prepare environment")
}

func (b *MeerChain) PrepareEnvironment(state model.BlockState) (*types.Header, error) {
return b.prepareEnvironment(state)
}

func (b *MeerChain) RewindTo(state model.BlockState) error {
curBlockHeader := b.chain.Ether().BlockChain().CurrentBlock()
if curBlockHeader.Number.Uint64() <= state.GetEVMNumber() {
Expand Down
1 change: 0 additions & 1 deletion vm/consensus/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ type Block interface {
Height() uint64
Timestamp() time.Time
Transactions() []model.Tx
ParentState() model.BlockState
}

type BlockHeader interface {
Expand Down
1 change: 1 addition & 0 deletions vm/consensus/chainvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,5 @@ type ChainVM interface {
GetCurHeader() *etypes.Header
BlockChain() *core.BlockChain
ChainDatabase() ethdb.Database
PrepareEnvironment(state model.BlockState) (*etypes.Header, error)
}
16 changes: 12 additions & 4 deletions vm/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,12 @@ func (s *Service) GetMempoolSize() int64 {
return v.GetMempoolSize()
}

func (s *Service) CheckConnectBlock(block *types.SerializedBlock, state model.BlockState) error {
func (s *Service) CheckConnectBlock(block *types.SerializedBlock) error {
vm, err := s.GetVM(evm.MeerEVMID)
if err != nil {
return err
}
b, err := vmc.BuildEVMBlock(block, state)
b, err := vmc.BuildEVMBlock(block)
if err != nil {
return err
}
Expand All @@ -245,12 +245,12 @@ func (s *Service) CheckConnectBlock(block *types.SerializedBlock, state model.Bl
return vm.CheckConnectBlock(b)
}

func (s *Service) ConnectBlock(block *types.SerializedBlock, state model.BlockState) (uint64, error) {
func (s *Service) ConnectBlock(block *types.SerializedBlock) (uint64, error) {
vm, err := s.GetVM(evm.MeerEVMID)
if err != nil {
return 0, err
}
b, err := vmc.BuildEVMBlock(block, state)
b, err := vmc.BuildEVMBlock(block)
if err != nil {
return 0, err
}
Expand Down Expand Up @@ -382,6 +382,14 @@ func (s *Service) ChainDatabase() ethdb.Database {
return vm.ChainDatabase()
}

func (s *Service) PrepareEnvironment(state model.BlockState) (*etypes.Header, error) {
vm, err := s.GetVM(evm.MeerEVMID)
if err != nil {
return nil, nil
}
return vm.PrepareEnvironment(state)
}

func NewService(cons model.Consensus) (*Service, error) {
cfg := cons.Config()
ser := Service{
Expand Down

0 comments on commit ab2acce

Please sign in to comment.