OSDN Git Service

dispatch signature when proccess block (#85)
authormuscle_boy <shenao.78@163.com>
Thu, 23 May 2019 09:01:05 +0000 (17:01 +0800)
committerPaladz <yzhu101@uottawa.ca>
Thu, 23 May 2019 09:01:05 +0000 (17:01 +0800)
* dispatch signature when proccess block

* remove unuse code

* remove unuse code

* add event dispatcher to bbft

12 files changed:
account/accounts_test.go
database/store.go
event/event.go
node/node.go
protocol/bbft.go
protocol/block.go
protocol/protocol.go
protocol/store.go
protocol/txpool_test.go
test/bench_blockchain_test.go
test/util.go
wallet/wallet_test.go

index ad2a007..7d37f60 100644 (file)
@@ -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)
        }
index d218f0b..7db4a92 100644 (file)
@@ -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 {
index 1e6bd99..77bbb9f 100644 (file)
@@ -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
index b590a7c..01e901f 100644 (file)
@@ -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))
        }
index 7496591..aed4438 100644 (file)
@@ -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
index 983e6cd..a89047c 100644 (file)
@@ -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
+}
index 2ad9d6e..f3f4fc2 100644 (file)
@@ -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
 }
index 6854418..48ac4e8 100644 (file)
@@ -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
index ba1f672..a9e4583 100644 (file)
@@ -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{
index 824d684..e987946 100644 (file)
@@ -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
        }
index 9cd7150..d89ddd5 100644 (file)
@@ -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
 }
 
index a0a3708..3a65465 100644 (file)
@@ -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)
        }