From: muscle_boy Date: Thu, 23 May 2019 09:01:05 +0000 (+0800) Subject: dispatch signature when proccess block (#85) X-Git-Tag: v1.0.5~208^2~104 X-Git-Url: http://git.osdn.net/view?p=bytom%2Fvapor.git;a=commitdiff_plain;h=04e99309457c70c11b0538e38b6a0b68d5b64a87 dispatch signature when proccess block (#85) * dispatch signature when proccess block * remove unuse code * remove unuse code * add event dispatcher to bbft --- diff --git a/account/accounts_test.go b/account/accounts_test.go index ad2a007d..7d37f608 100644 --- a/account/accounts_test.go +++ b/account/accounts_test.go @@ -216,7 +216,7 @@ func mockAccountManager(t *testing.T) *Manager { store := database.NewStore(testDB) txPool := protocol.NewTxPool(store, dispatcher) - chain, err := protocol.NewChain(store, txPool) + chain, err := protocol.NewChain(store, txPool, dispatcher) if err != nil { t.Fatal(err) } diff --git a/database/store.go b/database/store.go index d218f0b1..7db4a92d 100644 --- a/database/store.go +++ b/database/store.go @@ -249,6 +249,22 @@ func (s *Store) SaveChainStatus(node, irreversibleNode *state.BlockNode, view *s return nil } +// SaveChainNodeStatus update the best node and irreversible node +func (s *Store) SaveChainNodeStatus(bestNode, irreversibleNode *state.BlockNode) error { + bytes, err := json.Marshal(protocol.BlockStoreState{ + Height: bestNode.Height, + Hash: &bestNode.Hash, + IrreversibleHeight: irreversibleNode.Height, + IrreversibleHash: &irreversibleNode.Hash, + }) + if err != nil { + return err + } + + s.db.Set(blockStoreKey, bytes) + return nil +} + // saveVoteResult update the voting results generated by each irreversible block func saveVoteResult(batch dbm.Batch, voteMap map[uint64]*state.VoteResult) error { for _, vote := range voteMap { diff --git a/event/event.go b/event/event.go index 1e6bd992..77bbb9f6 100644 --- a/event/event.go +++ b/event/event.go @@ -9,6 +9,7 @@ import ( log "github.com/sirupsen/logrus" + "github.com/vapor/protocol/bc" "github.com/vapor/protocol/bc/types" ) @@ -26,6 +27,11 @@ var ( type NewMinedBlockEvent struct{ Block types.Block } +type BlockSignatureEvent struct { + BlockHash bc.Hash + Signature []byte +} + // TypeMuxEvent is a time-tagged notification pushed to subscribers. type TypeMuxEvent struct { Time time.Time diff --git a/node/node.go b/node/node.go index b590a7c2..01e901f9 100644 --- a/node/node.go +++ b/node/node.go @@ -78,7 +78,7 @@ func NewNode(config *cfg.Config) *Node { dispatcher := event.NewDispatcher() txPool := protocol.NewTxPool(store, dispatcher) - chain, err := protocol.NewChain(store, txPool) + chain, err := protocol.NewChain(store, txPool, dispatcher) if err != nil { cmn.Exit(cmn.Fmt("Failed to create chain structure: %v", err)) } diff --git a/protocol/bbft.go b/protocol/bbft.go index 74965919..aed4438f 100644 --- a/protocol/bbft.go +++ b/protocol/bbft.go @@ -11,6 +11,7 @@ import ( "github.com/vapor/crypto/ed25519" "github.com/vapor/crypto/ed25519/chainkd" "github.com/vapor/errors" + "github.com/vapor/event" "github.com/vapor/math/checked" "github.com/vapor/protocol/bc" "github.com/vapor/protocol/bc/types" @@ -31,13 +32,15 @@ type bbft struct { consensusNodeManager *consensusNodeManager orphanManage *OrphanManage signatureCache *lru.Cache + eventDispatcher *event.Dispatcher } -func newBbft(store Store, blockIndex *state.BlockIndex, orphanManage *OrphanManage) *bbft { +func newBbft(store Store, blockIndex *state.BlockIndex, orphanManage *OrphanManage, eventDispatcher *event.Dispatcher) *bbft { return &bbft{ orphanManage: orphanManage, consensusNodeManager: newConsensusNodeManager(store, blockIndex), signatureCache: lru.New(maxSignatureCacheSize), + eventDispatcher: eventDispatcher, } } @@ -306,20 +309,21 @@ func (b *bbft) checkDoubleSign(nodeOrder, blockHeight uint64, blockHash bc.Hash) } // SignBlock signing the block if current node is consensus node -func (b *bbft) SignBlock(block *types.Block) error { +func (b *bbft) SignBlock(block *types.Block) ([]byte, error) { var xprv chainkd.XPrv xpub := [64]byte(xprv.XPub()) node, err := b.consensusNodeManager.getConsensusNode(block.Height, hex.EncodeToString(xpub[:])) if err != nil && err != errNotFoundConsensusNode { - return err + return nil, err } if node == nil { - return nil + return nil, nil } - block.Witness[node.order] = xprv.Sign(block.Hash().Bytes()) - return nil + signature := xprv.Sign(block.Hash().Bytes()) + block.Witness[node.order] = signature + return signature, nil } // UpdateConsensusNodes used to update consensus node after each round of voting diff --git a/protocol/block.go b/protocol/block.go index 983e6cd8..a89047cf 100644 --- a/protocol/block.go +++ b/protocol/block.go @@ -4,6 +4,7 @@ import ( log "github.com/sirupsen/logrus" "github.com/vapor/errors" + "github.com/vapor/event" "github.com/vapor/protocol/bc" "github.com/vapor/protocol/bc/types" "github.com/vapor/protocol/state" @@ -186,10 +187,17 @@ func (c *Chain) saveBlock(block *types.Block) error { return errors.Sub(ErrBadBlock, err) } - if err := c.bbft.SignBlock(block); err != nil { + signature, err := c.bbft.SignBlock(block) + if err != nil { return errors.Sub(ErrBadBlock, err) } + if len(signature) != 0 { + if err := c.txPool.eventDispatcher.Post(event.BlockSignatureEvent{BlockHash: block.Hash(), Signature: signature}); err != nil { + return err + } + } + bcBlock := types.MapBlock(block) if err := c.store.SaveBlock(block, bcBlock.TransactionStatus); err != nil { return err @@ -293,3 +301,20 @@ func (c *Chain) processBlock(block *types.Block) (bool, error) { } return false, nil } + +func (c *Chain) processBlockSignature(signature, pubkey []byte, blockHeight uint64, blockHash *bc.Hash) error { + isBestIrreversible, err := c.bbft.ProcessBlockSignature(signature, pubkey, blockHeight, blockHash) + if err != nil { + return err + } + + if isBestIrreversible { + bestIrreversibleNode := c.index.GetNode(blockHash) + if err := c.store.SaveChainNodeStatus(c.bestNode, bestIrreversibleNode); err != nil { + return err + } + + c.bestIrreversibleNode = bestIrreversibleNode + } + return nil +} diff --git a/protocol/protocol.go b/protocol/protocol.go index 2ad9d6e4..f3f4fc26 100644 --- a/protocol/protocol.go +++ b/protocol/protocol.go @@ -6,6 +6,7 @@ import ( log "github.com/sirupsen/logrus" "github.com/vapor/config" + "github.com/vapor/event" "github.com/vapor/protocol/bc" "github.com/vapor/protocol/bc/types" "github.com/vapor/protocol/state" @@ -28,7 +29,7 @@ type Chain struct { } // NewChain returns a new Chain using store as the underlying storage. -func NewChain(store Store, txPool *TxPool) (*Chain, error) { +func NewChain(store Store, txPool *TxPool, eventDispatcher *event.Dispatcher) (*Chain, error) { c := &Chain{ orphanManage: NewOrphanManage(), txPool: txPool, @@ -52,7 +53,7 @@ func NewChain(store Store, txPool *TxPool) (*Chain, error) { c.bestNode = c.index.GetNode(storeStatus.Hash) c.index.SetMainChain(c.bestNode) - c.bbft = newBbft(store, c.index, c.orphanManage) + c.bbft = newBbft(store, c.index, c.orphanManage, eventDispatcher) go c.blockProcesser() return c, nil } diff --git a/protocol/store.go b/protocol/store.go index 68544185..48ac4e8e 100644 --- a/protocol/store.go +++ b/protocol/store.go @@ -27,6 +27,7 @@ type Store interface { LoadBlockIndex(uint64) (*state.BlockIndex, error) SaveBlock(*types.Block, *bc.TransactionStatus) error SaveChainStatus(*state.BlockNode, *state.BlockNode, *state.UtxoViewpoint, map[uint64]*state.VoteResult) error + SaveChainNodeStatus(*state.BlockNode, *state.BlockNode) error } // BlockStoreState represents the core's db status diff --git a/protocol/txpool_test.go b/protocol/txpool_test.go index ba1f672c..a9e45839 100644 --- a/protocol/txpool_test.go +++ b/protocol/txpool_test.go @@ -121,6 +121,7 @@ func (s *mockStore) GetVoteResult(uint64) (*state.VoteResult, error) func (s *mockStore) LoadBlockIndex(uint64) (*state.BlockIndex, error) { return nil, nil } func (s *mockStore) SaveBlock(*types.Block, *bc.TransactionStatus) error { return nil } func (s *mockStore) SaveChainStatus(*state.BlockNode, *state.BlockNode, *state.UtxoViewpoint, map[uint64]*state.VoteResult) error { return nil } +func (s *mockStore) SaveChainNodeStatus(*state.BlockNode, *state.BlockNode) error { return nil } func TestAddOrphan(t *testing.T) { cases := []struct { @@ -666,6 +667,7 @@ func (s *mockStore1) GetVoteResult(uint64) (*state.VoteResult, error) func (s *mockStore1) LoadBlockIndex(uint64) (*state.BlockIndex, error) { return nil, nil } func (s *mockStore1) SaveBlock(*types.Block, *bc.TransactionStatus) error { return nil } func (s *mockStore1) SaveChainStatus(*state.BlockNode, *state.BlockNode, *state.UtxoViewpoint, map[uint64]*state.VoteResult) error { return nil } +func (s *mockStore1) SaveChainNodeStatus(*state.BlockNode, *state.BlockNode) error { return nil } func TestProcessTransaction(t *testing.T) { txPool := &TxPool{ diff --git a/test/bench_blockchain_test.go b/test/bench_blockchain_test.go index 824d6845..e987946b 100644 --- a/test/bench_blockchain_test.go +++ b/test/bench_blockchain_test.go @@ -140,7 +140,7 @@ func GenerateChainData(dirPath string, testDB dbm.DB, txNumber, otherAssetNum in store := database.NewStore(testDB) dispatcher := event.NewDispatcher() txPool := protocol.NewTxPool(store, dispatcher) - chain, err := protocol.NewChain(store, txPool) + chain, err := protocol.NewChain(store, txPool, dispatcher) if err != nil { return nil, nil, nil, err } diff --git a/test/util.go b/test/util.go index 9cd71500..d89ddd5b 100644 --- a/test/util.go +++ b/test/util.go @@ -28,7 +28,7 @@ func MockChain(testDB dbm.DB) (*protocol.Chain, *database.Store, *protocol.TxPoo store := database.NewStore(testDB) dispatcher := event.NewDispatcher() txPool := protocol.NewTxPool(store, dispatcher) - chain, err := protocol.NewChain(store, txPool) + chain, err := protocol.NewChain(store, txPool, dispatcher) return chain, store, txPool, err } diff --git a/wallet/wallet_test.go b/wallet/wallet_test.go index a0a3708f..3a65465d 100644 --- a/wallet/wallet_test.go +++ b/wallet/wallet_test.go @@ -120,7 +120,7 @@ func TestWalletUpdate(t *testing.T) { dispatcher := event.NewDispatcher() txPool := protocol.NewTxPool(store, dispatcher) - chain, err := protocol.NewChain(store, txPool) + chain, err := protocol.NewChain(store, txPool, dispatcher) if err != nil { t.Fatal(err) } @@ -212,7 +212,7 @@ func TestRescanWallet(t *testing.T) { store := database.NewStore(testDB) dispatcher := event.NewDispatcher() txPool := protocol.NewTxPool(store, dispatcher) - chain, err := protocol.NewChain(store, txPool) + chain, err := protocol.NewChain(store, txPool, dispatcher) if err != nil { t.Fatal(err) } @@ -261,7 +261,7 @@ func TestMemPoolTxQueryLoop(t *testing.T) { dispatcher := event.NewDispatcher() txPool := protocol.NewTxPool(store, dispatcher) - chain, err := protocol.NewChain(store, txPool) + chain, err := protocol.NewChain(store, txPool, dispatcher) if err != nil { t.Fatal(err) }