aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2015-04-26 17:19:40 +0800
committerobscuren <geffobscura@gmail.com>2015-04-26 17:19:40 +0800
commit145e02fc5444eb878f67c58e310e7c5e324bb27a (patch)
tree8e0ffc8003c8f3b58cb8cb6edcc2fce2865e59ad /core
parent8d09f95bc7a73aaf567b05028ebdb4f2ac5129e4 (diff)
downloadgo-tangerine-145e02fc5444eb878f67c58e310e7c5e324bb27a.tar.gz
go-tangerine-145e02fc5444eb878f67c58e310e7c5e324bb27a.tar.zst
go-tangerine-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.go4
-rw-r--r--core/chain_manager.go10
-rw-r--r--core/transaction_pool.go18
-rw-r--r--core/transaction_pool_test.go5
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)