mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 09:23:48 +00:00
Merge pull request #4 from ethereum/master
Take latest changes from go-ethereum
This commit is contained in:
commit
50ad80e946
140 changed files with 2035 additions and 1039 deletions
|
|
@ -87,13 +87,13 @@ matrix:
|
||||||
- sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-arm-linux-gnueabihf libc6-dev-armhf-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross
|
- sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-arm-linux-gnueabihf libc6-dev-armhf-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross
|
||||||
- sudo ln -s /usr/include/asm-generic /usr/include/asm
|
- sudo ln -s /usr/include/asm-generic /usr/include/asm
|
||||||
|
|
||||||
- GOARM=5 CC=arm-linux-gnueabi-gcc go run build/ci.go install -arch arm
|
- GOARM=5 go run build/ci.go install -arch arm -cc arm-linux-gnueabi-gcc
|
||||||
- GOARM=5 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
- GOARM=5 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
||||||
- GOARM=6 CC=arm-linux-gnueabi-gcc go run build/ci.go install -arch arm
|
- GOARM=6 go run build/ci.go install -arch arm -cc arm-linux-gnueabi-gcc
|
||||||
- GOARM=6 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
- GOARM=6 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
||||||
- GOARM=7 CC=arm-linux-gnueabihf-gcc go run build/ci.go install -arch arm
|
- GOARM=7 go run build/ci.go install -arch arm -cc arm-linux-gnueabihf-gcc
|
||||||
- GOARM=7 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
- GOARM=7 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
||||||
- CC=aarch64-linux-gnu-gcc go run build/ci.go install -arch arm64
|
- go run build/ci.go install -arch arm64 -cc aarch64-linux-gnu-gcc
|
||||||
- go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
- go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
||||||
|
|
||||||
# This builder does the Linux Azure MIPS xgo uploads
|
# This builder does the Linux Azure MIPS xgo uploads
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,20 @@ func (arguments Arguments) unpackTuple(v interface{}, output []byte) error {
|
||||||
if err := requireUnpackKind(value, typ, kind, arguments); err != nil {
|
if err := requireUnpackKind(value, typ, kind, arguments); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// If the output interface is a struct, make sure names don't collide
|
||||||
|
if kind == reflect.Struct {
|
||||||
|
exists := make(map[string]bool)
|
||||||
|
for _, arg := range arguments {
|
||||||
|
field := capitalise(arg.Name)
|
||||||
|
if field == "" {
|
||||||
|
return fmt.Errorf("abi: purely underscored output cannot unpack to struct")
|
||||||
|
}
|
||||||
|
if exists[field] {
|
||||||
|
return fmt.Errorf("abi: multiple outputs mapping to the same struct field '%s'", field)
|
||||||
|
}
|
||||||
|
exists[field] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
// `i` counts the nonindexed arguments.
|
// `i` counts the nonindexed arguments.
|
||||||
// `j` counts the number of complex types.
|
// `j` counts the number of complex types.
|
||||||
// both `i` and `j` are used to to correctly compute `data` offset.
|
// both `i` and `j` are used to to correctly compute `data` offset.
|
||||||
|
|
@ -123,10 +137,10 @@ func (arguments Arguments) unpackTuple(v interface{}, output []byte) error {
|
||||||
|
|
||||||
switch kind {
|
switch kind {
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
|
name := capitalise(arg.Name)
|
||||||
for j := 0; j < typ.NumField(); j++ {
|
for j := 0; j < typ.NumField(); j++ {
|
||||||
field := typ.Field(j)
|
|
||||||
// TODO read tags: `abi:"fieldName"`
|
// TODO read tags: `abi:"fieldName"`
|
||||||
if field.Name == strings.ToUpper(arg.Name[:1])+arg.Name[1:] {
|
if typ.Field(j).Name == name {
|
||||||
if err := set(value.Field(j), reflectValue, arg); err != nil {
|
if err := set(value.Field(j), reflectValue, arg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -188,7 +202,7 @@ func (arguments Arguments) Pack(args ...interface{}) ([]byte, error) {
|
||||||
inputOffset := 0
|
inputOffset := 0
|
||||||
for _, abiArg := range abiArgs {
|
for _, abiArg := range abiArgs {
|
||||||
if abiArg.Type.T == ArrayTy {
|
if abiArg.Type.T == ArrayTy {
|
||||||
inputOffset += (32 * abiArg.Type.Size)
|
inputOffset += 32 * abiArg.Type.Size
|
||||||
} else {
|
} else {
|
||||||
inputOffset += 32
|
inputOffset += 32
|
||||||
}
|
}
|
||||||
|
|
@ -222,3 +236,15 @@ func (arguments Arguments) Pack(args ...interface{}) ([]byte, error) {
|
||||||
|
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// capitalise makes the first character of a string upper case, also removing any
|
||||||
|
// prefixing underscores from the variable names.
|
||||||
|
func capitalise(input string) string {
|
||||||
|
for len(input) > 0 && input[0] == '_' {
|
||||||
|
input = input[1:]
|
||||||
|
}
|
||||||
|
if len(input) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return strings.ToUpper(input[:1]) + input[1:]
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 }
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -304,8 +304,15 @@ var methodNormalizer = map[Lang]func(string) string{
|
||||||
LangJava: decapitalise,
|
LangJava: decapitalise,
|
||||||
}
|
}
|
||||||
|
|
||||||
// capitalise makes the first character of a string upper case.
|
// capitalise makes the first character of a string upper case, also removing any
|
||||||
|
// prefixing underscores from the variable names.
|
||||||
func capitalise(input string) string {
|
func capitalise(input string) string {
|
||||||
|
for len(input) > 0 && input[0] == '_' {
|
||||||
|
input = input[1:]
|
||||||
|
}
|
||||||
|
if len(input) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
return strings.ToUpper(input[:1]) + input[1:]
|
return strings.ToUpper(input[:1]) + input[1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -315,15 +322,24 @@ func decapitalise(input string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// structured checks whether a method has enough information to return a proper
|
// structured checks whether a method has enough information to return a proper
|
||||||
// Go struct ot if flat returns are needed.
|
// Go struct or if flat returns are needed.
|
||||||
func structured(method abi.Method) bool {
|
func structured(method abi.Method) bool {
|
||||||
if len(method.Outputs) < 2 {
|
if len(method.Outputs) < 2 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
exists := make(map[string]bool)
|
||||||
for _, out := range method.Outputs {
|
for _, out := range method.Outputs {
|
||||||
|
// If the name is anonymous, we can't organize into a struct
|
||||||
if out.Name == "" {
|
if out.Name == "" {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
// If the field name is empty when normalized or collides (var, Var, _var, _Var),
|
||||||
|
// we can't organize into a struct
|
||||||
|
field := capitalise(out.Name)
|
||||||
|
if field == "" || exists[field] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
exists[field] = true
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,7 @@ var bindTests = []struct {
|
||||||
{"type":"function","name":"namedOutput","constant":true,"inputs":[],"outputs":[{"name":"str","type":"string"}]},
|
{"type":"function","name":"namedOutput","constant":true,"inputs":[],"outputs":[{"name":"str","type":"string"}]},
|
||||||
{"type":"function","name":"anonOutput","constant":true,"inputs":[],"outputs":[{"name":"","type":"string"}]},
|
{"type":"function","name":"anonOutput","constant":true,"inputs":[],"outputs":[{"name":"","type":"string"}]},
|
||||||
{"type":"function","name":"namedOutputs","constant":true,"inputs":[],"outputs":[{"name":"str1","type":"string"},{"name":"str2","type":"string"}]},
|
{"type":"function","name":"namedOutputs","constant":true,"inputs":[],"outputs":[{"name":"str1","type":"string"},{"name":"str2","type":"string"}]},
|
||||||
|
{"type":"function","name":"collidingOutputs","constant":true,"inputs":[],"outputs":[{"name":"str","type":"string"},{"name":"Str","type":"string"}]},
|
||||||
{"type":"function","name":"anonOutputs","constant":true,"inputs":[],"outputs":[{"name":"","type":"string"},{"name":"","type":"string"}]},
|
{"type":"function","name":"anonOutputs","constant":true,"inputs":[],"outputs":[{"name":"","type":"string"},{"name":"","type":"string"}]},
|
||||||
{"type":"function","name":"mixedOutputs","constant":true,"inputs":[],"outputs":[{"name":"","type":"string"},{"name":"str","type":"string"}]}
|
{"type":"function","name":"mixedOutputs","constant":true,"inputs":[],"outputs":[{"name":"","type":"string"},{"name":"str","type":"string"}]}
|
||||||
]
|
]
|
||||||
|
|
@ -140,6 +141,7 @@ var bindTests = []struct {
|
||||||
str1, err = b.NamedOutput(nil)
|
str1, err = b.NamedOutput(nil)
|
||||||
str1, err = b.AnonOutput(nil)
|
str1, err = b.AnonOutput(nil)
|
||||||
res, _ := b.NamedOutputs(nil)
|
res, _ := b.NamedOutputs(nil)
|
||||||
|
str1, str2, err = b.CollidingOutputs(nil)
|
||||||
str1, str2, err = b.AnonOutputs(nil)
|
str1, str2, err = b.AnonOutputs(nil)
|
||||||
str1, str2, err = b.MixedOutputs(nil)
|
str1, str2, err = b.MixedOutputs(nil)
|
||||||
|
|
||||||
|
|
@ -397,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)
|
||||||
}
|
}
|
||||||
|
|
@ -447,6 +448,66 @@ var bindTests = []struct {
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
`Underscorer`,
|
||||||
|
`
|
||||||
|
contract Underscorer {
|
||||||
|
function UnderscoredOutput() constant returns (int _int, string _string) {
|
||||||
|
return (314, "pi");
|
||||||
|
}
|
||||||
|
function LowerLowerCollision() constant returns (int _res, int res) {
|
||||||
|
return (1, 2);
|
||||||
|
}
|
||||||
|
function LowerUpperCollision() constant returns (int _res, int Res) {
|
||||||
|
return (1, 2);
|
||||||
|
}
|
||||||
|
function UpperLowerCollision() constant returns (int _Res, int res) {
|
||||||
|
return (1, 2);
|
||||||
|
}
|
||||||
|
function UpperUpperCollision() constant returns (int _Res, int Res) {
|
||||||
|
return (1, 2);
|
||||||
|
}
|
||||||
|
function PurelyUnderscoredOutput() constant returns (int _, int res) {
|
||||||
|
return (1, 2);
|
||||||
|
}
|
||||||
|
function AllPurelyUnderscoredOutput() constant returns (int _, int __) {
|
||||||
|
return (1, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`, `6060604052341561000f57600080fd5b6103498061001e6000396000f300606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806303a592131461008857806367e6633d146100b85780639df484851461014d578063af7486ab1461017d578063b564b34d146101ad578063e02ab24d146101dd578063e409ca451461020d575b600080fd5b341561009357600080fd5b61009b61023d565b604051808381526020018281526020019250505060405180910390f35b34156100c357600080fd5b6100cb610252565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156101115780820151818401526020810190506100f6565b50505050905090810190601f16801561013e5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b341561015857600080fd5b6101606102a0565b604051808381526020018281526020019250505060405180910390f35b341561018857600080fd5b6101906102b5565b604051808381526020018281526020019250505060405180910390f35b34156101b857600080fd5b6101c06102ca565b604051808381526020018281526020019250505060405180910390f35b34156101e857600080fd5b6101f06102df565b604051808381526020018281526020019250505060405180910390f35b341561021857600080fd5b6102206102f4565b604051808381526020018281526020019250505060405180910390f35b60008060016002819150809050915091509091565b600061025c610309565b61013a8090506040805190810160405280600281526020017f7069000000000000000000000000000000000000000000000000000000000000815250915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b6020604051908101604052806000815250905600a165627a7a72305820c11dcfa136fc7d182ee4d34f0b12d988496228f7e2d02d2b5376d996ca1743d00029`,
|
||||||
|
`[{"constant":true,"inputs":[],"name":"LowerUpperCollision","outputs":[{"name":"_res","type":"int256"},{"name":"Res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UnderscoredOutput","outputs":[{"name":"_int","type":"int256"},{"name":"_string","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PurelyUnderscoredOutput","outputs":[{"name":"_","type":"int256"},{"name":"res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UpperLowerCollision","outputs":[{"name":"_Res","type":"int256"},{"name":"res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"AllPurelyUnderscoredOutput","outputs":[{"name":"_","type":"int256"},{"name":"__","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UpperUpperCollision","outputs":[{"name":"_Res","type":"int256"},{"name":"Res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"LowerLowerCollision","outputs":[{"name":"_res","type":"int256"},{"name":"res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"}]`,
|
||||||
|
`
|
||||||
|
// Generate a new random account and a funded simulator
|
||||||
|
key, _ := crypto.GenerateKey()
|
||||||
|
auth := bind.NewKeyedTransactor(key)
|
||||||
|
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}})
|
||||||
|
|
||||||
|
// Deploy a underscorer tester contract and execute a structured call on it
|
||||||
|
_, _, underscorer, err := DeployUnderscorer(auth, sim)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to deploy underscorer contract: %v", err)
|
||||||
|
}
|
||||||
|
sim.Commit()
|
||||||
|
|
||||||
|
// Verify that underscored return values correctly parse into structs
|
||||||
|
if res, err := underscorer.UnderscoredOutput(nil); err != nil {
|
||||||
|
t.Errorf("Failed to call constant function: %v", err)
|
||||||
|
} else if res.Int.Cmp(big.NewInt(314)) != 0 || res.String != "pi" {
|
||||||
|
t.Errorf("Invalid result, want: {314, \"pi\"}, got: %+v", res)
|
||||||
|
}
|
||||||
|
// Verify that underscored and non-underscored name collisions force tuple outputs
|
||||||
|
var a, b *big.Int
|
||||||
|
|
||||||
|
a, b, _ = underscorer.LowerLowerCollision(nil)
|
||||||
|
a, b, _ = underscorer.LowerUpperCollision(nil)
|
||||||
|
a, b, _ = underscorer.UpperLowerCollision(nil)
|
||||||
|
a, b, _ = underscorer.UpperUpperCollision(nil)
|
||||||
|
a, b, _ = underscorer.PurelyUnderscoredOutput(nil)
|
||||||
|
a, b, _ = underscorer.AllPurelyUnderscoredOutput(nil)
|
||||||
|
|
||||||
|
fmt.Println(a, b, err)
|
||||||
|
`,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that packages generated by the binder can be successfully compiled and
|
// Tests that packages generated by the binder can be successfully compiled and
|
||||||
|
|
|
||||||
|
|
@ -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"),
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -259,6 +259,51 @@ var unpackTests = []unpackTest{
|
||||||
enc: "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003",
|
enc: "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003",
|
||||||
want: [3]*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)},
|
want: [3]*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)},
|
||||||
},
|
},
|
||||||
|
// struct outputs
|
||||||
|
{
|
||||||
|
def: `[{"name":"int1","type":"int256"},{"name":"int2","type":"int256"}]`,
|
||||||
|
enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
|
||||||
|
want: struct {
|
||||||
|
Int1 *big.Int
|
||||||
|
Int2 *big.Int
|
||||||
|
}{big.NewInt(1), big.NewInt(2)},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
def: `[{"name":"int","type":"int256"},{"name":"Int","type":"int256"}]`,
|
||||||
|
enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
|
||||||
|
want: struct {
|
||||||
|
Int1 *big.Int
|
||||||
|
Int2 *big.Int
|
||||||
|
}{},
|
||||||
|
err: "abi: multiple outputs mapping to the same struct field 'Int'",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
def: `[{"name":"int","type":"int256"},{"name":"_int","type":"int256"}]`,
|
||||||
|
enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
|
||||||
|
want: struct {
|
||||||
|
Int1 *big.Int
|
||||||
|
Int2 *big.Int
|
||||||
|
}{},
|
||||||
|
err: "abi: multiple outputs mapping to the same struct field 'Int'",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
def: `[{"name":"Int","type":"int256"},{"name":"_int","type":"int256"}]`,
|
||||||
|
enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
|
||||||
|
want: struct {
|
||||||
|
Int1 *big.Int
|
||||||
|
Int2 *big.Int
|
||||||
|
}{},
|
||||||
|
err: "abi: multiple outputs mapping to the same struct field 'Int'",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
def: `[{"name":"Int","type":"int256"},{"name":"_","type":"int256"}]`,
|
||||||
|
enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
|
||||||
|
want: struct {
|
||||||
|
Int1 *big.Int
|
||||||
|
Int2 *big.Int
|
||||||
|
}{},
|
||||||
|
err: "abi: purely underscored output cannot unpack to struct",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnpack(t *testing.T) {
|
func TestUnpack(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
35
build/ci.go
35
build/ci.go
|
|
@ -23,7 +23,7 @@ Usage: go run build/ci.go <command> <command flags/arguments>
|
||||||
|
|
||||||
Available commands are:
|
Available commands are:
|
||||||
|
|
||||||
install [ -arch architecture ] [ packages... ] -- builds packages and executables
|
install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables
|
||||||
test [ -coverage ] [ packages... ] -- runs the tests
|
test [ -coverage ] [ packages... ] -- runs the tests
|
||||||
lint -- runs certain pre-selected linters
|
lint -- runs certain pre-selected linters
|
||||||
archive [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -upload dest ] -- archives build artefacts
|
archive [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -upload dest ] -- archives build artefacts
|
||||||
|
|
@ -173,17 +173,24 @@ func main() {
|
||||||
func doInstall(cmdline []string) {
|
func doInstall(cmdline []string) {
|
||||||
var (
|
var (
|
||||||
arch = flag.String("arch", "", "Architecture to cross build for")
|
arch = flag.String("arch", "", "Architecture to cross build for")
|
||||||
|
cc = flag.String("cc", "", "C compiler to cross build with")
|
||||||
)
|
)
|
||||||
flag.CommandLine.Parse(cmdline)
|
flag.CommandLine.Parse(cmdline)
|
||||||
env := build.Env()
|
env := build.Env()
|
||||||
|
|
||||||
// Check Go version. People regularly open issues about compilation
|
// Check Go version. People regularly open issues about compilation
|
||||||
// failure with outdated Go. This should save them the trouble.
|
// failure with outdated Go. This should save them the trouble.
|
||||||
if runtime.Version() < "go1.7" && !strings.Contains(runtime.Version(), "devel") {
|
if !strings.Contains(runtime.Version(), "devel") {
|
||||||
log.Println("You have Go version", runtime.Version())
|
// Figure out the minor version number since we can't textually compare (1.10 < 1.7)
|
||||||
log.Println("go-ethereum requires at least Go version 1.7 and cannot")
|
var minor int
|
||||||
log.Println("be compiled with an earlier version. Please upgrade your Go installation.")
|
fmt.Sscanf(strings.TrimPrefix(runtime.Version(), "go1."), "%d", &minor)
|
||||||
os.Exit(1)
|
|
||||||
|
if minor < 7 {
|
||||||
|
log.Println("You have Go version", runtime.Version())
|
||||||
|
log.Println("go-ethereum requires at least Go version 1.7 and cannot")
|
||||||
|
log.Println("be compiled with an earlier version. Please upgrade your Go installation.")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Compile packages given as arguments, or everything if there are no arguments.
|
// Compile packages given as arguments, or everything if there are no arguments.
|
||||||
packages := []string{"./..."}
|
packages := []string{"./..."}
|
||||||
|
|
@ -207,7 +214,7 @@ func doInstall(cmdline []string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Seems we are cross compiling, work around forbidden GOBIN
|
// Seems we are cross compiling, work around forbidden GOBIN
|
||||||
goinstall := goToolArch(*arch, "install", buildFlags(env)...)
|
goinstall := goToolArch(*arch, *cc, "install", buildFlags(env)...)
|
||||||
goinstall.Args = append(goinstall.Args, "-v")
|
goinstall.Args = append(goinstall.Args, "-v")
|
||||||
goinstall.Args = append(goinstall.Args, []string{"-buildmode", "archive"}...)
|
goinstall.Args = append(goinstall.Args, []string{"-buildmode", "archive"}...)
|
||||||
goinstall.Args = append(goinstall.Args, packages...)
|
goinstall.Args = append(goinstall.Args, packages...)
|
||||||
|
|
@ -221,7 +228,7 @@ func doInstall(cmdline []string) {
|
||||||
}
|
}
|
||||||
for name := range pkgs {
|
for name := range pkgs {
|
||||||
if name == "main" {
|
if name == "main" {
|
||||||
gobuild := goToolArch(*arch, "build", buildFlags(env)...)
|
gobuild := goToolArch(*arch, *cc, "build", buildFlags(env)...)
|
||||||
gobuild.Args = append(gobuild.Args, "-v")
|
gobuild.Args = append(gobuild.Args, "-v")
|
||||||
gobuild.Args = append(gobuild.Args, []string{"-o", executablePath(cmd.Name())}...)
|
gobuild.Args = append(gobuild.Args, []string{"-o", executablePath(cmd.Name())}...)
|
||||||
gobuild.Args = append(gobuild.Args, "."+string(filepath.Separator)+filepath.Join("cmd", cmd.Name()))
|
gobuild.Args = append(gobuild.Args, "."+string(filepath.Separator)+filepath.Join("cmd", cmd.Name()))
|
||||||
|
|
@ -249,15 +256,18 @@ func buildFlags(env build.Environment) (flags []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func goTool(subcmd string, args ...string) *exec.Cmd {
|
func goTool(subcmd string, args ...string) *exec.Cmd {
|
||||||
return goToolArch(runtime.GOARCH, subcmd, args...)
|
return goToolArch(runtime.GOARCH, os.Getenv("CC"), subcmd, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func goToolArch(arch string, subcmd string, args ...string) *exec.Cmd {
|
func goToolArch(arch string, cc string, subcmd string, args ...string) *exec.Cmd {
|
||||||
cmd := build.GoTool(subcmd, args...)
|
cmd := build.GoTool(subcmd, args...)
|
||||||
if subcmd == "build" || subcmd == "install" || subcmd == "test" {
|
if subcmd == "build" || subcmd == "install" || subcmd == "test" {
|
||||||
// Go CGO has a Windows linker error prior to 1.8 (https://github.com/golang/go/issues/8756).
|
// Go CGO has a Windows linker error prior to 1.8 (https://github.com/golang/go/issues/8756).
|
||||||
// Work around issue by allowing multiple definitions for <1.8 builds.
|
// Work around issue by allowing multiple definitions for <1.8 builds.
|
||||||
if runtime.GOOS == "windows" && runtime.Version() < "go1.8" {
|
var minor int
|
||||||
|
fmt.Sscanf(strings.TrimPrefix(runtime.Version(), "go1."), "%d", &minor)
|
||||||
|
|
||||||
|
if runtime.GOOS == "windows" && minor < 8 {
|
||||||
cmd.Args = append(cmd.Args, []string{"-ldflags", "-extldflags -Wl,--allow-multiple-definition"}...)
|
cmd.Args = append(cmd.Args, []string{"-ldflags", "-extldflags -Wl,--allow-multiple-definition"}...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -268,6 +278,9 @@ func goToolArch(arch string, subcmd string, args ...string) *exec.Cmd {
|
||||||
cmd.Env = append(cmd.Env, "CGO_ENABLED=1")
|
cmd.Env = append(cmd.Env, "CGO_ENABLED=1")
|
||||||
cmd.Env = append(cmd.Env, "GOARCH="+arch)
|
cmd.Env = append(cmd.Env, "GOARCH="+arch)
|
||||||
}
|
}
|
||||||
|
if cc != "" {
|
||||||
|
cmd.Env = append(cmd.Env, "CC="+cc)
|
||||||
|
}
|
||||||
for _, e := range os.Environ() {
|
for _, e := range os.Environ() {
|
||||||
if strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "GOBIN=") {
|
if strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "GOBIN=") {
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with geth. If not, see <http://www.gnu.org/licenses/>.
|
along with geth. If not, see <http://www.gnu.org/licenses/>.`)
|
||||||
`)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -315,7 +315,7 @@ func checkDeprecated(ctx *cli.Context) {
|
||||||
func printConfig(config *bzzapi.Config) string {
|
func printConfig(config *bzzapi.Config) string {
|
||||||
out, err := tomlSettings.Marshal(&config)
|
out, err := tomlSettings.Marshal(&config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return (fmt.Sprintf("Something is not right with the configuration: %v", err))
|
return fmt.Sprintf("Something is not right with the configuration: %v", err)
|
||||||
}
|
}
|
||||||
return string(out)
|
return string(out)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ func NewApp(gitCommit, usage string) *cli.App {
|
||||||
//app.Authors = nil
|
//app.Authors = nil
|
||||||
app.Email = ""
|
app.Email = ""
|
||||||
app.Version = params.Version
|
app.Version = params.Version
|
||||||
if gitCommit != "" {
|
if len(gitCommit) >= 8 {
|
||||||
app.Version += "-" + gitCommit[:8]
|
app.Version += "-" + gitCommit[:8]
|
||||||
}
|
}
|
||||||
app.Usage = usage
|
app.Usage = usage
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ func fastXORBytes(dst, a, b []byte) int {
|
||||||
dw[i] = aw[i] ^ bw[i]
|
dw[i] = aw[i] ^ bw[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := (n - n%wordSize); i < n; i++ {
|
for i := n - n%wordSize; i < n; i++ {
|
||||||
dst[i] = a[i] ^ b[i]
|
dst[i] = a[i] ^ b[i]
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
|
|
@ -84,7 +84,7 @@ func fastANDBytes(dst, a, b []byte) int {
|
||||||
dw[i] = aw[i] & bw[i]
|
dw[i] = aw[i] & bw[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := (n - n%wordSize); i < n; i++ {
|
for i := n - n%wordSize; i < n; i++ {
|
||||||
dst[i] = a[i] & b[i]
|
dst[i] = a[i] & b[i]
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
|
|
@ -128,7 +128,7 @@ func fastORBytes(dst, a, b []byte) int {
|
||||||
dw[i] = aw[i] | bw[i]
|
dw[i] = aw[i] | bw[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := (n - n%wordSize); i < n; i++ {
|
for i := n - n%wordSize; i < n; i++ {
|
||||||
dst[i] = a[i] | b[i]
|
dst[i] = a[i] | b[i]
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
|
|
@ -168,7 +168,7 @@ func fastTestBytes(p []byte) bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := (n - n%wordSize); i < n; i++ {
|
for i := n - n%wordSize; i < n; i++ {
|
||||||
if p[i] != 0 {
|
if p[i] != 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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"),
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
@ -381,7 +381,7 @@ func calcDifficultyByzantium(time uint64, parent *types.Header) *big.Int {
|
||||||
// the difficulty that a new block should have when created at time given the
|
// the difficulty that a new block should have when created at time given the
|
||||||
// parent block's time and difficulty. The calculation uses the Homestead rules.
|
// parent block's time and difficulty. The calculation uses the Homestead rules.
|
||||||
func calcDifficultyHomestead(time uint64, parent *types.Header) *big.Int {
|
func calcDifficultyHomestead(time uint64, parent *types.Header) *big.Int {
|
||||||
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.mediawiki
|
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.md
|
||||||
// algorithm:
|
// algorithm:
|
||||||
// diff = (parent_diff +
|
// diff = (parent_diff +
|
||||||
// (parent_diff / 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99))
|
// (parent_diff / 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99))
|
||||||
|
|
|
||||||
|
|
@ -155,8 +155,7 @@ func (p *terminalPrompter) SetHistory(history []string) {
|
||||||
p.State.ReadHistory(strings.NewReader(strings.Join(history, "\n")))
|
p.State.ReadHistory(strings.NewReader(strings.Join(history, "\n")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// AppendHistory appends an entry to the scrollback history. It should be called
|
// AppendHistory appends an entry to the scrollback history.
|
||||||
// if and only if the prompt to append was a valid command.
|
|
||||||
func (p *terminalPrompter) AppendHistory(command string) {
|
func (p *terminalPrompter) AppendHistory(command string) {
|
||||||
p.State.AppendHistory(command)
|
p.State.AppendHistory(command)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
FROM alpine:3.5
|
FROM alpine:3.7
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
apk add --update go git make gcc musl-dev linux-headers ca-certificates && \
|
apk add --update go git make gcc musl-dev linux-headers ca-certificates && \
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
FROM ubuntu:xenial
|
FROM ubuntu:xenial
|
||||||
|
|
||||||
|
ENV PATH=/usr/lib/go-1.9/bin:$PATH
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
apt-get update && apt-get upgrade -q -y && \
|
apt-get update && apt-get upgrade -q -y && \
|
||||||
apt-get install -y --no-install-recommends golang git make gcc libc-dev ca-certificates && \
|
apt-get install -y --no-install-recommends golang-1.9 git make gcc libc-dev ca-certificates && \
|
||||||
git clone --depth 1 https://github.com/ethereum/go-ethereum && \
|
git clone --depth 1 https://github.com/ethereum/go-ethereum && \
|
||||||
(cd go-ethereum && make geth) && \
|
(cd go-ethereum && make geth) && \
|
||||||
cp go-ethereum/build/bin/geth /geth && \
|
cp go-ethereum/build/bin/geth /geth && \
|
||||||
apt-get remove -y golang git make gcc libc-dev && apt autoremove -y && apt-get clean && \
|
apt-get remove -y golang-1.9 git make gcc libc-dev && apt autoremove -y && apt-get clean && \
|
||||||
rm -rf /go-ethereum
|
rm -rf /go-ethereum
|
||||||
|
|
||||||
EXPOSE 8545
|
EXPOSE 8545
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
FROM alpine:3.5
|
FROM alpine:3.7
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
apk add --update go git make gcc musl-dev linux-headers ca-certificates && \
|
apk add --update go git make gcc musl-dev linux-headers ca-certificates && \
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
FROM ubuntu:xenial
|
FROM ubuntu:xenial
|
||||||
|
|
||||||
|
ENV PATH=/usr/lib/go-1.9/bin:$PATH
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
apt-get update && apt-get upgrade -q -y && \
|
apt-get update && apt-get upgrade -q -y && \
|
||||||
apt-get install -y --no-install-recommends golang git make gcc libc-dev ca-certificates && \
|
apt-get install -y --no-install-recommends golang-1.9 git make gcc libc-dev ca-certificates && \
|
||||||
git clone --depth 1 --branch release/1.7 https://github.com/ethereum/go-ethereum && \
|
git clone --depth 1 --branch release/1.7 https://github.com/ethereum/go-ethereum && \
|
||||||
(cd go-ethereum && make geth) && \
|
(cd go-ethereum && make geth) && \
|
||||||
cp go-ethereum/build/bin/geth /geth && \
|
cp go-ethereum/build/bin/geth /geth && \
|
||||||
apt-get remove -y golang git make gcc libc-dev && apt autoremove -y && apt-get clean && \
|
apt-get remove -y golang-1.9 git make gcc libc-dev && apt autoremove -y && apt-get clean && \
|
||||||
rm -rf /go-ethereum
|
rm -rf /go-ethereum
|
||||||
|
|
||||||
EXPOSE 8545
|
EXPOSE 8545
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -1196,10 +1196,11 @@ func (bc *BlockChain) PostChainEvents(events []interface{}, logs []*types.Log) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *BlockChain) update() {
|
func (bc *BlockChain) update() {
|
||||||
futureTimer := time.Tick(5 * time.Second)
|
futureTimer := time.NewTicker(5 * time.Second)
|
||||||
|
defer futureTimer.Stop()
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-futureTimer:
|
case <-futureTimer.C:
|
||||||
bc.procFutureBlocks()
|
bc.procFutureBlocks()
|
||||||
case <-bc.quit:
|
case <-bc.quit:
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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"`
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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})
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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) }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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())
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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 }
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,8 @@ type StructLogger struct {
|
||||||
|
|
||||||
logs []StructLog
|
logs []StructLog
|
||||||
changedValues map[common.Address]Storage
|
changedValues map[common.Address]Storage
|
||||||
|
output []byte
|
||||||
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewStructLogger returns a new logger
|
// NewStructLogger returns a new logger
|
||||||
|
|
@ -172,17 +174,19 @@ func (l *StructLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost ui
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *StructLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error {
|
func (l *StructLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error {
|
||||||
fmt.Printf("0x%x", output)
|
l.output = output
|
||||||
if err != nil {
|
l.err = err
|
||||||
fmt.Printf(" error: %v\n", err)
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// StructLogs returns a list of captured log entries
|
// StructLogs returns the captured log entries.
|
||||||
func (l *StructLogger) StructLogs() []StructLog {
|
func (l *StructLogger) StructLogs() []StructLog { return l.logs }
|
||||||
return l.logs
|
|
||||||
}
|
// Error returns the VM error captured by the trace.
|
||||||
|
func (l *StructLogger) Error() error { return l.err }
|
||||||
|
|
||||||
|
// Output returns the VM return value captured by the trace.
|
||||||
|
func (l *StructLogger) Output() []byte { return l.output }
|
||||||
|
|
||||||
// WriteTrace writes a formatted trace to the given writer
|
// WriteTrace writes a formatted trace to the given writer
|
||||||
func WriteTrace(writer io.Writer, logs []StructLog) {
|
func WriteTrace(writer io.Writer, logs []StructLog) {
|
||||||
|
|
|
||||||
|
|
@ -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 }
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,16 @@ func toECDSA(d []byte, strict bool) (*ecdsa.PrivateKey, error) {
|
||||||
return nil, fmt.Errorf("invalid length, need %d bits", priv.Params().BitSize)
|
return nil, fmt.Errorf("invalid length, need %d bits", priv.Params().BitSize)
|
||||||
}
|
}
|
||||||
priv.D = new(big.Int).SetBytes(d)
|
priv.D = new(big.Int).SetBytes(d)
|
||||||
|
|
||||||
|
// The priv.D must < N
|
||||||
|
if priv.D.Cmp(secp256k1_N) >= 0 {
|
||||||
|
return nil, fmt.Errorf("invalid private key, >=N")
|
||||||
|
}
|
||||||
|
// The priv.D must not be zero or negative.
|
||||||
|
if priv.D.Sign() <= 0 {
|
||||||
|
return nil, fmt.Errorf("invalid private key, zero or negative")
|
||||||
|
}
|
||||||
|
|
||||||
priv.PublicKey.X, priv.PublicKey.Y = priv.PublicKey.Curve.ScalarBaseMult(d)
|
priv.PublicKey.X, priv.PublicKey.Y = priv.PublicKey.Curve.ScalarBaseMult(d)
|
||||||
if priv.PublicKey.X == nil {
|
if priv.PublicKey.X == nil {
|
||||||
return nil, errors.New("invalid private key")
|
return nil, errors.New("invalid private key")
|
||||||
|
|
|
||||||
|
|
@ -314,7 +314,7 @@ func (prv *PrivateKey) Decrypt(rand io.Reader, c, s1, s2 []byte) (m []byte, err
|
||||||
|
|
||||||
switch c[0] {
|
switch c[0] {
|
||||||
case 2, 3, 4:
|
case 2, 3, 4:
|
||||||
rLen = ((prv.PublicKey.Curve.Params().BitSize + 7) / 4)
|
rLen = (prv.PublicKey.Curve.Params().BitSize + 7) / 4
|
||||||
if len(c) < (rLen + hLen + 1) {
|
if len(c) < (rLen + hLen + 1) {
|
||||||
err = ErrInvalidMessage
|
err = ErrInvalidMessage
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -204,7 +204,7 @@ func (api *PrivateDebugAPI) traceChain(ctx context.Context, start, end *types.Bl
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If the starting state is missing, allow some number of blocks to be reexecuted
|
// If the starting state is missing, allow some number of blocks to be reexecuted
|
||||||
reexec := defaultTraceReexec
|
reexec := defaultTraceReexec
|
||||||
if config.Reexec != nil {
|
if config != nil && config.Reexec != nil {
|
||||||
reexec = *config.Reexec
|
reexec = *config.Reexec
|
||||||
}
|
}
|
||||||
// Find the most recent block that has the state available
|
// Find the most recent block that has the state available
|
||||||
|
|
@ -465,7 +465,7 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block,
|
||||||
return nil, fmt.Errorf("parent %x not found", block.ParentHash())
|
return nil, fmt.Errorf("parent %x not found", block.ParentHash())
|
||||||
}
|
}
|
||||||
reexec := defaultTraceReexec
|
reexec := defaultTraceReexec
|
||||||
if config.Reexec != nil {
|
if config != nil && config.Reexec != nil {
|
||||||
reexec = *config.Reexec
|
reexec = *config.Reexec
|
||||||
}
|
}
|
||||||
statedb, err := api.computeStateDB(parent, reexec)
|
statedb, err := api.computeStateDB(parent, reexec)
|
||||||
|
|
@ -619,7 +619,7 @@ func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, hash common.Ha
|
||||||
return nil, fmt.Errorf("transaction %x not found", hash)
|
return nil, fmt.Errorf("transaction %x not found", hash)
|
||||||
}
|
}
|
||||||
reexec := defaultTraceReexec
|
reexec := defaultTraceReexec
|
||||||
if config.Reexec != nil {
|
if config != nil && config.Reexec != nil {
|
||||||
reexec = *config.Reexec
|
reexec = *config.Reexec
|
||||||
}
|
}
|
||||||
msg, vmctx, statedb, err := api.computeTxEnv(blockHash, int(index), reexec)
|
msg, vmctx, statedb, err := api.computeTxEnv(blockHash, int(index), reexec)
|
||||||
|
|
|
||||||
10
eth/bind.go
10
eth/bind.go
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,10 @@ func (d *Downloader) runStateSync(s *stateSync) *stateSync {
|
||||||
|
|
||||||
// Send the next finished request to the current sync:
|
// Send the next finished request to the current sync:
|
||||||
case deliverReqCh <- deliverReq:
|
case deliverReqCh <- deliverReq:
|
||||||
finished = append(finished[:0], finished[1:]...)
|
// Shift out the first request, but also set the emptied slot to nil for GC
|
||||||
|
copy(finished, finished[1:])
|
||||||
|
finished[len(finished)-1] = nil
|
||||||
|
finished = finished[:len(finished)-1]
|
||||||
|
|
||||||
// Handle incoming state packs:
|
// Handle incoming state packs:
|
||||||
case pack := <-d.stateCh:
|
case pack := <-d.stateCh:
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -394,14 +394,14 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
case query.Reverse:
|
case query.Reverse:
|
||||||
// Number based traversal towards the genesis block
|
// Number based traversal towards the genesis block
|
||||||
if query.Origin.Number >= query.Skip+1 {
|
if query.Origin.Number >= query.Skip+1 {
|
||||||
query.Origin.Number -= (query.Skip + 1)
|
query.Origin.Number -= query.Skip + 1
|
||||||
} else {
|
} else {
|
||||||
unknown = true
|
unknown = true
|
||||||
}
|
}
|
||||||
|
|
||||||
case !query.Reverse:
|
case !query.Reverse:
|
||||||
// Number based traversal towards the leaf block
|
// Number based traversal towards the leaf block
|
||||||
query.Origin.Number += (query.Skip + 1)
|
query.Origin.Number += query.Skip + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return p.SendBlockHeaders(headers)
|
return p.SendBlockHeaders(headers)
|
||||||
|
|
@ -744,10 +744,10 @@ func (self *ProtocolManager) txBroadcastLoop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// EthNodeInfo represents a short summary of the Ethereum sub-protocol metadata known
|
// NodeInfo represents a short summary of the Ethereum sub-protocol metadata
|
||||||
// about the host peer.
|
// known about the host peer.
|
||||||
type EthNodeInfo struct {
|
type NodeInfo struct {
|
||||||
Network uint64 `json:"network"` // Ethereum network ID (1=Frontier, 2=Morden, Ropsten=3)
|
Network uint64 `json:"network"` // Ethereum network ID (1=Frontier, 2=Morden, Ropsten=3, Rinkeby=4)
|
||||||
Difficulty *big.Int `json:"difficulty"` // Total difficulty of the host's blockchain
|
Difficulty *big.Int `json:"difficulty"` // Total difficulty of the host's blockchain
|
||||||
Genesis common.Hash `json:"genesis"` // SHA3 hash of the host's genesis block
|
Genesis common.Hash `json:"genesis"` // SHA3 hash of the host's genesis block
|
||||||
Config *params.ChainConfig `json:"config"` // Chain configuration for the fork rules
|
Config *params.ChainConfig `json:"config"` // Chain configuration for the fork rules
|
||||||
|
|
@ -755,9 +755,9 @@ type EthNodeInfo struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeInfo retrieves some protocol metadata about the running host node.
|
// NodeInfo retrieves some protocol metadata about the running host node.
|
||||||
func (self *ProtocolManager) NodeInfo() *EthNodeInfo {
|
func (self *ProtocolManager) NodeInfo() *NodeInfo {
|
||||||
currentBlock := self.blockchain.CurrentBlock()
|
currentBlock := self.blockchain.CurrentBlock()
|
||||||
return &EthNodeInfo{
|
return &NodeInfo{
|
||||||
Network: self.networkId,
|
Network: self.networkId,
|
||||||
Difficulty: self.blockchain.GetTd(currentBlock.Hash(), currentBlock.NumberU64()),
|
Difficulty: self.blockchain.GetTd(currentBlock.Hash(), currentBlock.NumberU64()),
|
||||||
Genesis: self.blockchain.Genesis().Hash(),
|
Genesis: self.blockchain.Genesis().Hash(),
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -374,10 +374,10 @@ func (s *Service) login(conn *websocket.Conn) error {
|
||||||
|
|
||||||
var network, protocol string
|
var network, protocol string
|
||||||
if info := infos.Protocols["eth"]; info != nil {
|
if info := infos.Protocols["eth"]; info != nil {
|
||||||
network = fmt.Sprintf("%d", info.(*eth.EthNodeInfo).Network)
|
network = fmt.Sprintf("%d", info.(*eth.NodeInfo).Network)
|
||||||
protocol = fmt.Sprintf("eth/%d", eth.ProtocolVersions[0])
|
protocol = fmt.Sprintf("eth/%d", eth.ProtocolVersions[0])
|
||||||
} else {
|
} else {
|
||||||
network = fmt.Sprintf("%d", infos.Protocols["les"].(*eth.EthNodeInfo).Network)
|
network = fmt.Sprintf("%d", infos.Protocols["les"].(*les.NodeInfo).Network)
|
||||||
protocol = fmt.Sprintf("les/%d", les.ClientProtocolVersions[0])
|
protocol = fmt.Sprintf("les/%d", les.ClientProtocolVersions[0])
|
||||||
}
|
}
|
||||||
auth := &authMsg{
|
auth := &authMsg{
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"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/eth"
|
|
||||||
"github.com/ethereum/go-ethereum/eth/downloader"
|
"github.com/ethereum/go-ethereum/eth/downloader"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
|
|
@ -73,6 +72,7 @@ func errResp(code errCode, format string, v ...interface{}) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
type BlockChain interface {
|
type BlockChain interface {
|
||||||
|
Config() *params.ChainConfig
|
||||||
HasHeader(hash common.Hash, number uint64) bool
|
HasHeader(hash common.Hash, number uint64) bool
|
||||||
GetHeader(hash common.Hash, number uint64) *types.Header
|
GetHeader(hash common.Hash, number uint64) *types.Header
|
||||||
GetHeaderByHash(hash common.Hash) *types.Header
|
GetHeaderByHash(hash common.Hash) *types.Header
|
||||||
|
|
@ -454,14 +454,14 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
case query.Reverse:
|
case query.Reverse:
|
||||||
// Number based traversal towards the genesis block
|
// Number based traversal towards the genesis block
|
||||||
if query.Origin.Number >= query.Skip+1 {
|
if query.Origin.Number >= query.Skip+1 {
|
||||||
query.Origin.Number -= (query.Skip + 1)
|
query.Origin.Number -= query.Skip + 1
|
||||||
} else {
|
} else {
|
||||||
unknown = true
|
unknown = true
|
||||||
}
|
}
|
||||||
|
|
||||||
case !query.Reverse:
|
case !query.Reverse:
|
||||||
// Number based traversal towards the leaf block
|
// Number based traversal towards the leaf block
|
||||||
query.Origin.Number += (query.Skip + 1)
|
query.Origin.Number += query.Skip + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1123,12 +1123,23 @@ func (pm *ProtocolManager) txStatus(hashes []common.Hash) []txStatus {
|
||||||
return stats
|
return stats
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NodeInfo represents a short summary of the Ethereum sub-protocol metadata
|
||||||
|
// known about the host peer.
|
||||||
|
type NodeInfo struct {
|
||||||
|
Network uint64 `json:"network"` // Ethereum network ID (1=Frontier, 2=Morden, Ropsten=3, Rinkeby=4)
|
||||||
|
Difficulty *big.Int `json:"difficulty"` // Total difficulty of the host's blockchain
|
||||||
|
Genesis common.Hash `json:"genesis"` // SHA3 hash of the host's genesis block
|
||||||
|
Config *params.ChainConfig `json:"config"` // Chain configuration for the fork rules
|
||||||
|
Head common.Hash `json:"head"` // SHA3 hash of the host's best owned block
|
||||||
|
}
|
||||||
|
|
||||||
// NodeInfo retrieves some protocol metadata about the running host node.
|
// NodeInfo retrieves some protocol metadata about the running host node.
|
||||||
func (self *ProtocolManager) NodeInfo() *eth.EthNodeInfo {
|
func (self *ProtocolManager) NodeInfo() *NodeInfo {
|
||||||
return ð.EthNodeInfo{
|
return &NodeInfo{
|
||||||
Network: self.networkId,
|
Network: self.networkId,
|
||||||
Difficulty: self.blockchain.GetTdByHash(self.blockchain.LastBlockHash()),
|
Difficulty: self.blockchain.GetTdByHash(self.blockchain.LastBlockHash()),
|
||||||
Genesis: self.blockchain.Genesis().Hash(),
|
Genesis: self.blockchain.Genesis().Hash(),
|
||||||
|
Config: self.blockchain.Config(),
|
||||||
Head: self.blockchain.LastBlockHash(),
|
Head: self.blockchain.LastBlockHash(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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})
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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...)
|
||||||
|
|
|
||||||
|
|
@ -618,7 +618,7 @@ func (e *knownEntry) Weight() int64 {
|
||||||
if e.state != psNotConnected || !e.known || e.delayedRetry {
|
if e.state != psNotConnected || !e.known || e.delayedRetry {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return int64(1000000000 * e.connectStats.recentAvg() * math.Exp(-float64(e.lastConnected.fails)*failDropLn-e.responseStats.recentAvg()/float64(responseScoreTC)-e.delayStats.recentAvg()/float64(delayScoreTC)) * math.Pow((1-e.timeoutStats.recentAvg()), timeoutPow))
|
return int64(1000000000 * e.connectStats.recentAvg() * math.Exp(-float64(e.lastConnected.fails)*failDropLn-e.responseStats.recentAvg()/float64(responseScoreTC)-e.delayStats.recentAvg()/float64(delayScoreTC)) * math.Pow(1-e.timeoutStats.recentAvg(), timeoutPow))
|
||||||
}
|
}
|
||||||
|
|
||||||
// poolEntryAddress is a separate object because currently it is necessary to remember
|
// poolEntryAddress is a separate object because currently it is necessary to remember
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
||||||
|
|
@ -457,6 +457,9 @@ func (self *LightChain) GetHeaderByNumberOdr(ctx context.Context, number uint64)
|
||||||
return GetHeaderByNumber(ctx, self.odr, number)
|
return GetHeaderByNumber(ctx, self.odr, number)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Config retrieves the header chain's chain configuration.
|
||||||
|
func (self *LightChain) Config() *params.ChainConfig { return self.hc.Config() }
|
||||||
|
|
||||||
func (self *LightChain) SyncCht(ctx context.Context) bool {
|
func (self *LightChain) SyncCht(ctx context.Context) bool {
|
||||||
if self.odr.ChtIndexer() == nil {
|
if self.odr.ChtIndexer() == nil {
|
||||||
return false
|
return false
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 (
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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) }
|
||||||
|
|
|
||||||
|
|
@ -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) }
|
||||||
|
|
|
||||||
|
|
@ -239,14 +239,14 @@ func (db *nodeDB) ensureExpirer() {
|
||||||
// expirer should be started in a go routine, and is responsible for looping ad
|
// expirer should be started in a go routine, and is responsible for looping ad
|
||||||
// infinitum and dropping stale data from the database.
|
// infinitum and dropping stale data from the database.
|
||||||
func (db *nodeDB) expirer() {
|
func (db *nodeDB) expirer() {
|
||||||
tick := time.Tick(nodeDBCleanupCycle)
|
tick := time.NewTicker(nodeDBCleanupCycle)
|
||||||
|
defer tick.Stop()
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-tick:
|
case <-tick.C:
|
||||||
if err := db.expireNodes(); err != nil {
|
if err := db.expireNodes(); err != nil {
|
||||||
log.Error(fmt.Sprintf("Failed to expire nodedb items: %v", err))
|
log.Error(fmt.Sprintf("Failed to expire nodedb items: %v", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
case <-db.quit:
|
case <-db.quit:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,16 +51,9 @@ const (
|
||||||
const testTopic = "foo"
|
const testTopic = "foo"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
printDebugLogs = false
|
|
||||||
printTestImgLogs = false
|
printTestImgLogs = false
|
||||||
)
|
)
|
||||||
|
|
||||||
func debugLog(s string) {
|
|
||||||
if printDebugLogs {
|
|
||||||
fmt.Println(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Network manages the table and all protocol interaction.
|
// Network manages the table and all protocol interaction.
|
||||||
type Network struct {
|
type Network struct {
|
||||||
db *nodeDB // database of known nodes
|
db *nodeDB // database of known nodes
|
||||||
|
|
@ -388,14 +381,14 @@ func (net *Network) loop() {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
resetNextTicket := func() {
|
resetNextTicket := func() {
|
||||||
t, timeout := net.ticketStore.nextFilteredTicket()
|
ticket, timeout := net.ticketStore.nextFilteredTicket()
|
||||||
if t != nextTicket {
|
if nextTicket != ticket {
|
||||||
nextTicket = t
|
nextTicket = ticket
|
||||||
if nextRegisterTimer != nil {
|
if nextRegisterTimer != nil {
|
||||||
nextRegisterTimer.Stop()
|
nextRegisterTimer.Stop()
|
||||||
nextRegisterTime = nil
|
nextRegisterTime = nil
|
||||||
}
|
}
|
||||||
if t != nil {
|
if ticket != nil {
|
||||||
nextRegisterTimer = time.NewTimer(timeout)
|
nextRegisterTimer = time.NewTimer(timeout)
|
||||||
nextRegisterTime = nextRegisterTimer.C
|
nextRegisterTime = nextRegisterTimer.C
|
||||||
}
|
}
|
||||||
|
|
@ -423,13 +416,13 @@ loop:
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-net.closeReq:
|
case <-net.closeReq:
|
||||||
debugLog("<-net.closeReq")
|
log.Trace("<-net.closeReq")
|
||||||
break loop
|
break loop
|
||||||
|
|
||||||
// Ingress packet handling.
|
// Ingress packet handling.
|
||||||
case pkt := <-net.read:
|
case pkt := <-net.read:
|
||||||
//fmt.Println("read", pkt.ev)
|
//fmt.Println("read", pkt.ev)
|
||||||
debugLog("<-net.read")
|
log.Trace("<-net.read")
|
||||||
n := net.internNode(&pkt)
|
n := net.internNode(&pkt)
|
||||||
prestate := n.state
|
prestate := n.state
|
||||||
status := "ok"
|
status := "ok"
|
||||||
|
|
@ -444,7 +437,7 @@ loop:
|
||||||
|
|
||||||
// State transition timeouts.
|
// State transition timeouts.
|
||||||
case timeout := <-net.timeout:
|
case timeout := <-net.timeout:
|
||||||
debugLog("<-net.timeout")
|
log.Trace("<-net.timeout")
|
||||||
if net.timeoutTimers[timeout] == nil {
|
if net.timeoutTimers[timeout] == nil {
|
||||||
// Stale timer (was aborted).
|
// Stale timer (was aborted).
|
||||||
continue
|
continue
|
||||||
|
|
@ -462,20 +455,20 @@ loop:
|
||||||
|
|
||||||
// Querying.
|
// Querying.
|
||||||
case q := <-net.queryReq:
|
case q := <-net.queryReq:
|
||||||
debugLog("<-net.queryReq")
|
log.Trace("<-net.queryReq")
|
||||||
if !q.start(net) {
|
if !q.start(net) {
|
||||||
q.remote.deferQuery(q)
|
q.remote.deferQuery(q)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interacting with the table.
|
// Interacting with the table.
|
||||||
case f := <-net.tableOpReq:
|
case f := <-net.tableOpReq:
|
||||||
debugLog("<-net.tableOpReq")
|
log.Trace("<-net.tableOpReq")
|
||||||
f()
|
f()
|
||||||
net.tableOpResp <- struct{}{}
|
net.tableOpResp <- struct{}{}
|
||||||
|
|
||||||
// Topic registration stuff.
|
// Topic registration stuff.
|
||||||
case req := <-net.topicRegisterReq:
|
case req := <-net.topicRegisterReq:
|
||||||
debugLog("<-net.topicRegisterReq")
|
log.Trace("<-net.topicRegisterReq")
|
||||||
if !req.add {
|
if !req.add {
|
||||||
net.ticketStore.removeRegisterTopic(req.topic)
|
net.ticketStore.removeRegisterTopic(req.topic)
|
||||||
continue
|
continue
|
||||||
|
|
@ -486,7 +479,7 @@ loop:
|
||||||
// determination for new topics.
|
// determination for new topics.
|
||||||
// if topicRegisterLookupDone == nil {
|
// if topicRegisterLookupDone == nil {
|
||||||
if topicRegisterLookupTarget.target == (common.Hash{}) {
|
if topicRegisterLookupTarget.target == (common.Hash{}) {
|
||||||
debugLog("topicRegisterLookupTarget == null")
|
log.Trace("topicRegisterLookupTarget == null")
|
||||||
if topicRegisterLookupTick.Stop() {
|
if topicRegisterLookupTick.Stop() {
|
||||||
<-topicRegisterLookupTick.C
|
<-topicRegisterLookupTick.C
|
||||||
}
|
}
|
||||||
|
|
@ -496,7 +489,7 @@ loop:
|
||||||
}
|
}
|
||||||
|
|
||||||
case nodes := <-topicRegisterLookupDone:
|
case nodes := <-topicRegisterLookupDone:
|
||||||
debugLog("<-topicRegisterLookupDone")
|
log.Trace("<-topicRegisterLookupDone")
|
||||||
net.ticketStore.registerLookupDone(topicRegisterLookupTarget, nodes, func(n *Node) []byte {
|
net.ticketStore.registerLookupDone(topicRegisterLookupTarget, nodes, func(n *Node) []byte {
|
||||||
net.ping(n, n.addr())
|
net.ping(n, n.addr())
|
||||||
return n.pingEcho
|
return n.pingEcho
|
||||||
|
|
@ -507,7 +500,7 @@ loop:
|
||||||
topicRegisterLookupDone = nil
|
topicRegisterLookupDone = nil
|
||||||
|
|
||||||
case <-topicRegisterLookupTick.C:
|
case <-topicRegisterLookupTick.C:
|
||||||
debugLog("<-topicRegisterLookupTick")
|
log.Trace("<-topicRegisterLookupTick")
|
||||||
if (topicRegisterLookupTarget.target == common.Hash{}) {
|
if (topicRegisterLookupTarget.target == common.Hash{}) {
|
||||||
target, delay := net.ticketStore.nextRegisterLookup()
|
target, delay := net.ticketStore.nextRegisterLookup()
|
||||||
topicRegisterLookupTarget = target
|
topicRegisterLookupTarget = target
|
||||||
|
|
@ -520,14 +513,14 @@ loop:
|
||||||
}
|
}
|
||||||
|
|
||||||
case <-nextRegisterTime:
|
case <-nextRegisterTime:
|
||||||
debugLog("<-nextRegisterTime")
|
log.Trace("<-nextRegisterTime")
|
||||||
net.ticketStore.ticketRegistered(*nextTicket)
|
net.ticketStore.ticketRegistered(*nextTicket)
|
||||||
//fmt.Println("sendTopicRegister", nextTicket.t.node.addr().String(), nextTicket.t.topics, nextTicket.idx, nextTicket.t.pong)
|
//fmt.Println("sendTopicRegister", nextTicket.t.node.addr().String(), nextTicket.t.topics, nextTicket.idx, nextTicket.t.pong)
|
||||||
net.conn.sendTopicRegister(nextTicket.t.node, nextTicket.t.topics, nextTicket.idx, nextTicket.t.pong)
|
net.conn.sendTopicRegister(nextTicket.t.node, nextTicket.t.topics, nextTicket.idx, nextTicket.t.pong)
|
||||||
|
|
||||||
case req := <-net.topicSearchReq:
|
case req := <-net.topicSearchReq:
|
||||||
if refreshDone == nil {
|
if refreshDone == nil {
|
||||||
debugLog("<-net.topicSearchReq")
|
log.Trace("<-net.topicSearchReq")
|
||||||
info, ok := searchInfo[req.topic]
|
info, ok := searchInfo[req.topic]
|
||||||
if ok {
|
if ok {
|
||||||
if req.delay == time.Duration(0) {
|
if req.delay == time.Duration(0) {
|
||||||
|
|
@ -588,7 +581,7 @@ loop:
|
||||||
})
|
})
|
||||||
|
|
||||||
case <-statsDump.C:
|
case <-statsDump.C:
|
||||||
debugLog("<-statsDump.C")
|
log.Trace("<-statsDump.C")
|
||||||
/*r, ok := net.ticketStore.radius[testTopic]
|
/*r, ok := net.ticketStore.radius[testTopic]
|
||||||
if !ok {
|
if !ok {
|
||||||
fmt.Printf("(%x) no radius @ %v\n", net.tab.self.ID[:8], time.Now())
|
fmt.Printf("(%x) no radius @ %v\n", net.tab.self.ID[:8], time.Now())
|
||||||
|
|
@ -617,7 +610,7 @@ loop:
|
||||||
|
|
||||||
// Periodic / lookup-initiated bucket refresh.
|
// Periodic / lookup-initiated bucket refresh.
|
||||||
case <-refreshTimer.C:
|
case <-refreshTimer.C:
|
||||||
debugLog("<-refreshTimer.C")
|
log.Trace("<-refreshTimer.C")
|
||||||
// TODO: ideally we would start the refresh timer after
|
// TODO: ideally we would start the refresh timer after
|
||||||
// fallback nodes have been set for the first time.
|
// fallback nodes have been set for the first time.
|
||||||
if refreshDone == nil {
|
if refreshDone == nil {
|
||||||
|
|
@ -631,7 +624,7 @@ loop:
|
||||||
bucketRefreshTimer.Reset(bucketRefreshInterval)
|
bucketRefreshTimer.Reset(bucketRefreshInterval)
|
||||||
}()
|
}()
|
||||||
case newNursery := <-net.refreshReq:
|
case newNursery := <-net.refreshReq:
|
||||||
debugLog("<-net.refreshReq")
|
log.Trace("<-net.refreshReq")
|
||||||
if newNursery != nil {
|
if newNursery != nil {
|
||||||
net.nursery = newNursery
|
net.nursery = newNursery
|
||||||
}
|
}
|
||||||
|
|
@ -641,7 +634,7 @@ loop:
|
||||||
}
|
}
|
||||||
net.refreshResp <- refreshDone
|
net.refreshResp <- refreshDone
|
||||||
case <-refreshDone:
|
case <-refreshDone:
|
||||||
debugLog("<-net.refreshDone")
|
log.Trace("<-net.refreshDone")
|
||||||
refreshDone = nil
|
refreshDone = nil
|
||||||
list := searchReqWhenRefreshDone
|
list := searchReqWhenRefreshDone
|
||||||
searchReqWhenRefreshDone = nil
|
searchReqWhenRefreshDone = nil
|
||||||
|
|
@ -652,7 +645,7 @@ loop:
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
debugLog("loop stopped")
|
log.Trace("loop stopped")
|
||||||
|
|
||||||
log.Debug(fmt.Sprintf("shutting down"))
|
log.Debug(fmt.Sprintf("shutting down"))
|
||||||
if net.conn != nil {
|
if net.conn != nil {
|
||||||
|
|
@ -1109,14 +1102,14 @@ func (net *Network) ping(n *Node, addr *net.UDPAddr) {
|
||||||
//fmt.Println(" not sent")
|
//fmt.Println(" not sent")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
debugLog(fmt.Sprintf("ping(node = %x)", n.ID[:8]))
|
log.Trace("Pinging remote node", "node", n.ID)
|
||||||
n.pingTopics = net.ticketStore.regTopicSet()
|
n.pingTopics = net.ticketStore.regTopicSet()
|
||||||
n.pingEcho = net.conn.sendPing(n, addr, n.pingTopics)
|
n.pingEcho = net.conn.sendPing(n, addr, n.pingTopics)
|
||||||
net.timedEvent(respTimeout, n, pongTimeout)
|
net.timedEvent(respTimeout, n, pongTimeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (net *Network) handlePing(n *Node, pkt *ingressPacket) {
|
func (net *Network) handlePing(n *Node, pkt *ingressPacket) {
|
||||||
debugLog(fmt.Sprintf("handlePing(node = %x)", n.ID[:8]))
|
log.Trace("Handling remote ping", "node", n.ID)
|
||||||
ping := pkt.data.(*ping)
|
ping := pkt.data.(*ping)
|
||||||
n.TCP = ping.From.TCP
|
n.TCP = ping.From.TCP
|
||||||
t := net.topictab.getTicket(n, ping.Topics)
|
t := net.topictab.getTicket(n, ping.Topics)
|
||||||
|
|
@ -1131,7 +1124,7 @@ func (net *Network) handlePing(n *Node, pkt *ingressPacket) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (net *Network) handleKnownPong(n *Node, pkt *ingressPacket) error {
|
func (net *Network) handleKnownPong(n *Node, pkt *ingressPacket) error {
|
||||||
debugLog(fmt.Sprintf("handleKnownPong(node = %x)", n.ID[:8]))
|
log.Trace("Handling known pong", "node", n.ID)
|
||||||
net.abortTimedEvent(n, pongTimeout)
|
net.abortTimedEvent(n, pongTimeout)
|
||||||
now := mclock.Now()
|
now := mclock.Now()
|
||||||
ticket, err := pongToTicket(now, n.pingTopics, n, pkt)
|
ticket, err := pongToTicket(now, n.pingTopics, n, pkt)
|
||||||
|
|
@ -1139,9 +1132,8 @@ func (net *Network) handleKnownPong(n *Node, pkt *ingressPacket) error {
|
||||||
// fmt.Printf("(%x) ticket: %+v\n", net.tab.self.ID[:8], pkt.data)
|
// fmt.Printf("(%x) ticket: %+v\n", net.tab.self.ID[:8], pkt.data)
|
||||||
net.ticketStore.addTicket(now, pkt.data.(*pong).ReplyTok, ticket)
|
net.ticketStore.addTicket(now, pkt.data.(*pong).ReplyTok, ticket)
|
||||||
} else {
|
} else {
|
||||||
debugLog(fmt.Sprintf(" error: %v", err))
|
log.Trace("Failed to convert pong to ticket", "err", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
n.pingEcho = nil
|
n.pingEcho = nil
|
||||||
n.pingTopics = nil
|
n.pingTopics = nil
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -273,6 +273,11 @@ func (n NodeID) GoString() string {
|
||||||
return fmt.Sprintf("discover.HexID(\"%x\")", n[:])
|
return fmt.Sprintf("discover.HexID(\"%x\")", n[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TerminalString returns a shortened hex string for terminal logging.
|
||||||
|
func (n NodeID) TerminalString() string {
|
||||||
|
return hex.EncodeToString(n[:8])
|
||||||
|
}
|
||||||
|
|
||||||
// HexID converts a hex string to a NodeID.
|
// HexID converts a hex string to a NodeID.
|
||||||
// The string may be prefixed with 0x.
|
// The string may be prefixed with 0x.
|
||||||
func HexID(in string) (NodeID, error) {
|
func HexID(in string) (NodeID, error) {
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/mclock"
|
"github.com/ethereum/go-ethereum/common/mclock"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -128,8 +129,11 @@ type ticketStore struct {
|
||||||
// Contains buckets (for each absolute minute) of tickets
|
// Contains buckets (for each absolute minute) of tickets
|
||||||
// that can be used in that minute.
|
// that can be used in that minute.
|
||||||
// This is only set if the topic is being registered.
|
// This is only set if the topic is being registered.
|
||||||
tickets map[Topic]topicTickets
|
tickets map[Topic]*topicTickets
|
||||||
regtopics []Topic
|
|
||||||
|
regQueue []Topic // Topic registration queue for round robin attempts
|
||||||
|
regSet map[Topic]struct{} // Topic registration queue contents for fast filling
|
||||||
|
|
||||||
nodes map[*Node]*ticket
|
nodes map[*Node]*ticket
|
||||||
nodeLastReq map[*Node]reqInfo
|
nodeLastReq map[*Node]reqInfo
|
||||||
|
|
||||||
|
|
@ -152,14 +156,16 @@ type sentQuery struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type topicTickets struct {
|
type topicTickets struct {
|
||||||
buckets map[timeBucket][]ticketRef
|
buckets map[timeBucket][]ticketRef
|
||||||
nextLookup, nextReg mclock.AbsTime
|
nextLookup mclock.AbsTime
|
||||||
|
nextReg mclock.AbsTime
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTicketStore() *ticketStore {
|
func newTicketStore() *ticketStore {
|
||||||
return &ticketStore{
|
return &ticketStore{
|
||||||
radius: make(map[Topic]*topicRadius),
|
radius: make(map[Topic]*topicRadius),
|
||||||
tickets: make(map[Topic]topicTickets),
|
tickets: make(map[Topic]*topicTickets),
|
||||||
|
regSet: make(map[Topic]struct{}),
|
||||||
nodes: make(map[*Node]*ticket),
|
nodes: make(map[*Node]*ticket),
|
||||||
nodeLastReq: make(map[*Node]reqInfo),
|
nodeLastReq: make(map[*Node]reqInfo),
|
||||||
searchTopicMap: make(map[Topic]searchTopic),
|
searchTopicMap: make(map[Topic]searchTopic),
|
||||||
|
|
@ -169,13 +175,13 @@ func newTicketStore() *ticketStore {
|
||||||
|
|
||||||
// addTopic starts tracking a topic. If register is true,
|
// addTopic starts tracking a topic. If register is true,
|
||||||
// the local node will register the topic and tickets will be collected.
|
// the local node will register the topic and tickets will be collected.
|
||||||
func (s *ticketStore) addTopic(t Topic, register bool) {
|
func (s *ticketStore) addTopic(topic Topic, register bool) {
|
||||||
debugLog(fmt.Sprintf(" addTopic(%v, %v)", t, register))
|
log.Trace("Adding discovery topic", "topic", topic, "register", register)
|
||||||
if s.radius[t] == nil {
|
if s.radius[topic] == nil {
|
||||||
s.radius[t] = newTopicRadius(t)
|
s.radius[topic] = newTopicRadius(topic)
|
||||||
}
|
}
|
||||||
if register && s.tickets[t].buckets == nil {
|
if register && s.tickets[topic] == nil {
|
||||||
s.tickets[t] = topicTickets{buckets: make(map[timeBucket][]ticketRef)}
|
s.tickets[topic] = &topicTickets{buckets: make(map[timeBucket][]ticketRef)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -194,7 +200,11 @@ func (s *ticketStore) removeSearchTopic(t Topic) {
|
||||||
|
|
||||||
// removeRegisterTopic deletes all tickets for the given topic.
|
// removeRegisterTopic deletes all tickets for the given topic.
|
||||||
func (s *ticketStore) removeRegisterTopic(topic Topic) {
|
func (s *ticketStore) removeRegisterTopic(topic Topic) {
|
||||||
debugLog(fmt.Sprintf(" removeRegisterTopic(%v)", topic))
|
log.Trace("Removing discovery topic", "topic", topic)
|
||||||
|
if s.tickets[topic] == nil {
|
||||||
|
log.Warn("Removing non-existent discovery topic", "topic", topic)
|
||||||
|
return
|
||||||
|
}
|
||||||
for _, list := range s.tickets[topic].buckets {
|
for _, list := range s.tickets[topic].buckets {
|
||||||
for _, ref := range list {
|
for _, ref := range list {
|
||||||
ref.t.refCnt--
|
ref.t.refCnt--
|
||||||
|
|
@ -216,23 +226,35 @@ func (s *ticketStore) regTopicSet() []Topic {
|
||||||
}
|
}
|
||||||
|
|
||||||
// nextRegisterLookup returns the target of the next lookup for ticket collection.
|
// nextRegisterLookup returns the target of the next lookup for ticket collection.
|
||||||
func (s *ticketStore) nextRegisterLookup() (lookup lookupInfo, delay time.Duration) {
|
func (s *ticketStore) nextRegisterLookup() (lookupInfo, time.Duration) {
|
||||||
debugLog("nextRegisterLookup()")
|
// Queue up any new topics (or discarded ones), preserving iteration order
|
||||||
firstTopic, ok := s.iterRegTopics()
|
for topic := range s.tickets {
|
||||||
for topic := firstTopic; ok; {
|
if _, ok := s.regSet[topic]; !ok {
|
||||||
debugLog(fmt.Sprintf(" checking topic %v, len(s.tickets[topic]) = %d", topic, len(s.tickets[topic].buckets)))
|
s.regQueue = append(s.regQueue, topic)
|
||||||
if s.tickets[topic].buckets != nil && s.needMoreTickets(topic) {
|
s.regSet[topic] = struct{}{}
|
||||||
next := s.radius[topic].nextTarget(false)
|
|
||||||
debugLog(fmt.Sprintf(" %x 1s", next.target[:8]))
|
|
||||||
return next, 100 * time.Millisecond
|
|
||||||
}
|
|
||||||
topic, ok = s.iterRegTopics()
|
|
||||||
if topic == firstTopic {
|
|
||||||
break // We have checked all topics.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
debugLog(" null, 40s")
|
// Iterate over the set of all topics and look up the next suitable one
|
||||||
return lookupInfo{}, 40 * time.Second
|
for len(s.regQueue) > 0 {
|
||||||
|
// Fetch the next topic from the queue, and ensure it still exists
|
||||||
|
topic := s.regQueue[0]
|
||||||
|
s.regQueue = s.regQueue[1:]
|
||||||
|
delete(s.regSet, topic)
|
||||||
|
|
||||||
|
if s.tickets[topic] == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// If the topic needs more tickets, return it
|
||||||
|
if s.tickets[topic].nextLookup < mclock.Now() {
|
||||||
|
next, delay := s.radius[topic].nextTarget(false), 100*time.Millisecond
|
||||||
|
log.Trace("Found discovery topic to register", "topic", topic, "target", next.target, "delay", delay)
|
||||||
|
return next, delay
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// No registration topics found or all exhausted, sleep
|
||||||
|
delay := 40 * time.Second
|
||||||
|
log.Trace("No topic found to register", "delay", delay)
|
||||||
|
return lookupInfo{}, delay
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ticketStore) nextSearchLookup(topic Topic) lookupInfo {
|
func (s *ticketStore) nextSearchLookup(topic Topic) lookupInfo {
|
||||||
|
|
@ -246,40 +268,22 @@ func (s *ticketStore) nextSearchLookup(topic Topic) lookupInfo {
|
||||||
return target
|
return target
|
||||||
}
|
}
|
||||||
|
|
||||||
// iterRegTopics returns topics to register in arbitrary order.
|
|
||||||
// The second return value is false if there are no topics.
|
|
||||||
func (s *ticketStore) iterRegTopics() (Topic, bool) {
|
|
||||||
debugLog("iterRegTopics()")
|
|
||||||
if len(s.regtopics) == 0 {
|
|
||||||
if len(s.tickets) == 0 {
|
|
||||||
debugLog(" false")
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
// Refill register list.
|
|
||||||
for t := range s.tickets {
|
|
||||||
s.regtopics = append(s.regtopics, t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
topic := s.regtopics[len(s.regtopics)-1]
|
|
||||||
s.regtopics = s.regtopics[:len(s.regtopics)-1]
|
|
||||||
debugLog(" " + string(topic) + " true")
|
|
||||||
return topic, true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ticketStore) needMoreTickets(t Topic) bool {
|
|
||||||
return s.tickets[t].nextLookup < mclock.Now()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ticketsInWindow returns the tickets of a given topic in the registration window.
|
// ticketsInWindow returns the tickets of a given topic in the registration window.
|
||||||
func (s *ticketStore) ticketsInWindow(t Topic) []ticketRef {
|
func (s *ticketStore) ticketsInWindow(topic Topic) []ticketRef {
|
||||||
ltBucket := s.lastBucketFetched
|
// Sanity check that the topic still exists before operating on it
|
||||||
var res []ticketRef
|
if s.tickets[topic] == nil {
|
||||||
tickets := s.tickets[t].buckets
|
log.Warn("Listing non-existing discovery tickets", "topic", topic)
|
||||||
for g := ltBucket; g < ltBucket+timeWindow; g++ {
|
return nil
|
||||||
res = append(res, tickets[g]...)
|
|
||||||
}
|
}
|
||||||
debugLog(fmt.Sprintf("ticketsInWindow(%v) = %v", t, len(res)))
|
// Gather all the tickers in the next time window
|
||||||
return res
|
var tickets []ticketRef
|
||||||
|
|
||||||
|
buckets := s.tickets[topic].buckets
|
||||||
|
for idx := timeBucket(0); idx < timeWindow; idx++ {
|
||||||
|
tickets = append(tickets, buckets[s.lastBucketFetched+idx]...)
|
||||||
|
}
|
||||||
|
log.Trace("Retrieved discovery registration tickets", "topic", topic, "from", s.lastBucketFetched, "tickets", len(tickets))
|
||||||
|
return tickets
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ticketStore) removeExcessTickets(t Topic) {
|
func (s *ticketStore) removeExcessTickets(t Topic) {
|
||||||
|
|
@ -317,53 +321,55 @@ func (s ticketRefByWaitTime) Swap(i, j int) {
|
||||||
|
|
||||||
func (s *ticketStore) addTicketRef(r ticketRef) {
|
func (s *ticketStore) addTicketRef(r ticketRef) {
|
||||||
topic := r.t.topics[r.idx]
|
topic := r.t.topics[r.idx]
|
||||||
t := s.tickets[topic]
|
tickets := s.tickets[topic]
|
||||||
if t.buckets == nil {
|
if tickets == nil {
|
||||||
|
log.Warn("Adding ticket to non-existent topic", "topic", topic)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
bucket := timeBucket(r.t.regTime[r.idx] / mclock.AbsTime(ticketTimeBucketLen))
|
bucket := timeBucket(r.t.regTime[r.idx] / mclock.AbsTime(ticketTimeBucketLen))
|
||||||
t.buckets[bucket] = append(t.buckets[bucket], r)
|
tickets.buckets[bucket] = append(tickets.buckets[bucket], r)
|
||||||
r.t.refCnt++
|
r.t.refCnt++
|
||||||
|
|
||||||
min := mclock.Now() - mclock.AbsTime(collectFrequency)*maxCollectDebt
|
min := mclock.Now() - mclock.AbsTime(collectFrequency)*maxCollectDebt
|
||||||
if t.nextLookup < min {
|
if tickets.nextLookup < min {
|
||||||
t.nextLookup = min
|
tickets.nextLookup = min
|
||||||
}
|
}
|
||||||
t.nextLookup += mclock.AbsTime(collectFrequency)
|
tickets.nextLookup += mclock.AbsTime(collectFrequency)
|
||||||
s.tickets[topic] = t
|
|
||||||
|
|
||||||
//s.removeExcessTickets(topic)
|
//s.removeExcessTickets(topic)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ticketStore) nextFilteredTicket() (t *ticketRef, wait time.Duration) {
|
func (s *ticketStore) nextFilteredTicket() (*ticketRef, time.Duration) {
|
||||||
now := mclock.Now()
|
now := mclock.Now()
|
||||||
for {
|
for {
|
||||||
t, wait = s.nextRegisterableTicket()
|
ticket, wait := s.nextRegisterableTicket()
|
||||||
if t == nil {
|
if ticket == nil {
|
||||||
return
|
return ticket, wait
|
||||||
}
|
}
|
||||||
|
log.Trace("Found discovery ticket to register", "node", ticket.t.node, "serial", ticket.t.serial, "wait", wait)
|
||||||
|
|
||||||
regTime := now + mclock.AbsTime(wait)
|
regTime := now + mclock.AbsTime(wait)
|
||||||
topic := t.t.topics[t.idx]
|
topic := ticket.t.topics[ticket.idx]
|
||||||
if regTime >= s.tickets[topic].nextReg {
|
if regTime >= s.tickets[topic].nextReg {
|
||||||
return
|
return ticket, wait
|
||||||
}
|
}
|
||||||
s.removeTicketRef(*t)
|
s.removeTicketRef(*ticket)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ticketStore) ticketRegistered(t ticketRef) {
|
func (s *ticketStore) ticketRegistered(ref ticketRef) {
|
||||||
now := mclock.Now()
|
now := mclock.Now()
|
||||||
|
|
||||||
topic := t.t.topics[t.idx]
|
topic := ref.t.topics[ref.idx]
|
||||||
tt := s.tickets[topic]
|
tickets := s.tickets[topic]
|
||||||
min := now - mclock.AbsTime(registerFrequency)*maxRegisterDebt
|
min := now - mclock.AbsTime(registerFrequency)*maxRegisterDebt
|
||||||
if min > tt.nextReg {
|
if min > tickets.nextReg {
|
||||||
tt.nextReg = min
|
tickets.nextReg = min
|
||||||
}
|
}
|
||||||
tt.nextReg += mclock.AbsTime(registerFrequency)
|
tickets.nextReg += mclock.AbsTime(registerFrequency)
|
||||||
s.tickets[topic] = tt
|
s.tickets[topic] = tickets
|
||||||
|
|
||||||
s.removeTicketRef(t)
|
s.removeTicketRef(ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
// nextRegisterableTicket returns the next ticket that can be used
|
// nextRegisterableTicket returns the next ticket that can be used
|
||||||
|
|
@ -374,16 +380,7 @@ func (s *ticketStore) ticketRegistered(t ticketRef) {
|
||||||
//
|
//
|
||||||
// A ticket can be returned more than once with <= zero wait time in case
|
// A ticket can be returned more than once with <= zero wait time in case
|
||||||
// the ticket contains multiple topics.
|
// the ticket contains multiple topics.
|
||||||
func (s *ticketStore) nextRegisterableTicket() (t *ticketRef, wait time.Duration) {
|
func (s *ticketStore) nextRegisterableTicket() (*ticketRef, time.Duration) {
|
||||||
defer func() {
|
|
||||||
if t == nil {
|
|
||||||
debugLog(" nil")
|
|
||||||
} else {
|
|
||||||
debugLog(fmt.Sprintf(" node = %x sn = %v wait = %v", t.t.node.ID[:8], t.t.serial, wait))
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
debugLog("nextRegisterableTicket()")
|
|
||||||
now := mclock.Now()
|
now := mclock.Now()
|
||||||
if s.nextTicketCached != nil {
|
if s.nextTicketCached != nil {
|
||||||
return s.nextTicketCached, time.Duration(s.nextTicketCached.topicRegTime() - now)
|
return s.nextTicketCached, time.Duration(s.nextTicketCached.topicRegTime() - now)
|
||||||
|
|
@ -412,9 +409,8 @@ func (s *ticketStore) nextRegisterableTicket() (t *ticketRef, wait time.Duration
|
||||||
return nil, 0
|
return nil, 0
|
||||||
}
|
}
|
||||||
if nextTicket.t != nil {
|
if nextTicket.t != nil {
|
||||||
wait = time.Duration(nextTicket.topicRegTime() - now)
|
|
||||||
s.nextTicketCached = &nextTicket
|
s.nextTicketCached = &nextTicket
|
||||||
return &nextTicket, wait
|
return &nextTicket, time.Duration(nextTicket.topicRegTime() - now)
|
||||||
}
|
}
|
||||||
s.lastBucketFetched = bucket
|
s.lastBucketFetched = bucket
|
||||||
}
|
}
|
||||||
|
|
@ -422,14 +418,17 @@ func (s *ticketStore) nextRegisterableTicket() (t *ticketRef, wait time.Duration
|
||||||
|
|
||||||
// removeTicket removes a ticket from the ticket store
|
// removeTicket removes a ticket from the ticket store
|
||||||
func (s *ticketStore) removeTicketRef(ref ticketRef) {
|
func (s *ticketStore) removeTicketRef(ref ticketRef) {
|
||||||
debugLog(fmt.Sprintf("removeTicketRef(node = %x sn = %v)", ref.t.node.ID[:8], ref.t.serial))
|
log.Trace("Removing discovery ticket reference", "node", ref.t.node.ID, "serial", ref.t.serial)
|
||||||
|
|
||||||
topic := ref.topic()
|
topic := ref.topic()
|
||||||
tickets := s.tickets[topic].buckets
|
tickets := s.tickets[topic]
|
||||||
|
|
||||||
if tickets == nil {
|
if tickets == nil {
|
||||||
|
log.Warn("Removing tickets from unknown topic", "topic", topic)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
bucket := timeBucket(ref.t.regTime[ref.idx] / mclock.AbsTime(ticketTimeBucketLen))
|
bucket := timeBucket(ref.t.regTime[ref.idx] / mclock.AbsTime(ticketTimeBucketLen))
|
||||||
list := tickets[bucket]
|
list := tickets.buckets[bucket]
|
||||||
idx := -1
|
idx := -1
|
||||||
for i, bt := range list {
|
for i, bt := range list {
|
||||||
if bt.t == ref.t {
|
if bt.t == ref.t {
|
||||||
|
|
@ -442,9 +441,9 @@ func (s *ticketStore) removeTicketRef(ref ticketRef) {
|
||||||
}
|
}
|
||||||
list = append(list[:idx], list[idx+1:]...)
|
list = append(list[:idx], list[idx+1:]...)
|
||||||
if len(list) != 0 {
|
if len(list) != 0 {
|
||||||
tickets[bucket] = list
|
tickets.buckets[bucket] = list
|
||||||
} else {
|
} else {
|
||||||
delete(tickets, bucket)
|
delete(tickets.buckets, bucket)
|
||||||
}
|
}
|
||||||
ref.t.refCnt--
|
ref.t.refCnt--
|
||||||
if ref.t.refCnt == 0 {
|
if ref.t.refCnt == 0 {
|
||||||
|
|
@ -523,21 +522,21 @@ func (s *ticketStore) adjustWithTicket(now mclock.AbsTime, targetHash common.Has
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ticketStore) addTicket(localTime mclock.AbsTime, pingHash []byte, t *ticket) {
|
func (s *ticketStore) addTicket(localTime mclock.AbsTime, pingHash []byte, ticket *ticket) {
|
||||||
debugLog(fmt.Sprintf("add(node = %x sn = %v)", t.node.ID[:8], t.serial))
|
log.Trace("Adding discovery ticket", "node", ticket.node.ID, "serial", ticket.serial)
|
||||||
|
|
||||||
lastReq, ok := s.nodeLastReq[t.node]
|
lastReq, ok := s.nodeLastReq[ticket.node]
|
||||||
if !(ok && bytes.Equal(pingHash, lastReq.pingHash)) {
|
if !(ok && bytes.Equal(pingHash, lastReq.pingHash)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.adjustWithTicket(localTime, lastReq.lookup.target, t)
|
s.adjustWithTicket(localTime, lastReq.lookup.target, ticket)
|
||||||
|
|
||||||
if lastReq.lookup.radiusLookup || s.nodes[t.node] != nil {
|
if lastReq.lookup.radiusLookup || s.nodes[ticket.node] != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
topic := lastReq.lookup.topic
|
topic := lastReq.lookup.topic
|
||||||
topicIdx := t.findIdx(topic)
|
topicIdx := ticket.findIdx(topic)
|
||||||
if topicIdx == -1 {
|
if topicIdx == -1 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -548,29 +547,29 @@ func (s *ticketStore) addTicket(localTime mclock.AbsTime, pingHash []byte, t *ti
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := s.tickets[topic]; ok {
|
if _, ok := s.tickets[topic]; ok {
|
||||||
wait := t.regTime[topicIdx] - localTime
|
wait := ticket.regTime[topicIdx] - localTime
|
||||||
rnd := rand.ExpFloat64()
|
rnd := rand.ExpFloat64()
|
||||||
if rnd > 10 {
|
if rnd > 10 {
|
||||||
rnd = 10
|
rnd = 10
|
||||||
}
|
}
|
||||||
if float64(wait) < float64(keepTicketConst)+float64(keepTicketExp)*rnd {
|
if float64(wait) < float64(keepTicketConst)+float64(keepTicketExp)*rnd {
|
||||||
// use the ticket to register this topic
|
// use the ticket to register this topic
|
||||||
//fmt.Println("addTicket", t.node.ID[:8], t.node.addr().String(), t.serial, t.pong)
|
//fmt.Println("addTicket", ticket.node.ID[:8], ticket.node.addr().String(), ticket.serial, ticket.pong)
|
||||||
s.addTicketRef(ticketRef{t, topicIdx})
|
s.addTicketRef(ticketRef{ticket, topicIdx})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.refCnt > 0 {
|
if ticket.refCnt > 0 {
|
||||||
s.nextTicketCached = nil
|
s.nextTicketCached = nil
|
||||||
s.nodes[t.node] = t
|
s.nodes[ticket.node] = ticket
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ticketStore) getNodeTicket(node *Node) *ticket {
|
func (s *ticketStore) getNodeTicket(node *Node) *ticket {
|
||||||
if s.nodes[node] == nil {
|
if s.nodes[node] == nil {
|
||||||
debugLog(fmt.Sprintf("getNodeTicket(%x) sn = nil", node.ID[:8]))
|
log.Trace("Retrieving node ticket", "node", node.ID, "serial", nil)
|
||||||
} else {
|
} else {
|
||||||
debugLog(fmt.Sprintf("getNodeTicket(%x) sn = %v", node.ID[:8], s.nodes[node].serial))
|
log.Trace("Retrieving node ticket", "node", node.ID, "serial", s.nodes[node].serial)
|
||||||
}
|
}
|
||||||
return s.nodes[node]
|
return s.nodes[node]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue