From 6abf8ef78f1474fdeb7a6a6ce084bf994cc055f2 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 5 Jan 2015 17:10:42 +0100 Subject: Merge --- core/transaction_pool.go | 54 +++++++++++++++------------------ core/types/block.go | 77 ++++++++++++++++++++++-------------------------- 2 files changed, 58 insertions(+), 73 deletions(-) (limited to 'core') diff --git a/core/transaction_pool.go b/core/transaction_pool.go index fa284e52d..ff6c21aa9 100644 --- a/core/transaction_pool.go +++ b/core/transaction_pool.go @@ -7,7 +7,6 @@ import ( "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/logger" - "gopkg.in/fatih/set.v0" ) var txplogger = logger.NewLogger("TXP") @@ -38,7 +37,7 @@ type TxPool struct { quit chan bool // The actual pool //pool *list.List - pool *set.Set + txs map[string]*types.Transaction SecondaryProcessor TxProcessor @@ -49,21 +48,19 @@ type TxPool struct { func NewTxPool(eventMux *event.TypeMux) *TxPool { return &TxPool{ - pool: set.New(), + txs: make(map[string]*types.Transaction), queueChan: make(chan *types.Transaction, txPoolQueueSize), quit: make(chan bool), eventMux: eventMux, } } -func (pool *TxPool) addTransaction(tx *types.Transaction) { - pool.pool.Add(tx) - - // Broadcast the transaction to the rest of the peers - pool.eventMux.Post(TxPreEvent{tx}) -} - func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error { + hash := tx.Hash() + if pool.txs[string(hash)] != nil { + return fmt.Errorf("Known transaction (%x)", hash[0:4]) + } + if len(tx.To()) != 0 && len(tx.To()) != 20 { return fmt.Errorf("Invalid recipient. len = %d", len(tx.To())) } @@ -95,18 +92,17 @@ func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error { return nil } -func (self *TxPool) Add(tx *types.Transaction) error { - hash := tx.Hash() - if self.pool.Has(tx) { - return fmt.Errorf("Known transaction (%x)", hash[0:4]) - } +func (self *TxPool) addTx(tx *types.Transaction) { + self.txs[string(tx.Hash())] = tx +} +func (self *TxPool) Add(tx *types.Transaction) error { err := self.ValidateTransaction(tx) if err != nil { return err } - self.addTransaction(tx) + self.addTx(tx) var to string if len(tx.To()) > 0 { @@ -124,7 +120,7 @@ func (self *TxPool) Add(tx *types.Transaction) error { } func (self *TxPool) Size() int { - return self.pool.Size() + return len(self.txs) } func (self *TxPool) AddTransactions(txs []*types.Transaction) { @@ -137,43 +133,39 @@ func (self *TxPool) AddTransactions(txs []*types.Transaction) { } } -func (pool *TxPool) GetTransactions() []*types.Transaction { - txList := make([]*types.Transaction, pool.Size()) +func (self *TxPool) GetTransactions() (txs types.Transactions) { + txs = make(types.Transactions, self.Size()) i := 0 - pool.pool.Each(func(v interface{}) bool { - txList[i] = v.(*types.Transaction) + for _, tx := range self.txs { + txs[i] = tx i++ + } - return true - }) - - return txList + return } func (pool *TxPool) RemoveInvalid(query StateQuery) { var removedTxs types.Transactions - pool.pool.Each(func(v interface{}) bool { - tx := v.(*types.Transaction) + for _, tx := range pool.txs { sender := query.GetAccount(tx.From()) err := pool.ValidateTransaction(tx) if err != nil || sender.Nonce >= tx.Nonce() { removedTxs = append(removedTxs, tx) } + } - return true - }) pool.RemoveSet(removedTxs) } func (self *TxPool) RemoveSet(txs types.Transactions) { for _, tx := range txs { - self.pool.Remove(tx) + delete(self.txs, string(tx.Hash())) } } func (pool *TxPool) Flush() []*types.Transaction { txList := pool.GetTransactions() - pool.pool.Clear() + pool.txs = make(map[string]*types.Transaction) return txList } diff --git a/core/types/block.go b/core/types/block.go index b59044bfc..7e19d003f 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -67,10 +67,13 @@ func (self *Header) HashNoNonce() []byte { } type Block struct { - header *Header - uncles []*Header - transactions Transactions - Td *big.Int + // Preset Hash for mock + HeaderHash []byte + ParentHeaderHash []byte + header *Header + uncles []*Header + transactions Transactions + Td *big.Int receipts Receipts Reward *big.Int @@ -99,41 +102,19 @@ func NewBlockWithHeader(header *Header) *Block { } func (self *Block) DecodeRLP(s *rlp.Stream) error { - if _, err := s.List(); err != nil { - return err - } - - var header Header - if err := s.Decode(&header); err != nil { - return err - } - - var transactions []*Transaction - if err := s.Decode(&transactions); err != nil { - return err + var extblock struct { + Header *Header + Txs []*Transaction + Uncles []*Header + TD *big.Int // optional } - - var uncleHeaders []*Header - if err := s.Decode(&uncleHeaders); err != nil { - return err - } - - var tdBytes []byte - if err := s.Decode(&tdBytes); err != nil { - // If this block comes from the network that's fine. If loaded from disk it should be there - // Blocks don't store their Td when propagated over the network - } else { - self.Td = ethutil.BigD(tdBytes) - } - - if err := s.ListEnd(); err != nil { + if err := s.Decode(&extblock); err != nil { return err } - - self.header = &header - self.uncles = uncleHeaders - self.transactions = transactions - + self.header = extblock.Header + self.uncles = extblock.Uncles + self.transactions = extblock.Txs + self.Td = extblock.TD return nil } @@ -189,23 +170,35 @@ func (self *Block) RlpDataForStorage() interface{} { // Header accessors (add as you need them) func (self *Block) Number() *big.Int { return self.header.Number } func (self *Block) NumberU64() uint64 { return self.header.Number.Uint64() } -func (self *Block) ParentHash() []byte { return self.header.ParentHash } func (self *Block) Bloom() []byte { return self.header.Bloom } func (self *Block) Coinbase() []byte { return self.header.Coinbase } func (self *Block) Time() int64 { return int64(self.header.Time) } func (self *Block) GasLimit() *big.Int { return self.header.GasLimit } func (self *Block) GasUsed() *big.Int { return self.header.GasUsed } -func (self *Block) Hash() []byte { return self.header.Hash() } func (self *Block) Trie() *ptrie.Trie { return ptrie.New(self.header.Root, ethutil.Config.Db) } +func (self *Block) SetRoot(root []byte) { self.header.Root = root } func (self *Block) State() *state.StateDB { return state.New(self.Trie()) } func (self *Block) Size() ethutil.StorageSize { return ethutil.StorageSize(len(ethutil.Encode(self))) } -func (self *Block) SetRoot(root []byte) { self.header.Root = root } -// Implement block.Pow +// Implement pow.Block func (self *Block) Difficulty() *big.Int { return self.header.Difficulty } func (self *Block) N() []byte { return self.header.Nonce } -func (self *Block) HashNoNonce() []byte { - return crypto.Sha3(ethutil.Encode(self.header.rlpData(false))) +func (self *Block) HashNoNonce() []byte { return self.header.HashNoNonce() } + +func (self *Block) Hash() []byte { + if self.HeaderHash != nil { + return self.HeaderHash + } else { + return self.header.Hash() + } +} + +func (self *Block) ParentHash() []byte { + if self.ParentHeaderHash != nil { + return self.ParentHeaderHash + } else { + return self.header.ParentHash + } } func (self *Block) String() string { -- cgit