From 6dc46d3341dc5fa25bd005f9606de258874139be Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 1 Dec 2014 20:18:09 +0100 Subject: Changed the way transactions are being added to the transaction pool --- chain/block_manager.go | 2 +- chain/chain_manager.go | 21 +++++++++++++++++++++ chain/transaction.go | 7 +------ chain/transaction_pool.go | 31 ++++++++++++++++++++++++++++++- 4 files changed, 53 insertions(+), 8 deletions(-) (limited to 'chain') diff --git a/chain/block_manager.go b/chain/block_manager.go index fdb221cc3..4d8d8dae6 100644 --- a/chain/block_manager.go +++ b/chain/block_manager.go @@ -246,7 +246,7 @@ func (sm *BlockManager) ProcessWithParent(block, parent *Block) (td *big.Int, me return } - state.Update(nil) + state.Update(ethutil.Big0) if !block.State().Cmp(state) { err = fmt.Errorf("invalid merkle root. received=%x got=%x", block.Root(), state.Root()) diff --git a/chain/chain_manager.go b/chain/chain_manager.go index 0c3a7a928..75c8b22a2 100644 --- a/chain/chain_manager.go +++ b/chain/chain_manager.go @@ -321,6 +321,24 @@ func NewChain(blocks Blocks) *BlockChain { return chain } +// This function assumes you've done your checking. No checking is done at this stage anymore +func (self *ChainManager) InsertChain(chain Blocks) error { + for _, block := range chain { + td, messages, err := self.Ethereum.BlockManager().Process(block) + if err != nil { + return err + } + + self.add(block) + self.SetTotalDifficulty(td) + self.Ethereum.EventMux().Post(NewBlockEvent{block}) + self.Ethereum.EventMux().Post(messages) + } + + return nil +} + +/* // This function assumes you've done your checking. No checking is done at this stage anymore func (self *ChainManager) InsertChain(chain *BlockChain) { for e := chain.Front(); e != nil; e = e.Next() { @@ -338,7 +356,9 @@ func (self *ChainManager) InsertChain(chain *BlockChain) { chainlogger.Infof("Imported %d blocks. #%v (%x) / %#v (%x)", chain.Len(), front.Number, front.Hash()[0:4], back.Number, back.Hash()[0:4]) } } +*/ +/* func (self *ChainManager) TestChain(chain *BlockChain) (td *big.Int, err error) { self.workingChain = chain defer func() { self.workingChain = nil }() @@ -381,3 +401,4 @@ func (self *ChainManager) TestChain(chain *BlockChain) (td *big.Int, err error) return } +*/ diff --git a/chain/transaction.go b/chain/transaction.go index d81a0ea1b..47257a3f0 100644 --- a/chain/transaction.go +++ b/chain/transaction.go @@ -79,12 +79,7 @@ func (tx *Transaction) IsContract() bool { func (tx *Transaction) CreationAddress(state *state.State) []byte { // Generate a new address - addr := crypto.Sha3(ethutil.NewValue([]interface{}{tx.Sender(), tx.Nonce}).Encode())[12:] - //for i := uint64(0); state.GetStateObject(addr) != nil; i++ { - // addr = crypto.Sha3(ethutil.NewValue([]interface{}{tx.Sender(), tx.Nonce + i}).Encode())[12:] - //} - - return addr + return crypto.Sha3(ethutil.NewValue([]interface{}{tx.Sender(), tx.Nonce}).Encode())[12:] } func (tx *Transaction) Signature(key []byte) []byte { diff --git a/chain/transaction_pool.go b/chain/transaction_pool.go index ff75089d6..fbf882163 100644 --- a/chain/transaction_pool.go +++ b/chain/transaction_pool.go @@ -114,7 +114,6 @@ func (pool *TxPool) ValidateTransaction(tx *Transaction) error { } // Get the sender - //sender := pool.Ethereum.BlockManager().procState.GetAccount(tx.Sender()) sender := pool.Ethereum.BlockManager().CurrentState().GetAccount(tx.Sender()) totAmount := new(big.Int).Set(tx.Value) @@ -136,6 +135,34 @@ func (pool *TxPool) ValidateTransaction(tx *Transaction) error { return nil } +func (self *TxPool) Add(tx *Transaction) error { + hash := tx.Hash() + foundTx := FindTx(self.pool, func(tx *Transaction, e *list.Element) bool { + return bytes.Compare(tx.Hash(), hash) == 0 + }) + + if foundTx != nil { + return fmt.Errorf("Known transaction (%x)", hash[0:4]) + } + + err := self.ValidateTransaction(tx) + if err != nil { + return err + } + + self.addTransaction(tx) + + tmp := make([]byte, 4) + copy(tmp, tx.Recipient) + + txplogger.Debugf("(t) %x => %x (%v) %x\n", tx.Sender()[:4], tmp, tx.Value, tx.Hash()) + + // Notify the subscribers + self.Ethereum.EventMux().Post(TxPreEvent{tx}) + + return nil +} + func (pool *TxPool) queueHandler() { out: for { @@ -172,9 +199,11 @@ out: } } +/* func (pool *TxPool) QueueTransaction(tx *Transaction) { pool.queueChan <- tx } +*/ func (pool *TxPool) CurrentTransactions() []*Transaction { pool.mutex.Lock() -- cgit v1.2.3 From b4eeffa8f1f4c3c1f94d338b3dafcc899fd6edcb Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 2 Dec 2014 00:14:34 +0100 Subject: Transaction strictness --- chain/transaction_pool.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'chain') diff --git a/chain/transaction_pool.go b/chain/transaction_pool.go index fbf882163..0c2083088 100644 --- a/chain/transaction_pool.go +++ b/chain/transaction_pool.go @@ -102,11 +102,15 @@ func (pool *TxPool) ValidateTransaction(tx *Transaction) error { block := pool.Ethereum.ChainManager().CurrentBlock // Something has gone horribly wrong if this happens if block == nil { - return fmt.Errorf("[TXPL] No last block on the block chain") + return fmt.Errorf("No last block on the block chain") } if len(tx.Recipient) != 0 && len(tx.Recipient) != 20 { - return fmt.Errorf("[TXPL] Invalid recipient. len = %d", len(tx.Recipient)) + return fmt.Errorf("Invalid recipient. len = %d", len(tx.Recipient)) + } + + if tx.v > 28 || tx.v < 27 { + return fmt.Errorf("tx.v != (28 || 27)") } if tx.GasPrice.Cmp(MinGasPrice) < 0 { @@ -120,12 +124,12 @@ func (pool *TxPool) ValidateTransaction(tx *Transaction) error { // Make sure there's enough in the sender's account. Having insufficient // funds won't invalidate this transaction but simple ignores it. if sender.Balance().Cmp(totAmount) < 0 { - return fmt.Errorf("[TXPL] Insufficient amount in sender's (%x) account", tx.Sender()) + return fmt.Errorf("Insufficient amount in sender's (%x) account", tx.Sender()) } if tx.IsContract() { if tx.GasPrice.Cmp(big.NewInt(minGasPrice)) < 0 { - return fmt.Errorf("[TXPL] Gasprice too low, %s given should be at least %d.", tx.GasPrice, minGasPrice) + return fmt.Errorf("Gasprice too low, %s given should be at least %d.", tx.GasPrice, minGasPrice) } } -- cgit v1.2.3 From 99481a245adc2c4814ab6b38d94d63114f7bbb15 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 2 Dec 2014 11:37:33 +0100 Subject: Check for known block err and ignore --- chain/block_manager.go | 30 +++++++++++++--------- chain/chain_manager.go | 70 ++++---------------------------------------------- chain/error.go | 13 ++++++++++ 3 files changed, 36 insertions(+), 77 deletions(-) (limited to 'chain') diff --git a/chain/block_manager.go b/chain/block_manager.go index 4d8d8dae6..c1a28e423 100644 --- a/chain/block_manager.go +++ b/chain/block_manager.go @@ -185,6 +185,7 @@ func (sm *BlockManager) Process(block *Block) (td *big.Int, msgs state.Messages, defer sm.mutex.Unlock() if sm.bc.HasBlock(block.Hash()) { + fmt.Println("already having this block") return nil, nil, nil } @@ -211,7 +212,7 @@ func (sm *BlockManager) ProcessWithParent(block, parent *Block) (td *big.Int, me fmt.Printf("## %x %x ##\n", block.Hash(), block.Number) } - receipts, err := sm.ApplyDiff(state, parent, block) + _, err = sm.ApplyDiff(state, parent, block) if err != nil { return } @@ -222,11 +223,13 @@ func (sm *BlockManager) ProcessWithParent(block, parent *Block) (td *big.Int, me return } - receiptSha := DeriveSha(receipts) - if bytes.Compare(receiptSha, block.ReceiptSha) != 0 { - err = fmt.Errorf("validating receipt root. received=%x got=%x", block.ReceiptSha, receiptSha) - return - } + /* + receiptSha := DeriveSha(receipts) + if bytes.Compare(receiptSha, block.ReceiptSha) != 0 { + err = fmt.Errorf("validating receipt root. received=%x got=%x", block.ReceiptSha, receiptSha) + return + } + */ // Block validation if err = sm.ValidateBlock(block, parent); err != nil { @@ -239,12 +242,14 @@ func (sm *BlockManager) ProcessWithParent(block, parent *Block) (td *big.Int, me return } - block.receipts = receipts // although this isn't necessary it be in the future - rbloom := CreateBloom(receipts) - if bytes.Compare(rbloom, block.LogsBloom) != 0 { - err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom) - return - } + /* + block.receipts = receipts // although this isn't necessary it be in the future + rbloom := CreateBloom(receipts) + if bytes.Compare(rbloom, block.LogsBloom) != 0 { + err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom) + return + } + */ state.Update(ethutil.Big0) @@ -266,6 +271,7 @@ func (sm *BlockManager) ProcessWithParent(block, parent *Block) (td *big.Int, me sm.transState = state.Copy() sm.eth.TxPool().RemoveSet(block.Transactions()) + fmt.Println("TD", td) return td, messages, nil } else { diff --git a/chain/chain_manager.go b/chain/chain_manager.go index 75c8b22a2..3448b02dd 100644 --- a/chain/chain_manager.go +++ b/chain/chain_manager.go @@ -326,9 +326,14 @@ func (self *ChainManager) InsertChain(chain Blocks) error { for _, block := range chain { td, messages, err := self.Ethereum.BlockManager().Process(block) if err != nil { + if IsKnownBlockErr(err) { + continue + } + return err } + fmt.Println(td, messages, err) self.add(block) self.SetTotalDifficulty(td) self.Ethereum.EventMux().Post(NewBlockEvent{block}) @@ -337,68 +342,3 @@ func (self *ChainManager) InsertChain(chain Blocks) error { return nil } - -/* -// This function assumes you've done your checking. No checking is done at this stage anymore -func (self *ChainManager) InsertChain(chain *BlockChain) { - for e := chain.Front(); e != nil; e = e.Next() { - link := e.Value.(*link) - - self.add(link.block) - self.SetTotalDifficulty(link.td) - self.Ethereum.EventMux().Post(NewBlockEvent{link.block}) - self.Ethereum.EventMux().Post(link.messages) - } - - b, e := chain.Front(), chain.Back() - if b != nil && e != nil { - front, back := b.Value.(*link).block, e.Value.(*link).block - chainlogger.Infof("Imported %d blocks. #%v (%x) / %#v (%x)", chain.Len(), front.Number, front.Hash()[0:4], back.Number, back.Hash()[0:4]) - } -} -*/ - -/* -func (self *ChainManager) TestChain(chain *BlockChain) (td *big.Int, err error) { - self.workingChain = chain - defer func() { self.workingChain = nil }() - - for e := chain.Front(); e != nil; e = e.Next() { - var ( - l = e.Value.(*link) - block = l.block - parent = self.GetBlock(block.PrevHash) - ) - - //fmt.Println("parent", parent) - //fmt.Println("current", block) - - if parent == nil { - err = fmt.Errorf("incoming chain broken on hash %x\n", block.PrevHash[0:4]) - return - } - - var messages state.Messages - td, messages, err = self.Ethereum.BlockManager().ProcessWithParent(block, parent) - if err != nil { - chainlogger.Infoln(err) - chainlogger.Debugf("Block #%v failed (%x...)\n", block.Number, block.Hash()[0:4]) - chainlogger.Debugln(block) - - err = fmt.Errorf("incoming chain failed %v\n", err) - return - } - l.td = td - l.messages = messages - } - - if td.Cmp(self.TD) <= 0 { - err = &TDError{td, self.TD} - return - } - - self.workingChain = nil - - return -} -*/ diff --git a/chain/error.go b/chain/error.go index 540eda95a..7dce2b608 100644 --- a/chain/error.go +++ b/chain/error.go @@ -126,3 +126,16 @@ func IsTDError(e error) bool { _, ok := e.(*TDError) return ok } + +type KnownBlockError struct { + number uint64 + hash []byte +} + +func (self *KnownBlockError) Error() string { + return fmt.Sprintf("block %d already known (%x)", self.number, self.hash[0:4]) +} +func IsKnownBlockErr(e error) bool { + _, ok := e.(*KnownBlockError) + return ok +} -- cgit v1.2.3