diff options
author | Péter Szilágyi <peterke@gmail.com> | 2017-11-13 19:47:27 +0800 |
---|---|---|
committer | Péter Szilágyi <peterke@gmail.com> | 2018-01-03 20:45:35 +0800 |
commit | 6f69cdd109b1dd692b8dfb15e7c53d2051fbc946 (patch) | |
tree | c92974f8b82209073ad1ee3faec6e149f834bf69 /core | |
parent | b8caba97099ee5eed33c3b80dd4ea540722e7d8f (diff) | |
download | dexon-6f69cdd109b1dd692b8dfb15e7c53d2051fbc946.tar dexon-6f69cdd109b1dd692b8dfb15e7c53d2051fbc946.tar.gz dexon-6f69cdd109b1dd692b8dfb15e7c53d2051fbc946.tar.bz2 dexon-6f69cdd109b1dd692b8dfb15e7c53d2051fbc946.tar.lz dexon-6f69cdd109b1dd692b8dfb15e7c53d2051fbc946.tar.xz dexon-6f69cdd109b1dd692b8dfb15e7c53d2051fbc946.tar.zst dexon-6f69cdd109b1dd692b8dfb15e7c53d2051fbc946.zip |
all: switch gas limits from big.Int to uint64
Diffstat (limited to 'core')
36 files changed, 376 insertions, 409 deletions
diff --git a/core/bench_test.go b/core/bench_test.go index 9c7cd81c4..f976331d1 100644 --- a/core/bench_test.go +++ b/core/bench_test.go @@ -84,7 +84,7 @@ func genValueTx(nbytes int) func(int, *BlockGen) { return func(i int, gen *BlockGen) { toaddr := common.Address{} data := make([]byte, nbytes) - gas := IntrinsicGas(data, false, false) + gas, _ := IntrinsicGas(data, false, false) tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(benchRootAddr), toaddr, big.NewInt(1), gas, nil, data), types.HomesteadSigner{}, benchRootKey) gen.AddTx(tx) } @@ -93,7 +93,6 @@ func genValueTx(nbytes int) func(int, *BlockGen) { var ( ringKeys = make([]*ecdsa.PrivateKey, 1000) ringAddrs = make([]common.Address, len(ringKeys)) - bigTxGas = new(big.Int).SetUint64(params.TxGas) ) func init() { @@ -113,8 +112,8 @@ func genTxRing(naccounts int) func(int, *BlockGen) { return func(i int, gen *BlockGen) { gas := CalcGasLimit(gen.PrevBlock(i - 1)) for { - gas.Sub(gas, bigTxGas) - if gas.Cmp(bigTxGas) < 0 { + gas -= params.TxGas + if gas < params.TxGas { break } to := (from + 1) % naccounts @@ -122,7 +121,7 @@ func genTxRing(naccounts int) func(int, *BlockGen) { gen.TxNonce(ringAddrs[from]), ringAddrs[to], benchRootFunds, - bigTxGas, + params.TxGas, nil, nil, ) diff --git a/core/block_validator.go b/core/block_validator.go index e9cfd0482..143728bb8 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -18,9 +18,7 @@ package core import ( "fmt" - "math/big" - "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" @@ -76,10 +74,10 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error { // transition, such as amount of used gas, the receipt roots and the state root // itself. ValidateState returns a database batch if the validation was a success // otherwise nil and an error is returned. -func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *state.StateDB, receipts types.Receipts, usedGas *big.Int) error { +func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *state.StateDB, receipts types.Receipts, usedGas uint64) error { header := block.Header() - if block.GasUsed().Cmp(usedGas) != 0 { - return fmt.Errorf("invalid gas used (remote: %v local: %v)", block.GasUsed(), usedGas) + if block.GasUsed() != usedGas { + return fmt.Errorf("invalid gas used (remote: %d local: %d)", block.GasUsed(), usedGas) } // Validate the received block's bloom with the one derived from the generated receipts. // For valid blocks this should always validate to true. @@ -101,17 +99,13 @@ func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *stat } // CalcGasLimit computes the gas limit of the next block after parent. -// The result may be modified by the caller. // This is miner strategy, not consensus protocol. -func CalcGasLimit(parent *types.Block) *big.Int { +func CalcGasLimit(parent *types.Block) uint64 { // contrib = (parentGasUsed * 3 / 2) / 1024 - contrib := new(big.Int).Mul(parent.GasUsed(), big.NewInt(3)) - contrib = contrib.Div(contrib, big.NewInt(2)) - contrib = contrib.Div(contrib, params.GasLimitBoundDivisor) + contrib := (parent.GasUsed() + parent.GasUsed()/2) / params.GasLimitBoundDivisor // decay = parentGasLimit / 1024 -1 - decay := new(big.Int).Div(parent.GasLimit(), params.GasLimitBoundDivisor) - decay.Sub(decay, big.NewInt(1)) + decay := parent.GasLimit()/params.GasLimitBoundDivisor - 1 /* strategy: gasLimit of block-to-mine is set based on parent's @@ -120,15 +114,17 @@ func CalcGasLimit(parent *types.Block) *big.Int { at that usage) the amount increased/decreased depends on how far away from parentGasLimit * (2/3) parentGasUsed is. */ - gl := new(big.Int).Sub(parent.GasLimit(), decay) - gl = gl.Add(gl, contrib) - gl.Set(math.BigMax(gl, params.MinGasLimit)) - + limit := parent.GasLimit() - decay + contrib + if limit < params.MinGasLimit { + limit = params.MinGasLimit + } // however, if we're now below the target (TargetGasLimit) we increase the // limit as much as we can (parentGasLimit / 1024 -1) - if gl.Cmp(params.TargetGasLimit) < 0 { - gl.Add(parent.GasLimit(), decay) - gl.Set(math.BigMin(gl, params.TargetGasLimit)) + if limit < params.TargetGasLimit { + limit = parent.GasLimit() + decay + if limit > params.TargetGasLimit { + limit = params.TargetGasLimit + } } - return gl + return limit } diff --git a/core/blockchain.go b/core/blockchain.go index 812f9e562..737fbe3ee 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -305,7 +305,7 @@ func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error { } // GasLimit returns the gas limit of the current HEAD block. -func (bc *BlockChain) GasLimit() *big.Int { +func (bc *BlockChain) GasLimit() uint64 { bc.mu.RLock() defer bc.mu.RUnlock() @@ -677,9 +677,9 @@ func SetReceiptsData(config *params.ChainConfig, block *types.Block, receipts ty } // The used gas can be calculated based on previous receipts if j == 0 { - receipts[j].GasUsed = new(big.Int).Set(receipts[j].CumulativeGasUsed) + receipts[j].GasUsed = receipts[j].CumulativeGasUsed } else { - receipts[j].GasUsed = new(big.Int).Sub(receipts[j].CumulativeGasUsed, receipts[j-1].CumulativeGasUsed) + receipts[j].GasUsed = receipts[j].CumulativeGasUsed - receipts[j-1].CumulativeGasUsed } // The derived log fields can simply be set from the block and transaction for k := 0; k < len(receipts[j].Logs); k++ { @@ -1002,7 +1002,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty events = append(events, ChainSideEvent{block}) } stats.processed++ - stats.usedGas += usedGas.Uint64() + stats.usedGas += usedGas stats.report(chain, i) } // Append a single chain head event if we've progressed the chain diff --git a/core/blockchain_test.go b/core/blockchain_test.go index cb2e47104..26c816027 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -340,11 +340,11 @@ func testBrokenChain(t *testing.T, full bool) { type bproc struct{} func (bproc) ValidateBody(*types.Block) error { return nil } -func (bproc) ValidateState(block, parent *types.Block, state *state.StateDB, receipts types.Receipts, usedGas *big.Int) error { +func (bproc) ValidateState(block, parent *types.Block, state *state.StateDB, receipts types.Receipts, usedGas uint64) error { return nil } -func (bproc) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, *big.Int, error) { - return nil, nil, new(big.Int), nil +func (bproc) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) { + return nil, nil, 0, nil } func makeHeaderChainWithDiff(genesis *types.Block, d []int, seed byte) []*types.Header { @@ -506,8 +506,8 @@ func testReorgBadHashes(t *testing.T, full bool) { if ncm.CurrentBlock().Hash() != blocks[2].Header().Hash() { t.Errorf("last block hash mismatch: have: %x, want %x", ncm.CurrentBlock().Hash(), blocks[2].Header().Hash()) } - if blocks[2].Header().GasLimit.Cmp(ncm.GasLimit()) != 0 { - t.Errorf("last block gasLimit mismatch: have: %x, want %x", ncm.GasLimit(), blocks[2].Header().GasLimit) + if blocks[2].Header().GasLimit != ncm.GasLimit() { + t.Errorf("last block gasLimit mismatch: have: %d, want %d", ncm.GasLimit(), blocks[2].Header().GasLimit) } } else { if ncm.CurrentHeader().Hash() != headers[2].Hash() { @@ -594,7 +594,7 @@ func TestFastVsFullChains(t *testing.T) { // If the block number is multiple of 3, send a few bonus transactions to the miner if i%3 == 2 { for j := 0; j < i%4+1; j++ { - tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), bigTxGas, nil, nil), signer, key) + tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil), signer, key) if err != nil { panic(err) } @@ -767,8 +767,8 @@ func TestChainTxReorgs(t *testing.T) { // Create two transactions shared between the chains: // - postponed: transaction included at a later block in the forked chain // - swapped: transaction included at the same block number in the forked chain - postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), bigTxGas, nil, nil), signer, key1) - swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), bigTxGas, nil, nil), signer, key1) + postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1) + swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1) // Create two transactions that will be dropped by the forked chain: // - pastDrop: transaction dropped retroactively from a past block @@ -784,13 +784,13 @@ func TestChainTxReorgs(t *testing.T) { chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) { switch i { case 0: - pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), bigTxGas, nil, nil), signer, key2) + pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2) gen.AddTx(pastDrop) // This transaction will be dropped in the fork from below the split point gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork case 2: - freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), bigTxGas, nil, nil), signer, key2) + freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2) gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point gen.AddTx(swapped) // This transaction will be swapped out at the exact height @@ -809,18 +809,18 @@ func TestChainTxReorgs(t *testing.T) { chain, _ = GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 5, func(i int, gen *BlockGen) { switch i { case 0: - pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), bigTxGas, nil, nil), signer, key3) + pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3) gen.AddTx(pastAdd) // This transaction needs to be injected during reorg case 2: gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain gen.AddTx(swapped) // This transaction was swapped from the exact current spot in the original chain - freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), bigTxGas, nil, nil), signer, key3) + freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3) gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time case 3: - futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), bigTxGas, nil, nil), signer, key3) + futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3) gen.AddTx(futureAdd) // This transaction will be added after a full reorg } }) @@ -877,7 +877,7 @@ func TestLogReorgs(t *testing.T) { blockchain.SubscribeRemovedLogsEvent(rmLogsCh) chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) { if i == 1 { - tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), big.NewInt(1000000), new(big.Int), code), signer, key1) + tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1) if err != nil { t.Fatalf("failed to create tx: %v", err) } @@ -926,7 +926,7 @@ func TestReorgSideEvent(t *testing.T) { } replacementBlocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, gen *BlockGen) { - tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), big.NewInt(1000000), new(big.Int), nil), signer, key1) + tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), nil), signer, key1) if i == 2 { gen.OffsetTime(-9) } @@ -1051,7 +1051,7 @@ func TestEIP155Transition(t *testing.T) { tx *types.Transaction err error basicTx = func(signer types.Signer) (*types.Transaction, error) { - return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), big.NewInt(21000), new(big.Int), nil), signer, key) + return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key) } ) switch i { @@ -1114,7 +1114,7 @@ func TestEIP155Transition(t *testing.T) { tx *types.Transaction err error basicTx = func(signer types.Signer) (*types.Transaction, error) { - return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), big.NewInt(21000), new(big.Int), nil), signer, key) + return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key) } ) switch i { @@ -1162,11 +1162,11 @@ func TestEIP161AccountRemoval(t *testing.T) { ) switch i { case 0: - tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), big.NewInt(21000), new(big.Int), nil), signer, key) + tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key) case 1: - tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), big.NewInt(21000), new(big.Int), nil), signer, key) + tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key) case 2: - tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), big.NewInt(21000), new(big.Int), nil), signer, key) + tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key) } if err != nil { t.Fatal(err) diff --git a/core/chain_makers.go b/core/chain_makers.go index 0e5e3791e..5e264a994 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -86,7 +86,7 @@ func (b *BlockGen) AddTx(tx *types.Transaction) { b.SetCoinbase(common.Address{}) } b.statedb.Prepare(tx.Hash(), common.Hash{}, len(b.txs)) - receipt, _, err := ApplyTransaction(b.config, nil, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, b.header.GasUsed, vm.Config{}) + receipt, _, err := ApplyTransaction(b.config, nil, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vm.Config{}) if err != nil { panic(err) } @@ -232,7 +232,6 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.S UncleHash: parent.UncleHash(), }), GasLimit: CalcGasLimit(parent), - GasUsed: new(big.Int), Number: new(big.Int).Add(parent.Number(), common.Big1), Time: time, } diff --git a/core/chain_makers_test.go b/core/chain_makers_test.go index 011efe342..a3b80da29 100644 --- a/core/chain_makers_test.go +++ b/core/chain_makers_test.go @@ -54,13 +54,13 @@ func ExampleGenerateChain() { switch i { case 0: // In block 1, addr1 sends addr2 some ether. - tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(10000), bigTxGas, nil, nil), signer, key1) + tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(10000), params.TxGas, nil, nil), signer, key1) gen.AddTx(tx) case 1: // In block 2, addr1 sends some more ether to addr2. // addr2 passes it on to addr3. - tx1, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(1000), bigTxGas, nil, nil), signer, key1) - tx2, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr3, big.NewInt(1000), bigTxGas, nil, nil), signer, key2) + tx1, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key1) + tx2, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key2) gen.AddTx(tx1) gen.AddTx(tx2) case 2: diff --git a/core/database_util_test.go b/core/database_util_test.go index 36f43cf50..ab4e45a47 100644 --- a/core/database_util_test.go +++ b/core/database_util_test.go @@ -290,9 +290,9 @@ func TestHeadStorage(t *testing.T) { func TestLookupStorage(t *testing.T) { db, _ := ethdb.NewMemDatabase() - tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), big.NewInt(1111), big.NewInt(11111), []byte{0x11, 0x11, 0x11}) - tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), big.NewInt(2222), big.NewInt(22222), []byte{0x22, 0x22, 0x22}) - tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), big.NewInt(3333), big.NewInt(33333), []byte{0x33, 0x33, 0x33}) + tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11}) + tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), []byte{0x22, 0x22, 0x22}) + tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33}) txs := []*types.Transaction{tx1, tx2, tx3} block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, txs, nil, nil) @@ -337,25 +337,25 @@ func TestBlockReceiptStorage(t *testing.T) { receipt1 := &types.Receipt{ Status: types.ReceiptStatusFailed, - CumulativeGasUsed: big.NewInt(1), + CumulativeGasUsed: 1, Logs: []*types.Log{ {Address: common.BytesToAddress([]byte{0x11})}, {Address: common.BytesToAddress([]byte{0x01, 0x11})}, }, TxHash: common.BytesToHash([]byte{0x11, 0x11}), ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}), - GasUsed: big.NewInt(111111), + GasUsed: 111111, } receipt2 := &types.Receipt{ PostState: common.Hash{2}.Bytes(), - CumulativeGasUsed: big.NewInt(2), + CumulativeGasUsed: 2, Logs: []*types.Log{ {Address: common.BytesToAddress([]byte{0x22})}, {Address: common.BytesToAddress([]byte{0x02, 0x22})}, }, TxHash: common.BytesToHash([]byte{0x22, 0x22}), ContractAddress: common.BytesToAddress([]byte{0x02, 0x22, 0x22}), - GasUsed: big.NewInt(222222), + GasUsed: 222222, } receipts := []*types.Receipt{receipt1, receipt2} diff --git a/core/evm.go b/core/evm.go index 4912aa650..55db53927 100644 --- a/core/evm.go +++ b/core/evm.go @@ -53,7 +53,7 @@ func NewEVMContext(msg Message, header *types.Header, chain ChainContext, author BlockNumber: new(big.Int).Set(header.Number), Time: new(big.Int).Set(header.Time), Difficulty: new(big.Int).Set(header.Difficulty), - GasLimit: new(big.Int).Set(header.GasLimit), + GasLimit: header.GasLimit, GasPrice: new(big.Int).Set(msg.GasPrice()), } } diff --git a/core/gaspool.go b/core/gaspool.go index ef99908cf..c3ee5c198 100644 --- a/core/gaspool.go +++ b/core/gaspool.go @@ -16,31 +16,34 @@ package core -import "math/big" +import ( + "fmt" + "math" +) -// GasPool tracks the amount of gas available during -// execution of the transactions in a block. -// The zero value is a pool with zero gas available. -type GasPool big.Int +// GasPool tracks the amount of gas available during execution of the transactions +// in a block. The zero value is a pool with zero gas available. +type GasPool uint64 // AddGas makes gas available for execution. -func (gp *GasPool) AddGas(amount *big.Int) *GasPool { - i := (*big.Int)(gp) - i.Add(i, amount) +func (gp *GasPool) AddGas(amount uint64) *GasPool { + if uint64(*gp) > math.MaxUint64-amount { + panic("gas pool pushed above uint64") + } + *(*uint64)(gp) += amount return gp } // SubGas deducts the given amount from the pool if enough gas is // available and returns an error otherwise. -func (gp *GasPool) SubGas(amount *big.Int) error { - i := (*big.Int)(gp) - if i.Cmp(amount) < 0 { +func (gp *GasPool) SubGas(amount uint64) error { + if uint64(*gp) < amount { return ErrGasLimitReached } - i.Sub(i, amount) + *(*uint64)(gp) -= amount return nil } func (gp *GasPool) String() string { - return (*big.Int)(gp).String() + return fmt.Sprintf("%d", *gp) } diff --git a/core/gen_genesis.go b/core/gen_genesis.go index 4d75704a6..6f941e35a 100644 --- a/core/gen_genesis.go +++ b/core/gen_genesis.go @@ -13,6 +13,8 @@ import ( "github.com/ethereum/go-ethereum/params" ) +var _ = (*genesisSpecMarshaling)(nil) + func (g Genesis) MarshalJSON() ([]byte, error) { type Genesis struct { Config *params.ChainConfig `json:"config"` diff --git a/core/genesis.go b/core/genesis.go index df491ce0f..e22985b80 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -239,8 +239,8 @@ func (g *Genesis) ToBlock() (*types.Block, *state.StateDB) { Time: new(big.Int).SetUint64(g.Timestamp), ParentHash: g.ParentHash, Extra: g.ExtraData, - GasLimit: new(big.Int).SetUint64(g.GasLimit), - GasUsed: new(big.Int).SetUint64(g.GasUsed), + GasLimit: g.GasLimit, + GasUsed: g.GasUsed, Difficulty: g.Difficulty, MixDigest: g.Mixhash, Coinbase: g.Coinbase, diff --git a/core/state/journal.go b/core/state/journal.go index ddc819fe5..a89bb3d13 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -62,7 +62,7 @@ type ( // Changes to other state values. refundChange struct { - prev *big.Int + prev uint64 } addLogChange struct { txhash common.Hash diff --git a/core/state/statedb.go b/core/state/statedb.go index de9fb367d..8e29104d5 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -57,7 +57,7 @@ type StateDB struct { dbErr error // The refund counter, also used by state transitioning. - refund *big.Int + refund uint64 thash, bhash common.Hash txIndex int @@ -86,7 +86,6 @@ func New(root common.Hash, db Database) (*StateDB, error) { trie: tr, stateObjects: make(map[common.Address]*stateObject), stateObjectsDirty: make(map[common.Address]struct{}), - refund: new(big.Int), logs: make(map[common.Hash][]*types.Log), preimages: make(map[common.Hash][]byte), }, nil @@ -161,9 +160,9 @@ func (self *StateDB) Preimages() map[common.Hash][]byte { return self.preimages } -func (self *StateDB) AddRefund(gas *big.Int) { - self.journal = append(self.journal, refundChange{prev: new(big.Int).Set(self.refund)}) - self.refund.Add(self.refund, gas) +func (self *StateDB) AddRefund(gas uint64) { + self.journal = append(self.journal, refundChange{prev: self.refund}) + self.refund += gas } // Exist reports whether the given account address exists in the state. @@ -456,7 +455,7 @@ func (self *StateDB) Copy() *StateDB { trie: self.db.CopyTrie(self.trie), stateObjects: make(map[common.Address]*stateObject, len(self.stateObjectsDirty)), stateObjectsDirty: make(map[common.Address]struct{}, len(self.stateObjectsDirty)), - refund: new(big.Int).Set(self.refund), + refund: self.refund, logs: make(map[common.Hash][]*types.Log, len(self.logs)), logSize: self.logSize, preimages: make(map[common.Hash][]byte), @@ -506,9 +505,7 @@ func (self *StateDB) RevertToSnapshot(revid int) { } // GetRefund returns the current value of the refund counter. -// The return value must not be modified by the caller and will become -// invalid at the next call to AddRefund. -func (self *StateDB) GetRefund() *big.Int { +func (self *StateDB) GetRefund() uint64 { return self.refund } @@ -568,7 +565,7 @@ func (s *StateDB) DeleteSuicides() { func (s *StateDB) clearJournalAndRefund() { s.journal = nil s.validRevisions = s.validRevisions[:0] - s.refund = new(big.Int) + s.refund = 0 } // CommitTo writes the state to the given database. diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index e9944cd74..5c80e3aa5 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -263,7 +263,7 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction { { name: "AddRefund", fn: func(a testAction, s *StateDB) { - s.AddRefund(big.NewInt(a.args[0])) + s.AddRefund(uint64(a.args[0])) }, args: make([]int64, 1), noAddr: true, @@ -396,7 +396,7 @@ func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error { } } - if state.GetRefund().Cmp(checkstate.GetRefund()) != 0 { + if state.GetRefund() != checkstate.GetRefund() { return fmt.Errorf("got GetRefund() == %d, want GetRefund() == %d", state.GetRefund(), checkstate.GetRefund()) } diff --git a/core/state_processor.go b/core/state_processor.go index 689c83785..4dc58b9de 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -17,8 +17,6 @@ package core import ( - "math/big" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/misc" @@ -55,13 +53,13 @@ func NewStateProcessor(config *params.ChainConfig, bc *BlockChain, engine consen // Process returns the receipts and logs accumulated during the process and // returns the amount of gas that was used in the process. If any of the // transactions failed to execute due to insufficient gas it will return an error. -func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, *big.Int, error) { +func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) { var ( - receipts types.Receipts - totalUsedGas = big.NewInt(0) - header = block.Header() - allLogs []*types.Log - gp = new(GasPool).AddGas(block.GasLimit()) + receipts types.Receipts + usedGas = new(uint64) + header = block.Header() + allLogs []*types.Log + gp = new(GasPool).AddGas(block.GasLimit()) ) // Mutate the the block and state according to any hard-fork specs if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 { @@ -70,9 +68,9 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg // Iterate over and process the individual transactions for i, tx := range block.Transactions() { statedb.Prepare(tx.Hash(), block.Hash(), i) - receipt, _, err := ApplyTransaction(p.config, p.bc, nil, gp, statedb, header, tx, totalUsedGas, cfg) + receipt, _, err := ApplyTransaction(p.config, p.bc, nil, gp, statedb, header, tx, usedGas, cfg) if err != nil { - return nil, nil, nil, err + return nil, nil, 0, err } receipts = append(receipts, receipt) allLogs = append(allLogs, receipt.Logs...) @@ -80,17 +78,17 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg // Finalize the block, applying any consensus engine specific extras (e.g. block rewards) p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles(), receipts) - return receipts, allLogs, totalUsedGas, nil + return receipts, allLogs, *usedGas, nil } // ApplyTransaction attempts to apply a transaction to the given state database // and uses the input parameters for its environment. It returns the receipt // for the transaction, gas used and an error if the transaction failed, // indicating the block was invalid. -func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *big.Int, cfg vm.Config) (*types.Receipt, *big.Int, error) { +func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, uint64, error) { msg, err := tx.AsMessage(types.MakeSigner(config, header.Number)) if err != nil { - return nil, nil, err + return nil, 0, err } // Create a new context to be used in the EVM environment context := NewEVMContext(msg, header, bc, author) @@ -100,9 +98,8 @@ func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common // Apply the transaction to the current state (included in the env) _, gas, failed, err := ApplyMessage(vmenv, msg, gp) if err != nil { - return nil, nil, err + return nil, 0, err } - // Update the state with pending changes var root []byte if config.IsByzantium(header.Number) { @@ -110,18 +107,17 @@ func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common } else { root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes() } - usedGas.Add(usedGas, gas) + *usedGas += gas // Create a new receipt for the transaction, storing the intermediate root and gas used by the tx // based on the eip phase, we're passing wether the root touch-delete accounts. - receipt := types.NewReceipt(root, failed, usedGas) + receipt := types.NewReceipt(root, failed, *usedGas) receipt.TxHash = tx.Hash() - receipt.GasUsed = new(big.Int).Set(gas) + receipt.GasUsed = gas // if the transaction created a contract, store the creation address in the receipt. if msg.To() == nil { receipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce()) } - // Set the receipt logs and create a bloom for filtering receipt.Logs = statedb.GetLogs(tx.Hash()) receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) diff --git a/core/state_transition.go b/core/state_transition.go index e7a068589..390473fff 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -18,17 +18,16 @@ package core import ( "errors" + "math" "math/big" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" ) var ( - Big0 = big.NewInt(0) errInsufficientBalanceForGas = errors.New("insufficient balance to pay for gas") ) @@ -54,7 +53,7 @@ type StateTransition struct { msg Message gas uint64 gasPrice *big.Int - initialGas *big.Int + initialGas uint64 value *big.Int data []byte state vm.StateDB @@ -68,7 +67,7 @@ type Message interface { To() *common.Address GasPrice() *big.Int - Gas() *big.Int + Gas() uint64 Value() *big.Int Nonce() uint64 @@ -76,45 +75,49 @@ type Message interface { Data() []byte } -// IntrinsicGas computes the 'intrinsic gas' for a message -// with the given data. -// -// TODO convert to uint64 -func IntrinsicGas(data []byte, contractCreation, homestead bool) *big.Int { - igas := new(big.Int) +// IntrinsicGas computes the 'intrinsic gas' for a message with the given data. +func IntrinsicGas(data []byte, contractCreation, homestead bool) (uint64, error) { + // Set the starting gas for the raw transaction + var gas uint64 if contractCreation && homestead { - igas.SetUint64(params.TxGasContractCreation) + gas = params.TxGasContractCreation } else { - igas.SetUint64(params.TxGas) + gas = params.TxGas } + // Bump the required gas by the amount of transactional data if len(data) > 0 { - var nz int64 + // Zero and non-zero bytes are priced differently + var nz uint64 for _, byt := range data { if byt != 0 { nz++ } } - m := big.NewInt(nz) - m.Mul(m, new(big.Int).SetUint64(params.TxDataNonZeroGas)) - igas.Add(igas, m) - m.SetInt64(int64(len(data)) - nz) - m.Mul(m, new(big.Int).SetUint64(params.TxDataZeroGas)) - igas.Add(igas, m) + // Make sure we don't exceed uint64 for all data combinations + if (math.MaxUint64-gas)/params.TxDataNonZeroGas < nz { + return 0, vm.ErrOutOfGas + } + gas += nz * params.TxDataNonZeroGas + + z := uint64(len(data)) - nz + if (math.MaxUint64-gas)/params.TxDataZeroGas < z { + return 0, vm.ErrOutOfGas + } + gas += z * params.TxDataZeroGas } - return igas + return gas, nil } // NewStateTransition initialises and returns a new state transition object. func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition { return &StateTransition{ - gp: gp, - evm: evm, - msg: msg, - gasPrice: msg.GasPrice(), - initialGas: new(big.Int), - value: msg.Value(), - data: msg.Data(), - state: evm.StateDB, + gp: gp, + evm: evm, + msg: msg, + gasPrice: msg.GasPrice(), + value: msg.Value(), + data: msg.Data(), + state: evm.StateDB, } } @@ -125,11 +128,8 @@ func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition // the gas used (which includes gas refunds) and an error if it failed. An error always // indicates a core error meaning that the message would always fail for that particular // state and would never be accepted within a block. -func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) ([]byte, *big.Int, bool, error) { - st := NewStateTransition(evm, msg, gp) - - ret, _, gasUsed, failed, err := st.TransitionDb() - return ret, gasUsed, failed, err +func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) ([]byte, uint64, bool, error) { + return NewStateTransition(evm, msg, gp).TransitionDb() } func (st *StateTransition) from() vm.AccountRef { @@ -166,26 +166,20 @@ func (st *StateTransition) useGas(amount uint64) error { } func (st *StateTransition) buyGas() error { - mgas := st.msg.Gas() - if mgas.BitLen() > 64 { - return vm.ErrOutOfGas - } - - mgval := new(big.Int).Mul(mgas, st.gasPrice) - var ( state = st.state sender = st.from() ) + mgval := new(big.Int).Mul(new(big.Int).SetUint64(st.msg.Gas()), st.gasPrice) if state.GetBalance(sender.Address()).Cmp(mgval) < 0 { return errInsufficientBalanceForGas } - if err := st.gp.SubGas(mgas); err != nil { + if err := st.gp.SubGas(st.msg.Gas()); err != nil { return err } - st.gas += mgas.Uint64() + st.gas += st.msg.Gas() - st.initialGas.Set(mgas) + st.initialGas = st.msg.Gas() state.SubBalance(sender.Address(), mgval) return nil } @@ -206,10 +200,10 @@ func (st *StateTransition) preCheck() error { return st.buyGas() } -// TransitionDb will transition the state by applying the current message and returning the result -// including the required gas for the operation as well as the used gas. It returns an error if it +// TransitionDb will transition the state by applying the current message and +// returning the result including the the used gas. It returns an error if it // failed. An error indicates a consensus issue. -func (st *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big.Int, failed bool, err error) { +func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bool, err error) { if err = st.preCheck(); err != nil { return } @@ -220,13 +214,9 @@ func (st *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big contractCreation := msg.To() == nil // Pay intrinsic gas - // TODO convert to uint64 - intrinsicGas := IntrinsicGas(st.data, contractCreation, homestead) - if intrinsicGas.BitLen() > 64 { - return nil, nil, nil, false, vm.ErrOutOfGas - } - if err = st.useGas(intrinsicGas.Uint64()); err != nil { - return nil, nil, nil, false, err + gas, err := IntrinsicGas(st.data, contractCreation, homestead) + if err = st.useGas(gas); err != nil { + return nil, 0, false, err } var ( @@ -249,36 +239,35 @@ func (st *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big // sufficient balance to make the transfer happen. The first // balance transfer may never fail. if vmerr == vm.ErrInsufficientBalance { - return nil, nil, nil, false, vmerr + return nil, 0, false, vmerr } } - requiredGas = new(big.Int).Set(st.gasUsed()) - st.refundGas() - st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(st.gasUsed(), st.gasPrice)) + st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice)) - return ret, requiredGas, st.gasUsed(), vmerr != nil, err + return ret, st.gasUsed(), vmerr != nil, err } func (st *StateTransition) refundGas() { - // Return eth for remaining gas to the sender account, - // exchanged at the original rate. - sender := st.from() // err already checked - remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gas), st.gasPrice) - st.state.AddBalance(sender.Address(), remaining) - // Apply refund counter, capped to half of the used gas. - uhalf := remaining.Div(st.gasUsed(), common.Big2) - refund := math.BigMin(uhalf, st.state.GetRefund()) - st.gas += refund.Uint64() + refund := st.gasUsed() / 2 + if refund > st.state.GetRefund() { + refund = st.state.GetRefund() + } + st.gas += refund - st.state.AddBalance(sender.Address(), refund.Mul(refund, st.gasPrice)) + // Return ETH for remaining gas, exchanged at the original rate. + sender := st.from() + + remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gas), st.gasPrice) + st.state.AddBalance(sender.Address(), remaining) // Also return remaining gas to the block gas counter so it is // available for the next transaction. - st.gp.AddGas(new(big.Int).SetUint64(st.gas)) + st.gp.AddGas(st.gas) } -func (st *StateTransition) gasUsed() *big.Int { - return new(big.Int).Sub(st.initialGas, new(big.Int).SetUint64(st.gas)) +// gasUsed returns the amount of gas used up by the state transition. +func (st *StateTransition) gasUsed() uint64 { + return st.initialGas - st.gas } diff --git a/core/tx_list.go b/core/tx_list.go index 838433b89..55fc42617 100644 --- a/core/tx_list.go +++ b/core/tx_list.go @@ -224,7 +224,7 @@ type txList struct { txs *txSortedMap // Heap indexed sorted hash map of the transactions costcap *big.Int // Price of the highest costing transaction (reset only if exceeds balance) - gascap *big.Int // Gas limit of the highest spending transaction (reset only if exceeds block limit) + gascap uint64 // Gas limit of the highest spending transaction (reset only if exceeds block limit) } // newTxList create a new transaction list for maintaining nonce-indexable fast, @@ -234,7 +234,6 @@ func newTxList(strict bool) *txList { strict: strict, txs: newTxSortedMap(), costcap: new(big.Int), - gascap: new(big.Int), } } @@ -266,7 +265,7 @@ func (l *txList) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Tran if cost := tx.Cost(); l.costcap.Cmp(cost) < 0 { l.costcap = cost } - if gas := tx.Gas(); l.gascap.Cmp(gas) < 0 { + if gas := tx.Gas(); l.gascap < gas { l.gascap = gas } return true, old @@ -288,16 +287,16 @@ func (l *txList) Forward(threshold uint64) types.Transactions { // a point in calculating all the costs or if the balance covers all. If the threshold // is lower than the costgas cap, the caps will be reset to a new high after removing // the newly invalidated transactions. -func (l *txList) Filter(costLimit, gasLimit *big.Int) (types.Transactions, types.Transactions) { +func (l *txList) Filter(costLimit *big.Int, gasLimit uint64) (types.Transactions, types.Transactions) { // If all transactions are below the threshold, short circuit - if l.costcap.Cmp(costLimit) <= 0 && l.gascap.Cmp(gasLimit) <= 0 { + if l.costcap.Cmp(costLimit) <= 0 && l.gascap <= gasLimit { return nil, nil } l.costcap = new(big.Int).Set(costLimit) // Lower the caps to the thresholds - l.gascap = new(big.Int).Set(gasLimit) + l.gascap = gasLimit // Filter out all the transactions above the account's funds - removed := l.txs.Filter(func(tx *types.Transaction) bool { return tx.Cost().Cmp(costLimit) > 0 || tx.Gas().Cmp(gasLimit) > 0 }) + removed := l.txs.Filter(func(tx *types.Transaction) bool { return tx.Cost().Cmp(costLimit) > 0 || tx.Gas() > gasLimit }) // If the list was strict, filter anything above the lowest nonce var invalids types.Transactions diff --git a/core/tx_list_test.go b/core/tx_list_test.go index b4f0b5228..d579f501a 100644 --- a/core/tx_list_test.go +++ b/core/tx_list_test.go @@ -17,7 +17,6 @@ package core import ( - "math/big" "math/rand" "testing" @@ -33,7 +32,7 @@ func TestStrictTxListAdd(t *testing.T) { txs := make(types.Transactions, 1024) for i := 0; i < len(txs); i++ { - txs[i] = transaction(uint64(i), new(big.Int), key) + txs[i] = transaction(uint64(i), 0, key) } // Insert the transactions in a random order list := newTxList(true) diff --git a/core/tx_pool.go b/core/tx_pool.go index dade5d09f..dc3ddc423 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -197,7 +197,7 @@ type TxPool struct { currentState *state.StateDB // Current state in the blockchain head pendingState *state.ManagedState // Pending state tracking virtual nonces - currentMaxGas *big.Int // Current gas limit for transaction caps + currentMaxGas uint64 // Current gas limit for transaction caps locals *accountSet // Set of local transaction to exempt from eviction rules journal *txJournal // Journal of local transaction to back up to disk @@ -564,7 +564,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { return ErrNegativeValue } // Ensure the transaction doesn't exceed the current block limit gas. - if pool.currentMaxGas.Cmp(tx.Gas()) < 0 { + if pool.currentMaxGas < tx.Gas() { return ErrGasLimit } // Make sure the transaction is signed properly @@ -586,8 +586,11 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { if pool.currentState.GetBalance(from).Cmp(tx.Cost()) < 0 { return ErrInsufficientFunds } - intrGas := IntrinsicGas(tx.Data(), tx.To() == nil, pool.homestead) - if tx.Gas().Cmp(intrGas) < 0 { + intrGas, err := IntrinsicGas(tx.Data(), tx.To() == nil, pool.homestead) + if err != nil { + return err + } + if tx.Gas() < intrGas { return ErrIntrinsicGas } return nil diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go index 1f193a06c..cd11f2ba2 100644 --- a/core/tx_pool_test.go +++ b/core/tx_pool_test.go @@ -46,7 +46,7 @@ func init() { type testBlockChain struct { statedb *state.StateDB - gasLimit *big.Int + gasLimit uint64 chainHeadFeed *event.Feed } @@ -68,11 +68,11 @@ func (bc *testBlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) even return bc.chainHeadFeed.Subscribe(ch) } -func transaction(nonce uint64, gaslimit *big.Int, key *ecdsa.PrivateKey) *types.Transaction { +func transaction(nonce uint64, gaslimit uint64, key *ecdsa.PrivateKey) *types.Transaction { return pricedTransaction(nonce, gaslimit, big.NewInt(1), key) } -func pricedTransaction(nonce uint64, gaslimit, gasprice *big.Int, key *ecdsa.PrivateKey) *types.Transaction { +func pricedTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ecdsa.PrivateKey) *types.Transaction { tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(100), gaslimit, gasprice, nil), types.HomesteadSigner{}, key) return tx } @@ -80,7 +80,7 @@ func pricedTransaction(nonce uint64, gaslimit, gasprice *big.Int, key *ecdsa.Pri func setupTxPool() (*TxPool, *ecdsa.PrivateKey) { db, _ := ethdb.NewMemDatabase() statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) - blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} + blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} key, _ := crypto.GenerateKey() pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) @@ -184,10 +184,10 @@ func TestStateChangeDuringTransactionPoolReset(t *testing.T) { // setup pool with 2 transaction in it statedb.SetBalance(address, new(big.Int).SetUint64(params.Ether)) - blockchain := &testChain{&testBlockChain{statedb, big.NewInt(1000000000), new(event.Feed)}, address, &trigger} + blockchain := &testChain{&testBlockChain{statedb, 1000000000, new(event.Feed)}, address, &trigger} - tx0 := transaction(0, big.NewInt(100000), key) - tx1 := transaction(1, big.NewInt(100000), key) + tx0 := transaction(0, 100000, key) + tx1 := transaction(1, 100000, key) pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) defer pool.Stop() @@ -230,7 +230,7 @@ func TestInvalidTransactions(t *testing.T) { pool, key := setupTxPool() defer pool.Stop() - tx := transaction(0, big.NewInt(100), key) + tx := transaction(0, 100, key) from, _ := deriveSender(tx) pool.currentState.AddBalance(from, big.NewInt(1)) @@ -238,7 +238,7 @@ func TestInvalidTransactions(t *testing.T) { t.Error("expected", ErrInsufficientFunds) } - balance := new(big.Int).Add(tx.Value(), new(big.Int).Mul(tx.Gas(), tx.GasPrice())) + balance := new(big.Int).Add(tx.Value(), new(big.Int).Mul(new(big.Int).SetUint64(tx.Gas()), tx.GasPrice())) pool.currentState.AddBalance(from, balance) if err := pool.AddRemote(tx); err != ErrIntrinsicGas { t.Error("expected", ErrIntrinsicGas, "got", err) @@ -246,12 +246,12 @@ func TestInvalidTransactions(t *testing.T) { pool.currentState.SetNonce(from, 1) pool.currentState.AddBalance(from, big.NewInt(0xffffffffffffff)) - tx = transaction(0, big.NewInt(100000), key) + tx = transaction(0, 100000, key) if err := pool.AddRemote(tx); err != ErrNonceTooLow { t.Error("expected", ErrNonceTooLow) } - tx = transaction(1, big.NewInt(100000), key) + tx = transaction(1, 100000, key) pool.gasPrice = big.NewInt(1000) if err := pool.AddRemote(tx); err != ErrUnderpriced { t.Error("expected", ErrUnderpriced, "got", err) @@ -267,7 +267,7 @@ func TestTransactionQueue(t *testing.T) { pool, key := setupTxPool() defer pool.Stop() - tx := transaction(0, big.NewInt(100), key) + tx := transaction(0, 100, key) from, _ := deriveSender(tx) pool.currentState.AddBalance(from, big.NewInt(1000)) pool.lockedReset(nil, nil) @@ -278,7 +278,7 @@ func TestTransactionQueue(t *testing.T) { t.Error("expected valid txs to be 1 is", len(pool.pending)) } - tx = transaction(1, big.NewInt(100), key) + tx = transaction(1, 100, key) from, _ = deriveSender(tx) pool.currentState.SetNonce(from, 2) pool.enqueueTx(tx.Hash(), tx) @@ -294,9 +294,9 @@ func TestTransactionQueue(t *testing.T) { pool, key = setupTxPool() defer pool.Stop() - tx1 := transaction(0, big.NewInt(100), key) - tx2 := transaction(10, big.NewInt(100), key) - tx3 := transaction(11, big.NewInt(100), key) + tx1 := transaction(0, 100, key) + tx2 := transaction(10, 100, key) + tx3 := transaction(11, 100, key) from, _ = deriveSender(tx1) pool.currentState.AddBalance(from, big.NewInt(1000)) pool.lockedReset(nil, nil) @@ -321,7 +321,7 @@ func TestTransactionNegativeValue(t *testing.T) { pool, key := setupTxPool() defer pool.Stop() - tx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(-1), big.NewInt(100), big.NewInt(1), nil), types.HomesteadSigner{}, key) + tx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(-1), 100, big.NewInt(1), nil), types.HomesteadSigner{}, key) from, _ := deriveSender(tx) pool.currentState.AddBalance(from, big.NewInt(1)) if err := pool.AddRemote(tx); err != ErrNegativeValue { @@ -341,12 +341,12 @@ func TestTransactionChainFork(t *testing.T) { statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) statedb.AddBalance(addr, big.NewInt(100000000000000)) - pool.chain = &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} + pool.chain = &testBlockChain{statedb, 1000000, new(event.Feed)} pool.lockedReset(nil, nil) } resetState() - tx := transaction(0, big.NewInt(100000), key) + tx := transaction(0, 100000, key) if _, err := pool.add(tx, false); err != nil { t.Error("didn't expect error", err) } @@ -371,15 +371,15 @@ func TestTransactionDoubleNonce(t *testing.T) { statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) statedb.AddBalance(addr, big.NewInt(100000000000000)) - pool.chain = &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} + pool.chain = &testBlockChain{statedb, 1000000, new(event.Feed)} pool.lockedReset(nil, nil) } resetState() signer := types.HomesteadSigner{} - tx1, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), big.NewInt(100000), big.NewInt(1), nil), signer, key) - tx2, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), big.NewInt(1000000), big.NewInt(2), nil), signer, key) - tx3, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), big.NewInt(1000000), big.NewInt(1), nil), signer, key) + tx1, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 100000, big.NewInt(1), nil), signer, key) + tx2, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 1000000, big.NewInt(2), nil), signer, key) + tx3, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 1000000, big.NewInt(1), nil), signer, key) // Add the first two transaction, ensure higher priced stays only if replace, err := pool.add(tx1, false); err != nil || replace { @@ -418,7 +418,7 @@ func TestTransactionMissingNonce(t *testing.T) { addr := crypto.PubkeyToAddress(key.PublicKey) pool.currentState.AddBalance(addr, big.NewInt(100000000000000)) - tx := transaction(1, big.NewInt(100000), key) + tx := transaction(1, 100000, key) if _, err := pool.add(tx, false); err != nil { t.Error("didn't expect error", err) } @@ -445,7 +445,7 @@ func TestTransactionNonceRecovery(t *testing.T) { pool.currentState.AddBalance(addr, big.NewInt(100000000000000)) pool.lockedReset(nil, nil) - tx := transaction(n, big.NewInt(100000), key) + tx := transaction(n, 100000, key) if err := pool.AddRemote(tx); err != nil { t.Error(err) } @@ -466,17 +466,17 @@ func TestTransactionDropping(t *testing.T) { pool, key := setupTxPool() defer pool.Stop() - account, _ := deriveSender(transaction(0, big.NewInt(0), key)) + account, _ := deriveSender(transaction(0, 0, key)) pool.currentState.AddBalance(account, big.NewInt(1000)) // Add some pending and some queued transactions var ( - tx0 = transaction(0, big.NewInt(100), key) - tx1 = transaction(1, big.NewInt(200), key) - tx2 = transaction(2, big.NewInt(300), key) - tx10 = transaction(10, big.NewInt(100), key) - tx11 = transaction(11, big.NewInt(200), key) - tx12 = transaction(12, big.NewInt(300), key) + tx0 = transaction(0, 100, key) + tx1 = transaction(1, 200, key) + tx2 = transaction(2, 300, key) + tx10 = transaction(10, 100, key) + tx11 = transaction(11, 200, key) + tx12 = transaction(12, 300, key) ) pool.promoteTx(account, tx0.Hash(), tx0) pool.promoteTx(account, tx1.Hash(), tx1) @@ -531,7 +531,7 @@ func TestTransactionDropping(t *testing.T) { t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), 4) } // Reduce the block gas limit, check that invalidated transactions are dropped - pool.chain.(*testBlockChain).gasLimit = big.NewInt(100) + pool.chain.(*testBlockChain).gasLimit = 100 pool.lockedReset(nil, nil) if _, ok := pool.pending[account].txs.items[tx0.Nonce()]; !ok { @@ -561,7 +561,7 @@ func TestTransactionPostponing(t *testing.T) { pool, key := setupTxPool() defer pool.Stop() - account, _ := deriveSender(transaction(0, big.NewInt(0), key)) + account, _ := deriveSender(transaction(0, 0, key)) pool.currentState.AddBalance(account, big.NewInt(1000)) // Add a batch consecutive pending transactions for validation @@ -569,9 +569,9 @@ func TestTransactionPostponing(t *testing.T) { for i := 0; i < 100; i++ { var tx *types.Transaction if i%2 == 0 { - tx = transaction(uint64(i), big.NewInt(100), key) + tx = transaction(uint64(i), 100, key) } else { - tx = transaction(uint64(i), big.NewInt(500), key) + tx = transaction(uint64(i), 500, key) } pool.promoteTx(account, tx.Hash(), tx) txns = append(txns, tx) @@ -638,7 +638,7 @@ func TestTransactionGapFilling(t *testing.T) { pool, key := setupTxPool() defer pool.Stop() - account, _ := deriveSender(transaction(0, big.NewInt(0), key)) + account, _ := deriveSender(transaction(0, 0, key)) pool.currentState.AddBalance(account, big.NewInt(1000000)) // Keep track of transaction events to ensure all executables get announced @@ -647,10 +647,10 @@ func TestTransactionGapFilling(t *testing.T) { defer sub.Unsubscribe() // Create a pending and a queued transaction with a nonce-gap in between - if err := pool.AddRemote(transaction(0, big.NewInt(100000), key)); err != nil { + if err := pool.AddRemote(transaction(0, 100000, key)); err != nil { t.Fatalf("failed to add pending transaction: %v", err) } - if err := pool.AddRemote(transaction(2, big.NewInt(100000), key)); err != nil { + if err := pool.AddRemote(transaction(2, 100000, key)); err != nil { t.Fatalf("failed to add queued transaction: %v", err) } pending, queued := pool.Stats() @@ -667,7 +667,7 @@ func TestTransactionGapFilling(t *testing.T) { t.Fatalf("pool internal state corrupted: %v", err) } // Fill the nonce gap and ensure all transactions become pending - if err := pool.AddRemote(transaction(1, big.NewInt(100000), key)); err != nil { + if err := pool.AddRemote(transaction(1, 100000, key)); err != nil { t.Fatalf("failed to add gapped transaction: %v", err) } pending, queued = pool.Stats() @@ -694,12 +694,12 @@ func TestTransactionQueueAccountLimiting(t *testing.T) { pool, key := setupTxPool() defer pool.Stop() - account, _ := deriveSender(transaction(0, big.NewInt(0), key)) + account, _ := deriveSender(transaction(0, 0, key)) pool.currentState.AddBalance(account, big.NewInt(1000000)) // Keep queuing up transactions and make sure all above a limit are dropped for i := uint64(1); i <= testTxPoolConfig.AccountQueue+5; i++ { - if err := pool.AddRemote(transaction(i, big.NewInt(100000), key)); err != nil { + if err := pool.AddRemote(transaction(i, 100000, key)); err != nil { t.Fatalf("tx %d: failed to add transaction: %v", i, err) } if len(pool.pending) != 0 { @@ -738,7 +738,7 @@ func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) { // Create the pool to test the limit enforcement with db, _ := ethdb.NewMemDatabase() statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) - blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} + blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} config := testTxPoolConfig config.NoLocals = nolocals @@ -763,7 +763,7 @@ func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) { key := keys[rand.Intn(len(keys)-1)] // skip adding transactions with the local account addr := crypto.PubkeyToAddress(key.PublicKey) - txs = append(txs, transaction(nonces[addr]+1, big.NewInt(100000), key)) + txs = append(txs, transaction(nonces[addr]+1, 100000, key)) nonces[addr]++ } // Import the batch and verify that limits have been enforced @@ -782,7 +782,7 @@ func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) { // Generate a batch of transactions from the local account and import them txs = txs[:0] for i := uint64(0); i < 3*config.GlobalQueue; i++ { - txs = append(txs, transaction(i+1, big.NewInt(100000), local)) + txs = append(txs, transaction(i+1, 100000, local)) } pool.AddLocals(txs) @@ -827,7 +827,7 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) { // Create the pool to test the non-expiration enforcement db, _ := ethdb.NewMemDatabase() statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) - blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} + blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} config := testTxPoolConfig config.Lifetime = time.Second @@ -844,10 +844,10 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) { pool.currentState.AddBalance(crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000)) // Add the two transactions and ensure they both are queued up - if err := pool.AddLocal(pricedTransaction(1, big.NewInt(100000), big.NewInt(1), local)); err != nil { + if err := pool.AddLocal(pricedTransaction(1, 100000, big.NewInt(1), local)); err != nil { t.Fatalf("failed to add local transaction: %v", err) } - if err := pool.AddRemote(pricedTransaction(1, big.NewInt(100000), big.NewInt(1), remote)); err != nil { + if err := pool.AddRemote(pricedTransaction(1, 100000, big.NewInt(1), remote)); err != nil { t.Fatalf("failed to add remote transaction: %v", err) } pending, queued := pool.Stats() @@ -891,7 +891,7 @@ func TestTransactionPendingLimiting(t *testing.T) { pool, key := setupTxPool() defer pool.Stop() - account, _ := deriveSender(transaction(0, big.NewInt(0), key)) + account, _ := deriveSender(transaction(0, 0, key)) pool.currentState.AddBalance(account, big.NewInt(1000000)) // Keep track of transaction events to ensure all executables get announced @@ -901,7 +901,7 @@ func TestTransactionPendingLimiting(t *testing.T) { // Keep queuing up transactions and make sure all above a limit are dropped for i := uint64(0); i < testTxPoolConfig.AccountQueue+5; i++ { - if err := pool.AddRemote(transaction(i, big.NewInt(100000), key)); err != nil { + if err := pool.AddRemote(transaction(i, 100000, key)); err != nil { t.Fatalf("tx %d: failed to add transaction: %v", i, err) } if pool.pending[account].Len() != int(i)+1 { @@ -934,11 +934,11 @@ func testTransactionLimitingEquivalency(t *testing.T, origin uint64) { pool1, key1 := setupTxPool() defer pool1.Stop() - account1, _ := deriveSender(transaction(0, big.NewInt(0), key1)) + account1, _ := deriveSender(transaction(0, 0, key1)) pool1.currentState.AddBalance(account1, big.NewInt(1000000)) for i := uint64(0); i < testTxPoolConfig.AccountQueue+5; i++ { - if err := pool1.AddRemote(transaction(origin+i, big.NewInt(100000), key1)); err != nil { + if err := pool1.AddRemote(transaction(origin+i, 100000, key1)); err != nil { t.Fatalf("tx %d: failed to add transaction: %v", i, err) } } @@ -946,12 +946,12 @@ func testTransactionLimitingEquivalency(t *testing.T, origin uint64) { pool2, key2 := setupTxPool() defer pool2.Stop() - account2, _ := deriveSender(transaction(0, big.NewInt(0), key2)) + account2, _ := deriveSender(transaction(0, 0, key2)) pool2.currentState.AddBalance(account2, big.NewInt(1000000)) txns := []*types.Transaction{} for i := uint64(0); i < testTxPoolConfig.AccountQueue+5; i++ { - txns = append(txns, transaction(origin+i, big.NewInt(100000), key2)) + txns = append(txns, transaction(origin+i, 100000, key2)) } pool2.AddRemotes(txns) @@ -982,7 +982,7 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) { // Create the pool to test the limit enforcement with db, _ := ethdb.NewMemDatabase() statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) - blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} + blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} config := testTxPoolConfig config.GlobalSlots = config.AccountSlots * 10 @@ -1003,7 +1003,7 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) { for _, key := range keys { addr := crypto.PubkeyToAddress(key.PublicKey) for j := 0; j < int(config.GlobalSlots)/len(keys)*2; j++ { - txs = append(txs, transaction(nonces[addr], big.NewInt(100000), key)) + txs = append(txs, transaction(nonces[addr], 100000, key)) nonces[addr]++ } } @@ -1029,7 +1029,7 @@ func TestTransactionCapClearsFromAll(t *testing.T) { // Create the pool to test the limit enforcement with db, _ := ethdb.NewMemDatabase() statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) - blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} + blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} config := testTxPoolConfig config.AccountSlots = 2 @@ -1046,7 +1046,7 @@ func TestTransactionCapClearsFromAll(t *testing.T) { txs := types.Transactions{} for j := 0; j < int(config.GlobalSlots)*2; j++ { - txs = append(txs, transaction(uint64(j), big.NewInt(100000), key)) + txs = append(txs, transaction(uint64(j), 100000, key)) } // Import the batch and verify that limits have been enforced pool.AddRemotes(txs) @@ -1064,7 +1064,7 @@ func TestTransactionPendingMinimumAllowance(t *testing.T) { // Create the pool to test the limit enforcement with db, _ := ethdb.NewMemDatabase() statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) - blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} + blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} config := testTxPoolConfig config.GlobalSlots = 0 @@ -1085,7 +1085,7 @@ func TestTransactionPendingMinimumAllowance(t *testing.T) { for _, key := range keys { addr := crypto.PubkeyToAddress(key.PublicKey) for j := 0; j < int(config.AccountSlots)*2; j++ { - txs = append(txs, transaction(nonces[addr], big.NewInt(100000), key)) + txs = append(txs, transaction(nonces[addr], 100000, key)) nonces[addr]++ } } @@ -1113,7 +1113,7 @@ func TestTransactionPoolRepricing(t *testing.T) { // Create the pool to test the pricing enforcement with db, _ := ethdb.NewMemDatabase() statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) - blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} + blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) defer pool.Stop() @@ -1132,15 +1132,15 @@ func TestTransactionPoolRepricing(t *testing.T) { // Generate and queue a batch of transactions, both pending and queued txs := types.Transactions{} - txs = append(txs, pricedTransaction(0, big.NewInt(100000), big.NewInt(2), keys[0])) - txs = append(txs, pricedTransaction(1, big.NewInt(100000), big.NewInt(1), keys[0])) - txs = append(txs, pricedTransaction(2, big.NewInt(100000), big.NewInt(2), keys[0])) + txs = append(txs, pricedTransaction(0, 100000, big.NewInt(2), keys[0])) + txs = append(txs, pricedTransaction(1, 100000, big.NewInt(1), keys[0])) + txs = append(txs, pricedTransaction(2, 100000, big.NewInt(2), keys[0])) - txs = append(txs, pricedTransaction(1, big.NewInt(100000), big.NewInt(2), keys[1])) - txs = append(txs, pricedTransaction(2, big.NewInt(100000), big.NewInt(1), keys[1])) - txs = append(txs, pricedTransaction(3, big.NewInt(100000), big.NewInt(2), keys[1])) + txs = append(txs, pricedTransaction(1, 100000, big.NewInt(2), keys[1])) + txs = append(txs, pricedTransaction(2, 100000, big.NewInt(1), keys[1])) + txs = append(txs, pricedTransaction(3, 100000, big.NewInt(2), keys[1])) - ltx := pricedTransaction(0, big.NewInt(100000), big.NewInt(1), keys[2]) + ltx := pricedTransaction(0, 100000, big.NewInt(1), keys[2]) // Import the batch and that both pending and queued transactions match up pool.AddRemotes(txs) @@ -1176,10 +1176,10 @@ func TestTransactionPoolRepricing(t *testing.T) { t.Fatalf("pool internal state corrupted: %v", err) } // Check that we can't add the old transactions back - if err := pool.AddRemote(pricedTransaction(1, big.NewInt(100000), big.NewInt(1), keys[0])); err != ErrUnderpriced { + if err := pool.AddRemote(pricedTransaction(1, 100000, big.NewInt(1), keys[0])); err != ErrUnderpriced { t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced) } - if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100000), big.NewInt(1), keys[1])); err != ErrUnderpriced { + if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(1), keys[1])); err != ErrUnderpriced { t.Fatalf("adding underpriced queued transaction error mismatch: have %v, want %v", err, ErrUnderpriced) } if err := validateEvents(events, 0); err != nil { @@ -1189,7 +1189,7 @@ func TestTransactionPoolRepricing(t *testing.T) { t.Fatalf("pool internal state corrupted: %v", err) } // However we can add local underpriced transactions - tx := pricedTransaction(1, big.NewInt(100000), big.NewInt(1), keys[2]) + tx := pricedTransaction(1, 100000, big.NewInt(1), keys[2]) if err := pool.AddLocal(tx); err != nil { t.Fatalf("failed to add underpriced local transaction: %v", err) } @@ -1212,7 +1212,7 @@ func TestTransactionPoolRepricingKeepsLocals(t *testing.T) { // Create the pool to test the pricing enforcement with db, _ := ethdb.NewMemDatabase() statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) - blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} + blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) defer pool.Stop() @@ -1226,12 +1226,12 @@ func TestTransactionPoolRepricingKeepsLocals(t *testing.T) { // Create transaction (both pending and queued) with a linearly growing gasprice for i := uint64(0); i < 500; i++ { // Add pending - p_tx := pricedTransaction(i, big.NewInt(100000), big.NewInt(int64(i)), keys[2]) + p_tx := pricedTransaction(i, 100000, big.NewInt(int64(i)), keys[2]) if err := pool.AddLocal(p_tx); err != nil { t.Fatal(err) } // Add queued - q_tx := pricedTransaction(i+501, big.NewInt(100000), big.NewInt(int64(i)), keys[2]) + q_tx := pricedTransaction(i+501, 100000, big.NewInt(int64(i)), keys[2]) if err := pool.AddLocal(q_tx); err != nil { t.Fatal(err) } @@ -1275,7 +1275,7 @@ func TestTransactionPoolUnderpricing(t *testing.T) { // Create the pool to test the pricing enforcement with db, _ := ethdb.NewMemDatabase() statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) - blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} + blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} config := testTxPoolConfig config.GlobalSlots = 2 @@ -1298,12 +1298,12 @@ func TestTransactionPoolUnderpricing(t *testing.T) { // Generate and queue a batch of transactions, both pending and queued txs := types.Transactions{} - txs = append(txs, pricedTransaction(0, big.NewInt(100000), big.NewInt(1), keys[0])) - txs = append(txs, pricedTransaction(1, big.NewInt(100000), big.NewInt(2), keys[0])) + txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[0])) + txs = append(txs, pricedTransaction(1, 100000, big.NewInt(2), keys[0])) - txs = append(txs, pricedTransaction(1, big.NewInt(100000), big.NewInt(1), keys[1])) + txs = append(txs, pricedTransaction(1, 100000, big.NewInt(1), keys[1])) - ltx := pricedTransaction(0, big.NewInt(100000), big.NewInt(1), keys[2]) + ltx := pricedTransaction(0, 100000, big.NewInt(1), keys[2]) // Import the batch and that both pending and queued transactions match up pool.AddRemotes(txs) @@ -1323,17 +1323,17 @@ func TestTransactionPoolUnderpricing(t *testing.T) { t.Fatalf("pool internal state corrupted: %v", err) } // Ensure that adding an underpriced transaction on block limit fails - if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(1), keys[1])); err != ErrUnderpriced { + if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(1), keys[1])); err != ErrUnderpriced { t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced) } // Ensure that adding high priced transactions drops cheap ones, but not own - if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(3), keys[1])); err != nil { + if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(3), keys[1])); err != nil { t.Fatalf("failed to add well priced transaction: %v", err) } - if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100000), big.NewInt(4), keys[1])); err != nil { + if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(4), keys[1])); err != nil { t.Fatalf("failed to add well priced transaction: %v", err) } - if err := pool.AddRemote(pricedTransaction(3, big.NewInt(100000), big.NewInt(5), keys[1])); err != nil { + if err := pool.AddRemote(pricedTransaction(3, 100000, big.NewInt(5), keys[1])); err != nil { t.Fatalf("failed to add well priced transaction: %v", err) } pending, queued = pool.Stats() @@ -1350,7 +1350,7 @@ func TestTransactionPoolUnderpricing(t *testing.T) { t.Fatalf("pool internal state corrupted: %v", err) } // Ensure that adding local transactions can push out even higher priced ones - tx := pricedTransaction(1, big.NewInt(100000), big.NewInt(0), keys[2]) + tx := pricedTransaction(1, 100000, big.NewInt(0), keys[2]) if err := pool.AddLocal(tx); err != nil { t.Fatalf("failed to add underpriced local transaction: %v", err) } @@ -1377,7 +1377,7 @@ func TestTransactionReplacement(t *testing.T) { // Create the pool to test the pricing enforcement with db, _ := ethdb.NewMemDatabase() statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) - blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} + blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) defer pool.Stop() @@ -1395,49 +1395,49 @@ func TestTransactionReplacement(t *testing.T) { price := int64(100) threshold := (price * (100 + int64(testTxPoolConfig.PriceBump))) / 100 - if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(1), key)); err != nil { + if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(1), key)); err != nil { t.Fatalf("failed to add original cheap pending transaction: %v", err) } - if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100001), big.NewInt(1), key)); err != ErrReplaceUnderpriced { + if err := pool.AddRemote(pricedTransaction(0, 100001, big.NewInt(1), key)); err != ErrReplaceUnderpriced { t.Fatalf("original cheap pending transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced) } - if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(2), key)); err != nil { + if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(2), key)); err != nil { t.Fatalf("failed to replace original cheap pending transaction: %v", err) } if err := validateEvents(events, 2); err != nil { t.Fatalf("cheap replacement event firing failed: %v", err) } - if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(price), key)); err != nil { + if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(price), key)); err != nil { t.Fatalf("failed to add original proper pending transaction: %v", err) } - if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100001), big.NewInt(threshold-1), key)); err != ErrReplaceUnderpriced { + if err := pool.AddRemote(pricedTransaction(0, 100001, big.NewInt(threshold-1), key)); err != ErrReplaceUnderpriced { t.Fatalf("original proper pending transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced) } - if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(threshold), key)); err != nil { + if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(threshold), key)); err != nil { t.Fatalf("failed to replace original proper pending transaction: %v", err) } if err := validateEvents(events, 2); err != nil { t.Fatalf("proper replacement event firing failed: %v", err) } // Add queued transactions, ensuring the minimum price bump is enforced for replacement (for ultra low prices too) - if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100000), big.NewInt(1), key)); err != nil { + if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(1), key)); err != nil { t.Fatalf("failed to add original cheap queued transaction: %v", err) } - if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100001), big.NewInt(1), key)); err != ErrReplaceUnderpriced { + if err := pool.AddRemote(pricedTransaction(2, 100001, big.NewInt(1), key)); err != ErrReplaceUnderpriced { t.Fatalf("original cheap queued transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced) } - if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100000), big.NewInt(2), key)); err != nil { + if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(2), key)); err != nil { t.Fatalf("failed to replace original cheap queued transaction: %v", err) } - if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100000), big.NewInt(price), key)); err != nil { + if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(price), key)); err != nil { t.Fatalf("failed to add original proper queued transaction: %v", err) } - if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100001), big.NewInt(threshold-1), key)); err != ErrReplaceUnderpriced { + if err := pool.AddRemote(pricedTransaction(2, 100001, big.NewInt(threshold-1), key)); err != ErrReplaceUnderpriced { t.Fatalf("original proper queued transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced) } - if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100000), big.NewInt(threshold), key)); err != nil { + if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(threshold), key)); err != nil { t.Fatalf("failed to replace original proper queued transaction: %v", err) } @@ -1472,7 +1472,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) { // Create the original pool to inject transaction into the journal db, _ := ethdb.NewMemDatabase() statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) - blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} + blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} config := testTxPoolConfig config.NoLocals = nolocals @@ -1489,16 +1489,16 @@ func testTransactionJournaling(t *testing.T, nolocals bool) { pool.currentState.AddBalance(crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000)) // Add three local and a remote transactions and ensure they are queued up - if err := pool.AddLocal(pricedTransaction(0, big.NewInt(100000), big.NewInt(1), local)); err != nil { + if err := pool.AddLocal(pricedTransaction(0, 100000, big.NewInt(1), local)); err != nil { t.Fatalf("failed to add local transaction: %v", err) } - if err := pool.AddLocal(pricedTransaction(1, big.NewInt(100000), big.NewInt(1), local)); err != nil { + if err := pool.AddLocal(pricedTransaction(1, 100000, big.NewInt(1), local)); err != nil { t.Fatalf("failed to add local transaction: %v", err) } - if err := pool.AddLocal(pricedTransaction(2, big.NewInt(100000), big.NewInt(1), local)); err != nil { + if err := pool.AddLocal(pricedTransaction(2, 100000, big.NewInt(1), local)); err != nil { t.Fatalf("failed to add local transaction: %v", err) } - if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(1), remote)); err != nil { + if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(1), remote)); err != nil { t.Fatalf("failed to add remote transaction: %v", err) } pending, queued := pool.Stats() @@ -1514,7 +1514,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) { // Terminate the old pool, bump the local nonce, create a new pool and ensure relevant transaction survive pool.Stop() statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1) - blockchain = &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} + blockchain = &testBlockChain{statedb, 1000000, new(event.Feed)} pool = NewTxPool(config, params.TestChainConfig, blockchain) @@ -1541,7 +1541,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) { pool.Stop() statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1) - blockchain = &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} + blockchain = &testBlockChain{statedb, 1000000, new(event.Feed)} pool = NewTxPool(config, params.TestChainConfig, blockchain) pending, queued = pool.Stats() @@ -1571,7 +1571,7 @@ func TestTransactionStatusCheck(t *testing.T) { // Create the pool to test the status retrievals with db, _ := ethdb.NewMemDatabase() statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) - blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} + blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) defer pool.Stop() @@ -1585,10 +1585,10 @@ func TestTransactionStatusCheck(t *testing.T) { // Generate and queue a batch of transactions, both pending and queued txs := types.Transactions{} - txs = append(txs, pricedTransaction(0, big.NewInt(100000), big.NewInt(1), keys[0])) // Pending only - txs = append(txs, pricedTransaction(0, big.NewInt(100000), big.NewInt(1), keys[1])) // Pending and queued - txs = append(txs, pricedTransaction(2, big.NewInt(100000), big.NewInt(1), keys[1])) - txs = append(txs, pricedTransaction(2, big.NewInt(100000), big.NewInt(1), keys[2])) // Queued only + txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[0])) // Pending only + txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[1])) // Pending and queued + txs = append(txs, pricedTransaction(2, 100000, big.NewInt(1), keys[1])) + txs = append(txs, pricedTransaction(2, 100000, big.NewInt(1), keys[2])) // Queued only // Import the transaction and ensure they are correctly added pool.AddRemotes(txs) @@ -1631,11 +1631,11 @@ func benchmarkPendingDemotion(b *testing.B, size int) { pool, key := setupTxPool() defer pool.Stop() - account, _ := deriveSender(transaction(0, big.NewInt(0), key)) + account, _ := deriveSender(transaction(0, 0, key)) pool.currentState.AddBalance(account, big.NewInt(1000000)) for i := 0; i < size; i++ { - tx := transaction(uint64(i), big.NewInt(100000), key) + tx := transaction(uint64(i), 100000, key) pool.promoteTx(account, tx.Hash(), tx) } // Benchmark the speed of pool validation @@ -1656,11 +1656,11 @@ func benchmarkFuturePromotion(b *testing.B, size int) { pool, key := setupTxPool() defer pool.Stop() - account, _ := deriveSender(transaction(0, big.NewInt(0), key)) + account, _ := deriveSender(transaction(0, 0, key)) pool.currentState.AddBalance(account, big.NewInt(1000000)) for i := 0; i < size; i++ { - tx := transaction(uint64(1+i), big.NewInt(100000), key) + tx := transaction(uint64(1+i), 100000, key) pool.enqueueTx(tx.Hash(), tx) } // Benchmark the speed of pool validation @@ -1676,12 +1676,12 @@ func BenchmarkPoolInsert(b *testing.B) { pool, key := setupTxPool() defer pool.Stop() - account, _ := deriveSender(transaction(0, big.NewInt(0), key)) + account, _ := deriveSender(transaction(0, 0, key)) pool.currentState.AddBalance(account, big.NewInt(1000000)) txs := make(types.Transactions, b.N) for i := 0; i < b.N; i++ { - txs[i] = transaction(uint64(i), big.NewInt(100000), key) + txs[i] = transaction(uint64(i), 100000, key) } // Benchmark importing the transactions into the queue b.ResetTimer() @@ -1700,14 +1700,14 @@ func benchmarkPoolBatchInsert(b *testing.B, size int) { pool, key := setupTxPool() defer pool.Stop() - account, _ := deriveSender(transaction(0, big.NewInt(0), key)) + account, _ := deriveSender(transaction(0, 0, key)) pool.currentState.AddBalance(account, big.NewInt(1000000)) batches := make([]types.Transactions, b.N) for i := 0; i < b.N; i++ { batches[i] = make(types.Transactions, size) for j := 0; j < size; j++ { - batches[i][j] = transaction(uint64(size*i+j), big.NewInt(100000), key) + batches[i][j] = transaction(uint64(size*i+j), 100000, key) } } // Benchmark importing the transactions into the queue diff --git a/core/types.go b/core/types.go index 1cfbbab29..d0bbaf0aa 100644 --- a/core/types.go +++ b/core/types.go @@ -17,8 +17,6 @@ package core import ( - "math/big" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" @@ -34,7 +32,7 @@ type Validator interface { // ValidateState validates the given statedb and optionally the receipts and // gas used. - ValidateState(block, parent *types.Block, state *state.StateDB, receipts types.Receipts, usedGas *big.Int) error + ValidateState(block, parent *types.Block, state *state.StateDB, receipts types.Receipts, usedGas uint64) error } // Processor is an interface for processing blocks using a given initial state. @@ -44,5 +42,5 @@ type Validator interface { // of gas used in the process and return an error if any of the internal rules // failed. type Processor interface { - Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, *big.Int, error) + Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) } diff --git a/core/types/block.go b/core/types/block.go index 1d00d9f93..9be62b9e0 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -77,8 +77,8 @@ type Header struct { Bloom Bloom `json:"logsBloom" gencodec:"required"` Difficulty *big.Int `json:"difficulty" gencodec:"required"` Number *big.Int `json:"number" gencodec:"required"` - GasLimit *big.Int `json:"gasLimit" gencodec:"required"` - GasUsed *big.Int `json:"gasUsed" gencodec:"required"` + GasLimit uint64 `json:"gasLimit" gencodec:"required"` + GasUsed uint64 `json:"gasUsed" gencodec:"required"` Time *big.Int `json:"timestamp" gencodec:"required"` Extra []byte `json:"extraData" gencodec:"required"` MixDigest common.Hash `json:"mixHash" gencodec:"required"` @@ -89,8 +89,8 @@ type Header struct { type headerMarshaling struct { Difficulty *hexutil.Big Number *hexutil.Big - GasLimit *hexutil.Big - GasUsed *hexutil.Big + GasLimit *hexutil.Uint64 + GasUsed *hexutil.Uint64 Time *hexutil.Big Extra hexutil.Bytes Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON @@ -243,12 +243,6 @@ func CopyHeader(h *Header) *Header { if cpy.Number = new(big.Int); h.Number != nil { cpy.Number.Set(h.Number) } - if cpy.GasLimit = new(big.Int); h.GasLimit != nil { - cpy.GasLimit.Set(h.GasLimit) - } - if cpy.GasUsed = new(big.Int); h.GasUsed != nil { - cpy.GasUsed.Set(h.GasUsed) - } if len(h.Extra) > 0 { cpy.Extra = make([]byte, len(h.Extra)) copy(cpy.Extra, h.Extra) @@ -302,8 +296,8 @@ func (b *Block) Transaction(hash common.Hash) *Transaction { } func (b *Block) Number() *big.Int { return new(big.Int).Set(b.header.Number) } -func (b *Block) GasLimit() *big.Int { return new(big.Int).Set(b.header.GasLimit) } -func (b *Block) GasUsed() *big.Int { return new(big.Int).Set(b.header.GasUsed) } +func (b *Block) GasLimit() uint64 { return b.header.GasLimit } +func (b *Block) GasUsed() uint64 { return b.header.GasUsed } func (b *Block) Difficulty() *big.Int { return new(big.Int).Set(b.header.Difficulty) } func (b *Block) Time() *big.Int { return new(big.Int).Set(b.header.Time) } diff --git a/core/types/block_test.go b/core/types/block_test.go index 93435ca00..a35fbc25b 100644 --- a/core/types/block_test.go +++ b/core/types/block_test.go @@ -41,8 +41,8 @@ func TestBlockEncoding(t *testing.T) { } } check("Difficulty", block.Difficulty(), big.NewInt(131072)) - check("GasLimit", block.GasLimit(), big.NewInt(3141592)) - check("GasUsed", block.GasUsed(), big.NewInt(21000)) + check("GasLimit", block.GasLimit(), uint64(3141592)) + check("GasUsed", block.GasUsed(), uint64(21000)) check("Coinbase", block.Coinbase(), common.HexToAddress("8888f1f195afa192cfee860698584c030f4c9db1")) check("MixDigest", block.MixDigest(), common.HexToHash("bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff498")) check("Root", block.Root(), common.HexToHash("ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017")) @@ -51,7 +51,7 @@ func TestBlockEncoding(t *testing.T) { check("Time", block.Time(), big.NewInt(1426516743)) check("Size", block.Size(), common.StorageSize(len(blockEnc))) - tx1 := NewTransaction(0, common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), big.NewInt(10), big.NewInt(50000), big.NewInt(10), nil) + tx1 := NewTransaction(0, common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), big.NewInt(10), 50000, big.NewInt(10), nil) tx1, _ = tx1.WithSignature(HomesteadSigner{}, common.Hex2Bytes("9bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094f8a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b100")) fmt.Println(block.Transactions()[0].Hash()) diff --git a/core/types/gen_header_json.go b/core/types/gen_header_json.go index bcff7a940..8af059104 100644 --- a/core/types/gen_header_json.go +++ b/core/types/gen_header_json.go @@ -22,8 +22,8 @@ func (h Header) MarshalJSON() ([]byte, error) { Bloom Bloom `json:"logsBloom" gencodec:"required"` Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` Number *hexutil.Big `json:"number" gencodec:"required"` - GasLimit *hexutil.Big `json:"gasLimit" gencodec:"required"` - GasUsed *hexutil.Big `json:"gasUsed" gencodec:"required"` + GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` + GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` Time *hexutil.Big `json:"timestamp" gencodec:"required"` Extra hexutil.Bytes `json:"extraData" gencodec:"required"` MixDigest common.Hash `json:"mixHash" gencodec:"required"` @@ -40,8 +40,8 @@ func (h Header) MarshalJSON() ([]byte, error) { enc.Bloom = h.Bloom enc.Difficulty = (*hexutil.Big)(h.Difficulty) enc.Number = (*hexutil.Big)(h.Number) - enc.GasLimit = (*hexutil.Big)(h.GasLimit) - enc.GasUsed = (*hexutil.Big)(h.GasUsed) + enc.GasLimit = hexutil.Uint64(h.GasLimit) + enc.GasUsed = hexutil.Uint64(h.GasUsed) enc.Time = (*hexutil.Big)(h.Time) enc.Extra = h.Extra enc.MixDigest = h.MixDigest @@ -61,8 +61,8 @@ func (h *Header) UnmarshalJSON(input []byte) error { Bloom *Bloom `json:"logsBloom" gencodec:"required"` Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` Number *hexutil.Big `json:"number" gencodec:"required"` - GasLimit *hexutil.Big `json:"gasLimit" gencodec:"required"` - GasUsed *hexutil.Big `json:"gasUsed" gencodec:"required"` + GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` + GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` Time *hexutil.Big `json:"timestamp" gencodec:"required"` Extra hexutil.Bytes `json:"extraData" gencodec:"required"` MixDigest *common.Hash `json:"mixHash" gencodec:"required"` @@ -111,11 +111,11 @@ func (h *Header) UnmarshalJSON(input []byte) error { if dec.GasLimit == nil { return errors.New("missing required field 'gasLimit' for Header") } - h.GasLimit = (*big.Int)(dec.GasLimit) + h.GasLimit = (uint64)(*dec.GasLimit) if dec.GasUsed == nil { return errors.New("missing required field 'gasUsed' for Header") } - h.GasUsed = (*big.Int)(dec.GasUsed) + h.GasUsed = (uint64)(*dec.GasUsed) if dec.Time == nil { return errors.New("missing required field 'timestamp' for Header") } diff --git a/core/types/gen_receipt_json.go b/core/types/gen_receipt_json.go index b95d99c95..520966874 100644 --- a/core/types/gen_receipt_json.go +++ b/core/types/gen_receipt_json.go @@ -5,7 +5,6 @@ package types import ( "encoding/json" "errors" - "math/big" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -15,22 +14,22 @@ func (r Receipt) MarshalJSON() ([]byte, error) { type Receipt struct { PostState hexutil.Bytes `json:"root"` Status hexutil.Uint `json:"status"` - CumulativeGasUsed *hexutil.Big `json:"cumulativeGasUsed" gencodec:"required"` + CumulativeGasUsed hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` Bloom Bloom `json:"logsBloom" gencodec:"required"` Logs []*Log `json:"logs" gencodec:"required"` TxHash common.Hash `json:"transactionHash" gencodec:"required"` ContractAddress common.Address `json:"contractAddress"` - GasUsed *hexutil.Big `json:"gasUsed" gencodec:"required"` + GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` } var enc Receipt enc.PostState = r.PostState enc.Status = hexutil.Uint(r.Status) - enc.CumulativeGasUsed = (*hexutil.Big)(r.CumulativeGasUsed) + enc.CumulativeGasUsed = hexutil.Uint64(r.CumulativeGasUsed) enc.Bloom = r.Bloom enc.Logs = r.Logs enc.TxHash = r.TxHash enc.ContractAddress = r.ContractAddress - enc.GasUsed = (*hexutil.Big)(r.GasUsed) + enc.GasUsed = hexutil.Uint64(r.GasUsed) return json.Marshal(&enc) } @@ -38,12 +37,12 @@ func (r *Receipt) UnmarshalJSON(input []byte) error { type Receipt struct { PostState hexutil.Bytes `json:"root"` Status *hexutil.Uint `json:"status"` - CumulativeGasUsed *hexutil.Big `json:"cumulativeGasUsed" gencodec:"required"` + CumulativeGasUsed *hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` Bloom *Bloom `json:"logsBloom" gencodec:"required"` Logs []*Log `json:"logs" gencodec:"required"` TxHash *common.Hash `json:"transactionHash" gencodec:"required"` ContractAddress *common.Address `json:"contractAddress"` - GasUsed *hexutil.Big `json:"gasUsed" gencodec:"required"` + GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` } var dec Receipt if err := json.Unmarshal(input, &dec); err != nil { @@ -58,7 +57,7 @@ func (r *Receipt) UnmarshalJSON(input []byte) error { if dec.CumulativeGasUsed == nil { return errors.New("missing required field 'cumulativeGasUsed' for Receipt") } - r.CumulativeGasUsed = (*big.Int)(dec.CumulativeGasUsed) + r.CumulativeGasUsed = uint64(*dec.CumulativeGasUsed) if dec.Bloom == nil { return errors.New("missing required field 'logsBloom' for Receipt") } @@ -77,6 +76,6 @@ func (r *Receipt) UnmarshalJSON(input []byte) error { if dec.GasUsed == nil { return errors.New("missing required field 'gasUsed' for Receipt") } - r.GasUsed = (*big.Int)(dec.GasUsed) + r.GasUsed = uint64(*dec.GasUsed) return nil } diff --git a/core/types/gen_tx_json.go b/core/types/gen_tx_json.go index 4fb658e0d..a82822c36 100644 --- a/core/types/gen_tx_json.go +++ b/core/types/gen_tx_json.go @@ -15,7 +15,7 @@ func (t txdata) MarshalJSON() ([]byte, error) { type txdata struct { AccountNonce hexutil.Uint64 `json:"nonce" gencodec:"required"` Price *hexutil.Big `json:"gasPrice" gencodec:"required"` - GasLimit *hexutil.Big `json:"gas" gencodec:"required"` + GasLimit hexutil.Uint64 `json:"gas" gencodec:"required"` Recipient *common.Address `json:"to" rlp:"nil"` Amount *hexutil.Big `json:"value" gencodec:"required"` Payload hexutil.Bytes `json:"input" gencodec:"required"` @@ -27,7 +27,7 @@ func (t txdata) MarshalJSON() ([]byte, error) { var enc txdata enc.AccountNonce = hexutil.Uint64(t.AccountNonce) enc.Price = (*hexutil.Big)(t.Price) - enc.GasLimit = (*hexutil.Big)(t.GasLimit) + enc.GasLimit = hexutil.Uint64(t.GasLimit) enc.Recipient = t.Recipient enc.Amount = (*hexutil.Big)(t.Amount) enc.Payload = t.Payload @@ -42,7 +42,7 @@ func (t *txdata) UnmarshalJSON(input []byte) error { type txdata struct { AccountNonce *hexutil.Uint64 `json:"nonce" gencodec:"required"` Price *hexutil.Big `json:"gasPrice" gencodec:"required"` - GasLimit *hexutil.Big `json:"gas" gencodec:"required"` + GasLimit *hexutil.Uint64 `json:"gas" gencodec:"required"` Recipient *common.Address `json:"to" rlp:"nil"` Amount *hexutil.Big `json:"value" gencodec:"required"` Payload hexutil.Bytes `json:"input" gencodec:"required"` @@ -66,7 +66,7 @@ func (t *txdata) UnmarshalJSON(input []byte) error { if dec.GasLimit == nil { return errors.New("missing required field 'gas' for txdata") } - t.GasLimit = (*big.Int)(dec.GasLimit) + t.GasLimit = uint64(*dec.GasLimit) if dec.Recipient != nil { t.Recipient = dec.Recipient } diff --git a/core/types/receipt.go b/core/types/receipt.go index bc3c996b4..208d54aaa 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -20,7 +20,6 @@ import ( "bytes" "fmt" "io" - "math/big" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -45,46 +44,46 @@ const ( // Receipt represents the results of a transaction. type Receipt struct { // Consensus fields - PostState []byte `json:"root"` - Status uint `json:"status"` - CumulativeGasUsed *big.Int `json:"cumulativeGasUsed" gencodec:"required"` - Bloom Bloom `json:"logsBloom" gencodec:"required"` - Logs []*Log `json:"logs" gencodec:"required"` + PostState []byte `json:"root"` + Status uint `json:"status"` + CumulativeGasUsed uint64 `json:"cumulativeGasUsed" gencodec:"required"` + Bloom Bloom `json:"logsBloom" gencodec:"required"` + Logs []*Log `json:"logs" gencodec:"required"` // Implementation fields (don't reorder!) TxHash common.Hash `json:"transactionHash" gencodec:"required"` ContractAddress common.Address `json:"contractAddress"` - GasUsed *big.Int `json:"gasUsed" gencodec:"required"` + GasUsed uint64 `json:"gasUsed" gencodec:"required"` } type receiptMarshaling struct { PostState hexutil.Bytes Status hexutil.Uint - CumulativeGasUsed *hexutil.Big - GasUsed *hexutil.Big + CumulativeGasUsed hexutil.Uint64 + GasUsed hexutil.Uint64 } // receiptRLP is the consensus encoding of a receipt. type receiptRLP struct { PostStateOrStatus []byte - CumulativeGasUsed *big.Int + CumulativeGasUsed uint64 Bloom Bloom Logs []*Log } type receiptStorageRLP struct { PostStateOrStatus []byte - CumulativeGasUsed *big.Int + CumulativeGasUsed uint64 Bloom Bloom TxHash common.Hash ContractAddress common.Address Logs []*LogForStorage - GasUsed *big.Int + GasUsed uint64 } // NewReceipt creates a barebone transaction receipt, copying the init fields. -func NewReceipt(root []byte, failed bool, cumulativeGasUsed *big.Int) *Receipt { - r := &Receipt{PostState: common.CopyBytes(root), CumulativeGasUsed: new(big.Int).Set(cumulativeGasUsed)} +func NewReceipt(root []byte, failed bool, cumulativeGasUsed uint64) *Receipt { + r := &Receipt{PostState: common.CopyBytes(root), CumulativeGasUsed: cumulativeGasUsed} if failed { r.Status = ReceiptStatusFailed } else { diff --git a/core/types/transaction.go b/core/types/transaction.go index ee4140ce4..a7ed211e4 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -57,7 +57,7 @@ type Transaction struct { type txdata struct { AccountNonce uint64 `json:"nonce" gencodec:"required"` Price *big.Int `json:"gasPrice" gencodec:"required"` - GasLimit *big.Int `json:"gas" gencodec:"required"` + GasLimit uint64 `json:"gas" gencodec:"required"` Recipient *common.Address `json:"to" rlp:"nil"` // nil means contract creation Amount *big.Int `json:"value" gencodec:"required"` Payload []byte `json:"input" gencodec:"required"` @@ -74,7 +74,7 @@ type txdata struct { type txdataMarshaling struct { AccountNonce hexutil.Uint64 Price *hexutil.Big - GasLimit *hexutil.Big + GasLimit hexutil.Uint64 Amount *hexutil.Big Payload hexutil.Bytes V *hexutil.Big @@ -82,15 +82,15 @@ type txdataMarshaling struct { S *hexutil.Big } -func NewTransaction(nonce uint64, to common.Address, amount, gasLimit, gasPrice *big.Int, data []byte) *Transaction { +func NewTransaction(nonce uint64, to common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction { return newTransaction(nonce, &to, amount, gasLimit, gasPrice, data) } -func NewContractCreation(nonce uint64, amount, gasLimit, gasPrice *big.Int, data []byte) *Transaction { +func NewContractCreation(nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction { return newTransaction(nonce, nil, amount, gasLimit, gasPrice, data) } -func newTransaction(nonce uint64, to *common.Address, amount, gasLimit, gasPrice *big.Int, data []byte) *Transaction { +func newTransaction(nonce uint64, to *common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction { if len(data) > 0 { data = common.CopyBytes(data) } @@ -99,7 +99,7 @@ func newTransaction(nonce uint64, to *common.Address, amount, gasLimit, gasPrice Recipient: to, Payload: data, Amount: new(big.Int), - GasLimit: new(big.Int), + GasLimit: gasLimit, Price: new(big.Int), V: new(big.Int), R: new(big.Int), @@ -108,9 +108,6 @@ func newTransaction(nonce uint64, to *common.Address, amount, gasLimit, gasPrice if amount != nil { d.Amount.Set(amount) } - if gasLimit != nil { - d.GasLimit.Set(gasLimit) - } if gasPrice != nil { d.Price.Set(gasPrice) } @@ -182,7 +179,7 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error { } func (tx *Transaction) Data() []byte { return common.CopyBytes(tx.data.Payload) } -func (tx *Transaction) Gas() *big.Int { return new(big.Int).Set(tx.data.GasLimit) } +func (tx *Transaction) Gas() uint64 { return tx.data.GasLimit } func (tx *Transaction) GasPrice() *big.Int { return new(big.Int).Set(tx.data.Price) } func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.data.Amount) } func (tx *Transaction) Nonce() uint64 { return tx.data.AccountNonce } @@ -227,8 +224,8 @@ func (tx *Transaction) Size() common.StorageSize { func (tx *Transaction) AsMessage(s Signer) (Message, error) { msg := Message{ nonce: tx.data.AccountNonce, - price: new(big.Int).Set(tx.data.Price), - gasLimit: new(big.Int).Set(tx.data.GasLimit), + gasLimit: tx.data.GasLimit, + gasPrice: new(big.Int).Set(tx.data.Price), to: tx.data.Recipient, amount: tx.data.Amount, data: tx.data.Payload, @@ -254,7 +251,7 @@ func (tx *Transaction) WithSignature(signer Signer, sig []byte) (*Transaction, e // Cost returns amount + gasprice * gaslimit. func (tx *Transaction) Cost() *big.Int { - total := new(big.Int).Mul(tx.data.Price, tx.data.GasLimit) + total := new(big.Int).Mul(tx.data.Price, new(big.Int).SetUint64(tx.data.GasLimit)) total.Add(total, tx.data.Amount) return total } @@ -440,22 +437,24 @@ func (t *TransactionsByPriceAndNonce) Pop() { // // NOTE: In a future PR this will be removed. type Message struct { - to *common.Address - from common.Address - nonce uint64 - amount, price, gasLimit *big.Int - data []byte - checkNonce bool + to *common.Address + from common.Address + nonce uint64 + amount *big.Int + gasLimit uint64 + gasPrice *big.Int + data []byte + checkNonce bool } -func NewMessage(from common.Address, to *common.Address, nonce uint64, amount, gasLimit, price *big.Int, data []byte, checkNonce bool) Message { +func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, checkNonce bool) Message { return Message{ from: from, to: to, nonce: nonce, amount: amount, - price: price, gasLimit: gasLimit, + gasPrice: gasPrice, data: data, checkNonce: checkNonce, } @@ -463,9 +462,9 @@ func NewMessage(from common.Address, to *common.Address, nonce uint64, amount, g func (m Message) From() common.Address { return m.from } func (m Message) To() *common.Address { return m.to } -func (m Message) GasPrice() *big.Int { return m.price } +func (m Message) GasPrice() *big.Int { return m.gasPrice } func (m Message) Value() *big.Int { return m.amount } -func (m Message) Gas() *big.Int { return m.gasLimit } +func (m Message) Gas() uint64 { return m.gasLimit } func (m Message) Nonce() uint64 { return m.nonce } func (m Message) Data() []byte { return m.data } func (m Message) CheckNonce() bool { return m.checkNonce } diff --git a/core/types/transaction_signing_test.go b/core/types/transaction_signing_test.go index 7f799fb10..689fc38a9 100644 --- a/core/types/transaction_signing_test.go +++ b/core/types/transaction_signing_test.go @@ -30,7 +30,7 @@ func TestEIP155Signing(t *testing.T) { addr := crypto.PubkeyToAddress(key.PublicKey) signer := NewEIP155Signer(big.NewInt(18)) - tx, err := SignTx(NewTransaction(0, addr, new(big.Int), new(big.Int), new(big.Int), nil), signer, key) + tx, err := SignTx(NewTransaction(0, addr, new(big.Int), 0, new(big.Int), nil), signer, key) if err != nil { t.Fatal(err) } @@ -49,7 +49,7 @@ func TestEIP155ChainId(t *testing.T) { addr := crypto.PubkeyToAddress(key.PublicKey) signer := NewEIP155Signer(big.NewInt(18)) - tx, err := SignTx(NewTransaction(0, addr, new(big.Int), new(big.Int), new(big.Int), nil), signer, key) + tx, err := SignTx(NewTransaction(0, addr, new(big.Int), 0, new(big.Int), nil), signer, key) if err != nil { t.Fatal(err) } @@ -61,7 +61,7 @@ func TestEIP155ChainId(t *testing.T) { t.Error("expected chainId to be", signer.chainId, "got", tx.ChainId()) } - tx = NewTransaction(0, addr, new(big.Int), new(big.Int), new(big.Int), nil) + tx = NewTransaction(0, addr, new(big.Int), 0, new(big.Int), nil) tx, err = SignTx(tx, HomesteadSigner{}, key) if err != nil { t.Fatal(err) @@ -118,7 +118,7 @@ func TestEIP155SigningVitalik(t *testing.T) { func TestChainId(t *testing.T) { key, _ := defaultTestKey() - tx := NewTransaction(0, common.Address{}, new(big.Int), new(big.Int), new(big.Int), nil) + tx := NewTransaction(0, common.Address{}, new(big.Int), 0, new(big.Int), nil) var err error tx, err = SignTx(tx, NewEIP155Signer(big.NewInt(1)), key) diff --git a/core/types/transaction_test.go b/core/types/transaction_test.go index 82d74e3b3..d1861b14c 100644 --- a/core/types/transaction_test.go +++ b/core/types/transaction_test.go @@ -34,7 +34,7 @@ var ( emptyTx = NewTransaction( 0, common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), - big.NewInt(0), big.NewInt(0), big.NewInt(0), + big.NewInt(0), 0, big.NewInt(0), nil, ) @@ -42,7 +42,7 @@ var ( 3, common.HexToAddress("b94f5374fce5edbc8e2a8697c15331677e6ebf0b"), big.NewInt(10), - big.NewInt(2000), + 2000, big.NewInt(1), common.FromHex("5544"), ).WithSignature( @@ -139,7 +139,7 @@ func TestTransactionPriceNonceSort(t *testing.T) { for start, key := range keys { addr := crypto.PubkeyToAddress(key.PublicKey) for i := 0; i < 25; i++ { - tx, _ := SignTx(NewTransaction(uint64(start+i), common.Address{}, big.NewInt(100), big.NewInt(100), big.NewInt(int64(start+i)), nil), signer, key) + tx, _ := SignTx(NewTransaction(uint64(start+i), common.Address{}, big.NewInt(100), 100, big.NewInt(int64(start+i)), nil), signer, key) groups[addr] = append(groups[addr], tx) } } @@ -204,9 +204,9 @@ func TestTransactionJSON(t *testing.T) { var tx *Transaction switch i % 2 { case 0: - tx = NewTransaction(i, common.Address{1}, common.Big0, common.Big1, common.Big2, []byte("abcdef")) + tx = NewTransaction(i, common.Address{1}, common.Big0, 1, common.Big2, []byte("abcdef")) case 1: - tx = NewContractCreation(i, common.Big0, common.Big1, common.Big2, []byte("abcdef")) + tx = NewContractCreation(i, common.Big0, 1, common.Big2, []byte("abcdef")) } tx, err := SignTx(tx, signer, key) diff --git a/core/vm/evm.go b/core/vm/evm.go index a3f3a97cb..8796a633e 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -69,7 +69,7 @@ type Context struct { // Block information Coinbase common.Address // Provides information for COINBASE - GasLimit *big.Int // Provides information for GASLIMIT + GasLimit uint64 // Provides information for GASLIMIT BlockNumber *big.Int // Provides information for NUMBER Time *big.Int // Provides information for TIME Difficulty *big.Int // Provides information for DIFFICULTY diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index ff109af57..83adba428 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -17,8 +17,6 @@ package vm import ( - "math/big" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/params" @@ -130,7 +128,7 @@ func gasSStore(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, m // 0 => non 0 return params.SstoreSetGas, nil } else if !common.EmptyHash(val) && common.EmptyHash(common.BigToHash(y)) { - evm.StateDB.AddRefund(new(big.Int).SetUint64(params.SstoreRefundGas)) + evm.StateDB.AddRefund(params.SstoreRefundGas) return params.SstoreClearGas, nil } else { @@ -405,7 +403,7 @@ func gasSuicide(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, } if !evm.StateDB.HasSuicided(contract.Address()) { - evm.StateDB.AddRefund(new(big.Int).SetUint64(params.SuicideRefundGas)) + evm.StateDB.AddRefund(params.SuicideRefundGas) } return gas, nil } diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 1d1585fca..766172501 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -472,7 +472,7 @@ func opDifficulty(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stac } func opGasLimit(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(math.U256(new(big.Int).Set(evm.GasLimit))) + stack.push(math.U256(new(big.Int).SetUint64(evm.GasLimit))) return nil, nil } diff --git a/core/vm/interface.go b/core/vm/interface.go index c0c52732b..1ef91cf1d 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -39,8 +39,8 @@ type StateDB interface { SetCode(common.Address, []byte) GetCodeSize(common.Address) int - AddRefund(*big.Int) - GetRefund() *big.Int + AddRefund(uint64) + GetRefund() uint64 GetState(common.Address, common.Hash) common.Hash SetState(common.Address, common.Hash, common.Hash) diff --git a/core/vm/noop.go b/core/vm/noop.go index 2a04a9565..b71ead0d7 100644 --- a/core/vm/noop.go +++ b/core/vm/noop.go @@ -55,8 +55,8 @@ func (NoopStateDB) GetCodeHash(common.Address) common.Hash func (NoopStateDB) GetCode(common.Address) []byte { return nil } func (NoopStateDB) SetCode(common.Address, []byte) {} func (NoopStateDB) GetCodeSize(common.Address) int { return 0 } -func (NoopStateDB) AddRefund(*big.Int) {} -func (NoopStateDB) GetRefund() *big.Int { return nil } +func (NoopStateDB) AddRefund(uint64) {} +func (NoopStateDB) GetRefund() uint64 { return 0 } func (NoopStateDB) GetState(common.Address, common.Hash) common.Hash { return common.Hash{} } func (NoopStateDB) SetState(common.Address, common.Hash, common.Hash) {} func (NoopStateDB) Suicide(common.Address) bool { return false } diff --git a/core/vm/runtime/env.go b/core/vm/runtime/env.go index 818da1be2..31c9b9cf9 100644 --- a/core/vm/runtime/env.go +++ b/core/vm/runtime/env.go @@ -17,8 +17,6 @@ package runtime import ( - "math/big" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/vm" @@ -35,7 +33,7 @@ func NewEnv(cfg *Config) *vm.EVM { BlockNumber: cfg.BlockNumber, Time: cfg.Time, Difficulty: cfg.Difficulty, - GasLimit: new(big.Int).SetUint64(cfg.GasLimit), + GasLimit: cfg.GasLimit, GasPrice: cfg.GasPrice, } |