Преглед изворни кода

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

Transactions will be invalidated when the tx.gas_limit > block.gas_limit
obscuren пре 10 година
родитељ
комит
405720b218

+ 1 - 1
cmd/utils/flags.go

@@ -317,7 +317,7 @@ func GetChain(ctx *cli.Context) (*core.ChainManager, common.Database, common.Dat
 	eventMux := new(event.TypeMux)
 	chainManager := core.NewChainManager(blockDb, stateDb, eventMux)
 	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)
 	chainManager.SetProcessor(blockProcessor)
 

+ 1 - 1
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
 }

+ 18 - 11
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:

+ 2 - 2
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)

+ 9 - 1
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
 	}

+ 1 - 1
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) {

+ 1 - 1
eth/backend.go

@@ -219,7 +219,7 @@ func New(config *Config) (*Ethereum, error) {
 	eth.chainManager = core.NewChainManager(blockDb, stateDb, eth.EventMux())
 	eth.downloader = downloader.New(eth.chainManager.HasBlock, eth.chainManager.InsertChain)
 	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.chainManager.SetProcessor(eth.blockProcessor)
 	eth.whisper = whisper.New()

+ 4 - 0
xeth/xeth.go

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