consensus: fix panic during verifyBlock
Issue: panic during mixed 4-nodes consensus setup: ``` 2021-03-18T12:01:50.715Z INFO skip change view {"nc": 0, "nf": 3} 2021-03-18T12:01:52.786Z INFO received ChangeView {"validator": 0, "reason": "Timeout", "new view": 1} 2021-03-18T12:01:53.602Z INFO received ChangeView {"validator": 2, "reason": "Timeout", "new view": 1} 2021-03-18T12:01:56.736Z INFO received ChangeView {"validator": 1, "reason": "Timeout", "new view": 1} 2021-03-18T12:01:56.736Z INFO changing dbft view {"height": 3, "view": 1, "index": 3, "role": "Backup"} 2021-03-18T12:02:01.758Z INFO received PrepareRequest {"validator": 2, "tx": 0} panic: interface conversion: block.Block is nil, not *consensus.neoBlock goroutine 315 [running]: github.com/nspcc-dev/neo-go/pkg/consensus.(*service).verifyBlock(0xc000419540, 0x0, 0x0, 0x4) github.com/nspcc-dev/neo-go/pkg/consensus/consensus.go:427 +0x1306 github.com/nspcc-dev/dbft.(*DBFT).createAndCheckBlock(0xc0001f8840, 0x13f0002) github.com/nspcc-dev/dbft@v0.0.0-20210302103605-cc75991b7cfb/dbft.go:373 +0x27e github.com/nspcc-dev/dbft.(*DBFT).onPrepareRequest(0xc0001f8840, 0x13f4378, 0xc0003b8500) github.com/nspcc-dev/dbft@v0.0.0-20210302103605-cc75991b7cfb/dbft.go:329 +0xdf1 github.com/nspcc-dev/dbft.(*DBFT).OnReceive(0xc0001f8840, 0x13f4378, 0xc0003b8500) github.com/nspcc-dev/dbft@v0.0.0-20210302103605-cc75991b7cfb/dbft.go:247 +0xe25 github.com/nspcc-dev/neo-go/pkg/consensus.(*service).eventLoop(0xc000419540) github.com/nspcc-dev/neo-go/pkg/consensus/consensus.go:297 +0x79d created by github.com/nspcc-dev/neo-go/pkg/consensus.(*service).Start github.com/nspcc-dev/neo-go/pkg/consensus/consensus.go:249 +0xa5 ``` So (*service).verifyBlock is unable to work with nil block.
This commit is contained in:
parent
e5cdecfa9f
commit
4809cdf0b0
1 changed files with 4 additions and 6 deletions
|
@ -648,9 +648,6 @@ func convertKeys(validators []crypto.PublicKey) (pubs []*keys.PublicKey) {
|
||||||
|
|
||||||
func (s *service) newBlockFromContext(ctx *dbft.Context) block.Block {
|
func (s *service) newBlockFromContext(ctx *dbft.Context) block.Block {
|
||||||
block := new(neoBlock)
|
block := new(neoBlock)
|
||||||
if ctx.TransactionHashes == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
block.Block.Network = s.ProtocolConfiguration.Magic
|
block.Block.Network = s.ProtocolConfiguration.Magic
|
||||||
block.Block.Timestamp = ctx.Timestamp / nsInMs
|
block.Block.Timestamp = ctx.Timestamp / nsInMs
|
||||||
|
@ -658,7 +655,7 @@ func (s *service) newBlockFromContext(ctx *dbft.Context) block.Block {
|
||||||
if s.ProtocolConfiguration.StateRootInHeader {
|
if s.ProtocolConfiguration.StateRootInHeader {
|
||||||
sr, err := s.Chain.GetStateModule().GetStateRoot(ctx.BlockIndex - 1)
|
sr, err := s.Chain.GetStateModule().GetStateRoot(ctx.BlockIndex - 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
s.log.Fatal(fmt.Sprintf("failed to get state root: %s", err.Error()))
|
||||||
}
|
}
|
||||||
block.StateRootEnabled = true
|
block.StateRootEnabled = true
|
||||||
block.PrevStateRoot = sr.Root
|
block.PrevStateRoot = sr.Root
|
||||||
|
@ -672,11 +669,11 @@ func (s *service) newBlockFromContext(ctx *dbft.Context) block.Block {
|
||||||
validators, err = s.Chain.GetNextBlockValidators()
|
validators, err = s.Chain.GetNextBlockValidators()
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
s.log.Fatal(fmt.Sprintf("failed to get validators: %s", err.Error()))
|
||||||
}
|
}
|
||||||
script, err := smartcontract.CreateMultiSigRedeemScript(s.dbft.Context.M(), validators)
|
script, err := smartcontract.CreateMultiSigRedeemScript(s.dbft.Context.M(), validators)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
s.log.Fatal(fmt.Sprintf("failed to create multisignature script: %s", err.Error()))
|
||||||
}
|
}
|
||||||
block.Block.NextConsensus = crypto.Hash160(script)
|
block.Block.NextConsensus = crypto.Hash160(script)
|
||||||
block.Block.PrevHash = ctx.PrevHash
|
block.Block.PrevHash = ctx.PrevHash
|
||||||
|
@ -685,6 +682,7 @@ func (s *service) newBlockFromContext(ctx *dbft.Context) block.Block {
|
||||||
primaryIndex := byte(ctx.PrimaryIndex)
|
primaryIndex := byte(ctx.PrimaryIndex)
|
||||||
block.Block.PrimaryIndex = primaryIndex
|
block.Block.PrimaryIndex = primaryIndex
|
||||||
|
|
||||||
|
// it's OK to have ctx.TransactionsHashes == nil here
|
||||||
hashes := make([]util.Uint256, len(ctx.TransactionHashes))
|
hashes := make([]util.Uint256, len(ctx.TransactionHashes))
|
||||||
copy(hashes, ctx.TransactionHashes)
|
copy(hashes, ctx.TransactionHashes)
|
||||||
block.Block.MerkleRoot = hash.CalcMerkleRoot(hashes)
|
block.Block.MerkleRoot = hash.CalcMerkleRoot(hashes)
|
||||||
|
|
Loading…
Reference in a new issue