diff options
Diffstat (limited to 'core/blockchain.go')
-rw-r--r-- | core/blockchain.go | 84 |
1 files changed, 19 insertions, 65 deletions
diff --git a/core/blockchain.go b/core/blockchain.go index 610ab28..0ecd083 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -32,18 +32,19 @@ import ( // Errors for sanity check error. var ( - ErrBlockFromOlderPosition = errors.New("block from older position") - ErrNotGenesisBlock = errors.New("not a genesis block") - ErrIsGenesisBlock = errors.New("is a genesis block") - ErrIncorrectParentHash = errors.New("incorrect parent hash") - ErrInvalidBlockHeight = errors.New("invalid block height") - ErrInvalidRoundID = errors.New("invalid round id") - ErrNotFollowTipPosition = errors.New("not follow tip position") - ErrDuplicatedPendingBlock = errors.New("duplicated pending block") - ErrRetrySanityCheckLater = errors.New("retry sanity check later") - ErrRoundNotSwitch = errors.New("round not switch") - ErrIncorrectBlockRandomnessResult = errors.New( + ErrBlockFromOlderPosition = errors.New("block from older position") + ErrNotGenesisBlock = errors.New("not a genesis block") + ErrIsGenesisBlock = errors.New("is a genesis block") + ErrIncorrectParentHash = errors.New("incorrect parent hash") + ErrInvalidBlockHeight = errors.New("invalid block height") + ErrInvalidRoundID = errors.New("invalid round id") + ErrNotFollowTipPosition = errors.New("not follow tip position") + ErrDuplicatedPendingBlock = errors.New("duplicated pending block") + ErrRetrySanityCheckLater = errors.New("retry sanity check later") + ErrRoundNotSwitch = errors.New("round not switch") + ErrIncorrectAgreementResult = errors.New( "incorrect block randomness result") + ErrMissingRandomness = errors.New("missing block randomness") ) type pendingBlockRecord struct { @@ -134,7 +135,7 @@ type blockChain struct { vGetter tsigVerifierGetter app Application logger common.Logger - pendingRandomnesses map[types.Position]*types.BlockRandomnessResult + pendingRandomnesses map[types.Position]*types.AgreementResult configs []blockChainConfig pendingBlocks pendingBlockRecords confirmedBlocks types.BlocksByPosition @@ -154,7 +155,7 @@ func newBlockChain(nID types.NodeID, dMoment time.Time, initBlock *types.Block, logger: logger, dMoment: dMoment, pendingRandomnesses: make( - map[types.Position]*types.BlockRandomnessResult), + map[types.Position]*types.AgreementResult), } } @@ -211,10 +212,10 @@ func (bc *blockChain) notifyRoundEvents(evts []utils.RoundEventParam) error { } func (bc *blockChain) proposeBlock(position types.Position, - proposeTime time.Time) (b *types.Block, err error) { + proposeTime time.Time, isEmpty bool) (b *types.Block, err error) { bc.lock.RLock() defer bc.lock.RUnlock() - return bc.prepareBlock(position, proposeTime, false) + return bc.prepareBlock(position, proposeTime, isEmpty) } func (bc *blockChain) extractBlocks() (ret []*types.Block) { @@ -222,9 +223,6 @@ func (bc *blockChain) extractBlocks() (ret []*types.Block) { defer bc.lock.Unlock() for len(bc.confirmedBlocks) > 0 { c := bc.confirmedBlocks[0] - if c.Position.Round >= DKGDelayRound && len(c.Finalization.Randomness) == 0 { - break - } c, bc.confirmedBlocks = bc.confirmedBlocks[0], bc.confirmedBlocks[1:] // TODO(mission): remove these duplicated field if we fully converted // to single chain. @@ -315,6 +313,9 @@ func (bc *blockChain) addEmptyBlock(position types.Position) ( // addBlock should be called when the block is confirmed by BA, we won't perform // sanity check against this block, it's ok to add block with skipping height. func (bc *blockChain) addBlock(b *types.Block) error { + if b.Position.Round >= DKGDelayRound && len(b.Finalization.Randomness) == 0 { + return ErrMissingRandomness + } bc.lock.Lock() defer bc.lock.Unlock() confirmed := false @@ -338,45 +339,6 @@ func (bc *blockChain) addBlock(b *types.Block) error { return nil } -func (bc *blockChain) shouldAddRandomness(r *types.BlockRandomnessResult) bool { - bc.lock.RLock() - defer bc.lock.RUnlock() - if bc.lastDelivered != nil && - bc.lastDelivered.Position.Newer(r.Position) { - return false - } - _, exists := bc.pendingRandomnesses[r.Position] - if exists { - return false - } - b := bc.findPendingBlock(r.Position) - return b == nil || len(b.Finalization.Randomness) == 0 -} - -func (bc *blockChain) addRandomness(r *types.BlockRandomnessResult) error { - if !bc.shouldAddRandomness(r) { - return nil - } - ok, err := bc.verifyRandomness(r.BlockHash, r.Position.Round, r.Randomness) - if err != nil { - return err - } - if !ok { - return ErrIncorrectBlockRandomnessResult - } - bc.lock.Lock() - defer bc.lock.Unlock() - if b := bc.findPendingBlock(r.Position); b != nil { - if !r.BlockHash.Equal(b.Hash) { - panic(fmt.Errorf("mismathed randomness: %s %s", b, r)) - } - b.Finalization.Randomness = r.Randomness - } else { - bc.pendingRandomnesses[r.Position] = r - } - return nil -} - // TODO(mission): remove this method after removing the strong binding between // BA and blockchain. func (bc *blockChain) tipRound() uint64 { @@ -456,14 +418,6 @@ func (bc *blockChain) lastPendingBlock() *types.Block { return bc.confirmedBlocks[0] } -func (bc *blockChain) processFinalizedBlock(b *types.Block) error { - return bc.addRandomness(&types.BlockRandomnessResult{ - BlockHash: b.Hash, - Position: b.Position, - Randomness: b.Finalization.Randomness, - }) -} - ///////////////////////////////////////////// // // internal helpers |