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:
parent
3bb6da9bd3
commit
405720b218
@ -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)
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -78,11 +78,12 @@ type ChainManager struct {
|
|||||||
eventMux *event.TypeMux
|
eventMux *event.TypeMux
|
||||||
genesisBlock *types.Block
|
genesisBlock *types.Block
|
||||||
// Last known total difficulty
|
// Last known total difficulty
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
tsmu sync.RWMutex
|
tsmu sync.RWMutex
|
||||||
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
|
||||||
@ -95,12 +96,13 @@ type ChainManager struct {
|
|||||||
|
|
||||||
func NewChainManager(blockDb, stateDb common.Database, mux *event.TypeMux) *ChainManager {
|
func NewChainManager(blockDb, stateDb common.Database, mux *event.TypeMux) *ChainManager {
|
||||||
bc := &ChainManager{
|
bc := &ChainManager{
|
||||||
blockDb: blockDb,
|
blockDb: blockDb,
|
||||||
stateDb: stateDb,
|
stateDb: stateDb,
|
||||||
genesisBlock: GenesisBlock(stateDb),
|
genesisBlock: GenesisBlock(stateDb),
|
||||||
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:
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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()
|
||||||
|
@ -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))
|
||||||
|
Loading…
Reference in New Issue
Block a user