X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=protocol%2Fprotocol.go;h=d7ea94484e8986833e1f2143f3b95e2fcd524dac;hb=4bc8c34936504eb903d2e8b5cf78473d41681b12;hp=80cb53a1ac5645080734e13fa1d353b3b89c3102;hpb=3bf61490e8df4a17777877b56176ce608f4ccc26;p=bytom%2Fvapor.git diff --git a/protocol/protocol.go b/protocol/protocol.go index 80cb53a1..d7ea9448 100644 --- a/protocol/protocol.go +++ b/protocol/protocol.go @@ -13,7 +13,10 @@ import ( "github.com/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 {