xeth, core, cmd/utils: Transaction can not be over block gas limit

Transactions will be invalidated when the tx.gas_limit > block.gas_limit
This commit is contained in:
obscuren 2015-04-24 17:45:51 +02:00
parent 3bb6da9bd3
commit 405720b218
8 changed files with 37 additions and 18 deletions

View File

@ -317,7 +317,7 @@ func GetChain(ctx *cli.Context) (*core.ChainManager, common.Database, common.Dat
eventMux := new(event.TypeMux) eventMux := new(event.TypeMux)
chainManager := core.NewChainManager(blockDb, stateDb, eventMux) chainManager := core.NewChainManager(blockDb, stateDb, eventMux)
pow := ethash.New(chainManager) pow := ethash.New(chainManager)
txPool := core.NewTxPool(eventMux, chainManager.State) txPool := core.NewTxPool(eventMux, chainManager.State, chainManager.GasLimit)
blockProcessor := core.NewBlockProcessor(stateDb, extraDb, pow, txPool, chainManager, eventMux) blockProcessor := core.NewBlockProcessor(stateDb, extraDb, pow, txPool, chainManager, eventMux)
chainManager.SetProcessor(blockProcessor) chainManager.SetProcessor(blockProcessor)

View File

@ -124,7 +124,7 @@ func newChainManager(block *types.Block, eventMux *event.TypeMux, db common.Data
// block processor with fake pow // block processor with fake pow
func newBlockProcessor(db common.Database, cman *ChainManager, eventMux *event.TypeMux) *BlockProcessor { func newBlockProcessor(db common.Database, cman *ChainManager, eventMux *event.TypeMux) *BlockProcessor {
chainMan := newChainManager(nil, eventMux, db) 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) bman := NewBlockProcessor(db, db, FakePow{}, txpool, chainMan, eventMux)
return bman return bman
} }

View File

@ -83,6 +83,7 @@ type ChainManager struct {
td *big.Int td *big.Int
currentBlock *types.Block currentBlock *types.Block
lastBlockHash common.Hash lastBlockHash common.Hash
currentGasLimit *big.Int
transState *state.StateDB transState *state.StateDB
txState *state.ManagedState txState *state.ManagedState
@ -101,6 +102,7 @@ func NewChainManager(blockDb, stateDb common.Database, mux *event.TypeMux) *Chai
eventMux: mux, eventMux: mux,
quit: make(chan struct{}), quit: make(chan struct{}),
cache: NewBlockCache(blockCacheLimit), cache: NewBlockCache(blockCacheLimit),
currentGasLimit: new(big.Int),
} }
bc.setLastBlock() bc.setLastBlock()
@ -157,6 +159,10 @@ func (self *ChainManager) Td() *big.Int {
return self.td return self.td
} }
func (self *ChainManager) GasLimit() *big.Int {
return self.currentGasLimit
}
func (self *ChainManager) LastBlockHash() common.Hash { func (self *ChainManager) LastBlockHash() common.Hash {
self.mu.RLock() self.mu.RLock()
defer self.mu.RUnlock() 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 // 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. // and in most cases isn't even necessary.
if i+1 == ev.canonicalCount { if i+1 == ev.canonicalCount {
self.currentGasLimit = CalcGasLimit(self.GetBlock(event.Block.ParentHash()), event.Block)
self.eventMux.Post(ChainHeadEvent{event.Block}) self.eventMux.Post(ChainHeadEvent{event.Block})
} }
case ChainSplitEvent: case ChainSplitEvent:

View File

@ -256,7 +256,7 @@ func TestChainInsertions(t *testing.T) {
var eventMux event.TypeMux var eventMux event.TypeMux
chainMan := NewChainManager(db, db, &eventMux) 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) blockMan := NewBlockProcessor(db, db, nil, txPool, chainMan, &eventMux)
chainMan.SetProcessor(blockMan) chainMan.SetProcessor(blockMan)
@ -302,7 +302,7 @@ func TestChainMultipleInsertions(t *testing.T) {
} }
var eventMux event.TypeMux var eventMux event.TypeMux
chainMan := NewChainManager(db, db, &eventMux) 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) blockMan := NewBlockProcessor(db, db, nil, txPool, chainMan, &eventMux)
chainMan.SetProcessor(blockMan) chainMan.SetProcessor(blockMan)
done := make(chan bool, max) done := make(chan bool, max)

