aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2015-04-24 23:45:51 +0800
committerobscuren <geffobscura@gmail.com>2015-04-24 23:48:13 +0800
commit405720b218c74ec730541cdcb360db54deb75474 (patch)
treeb403e8c1e35884aac71bd51cff8489e4305adba8 /core
parent3bb6da9bd3111c8083cdefde1aa93a7ac55d19d2 (diff)
downloaddexon-405720b218c74ec730541cdcb360db54deb75474.tar.gz
dexon-405720b218c74ec730541cdcb360db54deb75474.tar.zst
dexon-405720b218c74ec730541cdcb360db54deb75474.zip
xeth, core, cmd/utils: Transaction can not be over block gas limit
Transactions will be invalidated when the tx.gas_limit > block.gas_limit
Diffstat (limited to 'core')
-rw-r--r--core/chain_makers.go2
-rw-r--r--core/chain_manager.go29
-rw-r--r--core/chain_manager_test.go4
-rw-r--r--core/transaction_pool.go10
-rw-r--r--core/transaction_pool_test.go2
5 files changed, 31 insertions, 16 deletions
diff --git a/core/chain_makers.go b/core/chain_makers.go
index 9b4911fba..e7a65748e 100644
--- a/core/chain_makers.go
+++ b/core/chain_makers.go
@@ -124,7 +124,7 @@ func newChainManager(block *types.Block, eventMux *event.TypeMux, db common.Data
// block processor with fake pow
func newBlockProcessor(db common.Database, cman *ChainManager, eventMux *event.TypeMux) *BlockProcessor {
chainMan := newChainManager(nil, eventMux, db)
- txpool := NewTxPool(eventMux, chainMan.State)
+ txpool := NewTxPool(eventMux, chainMan.State, chainMan.GasLimit)
bman := NewBlockProcessor(db, db, FakePow{}, txpool, chainMan, eventMux)
return bman
}
diff --git a/core/chain_manager.go b/core/chain_manager.go
index a09b2e63b..bfe156262 100644
--- a/core/chain_manager.go
+++ b/core/chain_manager.go
@@ -78,11 +78,12 @@ type ChainManager struct {
eventMux *event.TypeMux
genesisBlock *types.Block
// Last known total difficulty
- mu sync.RWMutex
- tsmu sync.RWMutex
- td *big.Int
- currentBlock *types.Block
- lastBlockHash common.Hash
+ mu sync.RWMutex
+ tsmu sync.RWMutex
+ td *big.Int
+ currentBlock *types.Block
+ lastBlockHash common.Hash
+ currentGasLimit *big.Int
transState *state.StateDB
txState *state.ManagedState
@@ -95,12 +96,13 @@ type ChainManager struct {
func NewChainManager(blockDb, stateDb common.Database, mux *event.TypeMux) *ChainManager {
bc := &ChainManager{
- blockDb: blockDb,
- stateDb: stateDb,
- genesisBlock: GenesisBlock(stateDb),
- eventMux: mux,
- quit: make(chan struct{}),
- cache: NewBlockCache(blockCacheLimit),
+ blockDb: blockDb,
+ stateDb: stateDb,
+ genesisBlock: GenesisBlock(stateDb),
+ eventMux: mux,
+ quit: make(chan struct{}),
+ cache: NewBlockCache(blockCacheLimit),
+ currentGasLimit: new(big.Int),
}
bc.setLastBlock()
@@ -157,6 +159,10 @@ func (self *ChainManager) Td() *big.Int {
return self.td
}
+func (self *ChainManager) GasLimit() *big.Int {
+ return self.currentGasLimit
+}
+
func (self *ChainManager) LastBlockHash() common.Hash {
self.mu.RLock()
defer self.mu.RUnlock()
@@ -652,6 +658,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.eventMux.Post(ChainHeadEvent{event.Block})
}
case ChainSplitEvent:
diff --git a/core/chain_manager_test.go b/core/chain_manager_test.go
index f16c0f0c3..c2911150a 100644
--- a/core/chain_manager_test.go
+++ b/core/chain_manager_test.go
@@ -256,7 +256,7 @@ func TestChainInsertions(t *testing.T) {
var eventMux event.TypeMux
chainMan := NewChainManager(db, db, &eventMux)
- txPool := NewTxPool(&eventMux, chainMan.State)
+ txPool := NewTxPool(&eventMux, chainMan.State, func() *big.Int { return big.NewInt(100000000) })
blockMan := NewBlockProcessor(db, db, nil, txPool, chainMan, &eventMux)
chainMan.SetProcessor(blockMan)
@@ -302,7 +302,7 @@ func TestChainMultipleInsertions(t *testing.T) {
}
var eventMux event.TypeMux
chainMan := NewChainManager(db, db, &eventMux)
- txPool := NewTxPool(&eventMux, chainMan.State)
+ txPool := NewTxPool(&eventMux, chainMan.State, func() *big.Int { return big.NewInt(100000000) })
blockMan := NewBlockProcessor(db, db, nil, txPool, chainMan, &eventMux)
chainMan.SetProcessor(blockMan)
done := make(chan bool, max)
diff --git a/core/transaction_pool.go b/core/transaction_pool.go
index 392e17856..f6414a882 100644
--- a/core/transaction_pool.go
+++ b/core/transaction_pool.go
@@ -23,6 +23,7 @@ var (
ErrNonExistentAccount = errors.New("Account does not exist")
ErrInsufficientFunds = errors.New("Insufficient funds")
ErrIntrinsicGas = errors.New("Intrinsic gas too low")
+ ErrGasLimit = errors.New("Exceeds block gas limit")
)
const txPoolQueueSize = 50
@@ -52,6 +53,8 @@ type TxPool struct {
quit chan bool
// The state function which will allow us to do some pre checkes
currentState stateFn
+ // The current gas limit function callback
+ gasLimit func() *big.Int
// The actual pool
txs map[common.Hash]*types.Transaction
invalidHashes *set.Set
@@ -63,7 +66,7 @@ type TxPool struct {
eventMux *event.TypeMux
}
-func NewTxPool(eventMux *event.TypeMux, currentStateFn stateFn) *TxPool {
+func NewTxPool(eventMux *event.TypeMux, currentStateFn stateFn, gasLimitFn func() *big.Int) *TxPool {
txPool := &TxPool{
txs: make(map[common.Hash]*types.Transaction),
queue: make(map[common.Address]types.Transactions),
@@ -72,6 +75,7 @@ func NewTxPool(eventMux *event.TypeMux, currentStateFn stateFn) *TxPool {
eventMux: eventMux,
invalidHashes: set.New(),
currentState: currentStateFn,
+ gasLimit: gasLimitFn,
}
return txPool
}
@@ -116,6 +120,10 @@ func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error {
return ErrNonExistentAccount
}
+ if pool.gasLimit().Cmp(tx.GasLimit) < 0 {
+ return ErrGasLimit
+ }
+
if pool.currentState().GetBalance(from).Cmp(new(big.Int).Mul(tx.Price, tx.GasLimit)) < 0 {
return ErrInsufficientFunds
}
diff --git a/core/transaction_pool_test.go b/core/transaction_pool_test.go
index 0e049139e..f96d2b651 100644
--- a/core/transaction_pool_test.go
+++ b/core/transaction_pool_test.go
@@ -23,7 +23,7 @@ func setupTxPool() (*TxPool, *ecdsa.PrivateKey) {
var m event.TypeMux
key, _ := crypto.GenerateKey()
- return NewTxPool(&m, func() *state.StateDB { return statedb }), key
+ return NewTxPool(&m, func() *state.StateDB { return statedb }, func() *big.Int { return big.NewInt(1000000) }), key
}
func TestInvalidTransactions(t *testing.T) {