diff options
author | obscuren <geffobscura@gmail.com> | 2015-04-26 17:19:40 +0800 |
---|---|---|
committer | obscuren <geffobscura@gmail.com> | 2015-04-26 17:19:40 +0800 |
commit | 145e02fc5444eb878f67c58e310e7c5e324bb27a (patch) | |
tree | 8e0ffc8003c8f3b58cb8cb6edcc2fce2865e59ad /core | |
parent | 8d09f95bc7a73aaf567b05028ebdb4f2ac5129e4 (diff) | |
download | dexon-145e02fc5444eb878f67c58e310e7c5e324bb27a.tar.gz dexon-145e02fc5444eb878f67c58e310e7c5e324bb27a.tar.zst dexon-145e02fc5444eb878f67c58e310e7c5e324bb27a.zip |
core, miner: added value check on tx validation
* Changed CalcGasLimit to no longer need current block
* Added a gas * price + value on tx validation
* Transactions in the pool are now re-validated once every X
Diffstat (limited to 'core')
-rw-r--r-- | core/chain_makers.go | 4 | ||||
-rw-r--r-- | core/chain_manager.go | 10 | ||||
-rw-r--r-- | core/transaction_pool.go | 18 | ||||
-rw-r--r-- | core/transaction_pool_test.go | 5 |
4 files changed, 17 insertions, 20 deletions
diff --git a/core/chain_makers.go b/core/chain_makers.go index e7a65748e..4512a5493 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -64,7 +64,7 @@ func newBlockFromParent(addr common.Address, parent *types.Block) *types.Block { header.Difficulty = CalcDifficulty(block.Header(), parent.Header()) header.Number = new(big.Int).Add(parent.Header().Number, common.Big1) header.Time = parent.Header().Time + 10 - header.GasLimit = CalcGasLimit(parent, block) + header.GasLimit = CalcGasLimit(parent) block.Td = parent.Td @@ -79,7 +79,7 @@ func makeBlock(bman *BlockProcessor, parent *types.Block, i int, db common.Datab block := newBlockFromParent(addr, parent) state := state.New(block.Root(), db) cbase := state.GetOrNewStateObject(addr) - cbase.SetGasPool(CalcGasLimit(parent, block)) + cbase.SetGasPool(CalcGasLimit(parent)) cbase.AddBalance(BlockReward) state.Update() block.SetRoot(state.Root()) diff --git a/core/chain_manager.go b/core/chain_manager.go index bfe156262..fb2af0280 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -54,11 +54,7 @@ func CalculateTD(block, parent *types.Block) *big.Int { return td } -func CalcGasLimit(parent, block *types.Block) *big.Int { - if block.Number().Cmp(big.NewInt(0)) == 0 { - return common.BigPow(10, 6) - } - +func CalcGasLimit(parent *types.Block) *big.Int { // ((1024-1) * parent.gasLimit + (gasUsed * 6 / 5)) / 1024 previous := new(big.Int).Mul(big.NewInt(1024-1), parent.GasLimit()) current := new(big.Rat).Mul(new(big.Rat).SetInt(parent.GasUsed()), big.NewRat(6, 5)) @@ -277,7 +273,7 @@ func (bc *ChainManager) NewBlock(coinbase common.Address) *types.Block { header := block.Header() header.Difficulty = CalcDifficulty(block.Header(), parent.Header()) header.Number = new(big.Int).Add(parent.Header().Number, common.Big1) - header.GasLimit = CalcGasLimit(parent, block) + header.GasLimit = CalcGasLimit(parent) } @@ -658,7 +654,7 @@ out: // We need some control over the mining operation. Acquiring locks and waiting for the miner to create new block takes too long // and in most cases isn't even necessary. if i+1 == ev.canonicalCount { - self.currentGasLimit = CalcGasLimit(self.GetBlock(event.Block.ParentHash()), event.Block) + self.currentGasLimit = CalcGasLimit(event.Block) self.eventMux.Post(ChainHeadEvent{event.Block}) } case ChainSplitEvent: diff --git a/core/transaction_pool.go b/core/transaction_pool.go index f6414a882..8543aa017 100644 --- a/core/transaction_pool.go +++ b/core/transaction_pool.go @@ -20,8 +20,9 @@ import ( var ( ErrInvalidSender = errors.New("Invalid sender") ErrNonce = errors.New("Nonce too low") + ErrBalance = errors.New("Insufficient balance") ErrNonExistentAccount = errors.New("Account does not exist") - ErrInsufficientFunds = errors.New("Insufficient funds") + ErrInsufficientFunds = errors.New("Insufficient funds for gas * price + value") ErrIntrinsicGas = errors.New("Intrinsic gas too low") ErrGasLimit = errors.New("Exceeds block gas limit") ) @@ -124,7 +125,9 @@ func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error { return ErrGasLimit } - if pool.currentState().GetBalance(from).Cmp(new(big.Int).Mul(tx.Price, tx.GasLimit)) < 0 { + total := new(big.Int).Mul(tx.Price, tx.GasLimit) + total.Add(total, tx.Value()) + if pool.currentState().GetBalance(from).Cmp(total) < 0 { return ErrInsufficientFunds } @@ -193,7 +196,7 @@ func (self *TxPool) AddTransactions(txs []*types.Transaction) { for _, tx := range txs { if err := self.add(tx); err != nil { - glog.V(logger.Debug).Infoln(err) + glog.V(logger.Debug).Infoln("tx error:", err) } else { h := tx.Hash() glog.V(logger.Debug).Infof("tx %x\n", h[:4]) @@ -296,7 +299,6 @@ func (pool *TxPool) checkQueue() { pool.addTx(tx) } - //pool.queue[address] = txs[i:] // delete the entire queue entry if it's empty. There's no need to keep it if len(pool.queue[address]) == 0 { delete(pool.queue, address) @@ -308,12 +310,10 @@ func (pool *TxPool) validatePool() { pool.mu.Lock() defer pool.mu.Unlock() - statedb := pool.currentState() for hash, tx := range pool.txs { - from, _ := tx.From() - if nonce := statedb.GetNonce(from); nonce > tx.Nonce() { - if glog.V(logger.Debug) { - glog.Infof("removed tx (%x) from pool due to nonce error. state=%d tx=%d\n", hash[:4], nonce, tx.Nonce()) + if err := pool.ValidateTransaction(tx); err != nil { + if glog.V(logger.Info) { + glog.Infof("removed tx (%x) from pool: %v\n", hash[:4], err) } delete(pool.txs, hash) diff --git a/core/transaction_pool_test.go b/core/transaction_pool_test.go index f96d2b651..4d66776f0 100644 --- a/core/transaction_pool_test.go +++ b/core/transaction_pool_test.go @@ -43,10 +43,11 @@ func TestInvalidTransactions(t *testing.T) { t.Error("expected", ErrInsufficientFunds) } - pool.currentState().AddBalance(from, big.NewInt(100*100)) + balance := new(big.Int).Add(tx.Value(), new(big.Int).Mul(tx.Gas(), tx.GasPrice())) + pool.currentState().AddBalance(from, balance) err = pool.Add(tx) if err != ErrIntrinsicGas { - t.Error("expected", ErrIntrinsicGas) + t.Error("expected", ErrIntrinsicGas, "got", err) } pool.currentState().SetNonce(from, 1) |