X-Git-Url: http://git.osdn.net/view?p=bytom%2Fvapor.git;a=blobdiff_plain;f=protocol%2Fprotocol.go;h=56c85fb4ab4c56a71ab558cf3bb001187429aa86;hp=80cb53a1ac5645080734e13fa1d353b3b89c3102;hb=1337be95f74a1d2a1a7316737efde413f29bcb2f;hpb=3bf61490e8df4a17777877b56176ce608f4ccc26 diff --git a/protocol/protocol.go b/protocol/protocol.go index 80cb53a1..56c85fb4 100644 --- a/protocol/protocol.go +++ b/protocol/protocol.go @@ -5,15 +5,18 @@ import ( log "github.com/sirupsen/logrus" - "github.com/vapor/common" - "github.com/vapor/config" - "github.com/vapor/event" - "github.com/vapor/protocol/bc" - "github.com/vapor/protocol/bc/types" - "github.com/vapor/protocol/state" + "github.com/bytom/vapor/common" + "github.com/bytom/vapor/config" + "github.com/bytom/vapor/event" + "github.com/bytom/vapor/protocol/bc" + "github.com/bytom/vapor/protocol/bc/types" + "github.com/bytom/vapor/protocol/state" ) -const maxProcessBlockChSize = 1024 +const ( + maxProcessBlockChSize = 1024 + maxKnownTxs = 32768 // Maximum transactions hashes to keep in the known list (prevent DOS) +) // Chain provides functions for working with the Bytom block chain. type Chain struct { @@ -28,10 +31,13 @@ type Chain struct { cond sync.Cond bestBlockHeader *types.BlockHeader // the last block on current main chain lastIrrBlockHeader *types.BlockHeader // the last irreversible block + + knownTxs *common.OrderedSet } // NewChain returns a new Chain using store as the underlying storage. func NewChain(store Store, txPool *TxPool, eventDispatcher *event.Dispatcher) (*Chain, error) { + knownTxs, _ := common.NewOrderedSet(maxKnownTxs) c := &Chain{ orphanManage: NewOrphanManage(), txPool: txPool, @@ -39,6 +45,7 @@ func NewChain(store Store, txPool *TxPool, eventDispatcher *event.Dispatcher) (* signatureCache: common.NewCache(maxSignatureCacheSize), eventDispatcher: eventDispatcher, processBlockCh: make(chan *processBlockMsg, maxProcessBlockChSize), + knownTxs: knownTxs, } c.cond.L = new(sync.Mutex) @@ -143,10 +150,9 @@ func (c *Chain) InMainChain(hash bc.Hash) bool { func (c *Chain) traceLongestChainTail(blockHeader *types.BlockHeader) (*types.BlockHeader, error) { longestTail, workQueue := blockHeader, []*types.BlockHeader{blockHeader} - for len(workQueue) > 0 { + for ; len(workQueue) > 0; workQueue = workQueue[1:] { currentHeader := workQueue[0] currentHash := currentHeader.Hash() - workQueue = workQueue[1:] hashes, err := c.store.GetBlockHashesByHeight(currentHeader.Height + 1) if err != nil { return nil, err @@ -166,6 +172,16 @@ func (c *Chain) traceLongestChainTail(blockHeader *types.BlockHeader) (*types.Bl return longestTail, nil } +func (c *Chain) hasSeenTx(tx *types.Tx) bool { + return c.knownTxs.Has(tx.ID.String()) +} + +func (c *Chain) markTransactions(txs ...*types.Tx) { + for _, tx := range txs { + c.knownTxs.Add(tx.ID.String()) + } +} + // This function must be called with mu lock in above level func (c *Chain) setState(blockHeader, irrBlockHeader *types.BlockHeader, mainBlockHeaders []*types.BlockHeader, view *state.UtxoViewpoint, consensusResults []*state.ConsensusResult) error { if err := c.store.SaveChainStatus(blockHeader, irrBlockHeader, mainBlockHeaders, view, consensusResults); err != nil {