all: switch gas limits from big.Int to uint64

This commit is contained in:
Péter Szilágyi 2017-11-13 13:47:27 +02:00
parent b8caba9709
commit 6f69cdd109
No known key found for this signature in database
GPG Key ID: E9AE538CEDF8293D
82 changed files with 606 additions and 642 deletions

View File

@ -85,7 +85,7 @@ type ContractTransactor interface {
// There is no guarantee that this is the true gas limit requirement as other // There is no guarantee that this is the true gas limit requirement as other
// transactions may be added or removed by miners, but it should provide a basis // transactions may be added or removed by miners, but it should provide a basis
// for setting a reasonable default. // for setting a reasonable default.
EstimateGas(ctx context.Context, call ethereum.CallMsg) (usedGas *big.Int, err error) EstimateGas(ctx context.Context, call ethereum.CallMsg) (gas uint64, err error)
// SendTransaction injects the transaction into the pending pool for execution. // SendTransaction injects the transaction into the pending pool for execution.
SendTransaction(ctx context.Context, tx *types.Transaction) error SendTransaction(ctx context.Context, tx *types.Transaction) error
} }

View File

@ -200,7 +200,7 @@ func (b *SimulatedBackend) SuggestGasPrice(ctx context.Context) (*big.Int, error
// EstimateGas executes the requested code against the currently pending block/state and // EstimateGas executes the requested code against the currently pending block/state and
// returns the used amount of gas. // returns the used amount of gas.
func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMsg) (*big.Int, error) { func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error) {
b.mu.Lock() b.mu.Lock()
defer b.mu.Unlock() defer b.mu.Unlock()
@ -210,16 +210,16 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs
hi uint64 hi uint64
cap uint64 cap uint64
) )
if call.Gas != nil && call.Gas.Uint64() >= params.TxGas { if call.Gas >= params.TxGas {
hi = call.Gas.Uint64() hi = call.Gas
} else { } else {
hi = b.pendingBlock.GasLimit().Uint64() hi = b.pendingBlock.GasLimit()
} }
cap = hi cap = hi
// Create a helper to check if a gas allowance results in an executable transaction // Create a helper to check if a gas allowance results in an executable transaction
executable := func(gas uint64) bool { executable := func(gas uint64) bool {
call.Gas = new(big.Int).SetUint64(gas) call.Gas = gas
snapshot := b.pendingState.Snapshot() snapshot := b.pendingState.Snapshot()
_, _, failed, err := b.callContract(ctx, call, b.pendingBlock, b.pendingState) _, _, failed, err := b.callContract(ctx, call, b.pendingBlock, b.pendingState)
@ -242,21 +242,21 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs
// Reject the transaction as invalid if it still fails at the highest allowance // Reject the transaction as invalid if it still fails at the highest allowance
if hi == cap { if hi == cap {
if !executable(hi) { if !executable(hi) {
return nil, errGasEstimationFailed return 0, errGasEstimationFailed
} }
} }
return new(big.Int).SetUint64(hi), nil return hi, nil
} }
// callContract implemens common code between normal and pending contract calls. // callContract implemens common code between normal and pending contract calls.
// state is modified during execution, make sure to copy it if necessary. // state is modified during execution, make sure to copy it if necessary.
func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallMsg, block *types.Block, statedb *state.StateDB) ([]byte, *big.Int, bool, error) { func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallMsg, block *types.Block, statedb *state.StateDB) ([]byte, uint64, bool, error) {
// Ensure message is initialized properly. // Ensure message is initialized properly.
if call.GasPrice == nil { if call.GasPrice == nil {
call.GasPrice = big.NewInt(1) call.GasPrice = big.NewInt(1)
} }
if call.Gas == nil || call.Gas.Sign() == 0 { if call.Gas == 0 {
call.Gas = big.NewInt(50000000) call.Gas = 50000000
} }
if call.Value == nil { if call.Value == nil {
call.Value = new(big.Int) call.Value = new(big.Int)
@ -271,9 +271,9 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
// Create a new environment which holds all relevant information // Create a new environment which holds all relevant information
// about the transaction and calling mechanisms. // about the transaction and calling mechanisms.
vmenv := vm.NewEVM(evmContext, statedb, b.config, vm.Config{}) vmenv := vm.NewEVM(evmContext, statedb, b.config, vm.Config{})
gaspool := new(core.GasPool).AddGas(math.MaxBig256) gaspool := new(core.GasPool).AddGas(math.MaxUint64)
ret, gasUsed, _, failed, err := core.NewStateTransition(vmenv, msg, gaspool).TransitionDb()
return ret, gasUsed, failed, err return core.NewStateTransition(vmenv, msg, gaspool).TransitionDb()
} }
// SendTransaction updates the pending block to include the given transaction. // SendTransaction updates the pending block to include the given transaction.
@ -328,6 +328,6 @@ func (m callmsg) Nonce() uint64 { return 0 }
func (m callmsg) CheckNonce() bool { return false } func (m callmsg) CheckNonce() bool { return false }
func (m callmsg) To() *common.Address { return m.CallMsg.To } func (m callmsg) To() *common.Address { return m.CallMsg.To }
func (m callmsg) GasPrice() *big.Int { return m.CallMsg.GasPrice } func (m callmsg) GasPrice() *big.Int { return m.CallMsg.GasPrice }
func (m callmsg) Gas() *big.Int { return m.CallMsg.Gas } func (m callmsg) Gas() uint64 { return m.CallMsg.Gas }
func (m callmsg) Value() *big.Int { return m.CallMsg.Value } func (m callmsg) Value() *big.Int { return m.CallMsg.Value }
func (m callmsg) Data() []byte { return m.CallMsg.Data } func (m callmsg) Data() []byte { return m.CallMsg.Data }

View File

@ -50,7 +50,7 @@ type TransactOpts struct {
Value *big.Int // Funds to transfer along along the transaction (nil = 0 = no funds) Value *big.Int // Funds to transfer along along the transaction (nil = 0 = no funds)
GasPrice *big.Int // Gas price to use for the transaction execution (nil = gas price oracle) GasPrice *big.Int // Gas price to use for the transaction execution (nil = gas price oracle)
GasLimit *big.Int // Gas limit to set for the transaction execution (nil = estimate + 10%) GasLimit uint64 // Gas limit to set for the transaction execution (0 = estimate)
Context context.Context // Network context to support cancellation and timeouts (nil = no timeout) Context context.Context // Network context to support cancellation and timeouts (nil = no timeout)
} }
@ -189,7 +189,7 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i
} }
} }
gasLimit := opts.GasLimit gasLimit := opts.GasLimit
if gasLimit == nil { if gasLimit == 0 {
// Gas estimation cannot succeed without code for method invocations // Gas estimation cannot succeed without code for method invocations
if contract != nil { if contract != nil {
if code, err := c.transactor.PendingCodeAt(ensureContext(opts.Context), c.address); err != nil { if code, err := c.transactor.PendingCodeAt(ensureContext(opts.Context), c.address); err != nil {

View File

@ -399,7 +399,6 @@ var bindTests = []struct {
sim.Commit() sim.Commit()
// Set the field with automatic estimation and check that it succeeds // Set the field with automatic estimation and check that it succeeds
auth.GasLimit = nil
if _, err := limiter.SetField(auth, "automatic"); err != nil { if _, err := limiter.SetField(auth, "automatic"); err != nil {
t.Fatalf("Failed to call automatically gased transaction: %v", err) t.Fatalf("Failed to call automatically gased transaction: %v", err)
} }

View File

@ -34,18 +34,18 @@ var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d
var waitDeployedTests = map[string]struct { var waitDeployedTests = map[string]struct {
code string code string
gas *big.Int gas uint64
wantAddress common.Address wantAddress common.Address
wantErr error wantErr error
}{ }{
"successful deploy": { "successful deploy": {
code: `6060604052600a8060106000396000f360606040526008565b00`, code: `6060604052600a8060106000396000f360606040526008565b00`,
gas: big.NewInt(3000000), gas: 3000000,
wantAddress: common.HexToAddress("0x3a220f351252089d385b29beca14e27f204c296a"), wantAddress: common.HexToAddress("0x3a220f351252089d385b29beca14e27f204c296a"),
}, },
"empty code": { "empty code": {
code: ``, code: ``,
gas: big.NewInt(300000), gas: 300000,
wantErr: bind.ErrNoCodeAfterDeploy, wantErr: bind.ErrNoCodeAfterDeploy,
wantAddress: common.HexToAddress("0x3a220f351252089d385b29beca14e27f204c296a"), wantAddress: common.HexToAddress("0x3a220f351252089d385b29beca14e27f204c296a"),
}, },

View File

@ -180,7 +180,7 @@ func (w *trezorDriver) trezorSign(derivationPath []uint32, tx *types.Transaction
AddressN: derivationPath, AddressN: derivationPath,
Nonce: new(big.Int).SetUint64(tx.Nonce()).Bytes(), Nonce: new(big.Int).SetUint64(tx.Nonce()).Bytes(),
GasPrice: tx.GasPrice().Bytes(), GasPrice: tx.GasPrice().Bytes(),
GasLimit: tx.Gas().Bytes(), GasLimit: new(big.Int).SetUint64(tx.Gas()).Bytes(),
Value: tx.Value().Bytes(), Value: tx.Value().Bytes(),
DataLength: &length, DataLength: &length,
} }

View File

@ -473,7 +473,7 @@ func (f *faucet) apiHandler(conn *websocket.Conn) {
amount = new(big.Int).Mul(amount, new(big.Int).Exp(big.NewInt(5), big.NewInt(int64(msg.Tier)), nil)) amount = new(big.Int).Mul(amount, new(big.Int).Exp(big.NewInt(5), big.NewInt(int64(msg.Tier)), nil))
amount = new(big.Int).Div(amount, new(big.Int).Exp(big.NewInt(2), big.NewInt(int64(msg.Tier)), nil)) amount = new(big.Int).Div(amount, new(big.Int).Exp(big.NewInt(2), big.NewInt(int64(msg.Tier)), nil))
tx := types.NewTransaction(f.nonce+uint64(len(f.reqs)), address, amount, big.NewInt(21000), f.price, nil) tx := types.NewTransaction(f.nonce+uint64(len(f.reqs)), address, amount, 21000, f.price, nil)
signed, err := f.keystore.SignTx(f.account, tx, f.config.ChainId) signed, err := f.keystore.SignTx(f.account, tx, f.config.ChainId)
if err != nil { if err != nil {
f.lock.Unlock() f.lock.Unlock()

View File

@ -44,7 +44,7 @@ type cppEthereumGenesisSpec struct {
MaximumExtraDataSize hexutil.Uint64 `json:"maximumExtraDataSize"` MaximumExtraDataSize hexutil.Uint64 `json:"maximumExtraDataSize"`
MinGasLimit hexutil.Uint64 `json:"minGasLimit"` MinGasLimit hexutil.Uint64 `json:"minGasLimit"`
MaxGasLimit hexutil.Uint64 `json:"maxGasLimit"` MaxGasLimit hexutil.Uint64 `json:"maxGasLimit"`
GasLimitBoundDivisor *hexutil.Big `json:"gasLimitBoundDivisor"` GasLimitBoundDivisor hexutil.Uint64 `json:"gasLimitBoundDivisor"`
MinimumDifficulty *hexutil.Big `json:"minimumDifficulty"` MinimumDifficulty *hexutil.Big `json:"minimumDifficulty"`
DifficultyBoundDivisor *hexutil.Big `json:"difficultyBoundDivisor"` DifficultyBoundDivisor *hexutil.Big `json:"difficultyBoundDivisor"`
DurationLimit *hexutil.Big `json:"durationLimit"` DurationLimit *hexutil.Big `json:"durationLimit"`
@ -107,11 +107,11 @@ func newCppEthereumGenesisSpec(network string, genesis *core.Genesis) (*cppEther
spec.Params.ChainID = (hexutil.Uint64)(genesis.Config.ChainId.Uint64()) spec.Params.ChainID = (hexutil.Uint64)(genesis.Config.ChainId.Uint64())
spec.Params.MaximumExtraDataSize = (hexutil.Uint64)(params.MaximumExtraDataSize) spec.Params.MaximumExtraDataSize = (hexutil.Uint64)(params.MaximumExtraDataSize)
spec.Params.MinGasLimit = (hexutil.Uint64)(params.MinGasLimit.Uint64()) spec.Params.MinGasLimit = (hexutil.Uint64)(params.MinGasLimit)
spec.Params.MaxGasLimit = (hexutil.Uint64)(math.MaxUint64) spec.Params.MaxGasLimit = (hexutil.Uint64)(math.MaxUint64)
spec.Params.MinimumDifficulty = (*hexutil.Big)(params.MinimumDifficulty) spec.Params.MinimumDifficulty = (*hexutil.Big)(params.MinimumDifficulty)
spec.Params.DifficultyBoundDivisor = (*hexutil.Big)(params.DifficultyBoundDivisor) spec.Params.DifficultyBoundDivisor = (*hexutil.Big)(params.DifficultyBoundDivisor)
spec.Params.GasLimitBoundDivisor = (*hexutil.Big)(params.GasLimitBoundDivisor) spec.Params.GasLimitBoundDivisor = (hexutil.Uint64)(params.GasLimitBoundDivisor)
spec.Params.DurationLimit = (*hexutil.Big)(params.DurationLimit) spec.Params.DurationLimit = (*hexutil.Big)(params.DurationLimit)
spec.Params.BlockReward = (*hexutil.Big)(ethash.FrontierBlockReward) spec.Params.BlockReward = (*hexutil.Big)(ethash.FrontierBlockReward)
@ -168,26 +168,26 @@ type parityChainSpec struct {
Engine struct { Engine struct {
Ethash struct { Ethash struct {
Params struct { Params struct {
MinimumDifficulty *hexutil.Big `json:"minimumDifficulty"` MinimumDifficulty *hexutil.Big `json:"minimumDifficulty"`
DifficultyBoundDivisor *hexutil.Big `json:"difficultyBoundDivisor"` DifficultyBoundDivisor *hexutil.Big `json:"difficultyBoundDivisor"`
GasLimitBoundDivisor *hexutil.Big `json:"gasLimitBoundDivisor"` GasLimitBoundDivisor hexutil.Uint64 `json:"gasLimitBoundDivisor"`
DurationLimit *hexutil.Big `json:"durationLimit"` DurationLimit *hexutil.Big `json:"durationLimit"`
BlockReward *hexutil.Big `json:"blockReward"` BlockReward *hexutil.Big `json:"blockReward"`
HomesteadTransition uint64 `json:"homesteadTransition"` HomesteadTransition uint64 `json:"homesteadTransition"`
EIP150Transition uint64 `json:"eip150Transition"` EIP150Transition uint64 `json:"eip150Transition"`
EIP160Transition uint64 `json:"eip160Transition"` EIP160Transition uint64 `json:"eip160Transition"`
EIP161abcTransition uint64 `json:"eip161abcTransition"` EIP161abcTransition uint64 `json:"eip161abcTransition"`
EIP161dTransition uint64 `json:"eip161dTransition"` EIP161dTransition uint64 `json:"eip161dTransition"`
EIP649Reward *hexutil.Big `json:"eip649Reward"` EIP649Reward *hexutil.Big `json:"eip649Reward"`
EIP100bTransition uint64 `json:"eip100bTransition"` EIP100bTransition uint64 `json:"eip100bTransition"`
EIP649Transition uint64 `json:"eip649Transition"` EIP649Transition uint64 `json:"eip649Transition"`
} `json:"params"` } `json:"params"`
} `json:"Ethash"` } `json:"Ethash"`
} `json:"engine"` } `json:"engine"`
Params struct { Params struct {
MaximumExtraDataSize hexutil.Uint64 `json:"maximumExtraDataSize"` MaximumExtraDataSize hexutil.Uint64 `json:"maximumExtraDataSize"`
MinGasLimit *hexutil.Big `json:"minGasLimit"` MinGasLimit hexutil.Uint64 `json:"minGasLimit"`
NetworkID hexutil.Uint64 `json:"networkID"` NetworkID hexutil.Uint64 `json:"networkID"`
MaxCodeSize uint64 `json:"maxCodeSize"` MaxCodeSize uint64 `json:"maxCodeSize"`
EIP155Transition uint64 `json:"eip155Transition"` EIP155Transition uint64 `json:"eip155Transition"`
@ -270,7 +270,7 @@ func newParityChainSpec(network string, genesis *core.Genesis, bootnodes []strin
} }
spec.Engine.Ethash.Params.MinimumDifficulty = (*hexutil.Big)(params.MinimumDifficulty) spec.Engine.Ethash.Params.MinimumDifficulty = (*hexutil.Big)(params.MinimumDifficulty)
spec.Engine.Ethash.Params.DifficultyBoundDivisor = (*hexutil.Big)(params.DifficultyBoundDivisor) spec.Engine.Ethash.Params.DifficultyBoundDivisor = (*hexutil.Big)(params.DifficultyBoundDivisor)
spec.Engine.Ethash.Params.GasLimitBoundDivisor = (*hexutil.Big)(params.GasLimitBoundDivisor) spec.Engine.Ethash.Params.GasLimitBoundDivisor = (hexutil.Uint64)(params.GasLimitBoundDivisor)
spec.Engine.Ethash.Params.DurationLimit = (*hexutil.Big)(params.DurationLimit) spec.Engine.Ethash.Params.DurationLimit = (*hexutil.Big)(params.DurationLimit)
spec.Engine.Ethash.Params.BlockReward = (*hexutil.Big)(ethash.FrontierBlockReward) spec.Engine.Ethash.Params.BlockReward = (*hexutil.Big)(ethash.FrontierBlockReward)
spec.Engine.Ethash.Params.HomesteadTransition = genesis.Config.HomesteadBlock.Uint64() spec.Engine.Ethash.Params.HomesteadTransition = genesis.Config.HomesteadBlock.Uint64()
@ -283,7 +283,7 @@ func newParityChainSpec(network string, genesis *core.Genesis, bootnodes []strin
spec.Engine.Ethash.Params.EIP649Transition = genesis.Config.ByzantiumBlock.Uint64() spec.Engine.Ethash.Params.EIP649Transition = genesis.Config.ByzantiumBlock.Uint64()
spec.Params.MaximumExtraDataSize = (hexutil.Uint64)(params.MaximumExtraDataSize) spec.Params.MaximumExtraDataSize = (hexutil.Uint64)(params.MaximumExtraDataSize)
spec.Params.MinGasLimit = (*hexutil.Big)(params.MinGasLimit) spec.Params.MinGasLimit = (hexutil.Uint64)(params.MinGasLimit)
spec.Params.NetworkID = (hexutil.Uint64)(genesis.Config.ChainId.Uint64()) spec.Params.NetworkID = (hexutil.Uint64)(genesis.Config.ChainId.Uint64())
spec.Params.MaxCodeSize = params.MaxCodeSize spec.Params.MaxCodeSize = params.MaxCodeSize
spec.Params.EIP155Transition = genesis.Config.EIP155Block.Uint64() spec.Params.EIP155Transition = genesis.Config.EIP155Block.Uint64()

View File

@ -313,7 +313,7 @@ var (
TargetGasLimitFlag = cli.Uint64Flag{ TargetGasLimitFlag = cli.Uint64Flag{
Name: "targetgaslimit", Name: "targetgaslimit",
Usage: "Target gas limit sets the artificial target gas floor for the blocks to mine", Usage: "Target gas limit sets the artificial target gas floor for the blocks to mine",
Value: params.GenesisGasLimit.Uint64(), Value: params.GenesisGasLimit,
} }
EtherbaseFlag = cli.StringFlag{ EtherbaseFlag = cli.StringFlag{
Name: "etherbase", Name: "etherbase",
@ -1138,7 +1138,7 @@ func RegisterEthStatsService(stack *node.Node, url string) {
// SetupNetwork configures the system for either the main net or some test network. // SetupNetwork configures the system for either the main net or some test network.
func SetupNetwork(ctx *cli.Context) { func SetupNetwork(ctx *cli.Context) {
// TODO(fjl): move target gas limit into config // TODO(fjl): move target gas limit into config
params.TargetGasLimit = new(big.Int).SetUint64(ctx.GlobalUint64(TargetGasLimitFlag.Name)) params.TargetGasLimit = ctx.GlobalUint64(TargetGasLimitFlag.Name)
} }
// MakeChainDatabase open an LevelDB using the flags passed to the client and will hard crash if it fails. // MakeChainDatabase open an LevelDB using the flags passed to the client and will hard crash if it fails.

View File

@ -688,8 +688,8 @@ func TestConcurrentDiskCacheGeneration(t *testing.T) {
TxHash: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"), TxHash: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"),
ReceiptHash: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"), ReceiptHash: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"),
Difficulty: big.NewInt(167925187834220), Difficulty: big.NewInt(167925187834220),
GasLimit: big.NewInt(4015682), GasLimit: 4015682,
GasUsed: big.NewInt(0), GasUsed: 0,
Time: big.NewInt(1488928920), Time: big.NewInt(1488928920),
Extra: []byte("www.bw.com"), Extra: []byte("www.bw.com"),
MixDigest: common.HexToHash("0x3e140b0784516af5e5ec6730f2fb20cca22f32be399b9e4ad77d32541f798cd0"), MixDigest: common.HexToHash("0x3e140b0784516af5e5ec6730f2fb20cca22f32be399b9e4ad77d32541f798cd0"),

View File

@ -246,24 +246,24 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header, parent *
return fmt.Errorf("invalid difficulty: have %v, want %v", header.Difficulty, expected) return fmt.Errorf("invalid difficulty: have %v, want %v", header.Difficulty, expected)
} }
// Verify that the gas limit is <= 2^63-1 // Verify that the gas limit is <= 2^63-1
if header.GasLimit.Cmp(math.MaxBig63) > 0 { cap := uint64(0x7fffffffffffffff)
return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, math.MaxBig63) if header.GasLimit > cap {
return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, cap)
} }
// Verify that the gasUsed is <= gasLimit // Verify that the gasUsed is <= gasLimit
if header.GasUsed.Cmp(header.GasLimit) > 0 { if header.GasUsed > header.GasLimit {
return fmt.Errorf("invalid gasUsed: have %v, gasLimit %v", header.GasUsed, header.GasLimit) return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
} }
// Verify that the gas limit remains within allowed bounds // Verify that the gas limit remains within allowed bounds
diff := new(big.Int).Set(parent.GasLimit) diff := int64(parent.GasLimit) - int64(header.GasLimit)
diff = diff.Sub(diff, header.GasLimit) if diff < 0 {
diff.Abs(diff) diff *= -1
}
limit := parent.GasLimit / params.GasLimitBoundDivisor
limit := new(big.Int).Set(parent.GasLimit) if uint64(diff) >= limit || header.GasLimit < params.MinGasLimit {
limit = limit.Div(limit, params.GasLimitBoundDivisor) return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit)
if diff.Cmp(limit) >= 0 || header.GasLimit.Cmp(params.MinGasLimit) < 0 {
return fmt.Errorf("invalid gas limit: have %v, want %v += %v", header.GasLimit, parent.GasLimit, limit)
} }
// Verify that the block number is parent's +1 // Verify that the block number is parent's +1
if diff := new(big.Int).Sub(header.Number, parent.Number); diff.Cmp(big.NewInt(1)) != 0 { if diff := new(big.Int).Sub(header.Number, parent.Number); diff.Cmp(big.NewInt(1)) != 0 {

View File

@ -56,8 +56,8 @@ import (
// * watching incoming ether // * watching incoming ether
var ( var (
gasToCash = big.NewInt(2000000) // gas cost of a cash transaction using chequebook gasToCash = uint64(2000000) // gas cost of a cash transaction using chequebook
// gasToDeploy = big.NewInt(3000000) // gasToDeploy = uint64(3000000)
) )
// Backend wraps all methods required for chequebook operation. // Backend wraps all methods required for chequebook operation.

View File

@ -19,7 +19,6 @@ package ens
//go:generate abigen --sol contract/ens.sol --pkg contract --out contract/ens.go //go:generate abigen --sol contract/ens.sol --pkg contract --out contract/ens.go
import ( import (
"math/big"
"strings" "strings"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
@ -163,7 +162,7 @@ func (self *ENS) Register(name string) (*types.Transaction, error) {
} }
opts := self.TransactOpts opts := self.TransactOpts
opts.GasLimit = big.NewInt(200000) opts.GasLimit = 200000
return registrar.Contract.Register(&opts, label, self.TransactOpts.From) return registrar.Contract.Register(&opts, label, self.TransactOpts.From)
} }
@ -178,6 +177,6 @@ func (self *ENS) SetContentHash(name string, hash common.Hash) (*types.Transacti
} }
opts := self.TransactOpts opts := self.TransactOpts
opts.GasLimit = big.NewInt(200000) opts.GasLimit = 200000
return resolver.Contract.SetContent(&opts, node, hash) return resolver.Contract.SetContent(&opts, node, hash)
} }

View File

@ -37,7 +37,7 @@ func TestENS(t *testing.T) {
contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}) contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}})
transactOpts := bind.NewKeyedTransactor(key) transactOpts := bind.NewKeyedTransactor(key)
// Workaround for bug estimating gas in the call to Register // Workaround for bug estimating gas in the call to Register
transactOpts.GasLimit = big.NewInt(1000000) transactOpts.GasLimit = 1000000
ens, err := DeployENS(transactOpts, contractBackend) ens, err := DeployENS(transactOpts, contractBackend)
if err != nil { if err != nil {

View File

@ -84,7 +84,7 @@ func genValueTx(nbytes int) func(int, *BlockGen) {
return func(i int, gen *BlockGen) { return func(i int, gen *BlockGen) {
toaddr := common.Address{} toaddr := common.Address{}
data := make([]byte, nbytes) 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) tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(benchRootAddr), toaddr, big.NewInt(1), gas, nil, data), types.HomesteadSigner{}, benchRootKey)
gen.AddTx(tx) gen.AddTx(tx)
} }
@ -93,7 +93,6 @@ func genValueTx(nbytes int) func(int, *BlockGen) {
var ( var (
ringKeys = make([]*ecdsa.PrivateKey, 1000) ringKeys = make([]*ecdsa.PrivateKey, 1000)
ringAddrs = make([]common.Address, len(ringKeys)) ringAddrs = make([]common.Address, len(ringKeys))
bigTxGas = new(big.Int).SetUint64(params.TxGas)
) )
func init() { func init() {
@ -113,8 +112,8 @@ func genTxRing(naccounts int) func(int, *BlockGen) {
return func(i int, gen *BlockGen) { return func(i int, gen *BlockGen) {
gas := CalcGasLimit(gen.PrevBlock(i - 1)) gas := CalcGasLimit(gen.PrevBlock(i - 1))
for { for {
gas.Sub(gas, bigTxGas) gas -= params.TxGas
if gas.Cmp(bigTxGas) < 0 { if gas < params.TxGas {
break break
} }
to := (from + 1) % naccounts to := (from + 1) % naccounts
@ -122,7 +121,7 @@ func genTxRing(naccounts int) func(int, *BlockGen) {
gen.TxNonce(ringAddrs[from]), gen.TxNonce(ringAddrs[from]),
ringAddrs[to], ringAddrs[to],
benchRootFunds, benchRootFunds,
bigTxGas, params.TxGas,
nil, nil,
nil, nil,
) )

View File

@ -18,9 +18,7 @@ package core
import ( import (
"fmt" "fmt"
"math/big"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types" "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 // 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 // itself. ValidateState returns a database batch if the validation was a success
// otherwise nil and an error is returned. // 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() header := block.Header()
if block.GasUsed().Cmp(usedGas) != 0 { if block.GasUsed() != usedGas {
return fmt.Errorf("invalid gas used (remote: %v local: %v)", 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. // Validate the received block's bloom with the one derived from the generated receipts.
// For valid blocks this should always validate to true. // 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. // 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. // 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 = (parentGasUsed * 3 / 2) / 1024
contrib := new(big.Int).Mul(parent.GasUsed(), big.NewInt(3)) contrib := (parent.GasUsed() + parent.GasUsed()/2) / params.GasLimitBoundDivisor
contrib = contrib.Div(contrib, big.NewInt(2))
contrib = contrib.Div(contrib, params.GasLimitBoundDivisor)
// decay = parentGasLimit / 1024 -1 // decay = parentGasLimit / 1024 -1
decay := new(big.Int).Div(parent.GasLimit(), params.GasLimitBoundDivisor) decay := parent.GasLimit()/params.GasLimitBoundDivisor - 1
decay.Sub(decay, big.NewInt(1))
/* /*
strategy: gasLimit of block-to-mine is set based on parent's 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 at that usage) the amount increased/decreased depends on how far away
from parentGasLimit * (2/3) parentGasUsed is. from parentGasLimit * (2/3) parentGasUsed is.
*/ */
gl := new(big.Int).Sub(parent.GasLimit(), decay) limit := parent.GasLimit() - decay + contrib
gl = gl.Add(gl, contrib) if limit < params.MinGasLimit {
gl.Set(math.BigMax(gl, params.MinGasLimit)) limit = params.MinGasLimit
}
// however, if we're now below the target (TargetGasLimit) we increase the // however, if we're now below the target (TargetGasLimit) we increase the
// limit as much as we can (parentGasLimit / 1024 -1) // limit as much as we can (parentGasLimit / 1024 -1)
if gl.Cmp(params.TargetGasLimit) < 0 { if limit < params.TargetGasLimit {
gl.Add(parent.GasLimit(), decay) limit = parent.GasLimit() + decay
gl.Set(math.BigMin(gl, params.TargetGasLimit)) if limit > params.TargetGasLimit {
limit = params.TargetGasLimit
}
} }
return gl return limit
} }

View File

@ -305,7 +305,7 @@ func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error {
} }
// GasLimit returns the gas limit of the current HEAD block. // GasLimit returns the gas limit of the current HEAD block.
func (bc *BlockChain) GasLimit() *big.Int { func (bc *BlockChain) GasLimit() uint64 {
bc.mu.RLock() bc.mu.RLock()
defer bc.mu.RUnlock() 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 // The used gas can be calculated based on previous receipts
if j == 0 { if j == 0 {
receipts[j].GasUsed = new(big.Int).Set(receipts[j].CumulativeGasUsed) receipts[j].GasUsed = receipts[j].CumulativeGasUsed
} else { } 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 // The derived log fields can simply be set from the block and transaction
for k := 0; k < len(receipts[j].Logs); k++ { 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}) events = append(events, ChainSideEvent{block})
} }
stats.processed++ stats.processed++
stats.usedGas += usedGas.Uint64() stats.usedGas += usedGas
stats.report(chain, i) stats.report(chain, i)
} }
// Append a single chain head event if we've progressed the chain // Append a single chain head event if we've progressed the chain

View File

@ -340,11 +340,11 @@ func testBrokenChain(t *testing.T, full bool) {
type bproc struct{} type bproc struct{}
func (bproc) ValidateBody(*types.Block) error { return nil } 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 return nil
} }
func (bproc) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, *big.Int, error) { func (bproc) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) {
return nil, nil, new(big.Int), nil return nil, nil, 0, nil
} }
func makeHeaderChainWithDiff(genesis *types.Block, d []int, seed byte) []*types.Header { 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() { 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()) 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 { if blocks[2].Header().GasLimit != ncm.GasLimit() {
t.Errorf("last block gasLimit mismatch: have: %x, want %x", ncm.GasLimit(), blocks[2].Header().GasLimit) t.Errorf("last block gasLimit mismatch: have: %d, want %d", ncm.GasLimit(), blocks[2].Header().GasLimit)
} }
} else { } else {
if ncm.CurrentHeader().Hash() != headers[2].Hash() { 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 the block number is multiple of 3, send a few bonus transactions to the miner
if i%3 == 2 { if i%3 == 2 {
for j := 0; j < i%4+1; j++ { 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 { if err != nil {
panic(err) panic(err)
} }
@ -767,8 +767,8 @@ func TestChainTxReorgs(t *testing.T) {
// Create two transactions shared between the chains: // Create two transactions shared between the chains:
// - postponed: transaction included at a later block in the forked chain // - postponed: transaction included at a later block in the forked chain
// - swapped: transaction included at the same block number 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) 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), bigTxGas, 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: // Create two transactions that will be dropped by the forked chain:
// - pastDrop: transaction dropped retroactively from a past block // - 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) { chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {
switch i { switch i {
case 0: 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(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 gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork
case 2: 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(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 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) { chain, _ = GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 5, func(i int, gen *BlockGen) {
switch i { switch i {
case 0: 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 gen.AddTx(pastAdd) // This transaction needs to be injected during reorg
case 2: case 2:
gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain 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 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 gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time
case 3: 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 gen.AddTx(futureAdd) // This transaction will be added after a full reorg
} }
}) })
@ -877,7 +877,7 @@ func TestLogReorgs(t *testing.T) {
blockchain.SubscribeRemovedLogsEvent(rmLogsCh) blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) { chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
if i == 1 { 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 { if err != nil {
t.Fatalf("failed to create tx: %v", err) 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) { 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 { if i == 2 {
gen.OffsetTime(-9) gen.OffsetTime(-9)
} }
@ -1051,7 +1051,7 @@ func TestEIP155Transition(t *testing.T) {
tx *types.Transaction tx *types.Transaction
err error err error
basicTx = func(signer types.Signer) (*types.Transaction, 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 { switch i {
@ -1114,7 +1114,7 @@ func TestEIP155Transition(t *testing.T) {
tx *types.Transaction tx *types.Transaction
err error err error
basicTx = func(signer types.Signer) (*types.Transaction, 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 { switch i {
@ -1162,11 +1162,11 @@ func TestEIP161AccountRemoval(t *testing.T) {
) )
switch i { switch i {
case 0: 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: 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: 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 { if err != nil {
t.Fatal(err) t.Fatal(err)

View File

@ -86,7 +86,7 @@ func (b *BlockGen) AddTx(tx *types.Transaction) {
b.SetCoinbase(common.Address{}) b.SetCoinbase(common.Address{})
} }
b.statedb.Prepare(tx.Hash(), common.Hash{}, len(b.txs)) 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 { if err != nil {
panic(err) panic(err)
} }
@ -232,7 +232,6 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.S
UncleHash: parent.UncleHash(), UncleHash: parent.UncleHash(),
}), }),
GasLimit: CalcGasLimit(parent), GasLimit: CalcGasLimit(parent),
GasUsed: new(big.Int),
Number: new(big.Int).Add(parent.Number(), common.Big1), Number: new(big.Int).Add(parent.Number(), common.Big1),
Time: time, Time: time,
} }

View File

@ -54,13 +54,13 @@ func ExampleGenerateChain() {
switch i { switch i {
case 0: case 0:
// In block 1, addr1 sends addr2 some ether. // 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) gen.AddTx(tx)
case 1: case 1:
// In block 2, addr1 sends some more ether to addr2. // In block 2, addr1 sends some more ether to addr2.
// addr2 passes it on to addr3. // addr2 passes it on to addr3.
tx1, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(1000), bigTxGas, nil, nil), signer, key1) 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), bigTxGas, nil, nil), signer, key2) tx2, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
gen.AddTx(tx1) gen.AddTx(tx1)
gen.AddTx(tx2) gen.AddTx(tx2)
case 2: case 2:

View File

@ -290,9 +290,9 @@ func TestHeadStorage(t *testing.T) {
func TestLookupStorage(t *testing.T) { func TestLookupStorage(t *testing.T) {
db, _ := ethdb.NewMemDatabase() db, _ := ethdb.NewMemDatabase()
tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), big.NewInt(1111), big.NewInt(11111), []byte{0x11, 0x11, 0x11}) 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), big.NewInt(2222), big.NewInt(22222), []byte{0x22, 0x22, 0x22}) 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), big.NewInt(3333), big.NewInt(33333), []byte{0x33, 0x33, 0x33}) 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} txs := []*types.Transaction{tx1, tx2, tx3}
block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, txs, nil, nil) block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, txs, nil, nil)
@ -337,25 +337,25 @@ func TestBlockReceiptStorage(t *testing.T) {
receipt1 := &types.Receipt{ receipt1 := &types.Receipt{
Status: types.ReceiptStatusFailed, Status: types.ReceiptStatusFailed,
CumulativeGasUsed: big.NewInt(1), CumulativeGasUsed: 1,
Logs: []*types.Log{ Logs: []*types.Log{
{Address: common.BytesToAddress([]byte{0x11})}, {Address: common.BytesToAddress([]byte{0x11})},
{Address: common.BytesToAddress([]byte{0x01, 0x11})}, {Address: common.BytesToAddress([]byte{0x01, 0x11})},
}, },
TxHash: common.BytesToHash([]byte{0x11, 0x11}), TxHash: common.BytesToHash([]byte{0x11, 0x11}),
ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}), ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}),
GasUsed: big.NewInt(111111), GasUsed: 111111,
} }
receipt2 := &types.Receipt{ receipt2 := &types.Receipt{
PostState: common.Hash{2}.Bytes(), PostState: common.Hash{2}.Bytes(),
CumulativeGasUsed: big.NewInt(2), CumulativeGasUsed: 2,
Logs: []*types.Log{ Logs: []*types.Log{
{Address: common.BytesToAddress([]byte{0x22})}, {Address: common.BytesToAddress([]byte{0x22})},
{Address: common.BytesToAddress([]byte{0x02, 0x22})}, {Address: common.BytesToAddress([]byte{0x02, 0x22})},
}, },
TxHash: common.BytesToHash([]byte{0x22, 0x22}), TxHash: common.BytesToHash([]byte{0x22, 0x22}),
ContractAddress: common.BytesToAddress([]byte{0x02, 0x22, 0x22}), ContractAddress: common.BytesToAddress([]byte{0x02, 0x22, 0x22}),
GasUsed: big.NewInt(222222), GasUsed: 222222,
} }
receipts := []*types.Receipt{receipt1, receipt2} receipts := []*types.Receipt{receipt1, receipt2}

View File

@ -53,7 +53,7 @@ func NewEVMContext(msg Message, header *types.Header, chain ChainContext, author
BlockNumber: new(big.Int).Set(header.Number), BlockNumber: new(big.Int).Set(header.Number),
Time: new(big.Int).Set(header.Time), Time: new(big.Int).Set(header.Time),
Difficulty: new(big.Int).Set(header.Difficulty), Difficulty: new(big.Int).Set(header.Difficulty),
GasLimit: new(big.Int).Set(header.GasLimit), GasLimit: header.GasLimit,
GasPrice: new(big.Int).Set(msg.GasPrice()), GasPrice: new(big.Int).Set(msg.GasPrice()),
} }
} }

View File

@ -16,31 +16,34 @@
package core package core
import "math/big" import (
"fmt"
"math"
)
// GasPool tracks the amount of gas available during // GasPool tracks the amount of gas available during execution of the transactions
// execution of the transactions in a block. // in a block. The zero value is a pool with zero gas available.
// The zero value is a pool with zero gas available. type GasPool uint64
type GasPool big.Int
// AddGas makes gas available for execution. // AddGas makes gas available for execution.
func (gp *GasPool) AddGas(amount *big.Int) *GasPool { func (gp *GasPool) AddGas(amount uint64) *GasPool {
i := (*big.Int)(gp) if uint64(*gp) > math.MaxUint64-amount {
i.Add(i, amount) panic("gas pool pushed above uint64")
}
*(*uint64)(gp) += amount
return gp return gp
} }
// SubGas deducts the given amount from the pool if enough gas is // SubGas deducts the given amount from the pool if enough gas is
// available and returns an error otherwise. // available and returns an error otherwise.
func (gp *GasPool) SubGas(amount *big.Int) error { func (gp *GasPool) SubGas(amount uint64) error {
i := (*big.Int)(gp) if uint64(*gp) < amount {
if i.Cmp(amount) < 0 {
return ErrGasLimitReached return ErrGasLimitReached
} }
i.Sub(i, amount) *(*uint64)(gp) -= amount
return nil return nil
} }
func (gp *GasPool) String() string { func (gp *GasPool) String() string {
return (*big.Int)(gp).String() return fmt.Sprintf("%d", *gp)
} }

View File

@ -13,6 +13,8 @@ import (
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
) )
var _ = (*genesisSpecMarshaling)(nil)
func (g Genesis) MarshalJSON() ([]byte, error) { func (g Genesis) MarshalJSON() ([]byte, error) {
type Genesis struct { type Genesis struct {
Config *params.ChainConfig `json:"config"` Config *params.ChainConfig `json:"config"`

View File

@ -239,8 +239,8 @@ func (g *Genesis) ToBlock() (*types.Block, *state.StateDB) {
Time: new(big.Int).SetUint64(g.Timestamp), Time: new(big.Int).SetUint64(g.Timestamp),
ParentHash: g.ParentHash, ParentHash: g.ParentHash,
Extra: g.ExtraData, Extra: g.ExtraData,
GasLimit: new(big.Int).SetUint64(g.GasLimit), GasLimit: g.GasLimit,
GasUsed: new(big.Int).SetUint64(g.GasUsed), GasUsed: g.GasUsed,
Difficulty: g.Difficulty, Difficulty: g.Difficulty,
MixDigest: g.Mixhash, MixDigest: g.Mixhash,
Coinbase: g.Coinbase, Coinbase: g.Coinbase,

View File

@ -62,7 +62,7 @@ type (
// Changes to other state values. // Changes to other state values.
refundChange struct { refundChange struct {
prev *big.Int prev uint64
} }
addLogChange struct { addLogChange struct {
txhash common.Hash txhash common.Hash

View File

@ -57,7 +57,7 @@ type StateDB struct {
dbErr error dbErr error
// The refund counter, also used by state transitioning. // The refund counter, also used by state transitioning.
refund *big.Int refund uint64
thash, bhash common.Hash thash, bhash common.Hash
txIndex int txIndex int
@ -86,7 +86,6 @@ func New(root common.Hash, db Database) (*StateDB, error) {
trie: tr, trie: tr,
stateObjects: make(map[common.Address]*stateObject), stateObjects: make(map[common.Address]*stateObject),
stateObjectsDirty: make(map[common.Address]struct{}), stateObjectsDirty: make(map[common.Address]struct{}),
refund: new(big.Int),
logs: make(map[common.Hash][]*types.Log), logs: make(map[common.Hash][]*types.Log),
preimages: make(map[common.Hash][]byte), preimages: make(map[common.Hash][]byte),
}, nil }, nil
@ -161,9 +160,9 @@ func (self *StateDB) Preimages() map[common.Hash][]byte {
return self.preimages return self.preimages
} }
func (self *StateDB) AddRefund(gas *big.Int) { func (self *StateDB) AddRefund(gas uint64) {
self.journal = append(self.journal, refundChange{prev: new(big.Int).Set(self.refund)}) self.journal = append(self.journal, refundChange{prev: self.refund})
self.refund.Add(self.refund, gas) self.refund += gas
} }
// Exist reports whether the given account address exists in the state. // 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), trie: self.db.CopyTrie(self.trie),
stateObjects: make(map[common.Address]*stateObject, len(self.stateObjectsDirty)), stateObjects: make(map[common.Address]*stateObject, len(self.stateObjectsDirty)),
stateObjectsDirty: make(map[common.Address]struct{}, 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)), logs: make(map[common.Hash][]*types.Log, len(self.logs)),
logSize: self.logSize, logSize: self.logSize,
preimages: make(map[common.Hash][]byte), 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. // GetRefund returns the current value of the refund counter.
// The return value must not be modified by the caller and will become func (self *StateDB) GetRefund() uint64 {
// invalid at the next call to AddRefund.
func (self *StateDB) GetRefund() *big.Int {
return self.refund return self.refund
} }
@ -568,7 +565,7 @@ func (s *StateDB) DeleteSuicides() {
func (s *StateDB) clearJournalAndRefund() { func (s *StateDB) clearJournalAndRefund() {
s.journal = nil s.journal = nil
s.validRevisions = s.validRevisions[:0] s.validRevisions = s.validRevisions[:0]
s.refund = new(big.Int) s.refund = 0
} }
// CommitTo writes the state to the given database. // CommitTo writes the state to the given database.

View File

@ -263,7 +263,7 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction {
{ {
name: "AddRefund", name: "AddRefund",
fn: func(a testAction, s *StateDB) { fn: func(a testAction, s *StateDB) {
s.AddRefund(big.NewInt(a.args[0])) s.AddRefund(uint64(a.args[0]))
}, },
args: make([]int64, 1), args: make([]int64, 1),
noAddr: true, 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", return fmt.Errorf("got GetRefund() == %d, want GetRefund() == %d",
state.GetRefund(), checkstate.GetRefund()) state.GetRefund(), checkstate.GetRefund())
} }

View File

@ -17,8 +17,6 @@
package core package core
import ( import (
"math/big"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/misc" "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 // 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 // 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. // 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 ( var (
receipts types.Receipts receipts types.Receipts
totalUsedGas = big.NewInt(0) usedGas = new(uint64)
header = block.Header() header = block.Header()
allLogs []*types.Log allLogs []*types.Log
gp = new(GasPool).AddGas(block.GasLimit()) gp = new(GasPool).AddGas(block.GasLimit())
) )
// Mutate the the block and state according to any hard-fork specs // 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 { 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 // Iterate over and process the individual transactions
for i, tx := range block.Transactions() { for i, tx := range block.Transactions() {
statedb.Prepare(tx.Hash(), block.Hash(), i) 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 { if err != nil {
return nil, nil, nil, err return nil, nil, 0, err
} }
receipts = append(receipts, receipt) receipts = append(receipts, receipt)
allLogs = append(allLogs, receipt.Logs...) 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) // 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) 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 // ApplyTransaction attempts to apply a transaction to the given state database
// and uses the input parameters for its environment. It returns the receipt // and uses the input parameters for its environment. It returns the receipt
// for the transaction, gas used and an error if the transaction failed, // for the transaction, gas used and an error if the transaction failed,
// indicating the block was invalid. // 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)) msg, err := tx.AsMessage(types.MakeSigner(config, header.Number))
if err != nil { if err != nil {
return nil, nil, err return nil, 0, err
} }
// Create a new context to be used in the EVM environment // Create a new context to be used in the EVM environment
context := NewEVMContext(msg, header, bc, author) 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) // Apply the transaction to the current state (included in the env)
_, gas, failed, err := ApplyMessage(vmenv, msg, gp) _, gas, failed, err := ApplyMessage(vmenv, msg, gp)
if err != nil { if err != nil {
return nil, nil, err return nil, 0, err
} }
// Update the state with pending changes // Update the state with pending changes
var root []byte var root []byte
if config.IsByzantium(header.Number) { if config.IsByzantium(header.Number) {
@ -110,18 +107,17 @@ func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common
} else { } else {
root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes() 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 // 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. // 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.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 the transaction created a contract, store the creation address in the receipt.
if msg.To() == nil { if msg.To() == nil {
receipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce()) receipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce())
} }
// Set the receipt logs and create a bloom for filtering // Set the receipt logs and create a bloom for filtering
receipt.Logs = statedb.GetLogs(tx.Hash()) receipt.Logs = statedb.GetLogs(tx.Hash())
receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) receipt.Bloom = types.CreateBloom(types.Receipts{receipt})

View File

@ -18,17 +18,16 @@ package core
import ( import (
"errors" "errors"
"math"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/common" "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/core/vm"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
) )
var ( var (
Big0 = big.NewInt(0)
errInsufficientBalanceForGas = errors.New("insufficient balance to pay for gas") errInsufficientBalanceForGas = errors.New("insufficient balance to pay for gas")
) )
@ -54,7 +53,7 @@ type StateTransition struct {
msg Message msg Message
gas uint64 gas uint64
gasPrice *big.Int gasPrice *big.Int
initialGas *big.Int initialGas uint64
value *big.Int value *big.Int
data []byte data []byte
state vm.StateDB state vm.StateDB
@ -68,7 +67,7 @@ type Message interface {
To() *common.Address To() *common.Address
GasPrice() *big.Int GasPrice() *big.Int
Gas() *big.Int Gas() uint64
Value() *big.Int Value() *big.Int
Nonce() uint64 Nonce() uint64
@ -76,45 +75,49 @@ type Message interface {
Data() []byte Data() []byte
} }
// IntrinsicGas computes the 'intrinsic gas' for a message // IntrinsicGas computes the 'intrinsic gas' for a message with the given data.
// with the given data. func IntrinsicGas(data []byte, contractCreation, homestead bool) (uint64, error) {
// // Set the starting gas for the raw transaction
// TODO convert to uint64 var gas uint64
func IntrinsicGas(data []byte, contractCreation, homestead bool) *big.Int {
igas := new(big.Int)
if contractCreation && homestead { if contractCreation && homestead {
igas.SetUint64(params.TxGasContractCreation) gas = params.TxGasContractCreation
} else { } else {
igas.SetUint64(params.TxGas) gas = params.TxGas
} }
// Bump the required gas by the amount of transactional data
if len(data) > 0 { if len(data) > 0 {
var nz int64 // Zero and non-zero bytes are priced differently
var nz uint64
for _, byt := range data { for _, byt := range data {
if byt != 0 { if byt != 0 {
nz++ nz++
} }
} }
m := big.NewInt(nz) // Make sure we don't exceed uint64 for all data combinations
m.Mul(m, new(big.Int).SetUint64(params.TxDataNonZeroGas)) if (math.MaxUint64-gas)/params.TxDataNonZeroGas < nz {
igas.Add(igas, m) return 0, vm.ErrOutOfGas
m.SetInt64(int64(len(data)) - nz) }
m.Mul(m, new(big.Int).SetUint64(params.TxDataZeroGas)) gas += nz * params.TxDataNonZeroGas
igas.Add(igas, m)
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. // NewStateTransition initialises and returns a new state transition object.
func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition { func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition {
return &StateTransition{ return &StateTransition{
gp: gp, gp: gp,
evm: evm, evm: evm,
msg: msg, msg: msg,
gasPrice: msg.GasPrice(), gasPrice: msg.GasPrice(),
initialGas: new(big.Int), value: msg.Value(),
value: msg.Value(), data: msg.Data(),
data: msg.Data(), state: evm.StateDB,
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 // 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 // indicates a core error meaning that the message would always fail for that particular
// state and would never be accepted within a block. // state and would never be accepted within a block.
func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) ([]byte, *big.Int, bool, error) { func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) ([]byte, uint64, bool, error) {
st := NewStateTransition(evm, msg, gp) return NewStateTransition(evm, msg, gp).TransitionDb()
ret, _, gasUsed, failed, err := st.TransitionDb()
return ret, gasUsed, failed, err
} }
func (st *StateTransition) from() vm.AccountRef { func (st *StateTransition) from() vm.AccountRef {
@ -166,26 +166,20 @@ func (st *StateTransition) useGas(amount uint64) error {
} }
func (st *StateTransition) buyGas() 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 ( var (
state = st.state state = st.state
sender = st.from() 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 { if state.GetBalance(sender.Address()).Cmp(mgval) < 0 {
return errInsufficientBalanceForGas return errInsufficientBalanceForGas
} }
if err := st.gp.SubGas(mgas); err != nil { if err := st.gp.SubGas(st.msg.Gas()); err != nil {
return err 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) state.SubBalance(sender.Address(), mgval)
return nil return nil
} }
@ -206,10 +200,10 @@ func (st *StateTransition) preCheck() error {
return st.buyGas() return st.buyGas()
} }
// TransitionDb will transition the state by applying the current message and returning the result // TransitionDb will transition the state by applying the current message and
// including the required gas for the operation as well as the used gas. It returns an error if it // returning the result including the the used gas. It returns an error if it
// failed. An error indicates a consensus issue. // 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 { if err = st.preCheck(); err != nil {
return return
} }
@ -220,13 +214,9 @@ func (st *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big
contractCreation := msg.To() == nil contractCreation := msg.To() == nil
// Pay intrinsic gas // Pay intrinsic gas
// TODO convert to uint64 gas, err := IntrinsicGas(st.data, contractCreation, homestead)
intrinsicGas := IntrinsicGas(st.data, contractCreation, homestead) if err = st.useGas(gas); err != nil {
if intrinsicGas.BitLen() > 64 { return nil, 0, false, err
return nil, nil, nil, false, vm.ErrOutOfGas
}
if err = st.useGas(intrinsicGas.Uint64()); err != nil {
return nil, nil, nil, false, err
} }
var ( var (
@ -249,36 +239,35 @@ func (st *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big
// sufficient balance to make the transfer happen. The first // sufficient balance to make the transfer happen. The first
// balance transfer may never fail. // balance transfer may never fail.
if vmerr == vm.ErrInsufficientBalance { 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.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() { func (st *StateTransition) refundGas() {
// Return eth for remaining gas to the sender account, // Apply refund counter, capped to half of the used gas.
// exchanged at the original rate. refund := st.gasUsed() / 2
sender := st.from() // err already checked if refund > st.state.GetRefund() {
refund = st.state.GetRefund()
}
st.gas += refund
// 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) remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gas), st.gasPrice)
st.state.AddBalance(sender.Address(), remaining) 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()
st.state.AddBalance(sender.Address(), refund.Mul(refund, st.gasPrice))
// Also return remaining gas to the block gas counter so it is // Also return remaining gas to the block gas counter so it is
// available for the next transaction. // 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 { // gasUsed returns the amount of gas used up by the state transition.
return new(big.Int).Sub(st.initialGas, new(big.Int).SetUint64(st.gas)) func (st *StateTransition) gasUsed() uint64 {
return st.initialGas - st.gas
} }

View File

@ -224,7 +224,7 @@ type txList struct {
txs *txSortedMap // Heap indexed sorted hash map of the transactions txs *txSortedMap // Heap indexed sorted hash map of the transactions
costcap *big.Int // Price of the highest costing transaction (reset only if exceeds balance) 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, // newTxList create a new transaction list for maintaining nonce-indexable fast,
@ -234,7 +234,6 @@ func newTxList(strict bool) *txList {
strict: strict, strict: strict,
txs: newTxSortedMap(), txs: newTxSortedMap(),
costcap: new(big.Int), 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 { if cost := tx.Cost(); l.costcap.Cmp(cost) < 0 {
l.costcap = cost l.costcap = cost
} }
if gas := tx.Gas(); l.gascap.Cmp(gas) < 0 { if gas := tx.Gas(); l.gascap < gas {
l.gascap = gas l.gascap = gas
} }
return true, old 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 // 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 // is lower than the costgas cap, the caps will be reset to a new high after removing
// the newly invalidated transactions. // 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 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 return nil, nil
} }
l.costcap = new(big.Int).Set(costLimit) // Lower the caps to the thresholds 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 // 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 // If the list was strict, filter anything above the lowest nonce
var invalids types.Transactions var invalids types.Transactions

View File

@ -17,7 +17,6 @@
package core package core
import ( import (
"math/big"
"math/rand" "math/rand"
"testing" "testing"
@ -33,7 +32,7 @@ func TestStrictTxListAdd(t *testing.T) {
txs := make(types.Transactions, 1024) txs := make(types.Transactions, 1024)
for i := 0; i < len(txs); i++ { 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 // Insert the transactions in a random order
list := newTxList(true) list := newTxList(true)

View File

@ -197,7 +197,7 @@ type TxPool struct {
currentState *state.StateDB // Current state in the blockchain head currentState *state.StateDB // Current state in the blockchain head
pendingState *state.ManagedState // Pending state tracking virtual nonces 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 locals *accountSet // Set of local transaction to exempt from eviction rules
journal *txJournal // Journal of local transaction to back up to disk 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 return ErrNegativeValue
} }
// Ensure the transaction doesn't exceed the current block limit gas. // 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 return ErrGasLimit
} }
// Make sure the transaction is signed properly // 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 { if pool.currentState.GetBalance(from).Cmp(tx.Cost()) < 0 {
return ErrInsufficientFunds return ErrInsufficientFunds
} }
intrGas := IntrinsicGas(tx.Data(), tx.To() == nil, pool.homestead) intrGas, err := IntrinsicGas(tx.Data(), tx.To() == nil, pool.homestead)
if tx.Gas().Cmp(intrGas) < 0 { if err != nil {
return err
}
if tx.Gas() < intrGas {
return ErrIntrinsicGas return ErrIntrinsicGas
} }
return nil return nil

View File

@ -46,7 +46,7 @@ func init() {
type testBlockChain struct { type testBlockChain struct {
statedb *state.StateDB statedb *state.StateDB
gasLimit *big.Int gasLimit uint64
chainHeadFeed *event.Feed chainHeadFeed *event.Feed
} }
@ -68,11 +68,11 @@ func (bc *testBlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) even
return bc.chainHeadFeed.Subscribe(ch) 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) 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) tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(100), gaslimit, gasprice, nil), types.HomesteadSigner{}, key)
return tx return tx
} }
@ -80,7 +80,7 @@ func pricedTransaction(nonce uint64, gaslimit, gasprice *big.Int, key *ecdsa.Pri
func setupTxPool() (*TxPool, *ecdsa.PrivateKey) { func setupTxPool() (*TxPool, *ecdsa.PrivateKey) {
db, _ := ethdb.NewMemDatabase() db, _ := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 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() key, _ := crypto.GenerateKey()
pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
@ -184,10 +184,10 @@ func TestStateChangeDuringTransactionPoolReset(t *testing.T) {
// setup pool with 2 transaction in it // setup pool with 2 transaction in it
statedb.SetBalance(address, new(big.Int).SetUint64(params.Ether)) 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) tx0 := transaction(0, 100000, key)
tx1 := transaction(1, big.NewInt(100000), key) tx1 := transaction(1, 100000, key)
pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
defer pool.Stop() defer pool.Stop()
@ -230,7 +230,7 @@ func TestInvalidTransactions(t *testing.T) {
pool, key := setupTxPool() pool, key := setupTxPool()
defer pool.Stop() defer pool.Stop()
tx := transaction(0, big.NewInt(100), key) tx := transaction(0, 100, key)
from, _ := deriveSender(tx) from, _ := deriveSender(tx)
pool.currentState.AddBalance(from, big.NewInt(1)) pool.currentState.AddBalance(from, big.NewInt(1))
@ -238,7 +238,7 @@ func TestInvalidTransactions(t *testing.T) {
t.Error("expected", ErrInsufficientFunds) 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) pool.currentState.AddBalance(from, balance)
if err := pool.AddRemote(tx); err != ErrIntrinsicGas { if err := pool.AddRemote(tx); err != ErrIntrinsicGas {
t.Error("expected", ErrIntrinsicGas, "got", err) t.Error("expected", ErrIntrinsicGas, "got", err)
@ -246,12 +246,12 @@ func TestInvalidTransactions(t *testing.T) {
pool.currentState.SetNonce(from, 1) pool.currentState.SetNonce(from, 1)
pool.currentState.AddBalance(from, big.NewInt(0xffffffffffffff)) 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 { if err := pool.AddRemote(tx); err != ErrNonceTooLow {
t.Error("expected", ErrNonceTooLow) t.Error("expected", ErrNonceTooLow)
} }
tx = transaction(1, big.NewInt(100000), key) tx = transaction(1, 100000, key)
pool.gasPrice = big.NewInt(1000) pool.gasPrice = big.NewInt(1000)
if err := pool.AddRemote(tx); err != ErrUnderpriced { if err := pool.AddRemote(tx); err != ErrUnderpriced {
t.Error("expected", ErrUnderpriced, "got", err) t.Error("expected", ErrUnderpriced, "got", err)
@ -267,7 +267,7 @@ func TestTransactionQueue(t *testing.T) {
pool, key := setupTxPool() pool, key := setupTxPool()
defer pool.Stop() defer pool.Stop()
tx := transaction(0, big.NewInt(100), key) tx := transaction(0, 100, key)
from, _ := deriveSender(tx) from, _ := deriveSender(tx)
pool.currentState.AddBalance(from, big.NewInt(1000)) pool.currentState.AddBalance(from, big.NewInt(1000))
pool.lockedReset(nil, nil) 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)) 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) from, _ = deriveSender(tx)
pool.currentState.SetNonce(from, 2) pool.currentState.SetNonce(from, 2)
pool.enqueueTx(tx.Hash(), tx) pool.enqueueTx(tx.Hash(), tx)
@ -294,9 +294,9 @@ func TestTransactionQueue(t *testing.T) {
pool, key = setupTxPool() pool, key = setupTxPool()
defer pool.Stop() defer pool.Stop()
tx1 := transaction(0, big.NewInt(100), key) tx1 := transaction(0, 100, key)
tx2 := transaction(10, big.NewInt(100), key) tx2 := transaction(10, 100, key)
tx3 := transaction(11, big.NewInt(100), key) tx3 := transaction(11, 100, key)
from, _ = deriveSender(tx1) from, _ = deriveSender(tx1)
pool.currentState.AddBalance(from, big.NewInt(1000)) pool.currentState.AddBalance(from, big.NewInt(1000))
pool.lockedReset(nil, nil) pool.lockedReset(nil, nil)
@ -321,7 +321,7 @@ func TestTransactionNegativeValue(t *testing.T) {
pool, key := setupTxPool() pool, key := setupTxPool()
defer pool.Stop() 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) from, _ := deriveSender(tx)
pool.currentState.AddBalance(from, big.NewInt(1)) pool.currentState.AddBalance(from, big.NewInt(1))
if err := pool.AddRemote(tx); err != ErrNegativeValue { 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, _ := state.New(common.Hash{}, state.NewDatabase(db))
statedb.AddBalance(addr, big.NewInt(100000000000000)) 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) pool.lockedReset(nil, nil)
} }
resetState() resetState()
tx := transaction(0, big.NewInt(100000), key) tx := transaction(0, 100000, key)
if _, err := pool.add(tx, false); err != nil { if _, err := pool.add(tx, false); err != nil {
t.Error("didn't expect error", err) 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, _ := state.New(common.Hash{}, state.NewDatabase(db))
statedb.AddBalance(addr, big.NewInt(100000000000000)) 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) pool.lockedReset(nil, nil)
} }
resetState() resetState()
signer := types.HomesteadSigner{} signer := types.HomesteadSigner{}
tx1, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), big.NewInt(100000), 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), big.NewInt(1000000), big.NewInt(2), 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), big.NewInt(1000000), big.NewInt(1), 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 // Add the first two transaction, ensure higher priced stays only
if replace, err := pool.add(tx1, false); err != nil || replace { if replace, err := pool.add(tx1, false); err != nil || replace {
@ -418,7 +418,7 @@ func TestTransactionMissingNonce(t *testing.T) {
addr := crypto.PubkeyToAddress(key.PublicKey) addr := crypto.PubkeyToAddress(key.PublicKey)
pool.currentState.AddBalance(addr, big.NewInt(100000000000000)) 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 { if _, err := pool.add(tx, false); err != nil {
t.Error("didn't expect error", err) t.Error("didn't expect error", err)
} }
@ -445,7 +445,7 @@ func TestTransactionNonceRecovery(t *testing.T) {
pool.currentState.AddBalance(addr, big.NewInt(100000000000000)) pool.currentState.AddBalance(addr, big.NewInt(100000000000000))
pool.lockedReset(nil, nil) pool.lockedReset(nil, nil)
tx := transaction(n, big.NewInt(100000), key) tx := transaction(n, 100000, key)
if err := pool.AddRemote(tx); err != nil { if err := pool.AddRemote(tx); err != nil {
t.Error(err) t.Error(err)
} }
@ -466,17 +466,17 @@ func TestTransactionDropping(t *testing.T) {
pool, key := setupTxPool() pool, key := setupTxPool()
defer pool.Stop() defer pool.Stop()
account, _ := deriveSender(transaction(0, big.NewInt(0), key)) account, _ := deriveSender(transaction(0, 0, key))
pool.currentState.AddBalance(account, big.NewInt(1000)) pool.currentState.AddBalance(account, big.NewInt(1000))
// Add some pending and some queued transactions // Add some pending and some queued transactions
var ( var (
tx0 = transaction(0, big.NewInt(100), key) tx0 = transaction(0, 100, key)
tx1 = transaction(1, big.NewInt(200), key) tx1 = transaction(1, 200, key)
tx2 = transaction(2, big.NewInt(300), key) tx2 = transaction(2, 300, key)
tx10 = transaction(10, big.NewInt(100), key) tx10 = transaction(10, 100, key)
tx11 = transaction(11, big.NewInt(200), key) tx11 = transaction(11, 200, key)
tx12 = transaction(12, big.NewInt(300), key) tx12 = transaction(12, 300, key)
) )
pool.promoteTx(account, tx0.Hash(), tx0) pool.promoteTx(account, tx0.Hash(), tx0)
pool.promoteTx(account, tx1.Hash(), tx1) 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) t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), 4)
} }
// Reduce the block gas limit, check that invalidated transactions are dropped // 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) pool.lockedReset(nil, nil)
if _, ok := pool.pending[account].txs.items[tx0.Nonce()]; !ok { if _, ok := pool.pending[account].txs.items[tx0.Nonce()]; !ok {
@ -561,7 +561,7 @@ func TestTransactionPostponing(t *testing.T) {
pool, key := setupTxPool() pool, key := setupTxPool()
defer pool.Stop() defer pool.Stop()
account, _ := deriveSender(transaction(0, big.NewInt(0), key)) account, _ := deriveSender(transaction(0, 0, key))
pool.currentState.AddBalance(account, big.NewInt(1000)) pool.currentState.AddBalance(account, big.NewInt(1000))
// Add a batch consecutive pending transactions for validation // Add a batch consecutive pending transactions for validation
@ -569,9 +569,9 @@ func TestTransactionPostponing(t *testing.T) {
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
var tx *types.Transaction var tx *types.Transaction
if i%2 == 0 { if i%2 == 0 {
tx = transaction(uint64(i), big.NewInt(100), key) tx = transaction(uint64(i), 100, key)
} else { } else {
tx = transaction(uint64(i), big.NewInt(500), key) tx = transaction(uint64(i), 500, key)
} }
pool.promoteTx(account, tx.Hash(), tx) pool.promoteTx(account, tx.Hash(), tx)
txns = append(txns, tx) txns = append(txns, tx)
@ -638,7 +638,7 @@ func TestTransactionGapFilling(t *testing.T) {
pool, key := setupTxPool() pool, key := setupTxPool()
defer pool.Stop() defer pool.Stop()
account, _ := deriveSender(transaction(0, big.NewInt(0), key)) account, _ := deriveSender(transaction(0, 0, key))
pool.currentState.AddBalance(account, big.NewInt(1000000)) pool.currentState.AddBalance(account, big.NewInt(1000000))
// Keep track of transaction events to ensure all executables get announced // Keep track of transaction events to ensure all executables get announced
@ -647,10 +647,10 @@ func TestTransactionGapFilling(t *testing.T) {
defer sub.Unsubscribe() defer sub.Unsubscribe()
// Create a pending and a queued transaction with a nonce-gap in between // 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) 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) t.Fatalf("failed to add queued transaction: %v", err)
} }
pending, queued := pool.Stats() pending, queued := pool.Stats()
@ -667,7 +667,7 @@ func TestTransactionGapFilling(t *testing.T) {
t.Fatalf("pool internal state corrupted: %v", err) t.Fatalf("pool internal state corrupted: %v", err)
} }
// Fill the nonce gap and ensure all transactions become pending // 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) t.Fatalf("failed to add gapped transaction: %v", err)
} }
pending, queued = pool.Stats() pending, queued = pool.Stats()
@ -694,12 +694,12 @@ func TestTransactionQueueAccountLimiting(t *testing.T) {
pool, key := setupTxPool() pool, key := setupTxPool()
defer pool.Stop() defer pool.Stop()
account, _ := deriveSender(transaction(0, big.NewInt(0), key)) account, _ := deriveSender(transaction(0, 0, key))
pool.currentState.AddBalance(account, big.NewInt(1000000)) pool.currentState.AddBalance(account, big.NewInt(1000000))
// Keep queuing up transactions and make sure all above a limit are dropped // Keep queuing up transactions and make sure all above a limit are dropped
for i := uint64(1); i <= testTxPoolConfig.AccountQueue+5; i++ { 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) t.Fatalf("tx %d: failed to add transaction: %v", i, err)
} }
if len(pool.pending) != 0 { 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 // Create the pool to test the limit enforcement with
db, _ := ethdb.NewMemDatabase() db, _ := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 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 := testTxPoolConfig
config.NoLocals = nolocals 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 key := keys[rand.Intn(len(keys)-1)] // skip adding transactions with the local account
addr := crypto.PubkeyToAddress(key.PublicKey) 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]++ nonces[addr]++
} }
// Import the batch and verify that limits have been enforced // 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 // Generate a batch of transactions from the local account and import them
txs = txs[:0] txs = txs[:0]
for i := uint64(0); i < 3*config.GlobalQueue; i++ { 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) pool.AddLocals(txs)
@ -827,7 +827,7 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
// Create the pool to test the non-expiration enforcement // Create the pool to test the non-expiration enforcement
db, _ := ethdb.NewMemDatabase() db, _ := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 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 := testTxPoolConfig
config.Lifetime = time.Second 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)) pool.currentState.AddBalance(crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000))
// Add the two transactions and ensure they both are queued up // 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) 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) t.Fatalf("failed to add remote transaction: %v", err)
} }
pending, queued := pool.Stats() pending, queued := pool.Stats()
@ -891,7 +891,7 @@ func TestTransactionPendingLimiting(t *testing.T) {
pool, key := setupTxPool() pool, key := setupTxPool()
defer pool.Stop() defer pool.Stop()
account, _ := deriveSender(transaction(0, big.NewInt(0), key)) account, _ := deriveSender(transaction(0, 0, key))
pool.currentState.AddBalance(account, big.NewInt(1000000)) pool.currentState.AddBalance(account, big.NewInt(1000000))
// Keep track of transaction events to ensure all executables get announced // 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 // Keep queuing up transactions and make sure all above a limit are dropped
for i := uint64(0); i < testTxPoolConfig.AccountQueue+5; i++ { 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) t.Fatalf("tx %d: failed to add transaction: %v", i, err)
} }
if pool.pending[account].Len() != int(i)+1 { if pool.pending[account].Len() != int(i)+1 {
@ -934,11 +934,11 @@ func testTransactionLimitingEquivalency(t *testing.T, origin uint64) {
pool1, key1 := setupTxPool() pool1, key1 := setupTxPool()
defer pool1.Stop() defer pool1.Stop()
account1, _ := deriveSender(transaction(0, big.NewInt(0), key1)) account1, _ := deriveSender(transaction(0, 0, key1))
pool1.currentState.AddBalance(account1, big.NewInt(1000000)) pool1.currentState.AddBalance(account1, big.NewInt(1000000))
for i := uint64(0); i < testTxPoolConfig.AccountQueue+5; i++ { 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) 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() pool2, key2 := setupTxPool()
defer pool2.Stop() defer pool2.Stop()
account2, _ := deriveSender(transaction(0, big.NewInt(0), key2)) account2, _ := deriveSender(transaction(0, 0, key2))
pool2.currentState.AddBalance(account2, big.NewInt(1000000)) pool2.currentState.AddBalance(account2, big.NewInt(1000000))
txns := []*types.Transaction{} txns := []*types.Transaction{}
for i := uint64(0); i < testTxPoolConfig.AccountQueue+5; i++ { 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) pool2.AddRemotes(txns)
@ -982,7 +982,7 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) {
// Create the pool to test the limit enforcement with // Create the pool to test the limit enforcement with
db, _ := ethdb.NewMemDatabase() db, _ := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 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 := testTxPoolConfig
config.GlobalSlots = config.AccountSlots * 10 config.GlobalSlots = config.AccountSlots * 10
@ -1003,7 +1003,7 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) {
for _, key := range keys { for _, key := range keys {
addr := crypto.PubkeyToAddress(key.PublicKey) addr := crypto.PubkeyToAddress(key.PublicKey)
for j := 0; j < int(config.GlobalSlots)/len(keys)*2; j++ { 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]++ nonces[addr]++
} }
} }
@ -1029,7 +1029,7 @@ func TestTransactionCapClearsFromAll(t *testing.T) {
// Create the pool to test the limit enforcement with // Create the pool to test the limit enforcement with
db, _ := ethdb.NewMemDatabase() db, _ := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 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 := testTxPoolConfig
config.AccountSlots = 2 config.AccountSlots = 2
@ -1046,7 +1046,7 @@ func TestTransactionCapClearsFromAll(t *testing.T) {
txs := types.Transactions{} txs := types.Transactions{}
for j := 0; j < int(config.GlobalSlots)*2; j++ { 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 // Import the batch and verify that limits have been enforced
pool.AddRemotes(txs) pool.AddRemotes(txs)
@ -1064,7 +1064,7 @@ func TestTransactionPendingMinimumAllowance(t *testing.T) {
// Create the pool to test the limit enforcement with // Create the pool to test the limit enforcement with
db, _ := ethdb.NewMemDatabase() db, _ := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 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 := testTxPoolConfig
config.GlobalSlots = 0 config.GlobalSlots = 0
@ -1085,7 +1085,7 @@ func TestTransactionPendingMinimumAllowance(t *testing.T) {
for _, key := range keys { for _, key := range keys {
addr := crypto.PubkeyToAddress(key.PublicKey) addr := crypto.PubkeyToAddress(key.PublicKey)
for j := 0; j < int(config.AccountSlots)*2; j++ { 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]++ nonces[addr]++
} }
} }
@ -1113,7 +1113,7 @@ func TestTransactionPoolRepricing(t *testing.T) {
// Create the pool to test the pricing enforcement with // Create the pool to test the pricing enforcement with
db, _ := ethdb.NewMemDatabase() db, _ := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 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) pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
defer pool.Stop() defer pool.Stop()
@ -1132,15 +1132,15 @@ func TestTransactionPoolRepricing(t *testing.T) {
// Generate and queue a batch of transactions, both pending and queued // Generate and queue a batch of transactions, both pending and queued
txs := types.Transactions{} txs := types.Transactions{}
txs = append(txs, pricedTransaction(0, big.NewInt(100000), big.NewInt(2), keys[0])) txs = append(txs, pricedTransaction(0, 100000, big.NewInt(2), keys[0]))
txs = append(txs, pricedTransaction(1, big.NewInt(100000), big.NewInt(1), keys[0])) txs = append(txs, pricedTransaction(1, 100000, big.NewInt(1), keys[0]))
txs = append(txs, pricedTransaction(2, big.NewInt(100000), big.NewInt(2), 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(1, 100000, big.NewInt(2), keys[1]))
txs = append(txs, pricedTransaction(2, big.NewInt(100000), big.NewInt(1), keys[1])) txs = append(txs, pricedTransaction(2, 100000, big.NewInt(1), keys[1]))
txs = append(txs, pricedTransaction(3, big.NewInt(100000), big.NewInt(2), 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 // Import the batch and that both pending and queued transactions match up
pool.AddRemotes(txs) pool.AddRemotes(txs)
@ -1176,10 +1176,10 @@ func TestTransactionPoolRepricing(t *testing.T) {
t.Fatalf("pool internal state corrupted: %v", err) t.Fatalf("pool internal state corrupted: %v", err)
} }
// Check that we can't add the old transactions back // 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) 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) t.Fatalf("adding underpriced queued transaction error mismatch: have %v, want %v", err, ErrUnderpriced)
} }
if err := validateEvents(events, 0); err != nil { if err := validateEvents(events, 0); err != nil {
@ -1189,7 +1189,7 @@ func TestTransactionPoolRepricing(t *testing.T) {
t.Fatalf("pool internal state corrupted: %v", err) t.Fatalf("pool internal state corrupted: %v", err)
} }
// However we can add local underpriced transactions // 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 { if err := pool.AddLocal(tx); err != nil {
t.Fatalf("failed to add underpriced local transaction: %v", err) 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 // Create the pool to test the pricing enforcement with
db, _ := ethdb.NewMemDatabase() db, _ := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 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) pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
defer pool.Stop() defer pool.Stop()
@ -1226,12 +1226,12 @@ func TestTransactionPoolRepricingKeepsLocals(t *testing.T) {
// Create transaction (both pending and queued) with a linearly growing gasprice // Create transaction (both pending and queued) with a linearly growing gasprice
for i := uint64(0); i < 500; i++ { for i := uint64(0); i < 500; i++ {
// Add pending // 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 { if err := pool.AddLocal(p_tx); err != nil {
t.Fatal(err) t.Fatal(err)
} }
// Add queued // 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 { if err := pool.AddLocal(q_tx); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -1275,7 +1275,7 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
// Create the pool to test the pricing enforcement with // Create the pool to test the pricing enforcement with
db, _ := ethdb.NewMemDatabase() db, _ := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 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 := testTxPoolConfig
config.GlobalSlots = 2 config.GlobalSlots = 2
@ -1298,12 +1298,12 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
// Generate and queue a batch of transactions, both pending and queued // Generate and queue a batch of transactions, both pending and queued
txs := types.Transactions{} txs := types.Transactions{}
txs = append(txs, pricedTransaction(0, big.NewInt(100000), big.NewInt(1), keys[0])) txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[0]))
txs = append(txs, pricedTransaction(1, big.NewInt(100000), big.NewInt(2), 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 // Import the batch and that both pending and queued transactions match up
pool.AddRemotes(txs) pool.AddRemotes(txs)
@ -1323,17 +1323,17 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
t.Fatalf("pool internal state corrupted: %v", err) t.Fatalf("pool internal state corrupted: %v", err)
} }
// Ensure that adding an underpriced transaction on block limit fails // 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) 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 // 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) 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) 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) t.Fatalf("failed to add well priced transaction: %v", err)
} }
pending, queued = pool.Stats() pending, queued = pool.Stats()
@ -1350,7 +1350,7 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
t.Fatalf("pool internal state corrupted: %v", err) t.Fatalf("pool internal state corrupted: %v", err)
} }
// Ensure that adding local transactions can push out even higher priced ones // 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 { if err := pool.AddLocal(tx); err != nil {
t.Fatalf("failed to add underpriced local transaction: %v", err) 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 // Create the pool to test the pricing enforcement with
db, _ := ethdb.NewMemDatabase() db, _ := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 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) pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
defer pool.Stop() defer pool.Stop()
@ -1395,49 +1395,49 @@ func TestTransactionReplacement(t *testing.T) {
price := int64(100) price := int64(100)
threshold := (price * (100 + int64(testTxPoolConfig.PriceBump))) / 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) 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) 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) t.Fatalf("failed to replace original cheap pending transaction: %v", err)
} }
if err := validateEvents(events, 2); err != nil { if err := validateEvents(events, 2); err != nil {
t.Fatalf("cheap replacement event firing failed: %v", err) 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) 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) 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) t.Fatalf("failed to replace original proper pending transaction: %v", err)
} }
if err := validateEvents(events, 2); err != nil { if err := validateEvents(events, 2); err != nil {
t.Fatalf("proper replacement event firing failed: %v", err) 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) // 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) 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) 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) 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) 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) 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) 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 // Create the original pool to inject transaction into the journal
db, _ := ethdb.NewMemDatabase() db, _ := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 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 := testTxPoolConfig
config.NoLocals = nolocals config.NoLocals = nolocals
@ -1489,16 +1489,16 @@ func testTransactionJournaling(t *testing.T, nolocals bool) {
pool.currentState.AddBalance(crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000)) pool.currentState.AddBalance(crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000))
// Add three local and a remote transactions and ensure they are queued up // 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) 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) 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) 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) t.Fatalf("failed to add remote transaction: %v", err)
} }
pending, queued := pool.Stats() 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 // Terminate the old pool, bump the local nonce, create a new pool and ensure relevant transaction survive
pool.Stop() pool.Stop()
statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1) 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) pool = NewTxPool(config, params.TestChainConfig, blockchain)
@ -1541,7 +1541,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) {
pool.Stop() pool.Stop()
statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1) 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) pool = NewTxPool(config, params.TestChainConfig, blockchain)
pending, queued = pool.Stats() pending, queued = pool.Stats()
@ -1571,7 +1571,7 @@ func TestTransactionStatusCheck(t *testing.T) {
// Create the pool to test the status retrievals with // Create the pool to test the status retrievals with
db, _ := ethdb.NewMemDatabase() db, _ := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 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) pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
defer pool.Stop() defer pool.Stop()
@ -1585,10 +1585,10 @@ func TestTransactionStatusCheck(t *testing.T) {
// Generate and queue a batch of transactions, both pending and queued // Generate and queue a batch of transactions, both pending and queued
txs := types.Transactions{} txs := types.Transactions{}
txs = append(txs, pricedTransaction(0, big.NewInt(100000), big.NewInt(1), keys[0])) // Pending only txs = append(txs, pricedTransaction(0, 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(0, 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, 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(2, 100000, big.NewInt(1), keys[2])) // Queued only
// Import the transaction and ensure they are correctly added // Import the transaction and ensure they are correctly added
pool.AddRemotes(txs) pool.AddRemotes(txs)
@ -1631,11 +1631,11 @@ func benchmarkPendingDemotion(b *testing.B, size int) {
pool, key := setupTxPool() pool, key := setupTxPool()
defer pool.Stop() defer pool.Stop()
account, _ := deriveSender(transaction(0, big.NewInt(0), key)) account, _ := deriveSender(transaction(0, 0, key))
pool.currentState.AddBalance(account, big.NewInt(1000000)) pool.currentState.AddBalance(account, big.NewInt(1000000))
for i := 0; i < size; i++ { 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) pool.promoteTx(account, tx.Hash(), tx)
} }
// Benchmark the speed of pool validation // Benchmark the speed of pool validation
@ -1656,11 +1656,11 @@ func benchmarkFuturePromotion(b *testing.B, size int) {
pool, key := setupTxPool() pool, key := setupTxPool()
defer pool.Stop() defer pool.Stop()
account, _ := deriveSender(transaction(0, big.NewInt(0), key)) account, _ := deriveSender(transaction(0, 0, key))
pool.currentState.AddBalance(account, big.NewInt(1000000)) pool.currentState.AddBalance(account, big.NewInt(1000000))
for i := 0; i < size; i++ { 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) pool.enqueueTx(tx.Hash(), tx)
} }
// Benchmark the speed of pool validation // Benchmark the speed of pool validation
@ -1676,12 +1676,12 @@ func BenchmarkPoolInsert(b *testing.B) {
pool, key := setupTxPool() pool, key := setupTxPool()
defer pool.Stop() defer pool.Stop()
account, _ := deriveSender(transaction(0, big.NewInt(0), key)) account, _ := deriveSender(transaction(0, 0, key))
pool.currentState.AddBalance(account, big.NewInt(1000000)) pool.currentState.AddBalance(account, big.NewInt(1000000))
txs := make(types.Transactions, b.N) txs := make(types.Transactions, b.N)
for i := 0; i < b.N; i++ { 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 // Benchmark importing the transactions into the queue
b.ResetTimer() b.ResetTimer()
@ -1700,14 +1700,14 @@ func benchmarkPoolBatchInsert(b *testing.B, size int) {
pool, key := setupTxPool() pool, key := setupTxPool()
defer pool.Stop() defer pool.Stop()
account, _ := deriveSender(transaction(0, big.NewInt(0), key)) account, _ := deriveSender(transaction(0, 0, key))
pool.currentState.AddBalance(account, big.NewInt(1000000)) pool.currentState.AddBalance(account, big.NewInt(1000000))
batches := make([]types.Transactions, b.N) batches := make([]types.Transactions, b.N)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
batches[i] = make(types.Transactions, size) batches[i] = make(types.Transactions, size)
for j := 0; j < size; j++ { 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 // Benchmark importing the transactions into the queue

View File

@ -17,8 +17,6 @@
package core package core
import ( import (
"math/big"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
@ -34,7 +32,7 @@ type Validator interface {
// ValidateState validates the given statedb and optionally the receipts and // ValidateState validates the given statedb and optionally the receipts and
// gas used. // 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. // 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 // of gas used in the process and return an error if any of the internal rules
// failed. // failed.
type Processor interface { 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)
} }

View File

@ -77,8 +77,8 @@ type Header struct {
Bloom Bloom `json:"logsBloom" gencodec:"required"` Bloom Bloom `json:"logsBloom" gencodec:"required"`
Difficulty *big.Int `json:"difficulty" gencodec:"required"` Difficulty *big.Int `json:"difficulty" gencodec:"required"`
Number *big.Int `json:"number" gencodec:"required"` Number *big.Int `json:"number" gencodec:"required"`
GasLimit *big.Int `json:"gasLimit" gencodec:"required"` GasLimit uint64 `json:"gasLimit" gencodec:"required"`
GasUsed *big.Int `json:"gasUsed" gencodec:"required"` GasUsed uint64 `json:"gasUsed" gencodec:"required"`
Time *big.Int `json:"timestamp" gencodec:"required"` Time *big.Int `json:"timestamp" gencodec:"required"`
Extra []byte `json:"extraData" gencodec:"required"` Extra []byte `json:"extraData" gencodec:"required"`
MixDigest common.Hash `json:"mixHash" gencodec:"required"` MixDigest common.Hash `json:"mixHash" gencodec:"required"`
@ -89,8 +89,8 @@ type Header struct {
type headerMarshaling struct { type headerMarshaling struct {
Difficulty *hexutil.Big Difficulty *hexutil.Big
Number *hexutil.Big Number *hexutil.Big
GasLimit *hexutil.Big GasLimit *hexutil.Uint64
GasUsed *hexutil.Big GasUsed *hexutil.Uint64
Time *hexutil.Big Time *hexutil.Big
Extra hexutil.Bytes Extra hexutil.Bytes
Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON 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 { if cpy.Number = new(big.Int); h.Number != nil {
cpy.Number.Set(h.Number) 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 { if len(h.Extra) > 0 {
cpy.Extra = make([]byte, len(h.Extra)) cpy.Extra = make([]byte, len(h.Extra))
copy(cpy.Extra, 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) 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) GasLimit() uint64 { return b.header.GasLimit }
func (b *Block) GasUsed() *big.Int { return new(big.Int).Set(b.header.GasUsed) } 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) 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) } func (b *Block) Time() *big.Int { return new(big.Int).Set(b.header.Time) }

View File

@ -41,8 +41,8 @@ func TestBlockEncoding(t *testing.T) {
} }
} }
check("Difficulty", block.Difficulty(), big.NewInt(131072)) check("Difficulty", block.Difficulty(), big.NewInt(131072))
check("GasLimit", block.GasLimit(), big.NewInt(3141592)) check("GasLimit", block.GasLimit(), uint64(3141592))
check("GasUsed", block.GasUsed(), big.NewInt(21000)) check("GasUsed", block.GasUsed(), uint64(21000))
check("Coinbase", block.Coinbase(), common.HexToAddress("8888f1f195afa192cfee860698584c030f4c9db1")) check("Coinbase", block.Coinbase(), common.HexToAddress("8888f1f195afa192cfee860698584c030f4c9db1"))
check("MixDigest", block.MixDigest(), common.HexToHash("bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff498")) check("MixDigest", block.MixDigest(), common.HexToHash("bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff498"))
check("Root", block.Root(), common.HexToHash("ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017")) check("Root", block.Root(), common.HexToHash("ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017"))
@ -51,7 +51,7 @@ func TestBlockEncoding(t *testing.T) {
check("Time", block.Time(), big.NewInt(1426516743)) check("Time", block.Time(), big.NewInt(1426516743))
check("Size", block.Size(), common.StorageSize(len(blockEnc))) 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")) tx1, _ = tx1.WithSignature(HomesteadSigner{}, common.Hex2Bytes("9bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094f8a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b100"))
fmt.Println(block.Transactions()[0].Hash()) fmt.Println(block.Transactions()[0].Hash())

View File

@ -22,8 +22,8 @@ func (h Header) MarshalJSON() ([]byte, error) {
Bloom Bloom `json:"logsBloom" gencodec:"required"` Bloom Bloom `json:"logsBloom" gencodec:"required"`
Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"`
Number *hexutil.Big `json:"number" gencodec:"required"` Number *hexutil.Big `json:"number" gencodec:"required"`
GasLimit *hexutil.Big `json:"gasLimit" gencodec:"required"` GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"`
GasUsed *hexutil.Big `json:"gasUsed" gencodec:"required"` GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
Time *hexutil.Big `json:"timestamp" gencodec:"required"` Time *hexutil.Big `json:"timestamp" gencodec:"required"`
Extra hexutil.Bytes `json:"extraData" gencodec:"required"` Extra hexutil.Bytes `json:"extraData" gencodec:"required"`
MixDigest common.Hash `json:"mixHash" gencodec:"required"` MixDigest common.Hash `json:"mixHash" gencodec:"required"`
@ -40,8 +40,8 @@ func (h Header) MarshalJSON() ([]byte, error) {
enc.Bloom = h.Bloom enc.Bloom = h.Bloom
enc.Difficulty = (*hexutil.Big)(h.Difficulty) enc.Difficulty = (*hexutil.Big)(h.Difficulty)
enc.Number = (*hexutil.Big)(h.Number) enc.Number = (*hexutil.Big)(h.Number)
enc.GasLimit = (*hexutil.Big)(h.GasLimit) enc.GasLimit = hexutil.Uint64(h.GasLimit)
enc.GasUsed = (*hexutil.Big)(h.GasUsed) enc.GasUsed = hexutil.Uint64(h.GasUsed)
enc.Time = (*hexutil.Big)(h.Time) enc.Time = (*hexutil.Big)(h.Time)
enc.Extra = h.Extra enc.Extra = h.Extra
enc.MixDigest = h.MixDigest enc.MixDigest = h.MixDigest
@ -61,8 +61,8 @@ func (h *Header) UnmarshalJSON(input []byte) error {
Bloom *Bloom `json:"logsBloom" gencodec:"required"` Bloom *Bloom `json:"logsBloom" gencodec:"required"`
Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"`
Number *hexutil.Big `json:"number" gencodec:"required"` Number *hexutil.Big `json:"number" gencodec:"required"`
GasLimit *hexutil.Big `json:"gasLimit" gencodec:"required"` GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"`
GasUsed *hexutil.Big `json:"gasUsed" gencodec:"required"` GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
Time *hexutil.Big `json:"timestamp" gencodec:"required"` Time *hexutil.Big `json:"timestamp" gencodec:"required"`
Extra hexutil.Bytes `json:"extraData" gencodec:"required"` Extra hexutil.Bytes `json:"extraData" gencodec:"required"`
MixDigest *common.Hash `json:"mixHash" gencodec:"required"` MixDigest *common.Hash `json:"mixHash" gencodec:"required"`
@ -111,11 +111,11 @@ func (h *Header) UnmarshalJSON(input []byte) error {
if dec.GasLimit == nil { if dec.GasLimit == nil {
return errors.New("missing required field 'gasLimit' for Header") return errors.New("missing required field 'gasLimit' for Header")
} }
h.GasLimit = (*big.Int)(dec.GasLimit) h.GasLimit = (uint64)(*dec.GasLimit)
if dec.GasUsed == nil { if dec.GasUsed == nil {
return errors.New("missing required field 'gasUsed' for Header") return errors.New("missing required field 'gasUsed' for Header")
} }
h.GasUsed = (*big.Int)(dec.GasUsed) h.GasUsed = (uint64)(*dec.GasUsed)
if dec.Time == nil { if dec.Time == nil {
return errors.New("missing required field 'timestamp' for Header") return errors.New("missing required field 'timestamp' for Header")
} }

View File

@ -5,7 +5,6 @@ package types
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"math/big"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
@ -15,22 +14,22 @@ func (r Receipt) MarshalJSON() ([]byte, error) {
type Receipt struct { type Receipt struct {
PostState hexutil.Bytes `json:"root"` PostState hexutil.Bytes `json:"root"`
Status hexutil.Uint `json:"status"` 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"` Bloom Bloom `json:"logsBloom" gencodec:"required"`
Logs []*Log `json:"logs" gencodec:"required"` Logs []*Log `json:"logs" gencodec:"required"`
TxHash common.Hash `json:"transactionHash" gencodec:"required"` TxHash common.Hash `json:"transactionHash" gencodec:"required"`
ContractAddress common.Address `json:"contractAddress"` ContractAddress common.Address `json:"contractAddress"`
GasUsed *hexutil.Big `json:"gasUsed" gencodec:"required"` GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
} }
var enc Receipt var enc Receipt
enc.PostState = r.PostState enc.PostState = r.PostState
enc.Status = hexutil.Uint(r.Status) enc.Status = hexutil.Uint(r.Status)
enc.CumulativeGasUsed = (*hexutil.Big)(r.CumulativeGasUsed) enc.CumulativeGasUsed = hexutil.Uint64(r.CumulativeGasUsed)
enc.Bloom = r.Bloom enc.Bloom = r.Bloom
enc.Logs = r.Logs enc.Logs = r.Logs
enc.TxHash = r.TxHash enc.TxHash = r.TxHash
enc.ContractAddress = r.ContractAddress enc.ContractAddress = r.ContractAddress
enc.GasUsed = (*hexutil.Big)(r.GasUsed) enc.GasUsed = hexutil.Uint64(r.GasUsed)
return json.Marshal(&enc) return json.Marshal(&enc)
} }
@ -38,12 +37,12 @@ func (r *Receipt) UnmarshalJSON(input []byte) error {
type Receipt struct { type Receipt struct {
PostState hexutil.Bytes `json:"root"` PostState hexutil.Bytes `json:"root"`
Status *hexutil.Uint `json:"status"` 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"` Bloom *Bloom `json:"logsBloom" gencodec:"required"`
Logs []*Log `json:"logs" gencodec:"required"` Logs []*Log `json:"logs" gencodec:"required"`
TxHash *common.Hash `json:"transactionHash" gencodec:"required"` TxHash *common.Hash `json:"transactionHash" gencodec:"required"`
ContractAddress *common.Address `json:"contractAddress"` ContractAddress *common.Address `json:"contractAddress"`
GasUsed *hexutil.Big `json:"gasUsed" gencodec:"required"` GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
} }
var dec Receipt var dec Receipt
if err := json.Unmarshal(input, &dec); err != nil { if err := json.Unmarshal(input, &dec); err != nil {
@ -58,7 +57,7 @@ func (r *Receipt) UnmarshalJSON(input []byte) error {
if dec.CumulativeGasUsed == nil { if dec.CumulativeGasUsed == nil {
return errors.New("missing required field 'cumulativeGasUsed' for Receipt") return errors.New("missing required field 'cumulativeGasUsed' for Receipt")
} }
r.CumulativeGasUsed = (*big.Int)(dec.CumulativeGasUsed) r.CumulativeGasUsed = uint64(*dec.CumulativeGasUsed)
if dec.Bloom == nil { if dec.Bloom == nil {
return errors.New("missing required field 'logsBloom' for Receipt") return errors.New("missing required field 'logsBloom' for Receipt")
} }
@ -77,6 +76,6 @@ func (r *Receipt) UnmarshalJSON(input []byte) error {
if dec.GasUsed == nil { if dec.GasUsed == nil {
return errors.New("missing required field 'gasUsed' for Receipt") return errors.New("missing required field 'gasUsed' for Receipt")
} }
r.GasUsed = (*big.Int)(dec.GasUsed) r.GasUsed = uint64(*dec.GasUsed)
return nil return nil
} }

View File

@ -15,7 +15,7 @@ func (t txdata) MarshalJSON() ([]byte, error) {
type txdata struct { type txdata struct {
AccountNonce hexutil.Uint64 `json:"nonce" gencodec:"required"` AccountNonce hexutil.Uint64 `json:"nonce" gencodec:"required"`
Price *hexutil.Big `json:"gasPrice" 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"` Recipient *common.Address `json:"to" rlp:"nil"`
Amount *hexutil.Big `json:"value" gencodec:"required"` Amount *hexutil.Big `json:"value" gencodec:"required"`
Payload hexutil.Bytes `json:"input" gencodec:"required"` Payload hexutil.Bytes `json:"input" gencodec:"required"`
@ -27,7 +27,7 @@ func (t txdata) MarshalJSON() ([]byte, error) {
var enc txdata var enc txdata
enc.AccountNonce = hexutil.Uint64(t.AccountNonce) enc.AccountNonce = hexutil.Uint64(t.AccountNonce)
enc.Price = (*hexutil.Big)(t.Price) enc.Price = (*hexutil.Big)(t.Price)
enc.GasLimit = (*hexutil.Big)(t.GasLimit) enc.GasLimit = hexutil.Uint64(t.GasLimit)
enc.Recipient = t.Recipient enc.Recipient = t.Recipient
enc.Amount = (*hexutil.Big)(t.Amount) enc.Amount = (*hexutil.Big)(t.Amount)
enc.Payload = t.Payload enc.Payload = t.Payload
@ -42,7 +42,7 @@ func (t *txdata) UnmarshalJSON(input []byte) error {
type txdata struct { type txdata struct {
AccountNonce *hexutil.Uint64 `json:"nonce" gencodec:"required"` AccountNonce *hexutil.Uint64 `json:"nonce" gencodec:"required"`
Price *hexutil.Big `json:"gasPrice" 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"` Recipient *common.Address `json:"to" rlp:"nil"`
Amount *hexutil.Big `json:"value" gencodec:"required"` Amount *hexutil.Big `json:"value" gencodec:"required"`
Payload hexutil.Bytes `json:"input" gencodec:"required"` Payload hexutil.Bytes `json:"input" gencodec:"required"`
@ -66,7 +66,7 @@ func (t *txdata) UnmarshalJSON(input []byte) error {
if dec.GasLimit == nil { if dec.GasLimit == nil {
return errors.New("missing required field 'gas' for txdata") return errors.New("missing required field 'gas' for txdata")
} }
t.GasLimit = (*big.Int)(dec.GasLimit) t.GasLimit = uint64(*dec.GasLimit)
if dec.Recipient != nil { if dec.Recipient != nil {
t.Recipient = dec.Recipient t.Recipient = dec.Recipient
} }

View File

@ -20,7 +20,6 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"io" "io"
"math/big"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
@ -45,46 +44,46 @@ const (
// Receipt represents the results of a transaction. // Receipt represents the results of a transaction.
type Receipt struct { type Receipt struct {
// Consensus fields // Consensus fields
PostState []byte `json:"root"` PostState []byte `json:"root"`
Status uint `json:"status"` Status uint `json:"status"`
CumulativeGasUsed *big.Int `json:"cumulativeGasUsed" gencodec:"required"` CumulativeGasUsed uint64 `json:"cumulativeGasUsed" gencodec:"required"`
Bloom Bloom `json:"logsBloom" gencodec:"required"` Bloom Bloom `json:"logsBloom" gencodec:"required"`
Logs []*Log `json:"logs" gencodec:"required"` Logs []*Log `json:"logs" gencodec:"required"`
// Implementation fields (don't reorder!) // Implementation fields (don't reorder!)
TxHash common.Hash `json:"transactionHash" gencodec:"required"` TxHash common.Hash `json:"transactionHash" gencodec:"required"`
ContractAddress common.Address `json:"contractAddress"` ContractAddress common.Address `json:"contractAddress"`
GasUsed *big.Int `json:"gasUsed" gencodec:"required"` GasUsed uint64 `json:"gasUsed" gencodec:"required"`
} }
type receiptMarshaling struct { type receiptMarshaling struct {
PostState hexutil.Bytes PostState hexutil.Bytes
Status hexutil.Uint Status hexutil.Uint
CumulativeGasUsed *hexutil.Big CumulativeGasUsed hexutil.Uint64
GasUsed *hexutil.Big GasUsed hexutil.Uint64
} }
// receiptRLP is the consensus encoding of a receipt. // receiptRLP is the consensus encoding of a receipt.
type receiptRLP struct { type receiptRLP struct {
PostStateOrStatus []byte PostStateOrStatus []byte
CumulativeGasUsed *big.Int CumulativeGasUsed uint64
Bloom Bloom Bloom Bloom
Logs []*Log Logs []*Log
} }
type receiptStorageRLP struct { type receiptStorageRLP struct {
PostStateOrStatus []byte PostStateOrStatus []byte
CumulativeGasUsed *big.Int CumulativeGasUsed uint64
Bloom Bloom Bloom Bloom
TxHash common.Hash TxHash common.Hash
ContractAddress common.Address ContractAddress common.Address
Logs []*LogForStorage Logs []*LogForStorage
GasUsed *big.Int GasUsed uint64
} }
// NewReceipt creates a barebone transaction receipt, copying the init fields. // NewReceipt creates a barebone transaction receipt, copying the init fields.
func NewReceipt(root []byte, failed bool, cumulativeGasUsed *big.Int) *Receipt { func NewReceipt(root []byte, failed bool, cumulativeGasUsed uint64) *Receipt {
r := &Receipt{PostState: common.CopyBytes(root), CumulativeGasUsed: new(big.Int).Set(cumulativeGasUsed)} r := &Receipt{PostState: common.CopyBytes(root), CumulativeGasUsed: cumulativeGasUsed}
if failed { if failed {
r.Status = ReceiptStatusFailed r.Status = ReceiptStatusFailed
} else { } else {

View File

@ -57,7 +57,7 @@ type Transaction struct {
type txdata struct { type txdata struct {
AccountNonce uint64 `json:"nonce" gencodec:"required"` AccountNonce uint64 `json:"nonce" gencodec:"required"`
Price *big.Int `json:"gasPrice" 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 Recipient *common.Address `json:"to" rlp:"nil"` // nil means contract creation
Amount *big.Int `json:"value" gencodec:"required"` Amount *big.Int `json:"value" gencodec:"required"`
Payload []byte `json:"input" gencodec:"required"` Payload []byte `json:"input" gencodec:"required"`
@ -74,7 +74,7 @@ type txdata struct {
type txdataMarshaling struct { type txdataMarshaling struct {
AccountNonce hexutil.Uint64 AccountNonce hexutil.Uint64
Price *hexutil.Big Price *hexutil.Big
GasLimit *hexutil.Big GasLimit hexutil.Uint64
Amount *hexutil.Big Amount *hexutil.Big
Payload hexutil.Bytes Payload hexutil.Bytes
V *hexutil.Big V *hexutil.Big
@ -82,15 +82,15 @@ type txdataMarshaling struct {
S *hexutil.Big 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) 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) 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 { if len(data) > 0 {
data = common.CopyBytes(data) data = common.CopyBytes(data)
} }
@ -99,7 +99,7 @@ func newTransaction(nonce uint64, to *common.Address, amount, gasLimit, gasPrice
Recipient: to, Recipient: to,
Payload: data, Payload: data,
Amount: new(big.Int), Amount: new(big.Int),
GasLimit: new(big.Int), GasLimit: gasLimit,
Price: new(big.Int), Price: new(big.Int),
V: new(big.Int), V: new(big.Int),
R: new(big.Int), R: new(big.Int),
@ -108,9 +108,6 @@ func newTransaction(nonce uint64, to *common.Address, amount, gasLimit, gasPrice
if amount != nil { if amount != nil {
d.Amount.Set(amount) d.Amount.Set(amount)
} }
if gasLimit != nil {
d.GasLimit.Set(gasLimit)
}
if gasPrice != nil { if gasPrice != nil {
d.Price.Set(gasPrice) 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) 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) 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) Value() *big.Int { return new(big.Int).Set(tx.data.Amount) }
func (tx *Transaction) Nonce() uint64 { return tx.data.AccountNonce } 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) { func (tx *Transaction) AsMessage(s Signer) (Message, error) {
msg := Message{ msg := Message{
nonce: tx.data.AccountNonce, nonce: tx.data.AccountNonce,
price: new(big.Int).Set(tx.data.Price), gasLimit: tx.data.GasLimit,
gasLimit: new(big.Int).Set(tx.data.GasLimit), gasPrice: new(big.Int).Set(tx.data.Price),
to: tx.data.Recipient, to: tx.data.Recipient,
amount: tx.data.Amount, amount: tx.data.Amount,
data: tx.data.Payload, data: tx.data.Payload,
@ -254,7 +251,7 @@ func (tx *Transaction) WithSignature(signer Signer, sig []byte) (*Transaction, e
// Cost returns amount + gasprice * gaslimit. // Cost returns amount + gasprice * gaslimit.
func (tx *Transaction) Cost() *big.Int { 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) total.Add(total, tx.data.Amount)
return total return total
} }
@ -440,22 +437,24 @@ func (t *TransactionsByPriceAndNonce) Pop() {
// //
// NOTE: In a future PR this will be removed. // NOTE: In a future PR this will be removed.
type Message struct { type Message struct {
to *common.Address to *common.Address
from common.Address from common.Address
nonce uint64 nonce uint64
amount, price, gasLimit *big.Int amount *big.Int
data []byte gasLimit uint64
checkNonce bool 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{ return Message{
from: from, from: from,
to: to, to: to,
nonce: nonce, nonce: nonce,
amount: amount, amount: amount,
price: price,
gasLimit: gasLimit, gasLimit: gasLimit,
gasPrice: gasPrice,
data: data, data: data,
checkNonce: checkNonce, 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) From() common.Address { return m.from }
func (m Message) To() *common.Address { return m.to } 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) 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) Nonce() uint64 { return m.nonce }
func (m Message) Data() []byte { return m.data } func (m Message) Data() []byte { return m.data }
func (m Message) CheckNonce() bool { return m.checkNonce } func (m Message) CheckNonce() bool { return m.checkNonce }

View File

@ -30,7 +30,7 @@ func TestEIP155Signing(t *testing.T) {
addr := crypto.PubkeyToAddress(key.PublicKey) addr := crypto.PubkeyToAddress(key.PublicKey)
signer := NewEIP155Signer(big.NewInt(18)) 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 { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -49,7 +49,7 @@ func TestEIP155ChainId(t *testing.T) {
addr := crypto.PubkeyToAddress(key.PublicKey) addr := crypto.PubkeyToAddress(key.PublicKey)
signer := NewEIP155Signer(big.NewInt(18)) 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 { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -61,7 +61,7 @@ func TestEIP155ChainId(t *testing.T) {
t.Error("expected chainId to be", signer.chainId, "got", tx.ChainId()) 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) tx, err = SignTx(tx, HomesteadSigner{}, key)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -118,7 +118,7 @@ func TestEIP155SigningVitalik(t *testing.T) {
func TestChainId(t *testing.T) { func TestChainId(t *testing.T) {
key, _ := defaultTestKey() 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 var err error
tx, err = SignTx(tx, NewEIP155Signer(big.NewInt(1)), key) tx, err = SignTx(tx, NewEIP155Signer(big.NewInt(1)), key)

View File

@ -34,7 +34,7 @@ var (
emptyTx = NewTransaction( emptyTx = NewTransaction(
0, 0,
common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"),
big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), 0, big.NewInt(0),
nil, nil,
) )
@ -42,7 +42,7 @@ var (
3, 3,
common.HexToAddress("b94f5374fce5edbc8e2a8697c15331677e6ebf0b"), common.HexToAddress("b94f5374fce5edbc8e2a8697c15331677e6ebf0b"),
big.NewInt(10), big.NewInt(10),
big.NewInt(2000), 2000,
big.NewInt(1), big.NewInt(1),
common.FromHex("5544"), common.FromHex("5544"),
).WithSignature( ).WithSignature(
@ -139,7 +139,7 @@ func TestTransactionPriceNonceSort(t *testing.T) {
for start, key := range keys { for start, key := range keys {
addr := crypto.PubkeyToAddress(key.PublicKey) addr := crypto.PubkeyToAddress(key.PublicKey)
for i := 0; i < 25; i++ { 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) groups[addr] = append(groups[addr], tx)
} }
} }
@ -204,9 +204,9 @@ func TestTransactionJSON(t *testing.T) {
var tx *Transaction var tx *Transaction
switch i % 2 { switch i % 2 {
case 0: 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: 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) tx, err := SignTx(tx, signer, key)

View File

@ -69,7 +69,7 @@ type Context struct {
// Block information // Block information
Coinbase common.Address // Provides information for COINBASE 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 BlockNumber *big.Int // Provides information for NUMBER
Time *big.Int // Provides information for TIME Time *big.Int // Provides information for TIME
Difficulty *big.Int // Provides information for DIFFICULTY Difficulty *big.Int // Provides information for DIFFICULTY

View File

@ -17,8 +17,6 @@
package vm package vm
import ( import (
"math/big"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/params" "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 // 0 => non 0
return params.SstoreSetGas, nil return params.SstoreSetGas, nil
} else if !common.EmptyHash(val) && common.EmptyHash(common.BigToHash(y)) { } 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 return params.SstoreClearGas, nil
} else { } else {
@ -405,7 +403,7 @@ func gasSuicide(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack,
} }
if !evm.StateDB.HasSuicided(contract.Address()) { if !evm.StateDB.HasSuicided(contract.Address()) {
evm.StateDB.AddRefund(new(big.Int).SetUint64(params.SuicideRefundGas)) evm.StateDB.AddRefund(params.SuicideRefundGas)
} }
return gas, nil return gas, nil
} }

View File

@ -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) { 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 return nil, nil
} }

View File

@ -39,8 +39,8 @@ type StateDB interface {
SetCode(common.Address, []byte) SetCode(common.Address, []byte)
GetCodeSize(common.Address) int GetCodeSize(common.Address) int
AddRefund(*big.Int) AddRefund(uint64)
GetRefund() *big.Int GetRefund() uint64
GetState(common.Address, common.Hash) common.Hash GetState(common.Address, common.Hash) common.Hash
SetState(common.Address, common.Hash, common.Hash) SetState(common.Address, common.Hash, common.Hash)

View File

@ -55,8 +55,8 @@ func (NoopStateDB) GetCodeHash(common.Address) common.Hash
func (NoopStateDB) GetCode(common.Address) []byte { return nil } func (NoopStateDB) GetCode(common.Address) []byte { return nil }
func (NoopStateDB) SetCode(common.Address, []byte) {} func (NoopStateDB) SetCode(common.Address, []byte) {}
func (NoopStateDB) GetCodeSize(common.Address) int { return 0 } func (NoopStateDB) GetCodeSize(common.Address) int { return 0 }
func (NoopStateDB) AddRefund(*big.Int) {} func (NoopStateDB) AddRefund(uint64) {}
func (NoopStateDB) GetRefund() *big.Int { return nil } func (NoopStateDB) GetRefund() uint64 { return 0 }
func (NoopStateDB) GetState(common.Address, common.Hash) common.Hash { return common.Hash{} } func (NoopStateDB) GetState(common.Address, common.Hash) common.Hash { return common.Hash{} }
func (NoopStateDB) SetState(common.Address, common.Hash, common.Hash) {} func (NoopStateDB) SetState(common.Address, common.Hash, common.Hash) {}
func (NoopStateDB) Suicide(common.Address) bool { return false } func (NoopStateDB) Suicide(common.Address) bool { return false }

View File

@ -17,8 +17,6 @@
package runtime package runtime
import ( import (
"math/big"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
@ -35,7 +33,7 @@ func NewEnv(cfg *Config) *vm.EVM {
BlockNumber: cfg.BlockNumber, BlockNumber: cfg.BlockNumber,
Time: cfg.Time, Time: cfg.Time,
Difficulty: cfg.Difficulty, Difficulty: cfg.Difficulty,
GasLimit: new(big.Int).SetUint64(cfg.GasLimit), GasLimit: cfg.GasLimit,
GasPrice: cfg.GasPrice, GasPrice: cfg.GasPrice,
} }

View File

@ -83,9 +83,7 @@ func toCallArgs(msg ethereum.CallMsg) ethapi.CallArgs {
To: msg.To, To: msg.To,
From: msg.From, From: msg.From,
Data: msg.Data, Data: msg.Data,
} Gas: hexutil.Uint64(msg.Gas),
if msg.Gas != nil {
args.Gas = hexutil.Big(*msg.Gas)
} }
if msg.GasPrice != nil { if msg.GasPrice != nil {
args.GasPrice = hexutil.Big(*msg.GasPrice) args.GasPrice = hexutil.Big(*msg.GasPrice)
@ -124,9 +122,9 @@ func (b *ContractBackend) SuggestGasPrice(ctx context.Context) (*big.Int, error)
// the backend blockchain. There is no guarantee that this is the true gas limit // the backend blockchain. There is no guarantee that this is the true gas limit
// requirement as other transactions may be added or removed by miners, but it // requirement as other transactions may be added or removed by miners, but it
// should provide a basis for setting a reasonable default. // should provide a basis for setting a reasonable default.
func (b *ContractBackend) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (*big.Int, error) { func (b *ContractBackend) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64, error) {
out, err := b.bcapi.EstimateGas(ctx, toCallArgs(msg)) gas, err := b.bcapi.EstimateGas(ctx, toCallArgs(msg))
return out.ToInt(), err return uint64(gas), err
} }
// SendTransaction implements bind.ContractTransactor injects the transaction // SendTransaction implements bind.ContractTransactor injects the transaction

View File

@ -118,7 +118,7 @@ func (dl *downloadTester) makeChain(n int, seed byte, parent *types.Block, paren
// If the block number is multiple of 3, send a bonus transaction to the miner // If the block number is multiple of 3, send a bonus transaction to the miner
if parent == dl.genesis && i%3 == 0 { if parent == dl.genesis && i%3 == 0 {
signer := types.MakeSigner(params.TestChainConfig, block.Number()) signer := types.MakeSigner(params.TestChainConfig, block.Number())
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), new(big.Int).SetUint64(params.TxGas), nil, nil), signer, testKey) tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, nil, nil), signer, testKey)
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@ -52,7 +52,7 @@ func makeChain(n int, seed byte, parent *types.Block) ([]common.Hash, map[common
// If the block number is multiple of 3, send a bonus transaction to the miner // If the block number is multiple of 3, send a bonus transaction to the miner
if parent == genesis && i%3 == 0 { if parent == genesis && i%3 == 0 {
signer := types.MakeSigner(params.TestChainConfig, block.Number()) signer := types.MakeSigner(params.TestChainConfig, block.Number())
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), new(big.Int).SetUint64(params.TxGas), nil, nil), signer, testKey) tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, nil, nil), signer, testKey)
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@ -195,11 +195,11 @@ func TestPendingTxFilter(t *testing.T) {
api = NewPublicFilterAPI(backend, false) api = NewPublicFilterAPI(backend, false)
transactions = []*types.Transaction{ transactions = []*types.Transaction{
types.NewTransaction(0, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), new(big.Int), new(big.Int), nil), types.NewTransaction(0, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
types.NewTransaction(1, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), new(big.Int), new(big.Int), nil), types.NewTransaction(1, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
types.NewTransaction(2, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), new(big.Int), new(big.Int), nil), types.NewTransaction(2, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
types.NewTransaction(3, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), new(big.Int), new(big.Int), nil), types.NewTransaction(3, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
types.NewTransaction(4, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), new(big.Int), new(big.Int), nil), types.NewTransaction(4, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
} }
hashes []common.Hash hashes []common.Hash

View File

@ -34,7 +34,7 @@ import (
) )
func makeReceipt(addr common.Address) *types.Receipt { func makeReceipt(addr common.Address) *types.Receipt {
receipt := types.NewReceipt(nil, false, new(big.Int)) receipt := types.NewReceipt(nil, false, 0)
receipt.Logs = []*types.Log{ receipt.Logs = []*types.Log{
{Address: addr}, {Address: addr},
} }
@ -136,7 +136,7 @@ func TestFilters(t *testing.T) {
chain, receipts := core.GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 1000, func(i int, gen *core.BlockGen) { chain, receipts := core.GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 1000, func(i int, gen *core.BlockGen) {
switch i { switch i {
case 1: case 1:
receipt := types.NewReceipt(nil, false, new(big.Int)) receipt := types.NewReceipt(nil, false, 0)
receipt.Logs = []*types.Log{ receipt.Logs = []*types.Log{
{ {
Address: addr, Address: addr,
@ -145,7 +145,7 @@ func TestFilters(t *testing.T) {
} }
gen.AddUncheckedReceipt(receipt) gen.AddUncheckedReceipt(receipt)
case 2: case 2:
receipt := types.NewReceipt(nil, false, new(big.Int)) receipt := types.NewReceipt(nil, false, 0)
receipt.Logs = []*types.Log{ receipt.Logs = []*types.Log{
{ {
Address: addr, Address: addr,
@ -154,7 +154,7 @@ func TestFilters(t *testing.T) {
} }
gen.AddUncheckedReceipt(receipt) gen.AddUncheckedReceipt(receipt)
case 998: case 998:
receipt := types.NewReceipt(nil, false, new(big.Int)) receipt := types.NewReceipt(nil, false, 0)
receipt.Logs = []*types.Log{ receipt.Logs = []*types.Log{
{ {
Address: addr, Address: addr,
@ -163,7 +163,7 @@ func TestFilters(t *testing.T) {
} }
gen.AddUncheckedReceipt(receipt) gen.AddUncheckedReceipt(receipt)
case 999: case 999:
receipt := types.NewReceipt(nil, false, new(big.Int)) receipt := types.NewReceipt(nil, false, 0)
receipt.Logs = []*types.Log{ receipt.Logs = []*types.Log{
{ {
Address: addr, Address: addr,

View File

@ -37,8 +37,6 @@ import (
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
) )
var bigTxGas = new(big.Int).SetUint64(params.TxGas)
// Tests that protocol versions and modes of operations are matched up properly. // Tests that protocol versions and modes of operations are matched up properly.
func TestProtocolCompatibility(t *testing.T) { func TestProtocolCompatibility(t *testing.T) {
// Define the compatibility chart // Define the compatibility chart
@ -315,13 +313,13 @@ func testGetNodeData(t *testing.T, protocol int) {
switch i { switch i {
case 0: case 0:
// In block 1, the test bank sends account #1 some ether. // In block 1, the test bank sends account #1 some ether.
tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank), acc1Addr, big.NewInt(10000), bigTxGas, nil, nil), signer, testBankKey) tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil), signer, testBankKey)
block.AddTx(tx) block.AddTx(tx)
case 1: case 1:
// In block 2, the test bank sends some more ether to account #1. // In block 2, the test bank sends some more ether to account #1.
// acc1Addr passes it on to account #2. // acc1Addr passes it on to account #2.
tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank), acc1Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, testBankKey) tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank), acc1Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, testBankKey)
tx2, _ := types.SignTx(types.NewTransaction(block.TxNonce(acc1Addr), acc2Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, acc1Key) tx2, _ := types.SignTx(types.NewTransaction(block.TxNonce(acc1Addr), acc2Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, acc1Key)
block.AddTx(tx1) block.AddTx(tx1)
block.AddTx(tx2) block.AddTx(tx2)
case 2: case 2:
@ -407,13 +405,13 @@ func testGetReceipt(t *testing.T, protocol int) {
switch i { switch i {
case 0: case 0:
// In block 1, the test bank sends account #1 some ether. // In block 1, the test bank sends account #1 some ether.
tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank), acc1Addr, big.NewInt(10000), bigTxGas, nil, nil), signer, testBankKey) tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil), signer, testBankKey)
block.AddTx(tx) block.AddTx(tx)
case 1: case 1:
// In block 2, the test bank sends some more ether to account #1. // In block 2, the test bank sends some more ether to account #1.
// acc1Addr passes it on to account #2. // acc1Addr passes it on to account #2.
tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank), acc1Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, testBankKey) tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank), acc1Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, testBankKey)
tx2, _ := types.SignTx(types.NewTransaction(block.TxNonce(acc1Addr), acc2Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, acc1Key) tx2, _ := types.SignTx(types.NewTransaction(block.TxNonce(acc1Addr), acc2Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, acc1Key)
block.AddTx(tx1) block.AddTx(tx1)
block.AddTx(tx2) block.AddTx(tx2)
case 2: case 2:

View File

@ -130,7 +130,7 @@ func (p *testTxPool) SubscribeTxPreEvent(ch chan<- core.TxPreEvent) event.Subscr
// newTestTransaction create a new dummy transaction. // newTestTransaction create a new dummy transaction.
func newTestTransaction(from *ecdsa.PrivateKey, nonce uint64, datasize int) *types.Transaction { func newTestTransaction(from *ecdsa.PrivateKey, nonce uint64, datasize int) *types.Transaction {
tx := types.NewTransaction(nonce, common.Address{}, big.NewInt(0), big.NewInt(100000), big.NewInt(0), make([]byte, datasize)) tx := types.NewTransaction(nonce, common.Address{}, big.NewInt(0), 100000, big.NewInt(0), make([]byte, datasize))
tx, _ = types.SignTx(tx, types.HomesteadSigner{}, from) tx, _ = types.SignTx(tx, types.HomesteadSigner{}, from)
return tx return tx
} }

View File

@ -156,7 +156,7 @@ func TestCallTracer(t *testing.T) {
BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)), BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)),
Time: new(big.Int).SetUint64(uint64(test.Context.Time)), Time: new(big.Int).SetUint64(uint64(test.Context.Time)),
Difficulty: (*big.Int)(test.Context.Difficulty), Difficulty: (*big.Int)(test.Context.Difficulty),
GasLimit: new(big.Int).SetUint64(uint64(test.Context.GasLimit)), GasLimit: uint64(test.Context.GasLimit),
GasPrice: tx.GasPrice(), GasPrice: tx.GasPrice(),
} }
db, _ := ethdb.NewMemDatabase() db, _ := ethdb.NewMemDatabase()
@ -174,7 +174,7 @@ func TestCallTracer(t *testing.T) {
t.Fatalf("failed to prepare transaction for tracing: %v", err) t.Fatalf("failed to prepare transaction for tracing: %v", err)
} }
st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
if _, _, _, _, err = st.TransitionDb(); err != nil { if _, _, _, err = st.TransitionDb(); err != nil {
t.Fatalf("failed to execute transaction: %v", err) t.Fatalf("failed to execute transaction: %v", err)
} }
// Retrieve the trace result and compare against the etalon // Retrieve the trace result and compare against the etalon

View File

@ -455,13 +455,13 @@ func (ec *Client) SuggestGasPrice(ctx context.Context) (*big.Int, error) {
// the current pending state of the backend blockchain. There is no guarantee that this is // the current pending state of the backend blockchain. There is no guarantee that this is
// the true gas limit requirement as other transactions may be added or removed by miners, // the true gas limit requirement as other transactions may be added or removed by miners,
// but it should provide a basis for setting a reasonable default. // but it should provide a basis for setting a reasonable default.
func (ec *Client) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (*big.Int, error) { func (ec *Client) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64, error) {
var hex hexutil.Big var hex hexutil.Uint64
err := ec.c.CallContext(ctx, &hex, "eth_estimateGas", toCallArg(msg)) err := ec.c.CallContext(ctx, &hex, "eth_estimateGas", toCallArg(msg))
if err != nil { if err != nil {
return nil, err return 0, err
} }
return (*big.Int)(&hex), nil return uint64(hex), nil
} }
// SendTransaction injects a signed transaction into the pending pool for execution. // SendTransaction injects a signed transaction into the pending pool for execution.
@ -487,8 +487,8 @@ func toCallArg(msg ethereum.CallMsg) interface{} {
if msg.Value != nil { if msg.Value != nil {
arg["value"] = (*hexutil.Big)(msg.Value) arg["value"] = (*hexutil.Big)(msg.Value)
} }
if msg.Gas != nil { if msg.Gas != 0 {
arg["gas"] = (*hexutil.Big)(msg.Gas) arg["gas"] = hexutil.Uint64(msg.Gas)
} }
if msg.GasPrice != nil { if msg.GasPrice != nil {
arg["gasPrice"] = (*hexutil.Big)(msg.GasPrice) arg["gasPrice"] = (*hexutil.Big)(msg.GasPrice)

View File

@ -473,8 +473,8 @@ type blockStats struct {
ParentHash common.Hash `json:"parentHash"` ParentHash common.Hash `json:"parentHash"`
Timestamp *big.Int `json:"timestamp"` Timestamp *big.Int `json:"timestamp"`
Miner common.Address `json:"miner"` Miner common.Address `json:"miner"`
GasUsed *big.Int `json:"gasUsed"` GasUsed uint64 `json:"gasUsed"`
GasLimit *big.Int `json:"gasLimit"` GasLimit uint64 `json:"gasLimit"`
Diff string `json:"difficulty"` Diff string `json:"difficulty"`
TotalDiff string `json:"totalDifficulty"` TotalDiff string `json:"totalDifficulty"`
Txs []txStats `json:"transactions"` Txs []txStats `json:"transactions"`
@ -559,8 +559,8 @@ func (s *Service) assembleBlockStats(block *types.Block) *blockStats {
ParentHash: header.ParentHash, ParentHash: header.ParentHash,
Timestamp: header.Time, Timestamp: header.Time,
Miner: author, Miner: author,
GasUsed: new(big.Int).Set(header.GasUsed), GasUsed: header.GasUsed,
GasLimit: new(big.Int).Set(header.GasLimit), GasLimit: header.GasLimit,
Diff: header.Difficulty.String(), Diff: header.Difficulty.String(),
TotalDiff: td.String(), TotalDiff: td.String(),
Txs: txs, Txs: txs,

View File

@ -115,7 +115,7 @@ type ChainSyncReader interface {
type CallMsg struct { type CallMsg struct {
From common.Address // the sender of the 'transaction' From common.Address // the sender of the 'transaction'
To *common.Address // the destination contract (nil for contract creation) To *common.Address // the destination contract (nil for contract creation)
Gas *big.Int // if nil, the call executes with near-infinite gas Gas uint64 // if 0, the call executes with near-infinite gas
GasPrice *big.Int // wei <-> gas exchange ratio GasPrice *big.Int // wei <-> gas exchange ratio
Value *big.Int // amount of wei sent along with the call Value *big.Int // amount of wei sent along with the call
Data []byte // input data, usually an ABI-encoded contract method invocation Data []byte // input data, usually an ABI-encoded contract method invocation
@ -200,7 +200,7 @@ type PendingContractCaller interface {
// true gas limit requirement as other transactions may be added or removed by miners, but // true gas limit requirement as other transactions may be added or removed by miners, but
// it should provide a basis for setting a reasonable default. // it should provide a basis for setting a reasonable default.
type GasEstimator interface { type GasEstimator interface {
EstimateGas(ctx context.Context, call CallMsg) (usedGas *big.Int, err error) EstimateGas(ctx context.Context, call CallMsg) (uint64, error)
} }
// A PendingStateEventer provides access to real time notifications about changes to the // A PendingStateEventer provides access to real time notifications about changes to the

View File

@ -45,7 +45,6 @@ import (
) )
const ( const (
defaultGas = 90000
defaultGasPrice = 50 * params.Shannon defaultGasPrice = 50 * params.Shannon
) )
@ -575,18 +574,18 @@ func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.A
type CallArgs struct { type CallArgs struct {
From common.Address `json:"from"` From common.Address `json:"from"`
To *common.Address `json:"to"` To *common.Address `json:"to"`
Gas hexutil.Big `json:"gas"` Gas hexutil.Uint64 `json:"gas"`
GasPrice hexutil.Big `json:"gasPrice"` GasPrice hexutil.Big `json:"gasPrice"`
Value hexutil.Big `json:"value"` Value hexutil.Big `json:"value"`
Data hexutil.Bytes `json:"data"` Data hexutil.Bytes `json:"data"`
} }
func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber, vmCfg vm.Config) ([]byte, *big.Int, bool, error) { func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber, vmCfg vm.Config) ([]byte, uint64, bool, error) {
defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now())
state, header, err := s.b.StateAndHeaderByNumber(ctx, blockNr) state, header, err := s.b.StateAndHeaderByNumber(ctx, blockNr)
if state == nil || err != nil { if state == nil || err != nil {
return nil, common.Big0, false, err return nil, 0, false, err
} }
// Set sender address or use a default if none specified // Set sender address or use a default if none specified
addr := args.From addr := args.From
@ -598,9 +597,9 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr
} }
} }
// Set default gas & gas price if none were set // Set default gas & gas price if none were set
gas, gasPrice := args.Gas.ToInt(), args.GasPrice.ToInt() gas, gasPrice := uint64(args.Gas), args.GasPrice.ToInt()
if gas.Sign() == 0 { if gas == 0 {
gas = big.NewInt(50000000) gas = 50000000
} }
if gasPrice.Sign() == 0 { if gasPrice.Sign() == 0 {
gasPrice = new(big.Int).SetUint64(defaultGasPrice) gasPrice = new(big.Int).SetUint64(defaultGasPrice)
@ -624,7 +623,7 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr
// Get a new instance of the EVM. // Get a new instance of the EVM.
evm, vmError, err := s.b.GetEVM(ctx, msg, state, header, vmCfg) evm, vmError, err := s.b.GetEVM(ctx, msg, state, header, vmCfg)
if err != nil { if err != nil {
return nil, common.Big0, false, err return nil, 0, false, err
} }
// Wait for the context to be done and cancel the evm. Even if the // Wait for the context to be done and cancel the evm. Even if the
// EVM has finished, cancelling may be done (repeatedly) // EVM has finished, cancelling may be done (repeatedly)
@ -635,10 +634,10 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr
// Setup the gas pool (also for unmetered requests) // Setup the gas pool (also for unmetered requests)
// and apply the message. // and apply the message.
gp := new(core.GasPool).AddGas(math.MaxBig256) gp := new(core.GasPool).AddGas(math.MaxUint64)
res, gas, failed, err := core.ApplyMessage(evm, msg, gp) res, gas, failed, err := core.ApplyMessage(evm, msg, gp)
if err := vmError(); err != nil { if err := vmError(); err != nil {
return nil, common.Big0, false, err return nil, 0, false, err
} }
return res, gas, failed, err return res, gas, failed, err
} }
@ -652,28 +651,29 @@ func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNr r
// EstimateGas returns an estimate of the amount of gas needed to execute the // EstimateGas returns an estimate of the amount of gas needed to execute the
// given transaction against the current pending block. // given transaction against the current pending block.
func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (*hexutil.Big, error) { func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (hexutil.Uint64, error) {
// Determine the lowest and highest possible gas limits to binary search in between // Binary search the gas requirement, as it may be higher than the amount used
var ( var (
lo uint64 = params.TxGas - 1 lo uint64 = params.TxGas - 1
hi uint64 hi uint64
cap uint64 cap uint64
) )
if (*big.Int)(&args.Gas).Uint64() >= params.TxGas { if uint64(args.Gas) >= params.TxGas {
hi = (*big.Int)(&args.Gas).Uint64() hi = uint64(args.Gas)
} else { } else {
// Retrieve the current pending block to act as the gas ceiling // Retrieve the current pending block to act as the gas ceiling
block, err := s.b.BlockByNumber(ctx, rpc.PendingBlockNumber) block, err := s.b.BlockByNumber(ctx, rpc.PendingBlockNumber)
if err != nil { if err != nil {
return nil, err return 0, err
} }
hi = block.GasLimit().Uint64() hi = block.GasLimit()
} }
cap = hi cap = hi
// Create a helper to check if a gas allowance results in an executable transaction // Create a helper to check if a gas allowance results in an executable transaction
executable := func(gas uint64) bool { executable := func(gas uint64) bool {
(*big.Int)(&args.Gas).SetUint64(gas) args.Gas = hexutil.Uint64(gas)
_, _, failed, err := s.doCall(ctx, args, rpc.PendingBlockNumber, vm.Config{}) _, _, failed, err := s.doCall(ctx, args, rpc.PendingBlockNumber, vm.Config{})
if err != nil || failed { if err != nil || failed {
return false return false
@ -692,17 +692,17 @@ func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (*
// Reject the transaction as invalid if it still fails at the highest allowance // Reject the transaction as invalid if it still fails at the highest allowance
if hi == cap { if hi == cap {
if !executable(hi) { if !executable(hi) {
return nil, fmt.Errorf("gas required exceeds allowance or always failing transaction") return 0, fmt.Errorf("gas required exceeds allowance or always failing transaction")
} }
} }
return (*hexutil.Big)(new(big.Int).SetUint64(hi)), nil return hexutil.Uint64(hi), nil
} }
// ExecutionResult groups all structured logs emitted by the EVM // ExecutionResult groups all structured logs emitted by the EVM
// while replaying a transaction in debug mode as well as transaction // while replaying a transaction in debug mode as well as transaction
// execution status, the amount of gas used and the return value // execution status, the amount of gas used and the return value
type ExecutionResult struct { type ExecutionResult struct {
Gas *big.Int `json:"gas"` Gas uint64 `json:"gas"`
Failed bool `json:"failed"` Failed bool `json:"failed"`
ReturnValue string `json:"returnValue"` ReturnValue string `json:"returnValue"`
StructLogs []StructLogRes `json:"structLogs"` StructLogs []StructLogRes `json:"structLogs"`
@ -778,8 +778,8 @@ func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx
"totalDifficulty": (*hexutil.Big)(s.b.GetTd(b.Hash())), "totalDifficulty": (*hexutil.Big)(s.b.GetTd(b.Hash())),
"extraData": hexutil.Bytes(head.Extra), "extraData": hexutil.Bytes(head.Extra),
"size": hexutil.Uint64(uint64(b.Size().Int64())), "size": hexutil.Uint64(uint64(b.Size().Int64())),
"gasLimit": (*hexutil.Big)(head.GasLimit), "gasLimit": hexutil.Uint64(head.GasLimit),
"gasUsed": (*hexutil.Big)(head.GasUsed), "gasUsed": hexutil.Uint64(head.GasUsed),
"timestamp": (*hexutil.Big)(head.Time), "timestamp": (*hexutil.Big)(head.Time),
"transactionsRoot": head.TxHash, "transactionsRoot": head.TxHash,
"receiptsRoot": head.ReceiptHash, "receiptsRoot": head.ReceiptHash,
@ -822,7 +822,7 @@ type RPCTransaction struct {
BlockHash common.Hash `json:"blockHash"` BlockHash common.Hash `json:"blockHash"`
BlockNumber *hexutil.Big `json:"blockNumber"` BlockNumber *hexutil.Big `json:"blockNumber"`
From common.Address `json:"from"` From common.Address `json:"from"`
Gas *hexutil.Big `json:"gas"` Gas hexutil.Uint64 `json:"gas"`
GasPrice *hexutil.Big `json:"gasPrice"` GasPrice *hexutil.Big `json:"gasPrice"`
Hash common.Hash `json:"hash"` Hash common.Hash `json:"hash"`
Input hexutil.Bytes `json:"input"` Input hexutil.Bytes `json:"input"`
@ -847,7 +847,7 @@ func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber
result := &RPCTransaction{ result := &RPCTransaction{
From: from, From: from,
Gas: (*hexutil.Big)(tx.Gas()), Gas: hexutil.Uint64(tx.Gas()),
GasPrice: (*hexutil.Big)(tx.GasPrice()), GasPrice: (*hexutil.Big)(tx.GasPrice()),
Hash: tx.Hash(), Hash: tx.Hash(),
Input: hexutil.Bytes(tx.Data()), Input: hexutil.Bytes(tx.Data()),
@ -1024,8 +1024,8 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(hash common.Hash) (map[
"transactionIndex": hexutil.Uint64(index), "transactionIndex": hexutil.Uint64(index),
"from": from, "from": from,
"to": tx.To(), "to": tx.To(),
"gasUsed": (*hexutil.Big)(receipt.GasUsed), "gasUsed": hexutil.Uint64(receipt.GasUsed),
"cumulativeGasUsed": (*hexutil.Big)(receipt.CumulativeGasUsed), "cumulativeGasUsed": hexutil.Uint64(receipt.CumulativeGasUsed),
"contractAddress": nil, "contractAddress": nil,
"logs": receipt.Logs, "logs": receipt.Logs,
"logsBloom": receipt.Bloom, "logsBloom": receipt.Bloom,
@ -1068,7 +1068,7 @@ func (s *PublicTransactionPoolAPI) sign(addr common.Address, tx *types.Transacti
type SendTxArgs struct { type SendTxArgs struct {
From common.Address `json:"from"` From common.Address `json:"from"`
To *common.Address `json:"to"` To *common.Address `json:"to"`
Gas *hexutil.Big `json:"gas"` Gas *hexutil.Uint64 `json:"gas"`
GasPrice *hexutil.Big `json:"gasPrice"` GasPrice *hexutil.Big `json:"gasPrice"`
Value *hexutil.Big `json:"value"` Value *hexutil.Big `json:"value"`
Nonce *hexutil.Uint64 `json:"nonce"` Nonce *hexutil.Uint64 `json:"nonce"`
@ -1081,7 +1081,8 @@ type SendTxArgs struct {
// setDefaults is a helper function that fills in default values for unspecified tx fields. // setDefaults is a helper function that fills in default values for unspecified tx fields.
func (args *SendTxArgs) setDefaults(ctx context.Context, b Backend) error { func (args *SendTxArgs) setDefaults(ctx context.Context, b Backend) error {
if args.Gas == nil { if args.Gas == nil {
args.Gas = (*hexutil.Big)(big.NewInt(defaultGas)) args.Gas = new(hexutil.Uint64)
*(*uint64)(args.Gas) = 90000
} }
if args.GasPrice == nil { if args.GasPrice == nil {
price, err := b.SuggestPrice(ctx) price, err := b.SuggestPrice(ctx)
@ -1114,9 +1115,9 @@ func (args *SendTxArgs) toTransaction() *types.Transaction {
input = *args.Input input = *args.Input
} }
if args.To == nil { if args.To == nil {
return types.NewContractCreation(uint64(*args.Nonce), (*big.Int)(args.Value), (*big.Int)(args.Gas), (*big.Int)(args.GasPrice), input) return types.NewContractCreation(uint64(*args.Nonce), (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), input)
} }
return types.NewTransaction(uint64(*args.Nonce), *args.To, (*big.Int)(args.Value), (*big.Int)(args.Gas), (*big.Int)(args.GasPrice), input) return types.NewTransaction(uint64(*args.Nonce), *args.To, (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), input)
} }
// submitTransaction is a helper function that submits tx to txPool and logs a message. // submitTransaction is a helper function that submits tx to txPool and logs a message.
@ -1264,7 +1265,7 @@ func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, err
// Resend accepts an existing transaction and a new gas price and limit. It will remove // Resend accepts an existing transaction and a new gas price and limit. It will remove
// the given transaction from the pool and reinsert it with the new gas price and limit. // the given transaction from the pool and reinsert it with the new gas price and limit.
func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxArgs, gasPrice, gasLimit *hexutil.Big) (common.Hash, error) { func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxArgs, gasPrice *hexutil.Big, gasLimit *hexutil.Uint64) (common.Hash, error) {
if sendArgs.Nonce == nil { if sendArgs.Nonce == nil {
return common.Hash{}, fmt.Errorf("missing transaction nonce in transaction spec") return common.Hash{}, fmt.Errorf("missing transaction nonce in transaction spec")
} }

View File

@ -37,13 +37,14 @@ import (
// Backend interface provides the common API services (that are provided by // Backend interface provides the common API services (that are provided by
// both full and light clients) with access to necessary functions. // both full and light clients) with access to necessary functions.
type Backend interface { type Backend interface {
// general Ethereum API // General Ethereum API
Downloader() *downloader.Downloader Downloader() *downloader.Downloader
ProtocolVersion() int ProtocolVersion() int
SuggestPrice(ctx context.Context) (*big.Int, error) SuggestPrice(ctx context.Context) (*big.Int, error)
ChainDb() ethdb.Database ChainDb() ethdb.Database
EventMux() *event.TypeMux EventMux() *event.TypeMux
AccountManager() *accounts.Manager AccountManager() *accounts.Manager
// BlockChain API // BlockChain API
SetHead(number uint64) SetHead(number uint64)
HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error)

View File

@ -443,16 +443,16 @@ func TestTransactionStatusLes2(t *testing.T) {
signer := types.HomesteadSigner{} signer := types.HomesteadSigner{}
// test error status by sending an underpriced transaction // test error status by sending an underpriced transaction
tx0, _ := types.SignTx(types.NewTransaction(0, acc1Addr, big.NewInt(10000), bigTxGas, nil, nil), signer, testBankKey) tx0, _ := types.SignTx(types.NewTransaction(0, acc1Addr, big.NewInt(10000), params.TxGas, nil, nil), signer, testBankKey)
test(tx0, true, txStatus{Status: core.TxStatusUnknown, Error: core.ErrUnderpriced}) test(tx0, true, txStatus{Status: core.TxStatusUnknown, Error: core.ErrUnderpriced})
tx1, _ := types.SignTx(types.NewTransaction(0, acc1Addr, big.NewInt(10000), bigTxGas, big.NewInt(100000000000), nil), signer, testBankKey) tx1, _ := types.SignTx(types.NewTransaction(0, acc1Addr, big.NewInt(10000), params.TxGas, big.NewInt(100000000000), nil), signer, testBankKey)
test(tx1, false, txStatus{Status: core.TxStatusUnknown}) // query before sending, should be unknown test(tx1, false, txStatus{Status: core.TxStatusUnknown}) // query before sending, should be unknown
test(tx1, true, txStatus{Status: core.TxStatusPending}) // send valid processable tx, should return pending test(tx1, true, txStatus{Status: core.TxStatusPending}) // send valid processable tx, should return pending
test(tx1, true, txStatus{Status: core.TxStatusPending}) // adding it again should not return an error test(tx1, true, txStatus{Status: core.TxStatusPending}) // adding it again should not return an error
tx2, _ := types.SignTx(types.NewTransaction(1, acc1Addr, big.NewInt(10000), bigTxGas, big.NewInt(100000000000), nil), signer, testBankKey) tx2, _ := types.SignTx(types.NewTransaction(1, acc1Addr, big.NewInt(10000), params.TxGas, big.NewInt(100000000000), nil), signer, testBankKey)
tx3, _ := types.SignTx(types.NewTransaction(2, acc1Addr, big.NewInt(10000), bigTxGas, big.NewInt(100000000000), nil), signer, testBankKey) tx3, _ := types.SignTx(types.NewTransaction(2, acc1Addr, big.NewInt(10000), params.TxGas, big.NewInt(100000000000), nil), signer, testBankKey)
// send transactions in the wrong order, tx3 should be queued // send transactions in the wrong order, tx3 should be queued
test(tx3, true, txStatus{Status: core.TxStatusQueued}) test(tx3, true, txStatus{Status: core.TxStatusQueued})
test(tx2, true, txStatus{Status: core.TxStatusPending}) test(tx2, true, txStatus{Status: core.TxStatusPending})

View File

@ -56,8 +56,6 @@ var (
testContractDeployed = uint64(2) testContractDeployed = uint64(2)
testBufLimit = uint64(100) testBufLimit = uint64(100)
bigTxGas = new(big.Int).SetUint64(params.TxGas)
) )
/* /*
@ -81,17 +79,17 @@ func testChainGen(i int, block *core.BlockGen) {
switch i { switch i {
case 0: case 0:
// In block 1, the test bank sends account #1 some ether. // In block 1, the test bank sends account #1 some ether.
tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(10000), bigTxGas, nil, nil), signer, testBankKey) tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil), signer, testBankKey)
block.AddTx(tx) block.AddTx(tx)
case 1: case 1:
// In block 2, the test bank sends some more ether to account #1. // In block 2, the test bank sends some more ether to account #1.
// acc1Addr passes it on to account #2. // acc1Addr passes it on to account #2.
// acc1Addr creates a test contract. // acc1Addr creates a test contract.
tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, testBankKey) tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, testBankKey)
nonce := block.TxNonce(acc1Addr) nonce := block.TxNonce(acc1Addr)
tx2, _ := types.SignTx(types.NewTransaction(nonce, acc2Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, acc1Key) tx2, _ := types.SignTx(types.NewTransaction(nonce, acc2Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, acc1Key)
nonce++ nonce++
tx3, _ := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), big.NewInt(200000), big.NewInt(0), testContractCode), signer, acc1Key) tx3, _ := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), 200000, big.NewInt(0), testContractCode), signer, acc1Key)
testContractAddr = crypto.CreateAddress(acc1Addr, nonce) testContractAddr = crypto.CreateAddress(acc1Addr, nonce)
block.AddTx(tx1) block.AddTx(tx1)
block.AddTx(tx2) block.AddTx(tx2)
@ -101,7 +99,7 @@ func testChainGen(i int, block *core.BlockGen) {
block.SetCoinbase(acc2Addr) block.SetCoinbase(acc2Addr)
block.SetExtra([]byte("yeehaw")) block.SetExtra([]byte("yeehaw"))
data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001") data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001")
tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), testContractAddr, big.NewInt(0), big.NewInt(100000), nil, data), signer, testBankKey) tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), testContractAddr, big.NewInt(0), 100000, nil, data), signer, testBankKey)
block.AddTx(tx) block.AddTx(tx)
case 3: case 3:
// Block 4 includes blocks 2 and 3 as uncle headers (with modified extra data). // Block 4 includes blocks 2 and 3 as uncle headers (with modified extra data).
@ -112,7 +110,7 @@ func testChainGen(i int, block *core.BlockGen) {
b3.Extra = []byte("foo") b3.Extra = []byte("foo")
block.AddUncle(b3) block.AddUncle(b3)
data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002") data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002")
tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), testContractAddr, big.NewInt(0), big.NewInt(100000), nil, data), signer, testBankKey) tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), testContractAddr, big.NewInt(0), 100000, nil, data), signer, testBankKey)
block.AddTx(tx) block.AddTx(tx)
} }
} }

View File

@ -129,13 +129,13 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
from := statedb.GetOrNewStateObject(testBankAddress) from := statedb.GetOrNewStateObject(testBankAddress)
from.SetBalance(math.MaxBig256) from.SetBalance(math.MaxBig256)
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(100000), new(big.Int), data, false)} msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, false)}
context := core.NewEVMContext(msg, header, bc, nil) context := core.NewEVMContext(msg, header, bc, nil)
vmenv := vm.NewEVM(context, statedb, config, vm.Config{}) vmenv := vm.NewEVM(context, statedb, config, vm.Config{})
//vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{}) //vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{})
gp := new(core.GasPool).AddGas(math.MaxBig256) gp := new(core.GasPool).AddGas(math.MaxUint64)
ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp) ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp)
res = append(res, ret...) res = append(res, ret...)
} }
@ -143,10 +143,10 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
header := lc.GetHeaderByHash(bhash) header := lc.GetHeaderByHash(bhash)
state := light.NewState(ctx, header, lc.Odr()) state := light.NewState(ctx, header, lc.Odr())
state.SetBalance(testBankAddress, math.MaxBig256) state.SetBalance(testBankAddress, math.MaxBig256)
msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), big.NewInt(100000), new(big.Int), data, false)} msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, false)}
context := core.NewEVMContext(msg, header, lc, nil) context := core.NewEVMContext(msg, header, lc, nil)
vmenv := vm.NewEVM(context, state, config, vm.Config{}) vmenv := vm.NewEVM(context, state, config, vm.Config{})
gp := new(core.GasPool).AddGas(math.MaxBig256) gp := new(core.GasPool).AddGas(math.MaxUint64)
ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp) ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp)
if state.Error() == nil { if state.Error() == nil {
res = append(res, ret...) res = append(res, ret...)

View File

@ -169,7 +169,7 @@ func (bc *LightChain) SetHead(head uint64) {
} }
// GasLimit returns the gas limit of the current HEAD block. // GasLimit returns the gas limit of the current HEAD block.
func (self *LightChain) GasLimit() *big.Int { func (self *LightChain) GasLimit() uint64 {
self.mu.RLock() self.mu.RLock()
defer self.mu.RUnlock() defer self.mu.RUnlock()

View File

@ -50,8 +50,6 @@ var (
testContractCode = common.Hex2Bytes("606060405260cc8060106000396000f360606040526000357c01000000000000000000000000000000000000000000000000000000009004806360cd2685146041578063c16431b914606b57603f565b005b6055600480803590602001909190505060a9565b6040518082815260200191505060405180910390f35b60886004808035906020019091908035906020019091905050608a565b005b80600060005083606481101560025790900160005b50819055505b5050565b6000600060005082606481101560025790900160005b5054905060c7565b91905056") testContractCode = common.Hex2Bytes("606060405260cc8060106000396000f360606040526000357c01000000000000000000000000000000000000000000000000000000009004806360cd2685146041578063c16431b914606b57603f565b005b6055600480803590602001909190505060a9565b6040518082815260200191505060405180910390f35b60886004808035906020019091908035906020019091905050608a565b005b80600060005083606481101560025790900160005b50819055505b5050565b6000600060005082606481101560025790900160005b5054905060c7565b91905056")
testContractAddr common.Address testContractAddr common.Address
bigTxGas = new(big.Int).SetUint64(params.TxGas)
) )
type testOdr struct { type testOdr struct {
@ -178,10 +176,10 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
// Perform read-only call. // Perform read-only call.
st.SetBalance(testBankAddress, math.MaxBig256) st.SetBalance(testBankAddress, math.MaxBig256)
msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), big.NewInt(1000000), new(big.Int), data, false)} msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 1000000, new(big.Int), data, false)}
context := core.NewEVMContext(msg, header, chain, nil) context := core.NewEVMContext(msg, header, chain, nil)
vmenv := vm.NewEVM(context, st, config, vm.Config{}) vmenv := vm.NewEVM(context, st, config, vm.Config{})
gp := new(core.GasPool).AddGas(math.MaxBig256) gp := new(core.GasPool).AddGas(math.MaxUint64)
ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp) ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp)
res = append(res, ret...) res = append(res, ret...)
if st.Error() != nil { if st.Error() != nil {
@ -196,17 +194,17 @@ func testChainGen(i int, block *core.BlockGen) {
switch i { switch i {
case 0: case 0:
// In block 1, the test bank sends account #1 some ether. // In block 1, the test bank sends account #1 some ether.
tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(10000), bigTxGas, nil, nil), signer, testBankKey) tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil), signer, testBankKey)
block.AddTx(tx) block.AddTx(tx)
case 1: case 1:
// In block 2, the test bank sends some more ether to account #1. // In block 2, the test bank sends some more ether to account #1.
// acc1Addr passes it on to account #2. // acc1Addr passes it on to account #2.
// acc1Addr creates a test contract. // acc1Addr creates a test contract.
tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, testBankKey) tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, testBankKey)
nonce := block.TxNonce(acc1Addr) nonce := block.TxNonce(acc1Addr)
tx2, _ := types.SignTx(types.NewTransaction(nonce, acc2Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, acc1Key) tx2, _ := types.SignTx(types.NewTransaction(nonce, acc2Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, acc1Key)
nonce++ nonce++
tx3, _ := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), big.NewInt(1000000), big.NewInt(0), testContractCode), signer, acc1Key) tx3, _ := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), 1000000, big.NewInt(0), testContractCode), signer, acc1Key)
testContractAddr = crypto.CreateAddress(acc1Addr, nonce) testContractAddr = crypto.CreateAddress(acc1Addr, nonce)
block.AddTx(tx1) block.AddTx(tx1)
block.AddTx(tx2) block.AddTx(tx2)
@ -216,7 +214,7 @@ func testChainGen(i int, block *core.BlockGen) {
block.SetCoinbase(acc2Addr) block.SetCoinbase(acc2Addr)
block.SetExtra([]byte("yeehaw")) block.SetExtra([]byte("yeehaw"))
data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001") data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001")
tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), testContractAddr, big.NewInt(0), big.NewInt(100000), nil, data), signer, testBankKey) tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), testContractAddr, big.NewInt(0), 100000, nil, data), signer, testBankKey)
block.AddTx(tx) block.AddTx(tx)
case 3: case 3:
// Block 4 includes blocks 2 and 3 as uncle headers (with modified extra data). // Block 4 includes blocks 2 and 3 as uncle headers (with modified extra data).
@ -227,7 +225,7 @@ func testChainGen(i int, block *core.BlockGen) {
b3.Extra = []byte("foo") b3.Extra = []byte("foo")
block.AddUncle(b3) block.AddUncle(b3)
data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002") data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002")
tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), testContractAddr, big.NewInt(0), big.NewInt(100000), nil, data), signer, testBankKey) tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), testContractAddr, big.NewInt(0), 100000, nil, data), signer, testBankKey)
block.AddTx(tx) block.AddTx(tx)
} }
} }

View File

@ -358,7 +358,7 @@ func (pool *TxPool) validateTx(ctx context.Context, tx *types.Transaction) error
// Check the transaction doesn't exceed the current // Check the transaction doesn't exceed the current
// block limit gas. // block limit gas.
header := pool.chain.GetHeaderByHash(pool.head) header := pool.chain.GetHeaderByHash(pool.head)
if header.GasLimit.Cmp(tx.Gas()) < 0 { if header.GasLimit < tx.Gas() {
return core.ErrGasLimit return core.ErrGasLimit
} }
@ -376,10 +376,13 @@ func (pool *TxPool) validateTx(ctx context.Context, tx *types.Transaction) error
} }
// Should supply enough intrinsic gas // Should supply enough intrinsic gas
if tx.Gas().Cmp(core.IntrinsicGas(tx.Data(), tx.To() == nil, pool.homestead)) < 0 { gas, err := core.IntrinsicGas(tx.Data(), tx.To() == nil, pool.homestead)
if err != nil {
return err
}
if tx.Gas() < gas {
return core.ErrIntrinsicGas return core.ErrIntrinsicGas
} }
return currentState.Error() return currentState.Error()
} }

View File

@ -77,7 +77,7 @@ func txPoolTestChainGen(i int, block *core.BlockGen) {
func TestTxPool(t *testing.T) { func TestTxPool(t *testing.T) {
for i := range testTx { for i := range testTx {
testTx[i], _ = types.SignTx(types.NewTransaction(uint64(i), acc1Addr, big.NewInt(10000), bigTxGas, nil, nil), types.HomesteadSigner{}, testBankKey) testTx[i], _ = types.SignTx(types.NewTransaction(uint64(i), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil), types.HomesteadSigner{}, testBankKey)
} }
var ( var (

View File

@ -413,7 +413,6 @@ func (self *worker) commitNewWork() {
ParentHash: parent.Hash(), ParentHash: parent.Hash(),
Number: num.Add(num, common.Big1), Number: num.Add(num, common.Big1),
GasLimit: core.CalcGasLimit(parent), GasLimit: core.CalcGasLimit(parent),
GasUsed: new(big.Int),
Extra: self.extra, Extra: self.extra,
Time: big.NewInt(tstamp), Time: big.NewInt(tstamp),
} }
@ -588,7 +587,7 @@ func (env *Work) commitTransactions(mux *event.TypeMux, txs *types.TransactionsB
func (env *Work) commitTransaction(tx *types.Transaction, bc *core.BlockChain, coinbase common.Address, gp *core.GasPool) (error, []*types.Log) { func (env *Work) commitTransaction(tx *types.Transaction, bc *core.BlockChain, coinbase common.Address, gp *core.GasPool) (error, []*types.Log) {
snap := env.state.Snapshot() snap := env.state.Snapshot()
receipt, _, err := core.ApplyTransaction(env.config, bc, &coinbase, gp, env.state, env.header, tx, env.header.GasUsed, vm.Config{}) receipt, _, err := core.ApplyTransaction(env.config, bc, &coinbase, gp, env.state, env.header, tx, &env.header.GasUsed, vm.Config{})
if err != nil { if err != nil {
env.state.RevertToSnapshot(snap) env.state.RevertToSnapshot(snap)
return err, nil return err, nil

View File

@ -77,7 +77,7 @@ func (opts *TransactOpts) GetFrom() *Address { return &Address{opts.opts.From
func (opts *TransactOpts) GetNonce() int64 { return opts.opts.Nonce.Int64() } func (opts *TransactOpts) GetNonce() int64 { return opts.opts.Nonce.Int64() }
func (opts *TransactOpts) GetValue() *BigInt { return &BigInt{opts.opts.Value} } func (opts *TransactOpts) GetValue() *BigInt { return &BigInt{opts.opts.Value} }
func (opts *TransactOpts) GetGasPrice() *BigInt { return &BigInt{opts.opts.GasPrice} } func (opts *TransactOpts) GetGasPrice() *BigInt { return &BigInt{opts.opts.GasPrice} }
func (opts *TransactOpts) GetGasLimit() int64 { return opts.opts.GasLimit.Int64() } func (opts *TransactOpts) GetGasLimit() int64 { return int64(opts.opts.GasLimit) }
// GetSigner cannot be reliably implemented without identity preservation (https://github.com/golang/go/issues/16876) // GetSigner cannot be reliably implemented without identity preservation (https://github.com/golang/go/issues/16876)
// func (opts *TransactOpts) GetSigner() Signer { return &signer{opts.opts.Signer} } // func (opts *TransactOpts) GetSigner() Signer { return &signer{opts.opts.Signer} }
@ -99,7 +99,7 @@ func (opts *TransactOpts) SetSigner(s Signer) {
} }
func (opts *TransactOpts) SetValue(value *BigInt) { opts.opts.Value = value.bigint } func (opts *TransactOpts) SetValue(value *BigInt) { opts.opts.Value = value.bigint }
func (opts *TransactOpts) SetGasPrice(price *BigInt) { opts.opts.GasPrice = price.bigint } func (opts *TransactOpts) SetGasPrice(price *BigInt) { opts.opts.GasPrice = price.bigint }
func (opts *TransactOpts) SetGasLimit(limit int64) { opts.opts.GasLimit = big.NewInt(limit) } func (opts *TransactOpts) SetGasLimit(limit int64) { opts.opts.GasLimit = uint64(limit) }
func (opts *TransactOpts) SetContext(context *Context) { opts.opts.Context = context.context } func (opts *TransactOpts) SetContext(context *Context) { opts.opts.Context = context.context }
// BoundContract is the base wrapper object that reflects a contract on the // BoundContract is the base wrapper object that reflects a contract on the

View File

@ -298,9 +298,9 @@ func (ec *EthereumClient) SuggestGasPrice(ctx *Context) (price *BigInt, _ error)
// the current pending state of the backend blockchain. There is no guarantee that this is // the current pending state of the backend blockchain. There is no guarantee that this is
// the true gas limit requirement as other transactions may be added or removed by miners, // the true gas limit requirement as other transactions may be added or removed by miners,
// but it should provide a basis for setting a reasonable default. // but it should provide a basis for setting a reasonable default.
func (ec *EthereumClient) EstimateGas(ctx *Context, msg *CallMsg) (gas *BigInt, _ error) { func (ec *EthereumClient) EstimateGas(ctx *Context, msg *CallMsg) (gas int64, _ error) {
rawGas, err := ec.client.EstimateGas(ctx.context, msg.msg) rawGas, err := ec.client.EstimateGas(ctx.context, msg.msg)
return &BigInt{rawGas}, err return int64(rawGas), err
} }
// SendTransaction injects a signed transaction into the pending pool for execution. // SendTransaction injects a signed transaction into the pending pool for execution.

View File

@ -20,7 +20,6 @@ package geth
import ( import (
"errors" "errors"
"math/big"
ethereum "github.com/ethereum/go-ethereum" ethereum "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -49,7 +48,7 @@ func NewCallMsg() *CallMsg {
} }
func (msg *CallMsg) GetFrom() *Address { return &Address{msg.msg.From} } func (msg *CallMsg) GetFrom() *Address { return &Address{msg.msg.From} }
func (msg *CallMsg) GetGas() int64 { return msg.msg.Gas.Int64() } func (msg *CallMsg) GetGas() int64 { return int64(msg.msg.Gas) }
func (msg *CallMsg) GetGasPrice() *BigInt { return &BigInt{msg.msg.GasPrice} } func (msg *CallMsg) GetGasPrice() *BigInt { return &BigInt{msg.msg.GasPrice} }
func (msg *CallMsg) GetValue() *BigInt { return &BigInt{msg.msg.Value} } func (msg *CallMsg) GetValue() *BigInt { return &BigInt{msg.msg.Value} }
func (msg *CallMsg) GetData() []byte { return msg.msg.Data } func (msg *CallMsg) GetData() []byte { return msg.msg.Data }
@ -61,7 +60,7 @@ func (msg *CallMsg) GetTo() *Address {
} }
func (msg *CallMsg) SetFrom(address *Address) { msg.msg.From = address.address } func (msg *CallMsg) SetFrom(address *Address) { msg.msg.From = address.address }
func (msg *CallMsg) SetGas(gas int64) { msg.msg.Gas = big.NewInt(gas) } func (msg *CallMsg) SetGas(gas int64) { msg.msg.Gas = uint64(gas) }
func (msg *CallMsg) SetGasPrice(price *BigInt) { msg.msg.GasPrice = price.bigint } func (msg *CallMsg) SetGasPrice(price *BigInt) { msg.msg.GasPrice = price.bigint }
func (msg *CallMsg) SetValue(value *BigInt) { msg.msg.Value = value.bigint } func (msg *CallMsg) SetValue(value *BigInt) { msg.msg.Value = value.bigint }
func (msg *CallMsg) SetData(data []byte) { msg.msg.Data = common.CopyBytes(data) } func (msg *CallMsg) SetData(data []byte) { msg.msg.Data = common.CopyBytes(data) }

View File

@ -112,8 +112,8 @@ func (h *Header) GetReceiptHash() *Hash { return &Hash{h.header.ReceiptHash} }
func (h *Header) GetBloom() *Bloom { return &Bloom{h.header.Bloom} } func (h *Header) GetBloom() *Bloom { return &Bloom{h.header.Bloom} }
func (h *Header) GetDifficulty() *BigInt { return &BigInt{h.header.Difficulty} } func (h *Header) GetDifficulty() *BigInt { return &BigInt{h.header.Difficulty} }
func (h *Header) GetNumber() int64 { return h.header.Number.Int64() } func (h *Header) GetNumber() int64 { return h.header.Number.Int64() }
func (h *Header) GetGasLimit() int64 { return h.header.GasLimit.Int64() } func (h *Header) GetGasLimit() int64 { return int64(h.header.GasLimit) }
func (h *Header) GetGasUsed() int64 { return h.header.GasUsed.Int64() } func (h *Header) GetGasUsed() int64 { return int64(h.header.GasUsed) }
func (h *Header) GetTime() int64 { return h.header.Time.Int64() } func (h *Header) GetTime() int64 { return h.header.Time.Int64() }
func (h *Header) GetExtra() []byte { return h.header.Extra } func (h *Header) GetExtra() []byte { return h.header.Extra }
func (h *Header) GetMixDigest() *Hash { return &Hash{h.header.MixDigest} } func (h *Header) GetMixDigest() *Hash { return &Hash{h.header.MixDigest} }
@ -189,8 +189,8 @@ func (b *Block) GetReceiptHash() *Hash { return &Hash{b.block.ReceiptHash()} }
func (b *Block) GetBloom() *Bloom { return &Bloom{b.block.Bloom()} } func (b *Block) GetBloom() *Bloom { return &Bloom{b.block.Bloom()} }
func (b *Block) GetDifficulty() *BigInt { return &BigInt{b.block.Difficulty()} } func (b *Block) GetDifficulty() *BigInt { return &BigInt{b.block.Difficulty()} }
func (b *Block) GetNumber() int64 { return b.block.Number().Int64() } func (b *Block) GetNumber() int64 { return b.block.Number().Int64() }
func (b *Block) GetGasLimit() int64 { return b.block.GasLimit().Int64() } func (b *Block) GetGasLimit() int64 { return int64(b.block.GasLimit()) }
func (b *Block) GetGasUsed() int64 { return b.block.GasUsed().Int64() } func (b *Block) GetGasUsed() int64 { return int64(b.block.GasUsed()) }
func (b *Block) GetTime() int64 { return b.block.Time().Int64() } func (b *Block) GetTime() int64 { return b.block.Time().Int64() }
func (b *Block) GetExtra() []byte { return b.block.Extra() } func (b *Block) GetExtra() []byte { return b.block.Extra() }
func (b *Block) GetMixDigest() *Hash { return &Hash{b.block.MixDigest()} } func (b *Block) GetMixDigest() *Hash { return &Hash{b.block.MixDigest()} }
@ -212,8 +212,8 @@ type Transaction struct {
} }
// NewTransaction creates a new transaction with the given properties. // NewTransaction creates a new transaction with the given properties.
func NewTransaction(nonce int64, to *Address, amount, gasLimit, gasPrice *BigInt, data []byte) *Transaction { func NewTransaction(nonce int64, to *Address, amount *BigInt, gasLimit int64, gasPrice *BigInt, data []byte) *Transaction {
return &Transaction{types.NewTransaction(uint64(nonce), to.address, amount.bigint, gasLimit.bigint, gasPrice.bigint, common.CopyBytes(data))} return &Transaction{types.NewTransaction(uint64(nonce), to.address, amount.bigint, uint64(gasLimit), gasPrice.bigint, common.CopyBytes(data))}
} }
// NewTransactionFromRLP parses a transaction from an RLP data dump. // NewTransactionFromRLP parses a transaction from an RLP data dump.
@ -256,7 +256,7 @@ func (tx *Transaction) String() string {
} }
func (tx *Transaction) GetData() []byte { return tx.tx.Data() } func (tx *Transaction) GetData() []byte { return tx.tx.Data() }
func (tx *Transaction) GetGas() int64 { return tx.tx.Gas().Int64() } func (tx *Transaction) GetGas() int64 { return int64(tx.tx.Gas()) }
func (tx *Transaction) GetGasPrice() *BigInt { return &BigInt{tx.tx.GasPrice()} } func (tx *Transaction) GetGasPrice() *BigInt { return &BigInt{tx.tx.GasPrice()} }
func (tx *Transaction) GetValue() *BigInt { return &BigInt{tx.tx.Value()} } func (tx *Transaction) GetValue() *BigInt { return &BigInt{tx.tx.Value()} }
func (tx *Transaction) GetNonce() int64 { return int64(tx.tx.Nonce()) } func (tx *Transaction) GetNonce() int64 { return int64(tx.tx.Nonce()) }
@ -353,10 +353,10 @@ func (r *Receipt) String() string {
return r.receipt.String() return r.receipt.String()
} }
func (r *Receipt) GetPostState() []byte { return r.receipt.PostState } func (r *Receipt) GetPostState() []byte { return r.receipt.PostState }
func (r *Receipt) GetCumulativeGasUsed() *BigInt { return &BigInt{r.receipt.CumulativeGasUsed} } func (r *Receipt) GetCumulativeGasUsed() int64 { return int64(r.receipt.CumulativeGasUsed) }
func (r *Receipt) GetBloom() *Bloom { return &Bloom{r.receipt.Bloom} } func (r *Receipt) GetBloom() *Bloom { return &Bloom{r.receipt.Bloom} }
func (r *Receipt) GetLogs() *Logs { return &Logs{r.receipt.Logs} } func (r *Receipt) GetLogs() *Logs { return &Logs{r.receipt.Logs} }
func (r *Receipt) GetTxHash() *Hash { return &Hash{r.receipt.TxHash} } func (r *Receipt) GetTxHash() *Hash { return &Hash{r.receipt.TxHash} }
func (r *Receipt) GetContractAddress() *Address { return &Address{r.receipt.ContractAddress} } func (r *Receipt) GetContractAddress() *Address { return &Address{r.receipt.ContractAddress} }
func (r *Receipt) GetGasUsed() *BigInt { return &BigInt{r.receipt.GasUsed} } func (r *Receipt) GetGasUsed() int64 { return int64(r.receipt.GasUsed) }

View File

@ -18,7 +18,15 @@ package params
import "math/big" import "math/big"
var (
TargetGasLimit uint64 = GenesisGasLimit // The artificial target
)
const ( const (
GasLimitBoundDivisor uint64 = 1024 // The bound divisor of the gas limit, used in update calculations.
MinGasLimit uint64 = 5000 // Minimum the gas limit may ever be.
GenesisGasLimit uint64 = 4712388 // Gas limit of the Genesis block.
MaximumExtraDataSize uint64 = 32 // Maximum size extra data may be after Genesis. MaximumExtraDataSize uint64 = 32 // Maximum size extra data may be after Genesis.
ExpByteGas uint64 = 10 // Times ceil(log256(exponent)) for the EXP instruction. ExpByteGas uint64 = 10 // Times ceil(log256(exponent)) for the EXP instruction.
SloadGas uint64 = 50 // Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added. SloadGas uint64 = 50 // Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added.
@ -72,12 +80,8 @@ const (
) )
var ( var (
GasLimitBoundDivisor = big.NewInt(1024) // The bound divisor of the gas limit, used in update calculations. DifficultyBoundDivisor = big.NewInt(2048) // The bound divisor of the difficulty, used in the update calculations.
MinGasLimit = big.NewInt(5000) // Minimum the gas limit may ever be. GenesisDifficulty = big.NewInt(131072) // Difficulty of the Genesis block.
GenesisGasLimit = big.NewInt(4712388) // Gas limit of the Genesis block. MinimumDifficulty = big.NewInt(131072) // The minimum that the difficulty may ever be.
TargetGasLimit = new(big.Int).Set(GenesisGasLimit) // The artificial target DurationLimit = big.NewInt(13) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not.
DifficultyBoundDivisor = big.NewInt(2048) // The bound divisor of the difficulty, used in the update calculations.
GenesisDifficulty = big.NewInt(131072) // Difficulty of the Genesis block.
MinimumDifficulty = big.NewInt(131072) // The minimum that the difficulty may ever be.
DurationLimit = big.NewInt(13) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not.
) )

View File

@ -77,8 +77,8 @@ type btHeader struct {
UncleHash common.Hash UncleHash common.Hash
ExtraData []byte ExtraData []byte
Difficulty *big.Int Difficulty *big.Int
GasLimit *big.Int GasLimit uint64
GasUsed *big.Int GasUsed uint64
Timestamp *big.Int Timestamp *big.Int
} }
@ -86,8 +86,8 @@ type btHeaderMarshaling struct {
ExtraData hexutil.Bytes ExtraData hexutil.Bytes
Number *math.HexOrDecimal256 Number *math.HexOrDecimal256
Difficulty *math.HexOrDecimal256 Difficulty *math.HexOrDecimal256
GasLimit *math.HexOrDecimal256 GasLimit *math.HexOrDecimal64
GasUsed *math.HexOrDecimal256 GasUsed *math.HexOrDecimal64
Timestamp *math.HexOrDecimal256 Timestamp *math.HexOrDecimal256
} }
@ -141,8 +141,8 @@ func (t *BlockTest) genesis(config *params.ChainConfig) *core.Genesis {
Timestamp: t.json.Genesis.Timestamp.Uint64(), Timestamp: t.json.Genesis.Timestamp.Uint64(),
ParentHash: t.json.Genesis.ParentHash, ParentHash: t.json.Genesis.ParentHash,
ExtraData: t.json.Genesis.ExtraData, ExtraData: t.json.Genesis.ExtraData,
GasLimit: t.json.Genesis.GasLimit.Uint64(), GasLimit: t.json.Genesis.GasLimit,
GasUsed: t.json.Genesis.GasUsed.Uint64(), GasUsed: t.json.Genesis.GasUsed,
Difficulty: t.json.Genesis.Difficulty, Difficulty: t.json.Genesis.Difficulty,
Mixhash: t.json.Genesis.MixHash, Mixhash: t.json.Genesis.MixHash,
Coinbase: t.json.Genesis.Coinbase, Coinbase: t.json.Genesis.Coinbase,
@ -234,11 +234,11 @@ func validateHeader(h *btHeader, h2 *types.Header) error {
if h.Difficulty.Cmp(h2.Difficulty) != 0 { if h.Difficulty.Cmp(h2.Difficulty) != 0 {
return fmt.Errorf("Difficulty: want: %v have: %v", h.Difficulty, h2.Difficulty) return fmt.Errorf("Difficulty: want: %v have: %v", h.Difficulty, h2.Difficulty)
} }
if h.GasLimit.Cmp(h2.GasLimit) != 0 { if h.GasLimit != h2.GasLimit {
return fmt.Errorf("GasLimit: want: %v have: %v", h.GasLimit, h2.GasLimit) return fmt.Errorf("GasLimit: want: %d have: %d", h.GasLimit, h2.GasLimit)
} }
if h.GasUsed.Cmp(h2.GasUsed) != 0 { if h.GasUsed != h2.GasUsed {
return fmt.Errorf("GasUsed: want: %v have: %v", h.GasUsed, h2.GasUsed) return fmt.Errorf("GasUsed: want: %d have: %d", h.GasUsed, h2.GasUsed)
} }
if h.Timestamp.Cmp(h2.Time) != 0 { if h.Timestamp.Cmp(h2.Time) != 0 {
return fmt.Errorf("Timestamp: want: %v have: %v", h.Timestamp, h2.Time) return fmt.Errorf("Timestamp: want: %v have: %v", h.Timestamp, h2.Time)

View File

@ -29,8 +29,8 @@ func (b btHeader) MarshalJSON() ([]byte, error) {
UncleHash common.Hash UncleHash common.Hash
ExtraData hexutil.Bytes ExtraData hexutil.Bytes
Difficulty *math.HexOrDecimal256 Difficulty *math.HexOrDecimal256
GasLimit *math.HexOrDecimal256 GasLimit math.HexOrDecimal64
GasUsed *math.HexOrDecimal256 GasUsed math.HexOrDecimal64
Timestamp *math.HexOrDecimal256 Timestamp *math.HexOrDecimal256
} }
var enc btHeader var enc btHeader
@ -47,8 +47,8 @@ func (b btHeader) MarshalJSON() ([]byte, error) {
enc.UncleHash = b.UncleHash enc.UncleHash = b.UncleHash
enc.ExtraData = b.ExtraData enc.ExtraData = b.ExtraData
enc.Difficulty = (*math.HexOrDecimal256)(b.Difficulty) enc.Difficulty = (*math.HexOrDecimal256)(b.Difficulty)
enc.GasLimit = (*math.HexOrDecimal256)(b.GasLimit) enc.GasLimit = (math.HexOrDecimal64)(b.GasLimit)
enc.GasUsed = (*math.HexOrDecimal256)(b.GasUsed) enc.GasUsed = (math.HexOrDecimal64)(b.GasUsed)
enc.Timestamp = (*math.HexOrDecimal256)(b.Timestamp) enc.Timestamp = (*math.HexOrDecimal256)(b.Timestamp)
return json.Marshal(&enc) return json.Marshal(&enc)
} }
@ -68,8 +68,8 @@ func (b *btHeader) UnmarshalJSON(input []byte) error {
UncleHash *common.Hash UncleHash *common.Hash
ExtraData hexutil.Bytes ExtraData hexutil.Bytes
Difficulty *math.HexOrDecimal256 Difficulty *math.HexOrDecimal256
GasLimit *math.HexOrDecimal256 GasLimit *math.HexOrDecimal64
GasUsed *math.HexOrDecimal256 GasUsed *math.HexOrDecimal64
Timestamp *math.HexOrDecimal256 Timestamp *math.HexOrDecimal256
} }
var dec btHeader var dec btHeader
@ -116,10 +116,10 @@ func (b *btHeader) UnmarshalJSON(input []byte) error {
b.Difficulty = (*big.Int)(dec.Difficulty) b.Difficulty = (*big.Int)(dec.Difficulty)
} }
if dec.GasLimit != nil { if dec.GasLimit != nil {
b.GasLimit = (*big.Int)(dec.GasLimit) b.GasLimit = uint64(*dec.GasLimit)
} }
if dec.GasUsed != nil { if dec.GasUsed != nil {
b.GasUsed = (*big.Int)(dec.GasUsed) b.GasUsed = uint64(*dec.GasUsed)
} }
if dec.Timestamp != nil { if dec.Timestamp != nil {
b.Timestamp = (*big.Int)(dec.Timestamp) b.Timestamp = (*big.Int)(dec.Timestamp)

View File

@ -17,14 +17,14 @@ func (s stEnv) MarshalJSON() ([]byte, error) {
type stEnv struct { type stEnv struct {
Coinbase common.UnprefixedAddress `json:"currentCoinbase" gencodec:"required"` Coinbase common.UnprefixedAddress `json:"currentCoinbase" gencodec:"required"`
Difficulty *math.HexOrDecimal256 `json:"currentDifficulty" gencodec:"required"` Difficulty *math.HexOrDecimal256 `json:"currentDifficulty" gencodec:"required"`
GasLimit *math.HexOrDecimal256 `json:"currentGasLimit" gencodec:"required"` GasLimit math.HexOrDecimal64 `json:"currentGasLimit" gencodec:"required"`
Number math.HexOrDecimal64 `json:"currentNumber" gencodec:"required"` Number math.HexOrDecimal64 `json:"currentNumber" gencodec:"required"`
Timestamp math.HexOrDecimal64 `json:"currentTimestamp" gencodec:"required"` Timestamp math.HexOrDecimal64 `json:"currentTimestamp" gencodec:"required"`
} }
var enc stEnv var enc stEnv
enc.Coinbase = common.UnprefixedAddress(s.Coinbase) enc.Coinbase = common.UnprefixedAddress(s.Coinbase)
enc.Difficulty = (*math.HexOrDecimal256)(s.Difficulty) enc.Difficulty = (*math.HexOrDecimal256)(s.Difficulty)
enc.GasLimit = (*math.HexOrDecimal256)(s.GasLimit) enc.GasLimit = math.HexOrDecimal64(s.GasLimit)
enc.Number = math.HexOrDecimal64(s.Number) enc.Number = math.HexOrDecimal64(s.Number)
enc.Timestamp = math.HexOrDecimal64(s.Timestamp) enc.Timestamp = math.HexOrDecimal64(s.Timestamp)
return json.Marshal(&enc) return json.Marshal(&enc)
@ -34,7 +34,7 @@ func (s *stEnv) UnmarshalJSON(input []byte) error {
type stEnv struct { type stEnv struct {
Coinbase *common.UnprefixedAddress `json:"currentCoinbase" gencodec:"required"` Coinbase *common.UnprefixedAddress `json:"currentCoinbase" gencodec:"required"`
Difficulty *math.HexOrDecimal256 `json:"currentDifficulty" gencodec:"required"` Difficulty *math.HexOrDecimal256 `json:"currentDifficulty" gencodec:"required"`
GasLimit *math.HexOrDecimal256 `json:"currentGasLimit" gencodec:"required"` GasLimit *math.HexOrDecimal64 `json:"currentGasLimit" gencodec:"required"`
Number *math.HexOrDecimal64 `json:"currentNumber" gencodec:"required"` Number *math.HexOrDecimal64 `json:"currentNumber" gencodec:"required"`
Timestamp *math.HexOrDecimal64 `json:"currentTimestamp" gencodec:"required"` Timestamp *math.HexOrDecimal64 `json:"currentTimestamp" gencodec:"required"`
} }
@ -53,7 +53,7 @@ func (s *stEnv) UnmarshalJSON(input []byte) error {
if dec.GasLimit == nil { if dec.GasLimit == nil {
return errors.New("missing required field 'currentGasLimit' for stEnv") return errors.New("missing required field 'currentGasLimit' for stEnv")
} }
s.GasLimit = (*big.Int)(dec.GasLimit) s.GasLimit = uint64(*dec.GasLimit)
if dec.Number == nil { if dec.Number == nil {
return errors.New("missing required field 'currentNumber' for stEnv") return errors.New("missing required field 'currentNumber' for stEnv")
} }

View File

@ -17,7 +17,7 @@ var _ = (*ttTransactionMarshaling)(nil)
func (t ttTransaction) MarshalJSON() ([]byte, error) { func (t ttTransaction) MarshalJSON() ([]byte, error) {
type ttTransaction struct { type ttTransaction struct {
Data hexutil.Bytes `gencodec:"required"` Data hexutil.Bytes `gencodec:"required"`
GasLimit *math.HexOrDecimal256 `gencodec:"required"` GasLimit math.HexOrDecimal64 `gencodec:"required"`
GasPrice *math.HexOrDecimal256 `gencodec:"required"` GasPrice *math.HexOrDecimal256 `gencodec:"required"`
Nonce math.HexOrDecimal64 `gencodec:"required"` Nonce math.HexOrDecimal64 `gencodec:"required"`
Value *math.HexOrDecimal256 `gencodec:"required"` Value *math.HexOrDecimal256 `gencodec:"required"`
@ -28,7 +28,7 @@ func (t ttTransaction) MarshalJSON() ([]byte, error) {
} }
var enc ttTransaction var enc ttTransaction
enc.Data = t.Data enc.Data = t.Data
enc.GasLimit = (*math.HexOrDecimal256)(t.GasLimit) enc.GasLimit = (math.HexOrDecimal64)(t.GasLimit)
enc.GasPrice = (*math.HexOrDecimal256)(t.GasPrice) enc.GasPrice = (*math.HexOrDecimal256)(t.GasPrice)
enc.Nonce = math.HexOrDecimal64(t.Nonce) enc.Nonce = math.HexOrDecimal64(t.Nonce)
enc.Value = (*math.HexOrDecimal256)(t.Value) enc.Value = (*math.HexOrDecimal256)(t.Value)
@ -42,7 +42,7 @@ func (t ttTransaction) MarshalJSON() ([]byte, error) {
func (t *ttTransaction) UnmarshalJSON(input []byte) error { func (t *ttTransaction) UnmarshalJSON(input []byte) error {
type ttTransaction struct { type ttTransaction struct {
Data hexutil.Bytes `gencodec:"required"` Data hexutil.Bytes `gencodec:"required"`
GasLimit *math.HexOrDecimal256 `gencodec:"required"` GasLimit *math.HexOrDecimal64 `gencodec:"required"`
GasPrice *math.HexOrDecimal256 `gencodec:"required"` GasPrice *math.HexOrDecimal256 `gencodec:"required"`
Nonce *math.HexOrDecimal64 `gencodec:"required"` Nonce *math.HexOrDecimal64 `gencodec:"required"`
Value *math.HexOrDecimal256 `gencodec:"required"` Value *math.HexOrDecimal256 `gencodec:"required"`
@ -62,7 +62,7 @@ func (t *ttTransaction) UnmarshalJSON(input []byte) error {
if dec.GasLimit == nil { if dec.GasLimit == nil {
return errors.New("missing required field 'gasLimit' for ttTransaction") return errors.New("missing required field 'gasLimit' for ttTransaction")
} }
t.GasLimit = (*big.Int)(dec.GasLimit) t.GasLimit = uint64(*dec.GasLimit)
if dec.GasPrice == nil { if dec.GasPrice == nil {
return errors.New("missing required field 'gasPrice' for ttTransaction") return errors.New("missing required field 'gasPrice' for ttTransaction")
} }

View File

@ -76,7 +76,7 @@ type stPostState struct {
type stEnv struct { type stEnv struct {
Coinbase common.Address `json:"currentCoinbase" gencodec:"required"` Coinbase common.Address `json:"currentCoinbase" gencodec:"required"`
Difficulty *big.Int `json:"currentDifficulty" gencodec:"required"` Difficulty *big.Int `json:"currentDifficulty" gencodec:"required"`
GasLimit *big.Int `json:"currentGasLimit" gencodec:"required"` GasLimit uint64 `json:"currentGasLimit" gencodec:"required"`
Number uint64 `json:"currentNumber" gencodec:"required"` Number uint64 `json:"currentNumber" gencodec:"required"`
Timestamp uint64 `json:"currentTimestamp" gencodec:"required"` Timestamp uint64 `json:"currentTimestamp" gencodec:"required"`
} }
@ -84,7 +84,7 @@ type stEnv struct {
type stEnvMarshaling struct { type stEnvMarshaling struct {
Coinbase common.UnprefixedAddress Coinbase common.UnprefixedAddress
Difficulty *math.HexOrDecimal256 Difficulty *math.HexOrDecimal256
GasLimit *math.HexOrDecimal256 GasLimit math.HexOrDecimal64
Number math.HexOrDecimal64 Number math.HexOrDecimal64
Timestamp math.HexOrDecimal64 Timestamp math.HexOrDecimal64
} }
@ -180,7 +180,7 @@ func (t *StateTest) genesis(config *params.ChainConfig) *core.Genesis {
Config: config, Config: config,
Coinbase: t.json.Env.Coinbase, Coinbase: t.json.Env.Coinbase,
Difficulty: t.json.Env.Difficulty, Difficulty: t.json.Env.Difficulty,
GasLimit: t.json.Env.GasLimit.Uint64(), GasLimit: t.json.Env.GasLimit,
Number: t.json.Env.Number, Number: t.json.Env.Number,
Timestamp: t.json.Env.Timestamp, Timestamp: t.json.Env.Timestamp,
Alloc: t.json.Pre, Alloc: t.json.Pre,
@ -233,7 +233,7 @@ func (tx *stTransaction) toMessage(ps stPostState) (core.Message, error) {
return nil, fmt.Errorf("invalid tx data %q", dataHex) return nil, fmt.Errorf("invalid tx data %q", dataHex)
} }
msg := types.NewMessage(from, to, tx.Nonce, value, new(big.Int).SetUint64(gasLimit), tx.GasPrice, data, true) msg := types.NewMessage(from, to, tx.Nonce, value, gasLimit, tx.GasPrice, data, true)
return msg, nil return msg, nil
} }

View File

@ -46,7 +46,7 @@ type ttJSON struct {
type ttTransaction struct { type ttTransaction struct {
Data []byte `gencodec:"required"` Data []byte `gencodec:"required"`
GasLimit *big.Int `gencodec:"required"` GasLimit uint64 `gencodec:"required"`
GasPrice *big.Int `gencodec:"required"` GasPrice *big.Int `gencodec:"required"`
Nonce uint64 `gencodec:"required"` Nonce uint64 `gencodec:"required"`
Value *big.Int `gencodec:"required"` Value *big.Int `gencodec:"required"`
@ -58,7 +58,7 @@ type ttTransaction struct {
type ttTransactionMarshaling struct { type ttTransactionMarshaling struct {
Data hexutil.Bytes Data hexutil.Bytes
GasLimit *math.HexOrDecimal256 GasLimit math.HexOrDecimal64
GasPrice *math.HexOrDecimal256 GasPrice *math.HexOrDecimal256
Nonce math.HexOrDecimal64 Nonce math.HexOrDecimal64
Value *math.HexOrDecimal256 Value *math.HexOrDecimal256
@ -100,8 +100,8 @@ func (tt *ttTransaction) verify(signer types.Signer, tx *types.Transaction) erro
if !bytes.Equal(tx.Data(), tt.Data) { if !bytes.Equal(tx.Data(), tt.Data) {
return fmt.Errorf("Tx input data mismatch: got %x want %x", tx.Data(), tt.Data) return fmt.Errorf("Tx input data mismatch: got %x want %x", tx.Data(), tt.Data)
} }
if tx.Gas().Cmp(tt.GasLimit) != 0 { if tx.Gas() != tt.GasLimit {
return fmt.Errorf("GasLimit mismatch: got %v, want %v", tx.Gas(), tt.GasLimit) return fmt.Errorf("GasLimit mismatch: got %d, want %d", tx.Gas(), tt.GasLimit)
} }
if tx.GasPrice().Cmp(tt.GasPrice) != 0 { if tx.GasPrice().Cmp(tt.GasPrice) != 0 {
return fmt.Errorf("GasPrice mismatch: got %v, want %v", tx.GasPrice(), tt.GasPrice) return fmt.Errorf("GasPrice mismatch: got %v, want %v", tx.GasPrice(), tt.GasPrice)