View File

@ -23,6 +23,7 @@ var (
ErrNonExistentAccount = errors.New("Account does not exist") ErrNonExistentAccount = errors.New("Account does not exist")
ErrInsufficientFunds = errors.New("Insufficient funds") ErrInsufficientFunds = errors.New("Insufficient funds")
ErrIntrinsicGas = errors.New("Intrinsic gas too low") ErrIntrinsicGas = errors.New("Intrinsic gas too low")
ErrGasLimit = errors.New("Exceeds block gas limit")
) )
const txPoolQueueSize = 50 const txPoolQueueSize = 50
@ -52,6 +53,8 @@ type TxPool struct {
quit chan bool quit chan bool
// The state function which will allow us to do some pre checkes // The state function which will allow us to do some pre checkes
currentState stateFn currentState stateFn
// The current gas limit function callback
gasLimit func() *big.Int
// The actual pool // The actual pool
txs map[common.Hash]*types.Transaction txs map[common.Hash]*types.Transaction
invalidHashes *set.Set invalidHashes *set.Set
@ -63,7 +66,7 @@ type TxPool struct {
eventMux *event.TypeMux 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{ txPool := &TxPool{
txs: make(map[common.Hash]*types.Transaction), txs: make(map[common.Hash]*types.Transaction),
queue: make(map[common.Address]types.Transactions), queue: make(map[common.Address]types.Transactions),
@ -72,6 +75,7 @@ func NewTxPool(eventMux *event.TypeMux, currentStateFn stateFn) *TxPool {
eventMux: eventMux, eventMux: eventMux,
invalidHashes: set.New(), invalidHashes: set.New(),
currentState: currentStateFn, currentState: currentStateFn,
gasLimit: gasLimitFn,
} }
return txPool return txPool
} }
@ -116,6 +120,10 @@ func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error {
return ErrNonExistentAccount 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 { if pool.currentState().GetBalance(from).Cmp(new(big.Int).Mul(tx.Price, tx.GasLimit)) < 0 {
return ErrInsufficientFunds return ErrInsufficientFunds
} }

View File

@ -23,7 +23,7 @@ func setupTxPool() (*TxPool, *ecdsa.PrivateKey) {
var m event.TypeMux var m event.TypeMux
key, _ := crypto.GenerateKey() 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) { func TestInvalidTransactions(t *testing.T) {

View File

@ -219,7 +219,7 @@ func New(config *Config) (*Ethereum, error) {
eth.chainManager = core.NewChainManager(blockDb, stateDb, eth.EventMux()) eth.chainManager = core.NewChainManager(blockDb, stateDb, eth.EventMux())
eth.downloader = downloader.New(eth.chainManager.HasBlock, eth.chainManager.InsertChain) eth.downloader = downloader.New(eth.chainManager.HasBlock, eth.chainManager.InsertChain)
eth.pow = ethash.New(eth.chainManager) eth.pow = ethash.New(eth.chainManager)
eth.txPool = core.NewTxPool(eth.EventMux(), eth.chainManager.State) eth.txPool = core.NewTxPool(eth.EventMux(), eth.chainManager.State, eth.chainManager.GasLimit)
eth.blockProcessor = core.NewBlockProcessor(stateDb, extraDb, eth.pow, eth.txPool, eth.chainManager, eth.EventMux()) eth.blockProcessor = core.NewBlockProcessor(stateDb, extraDb, eth.pow, eth.txPool, eth.chainManager, eth.EventMux())
eth.chainManager.SetProcessor(eth.blockProcessor) eth.chainManager.SetProcessor(eth.blockProcessor)
eth.whisper = whisper.New() eth.whisper = whisper.New()

View File

@ -236,6 +236,10 @@ func (self *XEth) CurrentBlock() *types.Block {
return self.backend.ChainManager().CurrentBlock() return self.backend.ChainManager().CurrentBlock()
} }
func (self *XEth) GasLimit() *big.Int {
return self.backend.ChainManager().GasLimit()
}
func (self *XEth) Block(v interface{}) *Block { func (self *XEth) Block(v interface{}) *Block {
if n, ok := v.(int32); ok { if n, ok := v.(int32); ok {
return self.BlockByNumber(int64(n)) return self.BlockByNumber(int64(n))