Update from Upstream Go-Ethereum

This commit is contained in:
Yohan Graterol 2018-01-07 19:52:44 -05:00
commit d01e79ed5f
No known key found for this signature in database
GPG key ID: D8C4A70CC26A1F90
141 changed files with 2132 additions and 1136 deletions

View file

@ -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

View file

@ -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:]
}

View file

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

View file

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

View file

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

View file

@ -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
} }

View file

@ -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

View file

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

View file

@ -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) {

View file

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

View file

@ -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,18 +173,25 @@ 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") {
// Figure out the minor version number since we can't textually compare (1.10 < 1.7)
var minor int
fmt.Sscanf(strings.TrimPrefix(runtime.Version(), "go1."), "%d", &minor)
if minor < 7 {
log.Println("You have Go version", runtime.Version()) log.Println("You have Go version", runtime.Version())
log.Println("go-ethereum requires at least Go version 1.7 and cannot") 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.") log.Println("be compiled with an earlier version. Please upgrade your Go installation.")
os.Exit(1) 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{"./..."}
if flag.NArg() > 0 { if flag.NArg() > 0 {
@ -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

View file

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

View file

@ -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
} }

View file

@ -44,7 +44,7 @@ type cppEthereumGenesisSpec struct {
MaximumExtraDataSize hexutil.Uint64 `json:"maximumExtraDataSize"` MaximumExtraDataSize hexutil.Uint64 `json:"maximumExtraDataSize"`
MinGasLimit hexutil.Uint64 `json:"minGasLimit"` MinGasLimit hexutil.Uint64 `json:"minGasLimit"`
MaxGasLimit hexutil.Uint64 `json:"maxGasLimit"` MaxGasLimit hexutil.Uint64 `json:"maxGasLimit"`
GasLimitBoundDivisor *hexutil.Big `json:"gasLimitBoundDivisor"` GasLimitBoundDivisor hexutil.Uint64 `json:"gasLimitBoundDivisor"`
MinimumDifficulty *hexutil.Big `json:"minimumDifficulty"` MinimumDifficulty *hexutil.Big `json:"minimumDifficulty"`
DifficultyBoundDivisor *hexutil.Big `json:"difficultyBoundDivisor"` DifficultyBoundDivisor *hexutil.Big `json:"difficultyBoundDivisor"`
DurationLimit *hexutil.Big `json:"durationLimit"` DurationLimit *hexutil.Big `json:"durationLimit"`
@ -107,11 +107,11 @@ func newCppEthereumGenesisSpec(network string, genesis *core.Genesis) (*cppEther
spec.Params.ChainID = (hexutil.Uint64)(genesis.Config.ChainId.Uint64()) spec.Params.ChainID = (hexutil.Uint64)(genesis.Config.ChainId.Uint64())
spec.Params.MaximumExtraDataSize = (hexutil.Uint64)(params.MaximumExtraDataSize) spec.Params.MaximumExtraDataSize = (hexutil.Uint64)(params.MaximumExtraDataSize)
spec.Params.MinGasLimit = (hexutil.Uint64)(params.MinGasLimit.Uint64()) spec.Params.MinGasLimit = (hexutil.Uint64)(params.MinGasLimit)
spec.Params.MaxGasLimit = (hexutil.Uint64)(math.MaxUint64) spec.Params.MaxGasLimit = (hexutil.Uint64)(math.MaxUint64)
spec.Params.MinimumDifficulty = (*hexutil.Big)(params.MinimumDifficulty) spec.Params.MinimumDifficulty = (*hexutil.Big)(params.MinimumDifficulty)
spec.Params.DifficultyBoundDivisor = (*hexutil.Big)(params.DifficultyBoundDivisor) spec.Params.DifficultyBoundDivisor = (*hexutil.Big)(params.DifficultyBoundDivisor)
spec.Params.GasLimitBoundDivisor = (*hexutil.Big)(params.GasLimitBoundDivisor) spec.Params.GasLimitBoundDivisor = (hexutil.Uint64)(params.GasLimitBoundDivisor)
spec.Params.DurationLimit = (*hexutil.Big)(params.DurationLimit) spec.Params.DurationLimit = (*hexutil.Big)(params.DurationLimit)
spec.Params.BlockReward = (*hexutil.Big)(ethash.FrontierBlockReward) spec.Params.BlockReward = (*hexutil.Big)(ethash.FrontierBlockReward)
@ -170,7 +170,7 @@ type parityChainSpec 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"`
@ -187,7 +187,7 @@ type parityChainSpec struct {
Params struct { Params struct {
MaximumExtraDataSize hexutil.Uint64 `json:"maximumExtraDataSize"` MaximumExtraDataSize hexutil.Uint64 `json:"maximumExtraDataSize"`
MinGasLimit *hexutil.Big `json:"minGasLimit"` MinGasLimit hexutil.Uint64 `json:"minGasLimit"`
NetworkID hexutil.Uint64 `json:"networkID"` NetworkID hexutil.Uint64 `json:"networkID"`
MaxCodeSize uint64 `json:"maxCodeSize"` MaxCodeSize uint64 `json:"maxCodeSize"`
EIP155Transition uint64 `json:"eip155Transition"` EIP155Transition uint64 `json:"eip155Transition"`
@ -270,7 +270,7 @@ func newParityChainSpec(network string, genesis *core.Genesis, bootnodes []strin
} }
spec.Engine.Ethash.Params.MinimumDifficulty = (*hexutil.Big)(params.MinimumDifficulty) spec.Engine.Ethash.Params.MinimumDifficulty = (*hexutil.Big)(params.MinimumDifficulty)
spec.Engine.Ethash.Params.DifficultyBoundDivisor = (*hexutil.Big)(params.DifficultyBoundDivisor) spec.Engine.Ethash.Params.DifficultyBoundDivisor = (*hexutil.Big)(params.DifficultyBoundDivisor)
spec.Engine.Ethash.Params.GasLimitBoundDivisor = (*hexutil.Big)(params.GasLimitBoundDivisor) spec.Engine.Ethash.Params.GasLimitBoundDivisor = (hexutil.Uint64)(params.GasLimitBoundDivisor)
spec.Engine.Ethash.Params.DurationLimit = (*hexutil.Big)(params.DurationLimit) spec.Engine.Ethash.Params.DurationLimit = (*hexutil.Big)(params.DurationLimit)
spec.Engine.Ethash.Params.BlockReward = (*hexutil.Big)(ethash.FrontierBlockReward) spec.Engine.Ethash.Params.BlockReward = (*hexutil.Big)(ethash.FrontierBlockReward)
spec.Engine.Ethash.Params.HomesteadTransition = genesis.Config.HomesteadBlock.Uint64() spec.Engine.Ethash.Params.HomesteadTransition = genesis.Config.HomesteadBlock.Uint64()
@ -283,7 +283,7 @@ func newParityChainSpec(network string, genesis *core.Genesis, bootnodes []strin
spec.Engine.Ethash.Params.EIP649Transition = genesis.Config.ByzantiumBlock.Uint64() spec.Engine.Ethash.Params.EIP649Transition = genesis.Config.ByzantiumBlock.Uint64()
spec.Params.MaximumExtraDataSize = (hexutil.Uint64)(params.MaximumExtraDataSize) spec.Params.MaximumExtraDataSize = (hexutil.Uint64)(params.MaximumExtraDataSize)
spec.Params.MinGasLimit = (*hexutil.Big)(params.MinGasLimit) spec.Params.MinGasLimit = (hexutil.Uint64)(params.MinGasLimit)
spec.Params.NetworkID = (hexutil.Uint64)(genesis.Config.ChainId.Uint64()) spec.Params.NetworkID = (hexutil.Uint64)(genesis.Config.ChainId.Uint64())
spec.Params.MaxCodeSize = params.MaxCodeSize spec.Params.MaxCodeSize = params.MaxCodeSize
spec.Params.EIP155Transition = genesis.Config.EIP155Block.Uint64() spec.Params.EIP155Transition = genesis.Config.EIP155Block.Uint64()

View file

@ -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)
} }

View file

@ -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.

View file

@ -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
} }

View file

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

View file

@ -248,24 +248,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 {
@ -434,7 +434,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))

View file

@ -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)
} }

View file

@ -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 && \

View file

@ -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/EthereumCommonwealth/go-callisto && \ git clone --depth 1 https://github.com/EthereumCommonwealth/go-callisto && \
(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

View file

@ -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 && \

View file

@ -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/EthereumCommonwealth/go-callisto && \ git clone --depth 1 --branch release/1.7 https://github.com/EthereumCommonwealth/go-callisto && \
(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

View file

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

View file

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

View file

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

View file

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

View file

@ -18,9 +18,7 @@ package core
import ( import (
"fmt" "fmt"
"math/big"
"github.com/EthereumCommonwealth/go-callisto/common/math"
"github.com/EthereumCommonwealth/go-callisto/consensus" "github.com/EthereumCommonwealth/go-callisto/consensus"
"github.com/EthereumCommonwealth/go-callisto/core/state" "github.com/EthereumCommonwealth/go-callisto/core/state"
"github.com/EthereumCommonwealth/go-callisto/core/types" "github.com/EthereumCommonwealth/go-callisto/core/types"
@ -76,10 +74,10 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
// transition, such as amount of used gas, the receipt roots and the state root // transition, such as amount of used gas, the receipt roots and the state root
// itself. ValidateState returns a database batch if the validation was a success // itself. ValidateState returns a database batch if the validation was a success
// otherwise nil and an error is returned. // otherwise nil and an error is returned.
func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *state.StateDB, receipts types.Receipts, usedGas *big.Int) error { func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *state.StateDB, receipts types.Receipts, usedGas uint64) error {
header := block.Header() header := block.Header()
if block.GasUsed().Cmp(usedGas) != 0 { if block.GasUsed() != usedGas {
return fmt.Errorf("invalid gas used (remote: %v local: %v)", block.GasUsed(), usedGas) return fmt.Errorf("invalid gas used (remote: %d local: %d)", block.GasUsed(), usedGas)
} }
// Validate the received block's bloom with the one derived from the generated receipts. // Validate the received block's bloom with the one derived from the generated receipts.
// For valid blocks this should always validate to true. // For valid blocks this should always validate to true.
@ -101,17 +99,13 @@ func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *stat
} }
// CalcGasLimit computes the gas limit of the next block after parent. // CalcGasLimit computes the gas limit of the next block after parent.
// The result may be modified by the caller.
// This is miner strategy, not consensus protocol. // This is miner strategy, not consensus protocol.
func CalcGasLimit(parent *types.Block) *big.Int { func CalcGasLimit(parent *types.Block) uint64 {
// contrib = (parentGasUsed * 3 / 2) / 1024 // contrib = (parentGasUsed * 3 / 2) / 1024
contrib := new(big.Int).Mul(parent.GasUsed(), big.NewInt(3)) contrib := (parent.GasUsed() + parent.GasUsed()/2) / params.GasLimitBoundDivisor
contrib = contrib.Div(contrib, big.NewInt(2))
contrib = contrib.Div(contrib, params.GasLimitBoundDivisor)
// decay = parentGasLimit / 1024 -1 // decay = parentGasLimit / 1024 -1
decay := new(big.Int).Div(parent.GasLimit(), params.GasLimitBoundDivisor) decay := parent.GasLimit()/params.GasLimitBoundDivisor - 1
decay.Sub(decay, big.NewInt(1))
/* /*
strategy: gasLimit of block-to-mine is set based on parent's strategy: gasLimit of block-to-mine is set based on parent's
@ -120,15 +114,17 @@ func CalcGasLimit(parent *types.Block) *big.Int {
at that usage) the amount increased/decreased depends on how far away at that usage) the amount increased/decreased depends on how far away
from parentGasLimit * (2/3) parentGasUsed is. from parentGasLimit * (2/3) parentGasUsed is.
*/ */
gl := new(big.Int).Sub(parent.GasLimit(), decay) limit := parent.GasLimit() - decay + contrib
gl = gl.Add(gl, contrib) if limit < params.MinGasLimit {
gl.Set(math.BigMax(gl, params.MinGasLimit)) limit = params.MinGasLimit
}
// however, if we're now below the target (TargetGasLimit) we increase the // however, if we're now below the target (TargetGasLimit) we increase the
// limit as much as we can (parentGasLimit / 1024 -1) // limit as much as we can (parentGasLimit / 1024 -1)
if gl.Cmp(params.TargetGasLimit) < 0 { if limit < params.TargetGasLimit {
gl.Add(parent.GasLimit(), decay) limit = parent.GasLimit() + decay
gl.Set(math.BigMin(gl, params.TargetGasLimit)) if limit > params.TargetGasLimit {
limit = params.TargetGasLimit
} }
return gl }
return limit
} }

View file

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

View file

@ -340,11 +340,11 @@ func testBrokenChain(t *testing.T, full bool) {
type bproc struct{} type bproc struct{}
func (bproc) ValidateBody(*types.Block) error { return nil } func (bproc) ValidateBody(*types.Block) error { return nil }
func (bproc) ValidateState(block, parent *types.Block, state *state.StateDB, receipts types.Receipts, usedGas *big.Int) error { func (bproc) ValidateState(block, parent *types.Block, state *state.StateDB, receipts types.Receipts, usedGas uint64) error {
return nil return nil
} }
func (bproc) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, *big.Int, error) { func (bproc) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) {
return nil, nil, new(big.Int), nil return nil, nil, 0, nil
} }
func makeHeaderChainWithDiff(genesis *types.Block, d []int, seed byte) []*types.Header { func makeHeaderChainWithDiff(genesis *types.Block, d []int, seed byte) []*types.Header {
@ -506,8 +506,8 @@ func testReorgBadHashes(t *testing.T, full bool) {
if ncm.CurrentBlock().Hash() != blocks[2].Header().Hash() { if ncm.CurrentBlock().Hash() != blocks[2].Header().Hash() {
t.Errorf("last block hash mismatch: have: %x, want %x", ncm.CurrentBlock().Hash(), blocks[2].Header().Hash()) t.Errorf("last block hash mismatch: have: %x, want %x", ncm.CurrentBlock().Hash(), blocks[2].Header().Hash())
} }
if blocks[2].Header().GasLimit.Cmp(ncm.GasLimit()) != 0 { if blocks[2].Header().GasLimit != ncm.GasLimit() {
t.Errorf("last block gasLimit mismatch: have: %x, want %x", ncm.GasLimit(), blocks[2].Header().GasLimit) t.Errorf("last block gasLimit mismatch: have: %d, want %d", ncm.GasLimit(), blocks[2].Header().GasLimit)
} }
} else { } else {
if ncm.CurrentHeader().Hash() != headers[2].Hash() { if ncm.CurrentHeader().Hash() != headers[2].Hash() {
@ -594,7 +594,7 @@ func TestFastVsFullChains(t *testing.T) {
// If the block number is multiple of 3, send a few bonus transactions to the miner // If the block number is multiple of 3, send a few bonus transactions to the miner
if i%3 == 2 { if i%3 == 2 {
for j := 0; j < i%4+1; j++ { for j := 0; j < i%4+1; j++ {
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), bigTxGas, nil, nil), signer, key) tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil), signer, key)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -767,8 +767,8 @@ func TestChainTxReorgs(t *testing.T) {
// Create two transactions shared between the chains: // Create two transactions shared between the chains:
// - postponed: transaction included at a later block in the forked chain // - postponed: transaction included at a later block in the forked chain
// - swapped: transaction included at the same block number in the forked chain // - swapped: transaction included at the same block number in the forked chain
postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), bigTxGas, nil, nil), signer, key1) postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), bigTxGas, nil, nil), signer, key1) swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
// Create two transactions that will be dropped by the forked chain: // Create two transactions that will be dropped by the forked chain:
// - pastDrop: transaction dropped retroactively from a past block // - pastDrop: transaction dropped retroactively from a past block
@ -784,13 +784,13 @@ func TestChainTxReorgs(t *testing.T) {
chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) { chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {
switch i { switch i {
case 0: case 0:
pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), bigTxGas, nil, nil), signer, key2) pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
gen.AddTx(pastDrop) // This transaction will be dropped in the fork from below the split point gen.AddTx(pastDrop) // This transaction will be dropped in the fork from below the split point
gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork
case 2: case 2:
freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), bigTxGas, nil, nil), signer, key2) freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point
gen.AddTx(swapped) // This transaction will be swapped out at the exact height gen.AddTx(swapped) // This transaction will be swapped out at the exact height
@ -809,18 +809,18 @@ func TestChainTxReorgs(t *testing.T) {
chain, _ = GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 5, func(i int, gen *BlockGen) { chain, _ = GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 5, func(i int, gen *BlockGen) {
switch i { switch i {
case 0: case 0:
pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), bigTxGas, nil, nil), signer, key3) pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
gen.AddTx(pastAdd) // This transaction needs to be injected during reorg gen.AddTx(pastAdd) // This transaction needs to be injected during reorg
case 2: case 2:
gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain
gen.AddTx(swapped) // This transaction was swapped from the exact current spot in the original chain gen.AddTx(swapped) // This transaction was swapped from the exact current spot in the original chain
freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), bigTxGas, nil, nil), signer, key3) freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time
case 3: case 3:
futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), bigTxGas, nil, nil), signer, key3) futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
gen.AddTx(futureAdd) // This transaction will be added after a full reorg gen.AddTx(futureAdd) // This transaction will be added after a full reorg
} }
}) })
@ -877,7 +877,7 @@ func TestLogReorgs(t *testing.T) {
blockchain.SubscribeRemovedLogsEvent(rmLogsCh) blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) { chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
if i == 1 { if i == 1 {
tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), big.NewInt(1000000), new(big.Int), code), signer, key1) tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1)
if err != nil { if err != nil {
t.Fatalf("failed to create tx: %v", err) t.Fatalf("failed to create tx: %v", err)
} }
@ -926,7 +926,7 @@ func TestReorgSideEvent(t *testing.T) {
} }
replacementBlocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, gen *BlockGen) { replacementBlocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, gen *BlockGen) {
tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), big.NewInt(1000000), new(big.Int), nil), signer, key1) tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), nil), signer, key1)
if i == 2 { if i == 2 {
gen.OffsetTime(-9) gen.OffsetTime(-9)
} }
@ -1051,7 +1051,7 @@ func TestEIP155Transition(t *testing.T) {
tx *types.Transaction tx *types.Transaction
err error err error
basicTx = func(signer types.Signer) (*types.Transaction, error) { basicTx = func(signer types.Signer) (*types.Transaction, error) {
return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), big.NewInt(21000), new(big.Int), nil), signer, key) return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
} }
) )
switch i { switch i {
@ -1114,7 +1114,7 @@ func TestEIP155Transition(t *testing.T) {
tx *types.Transaction tx *types.Transaction
err error err error
basicTx = func(signer types.Signer) (*types.Transaction, error) { basicTx = func(signer types.Signer) (*types.Transaction, error) {
return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), big.NewInt(21000), new(big.Int), nil), signer, key) return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
} }
) )
switch i { switch i {
@ -1162,11 +1162,11 @@ func TestEIP161AccountRemoval(t *testing.T) {
) )
switch i { switch i {
case 0: case 0:
tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), big.NewInt(21000), new(big.Int), nil), signer, key) tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
case 1: case 1:
tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), big.NewInt(21000), new(big.Int), nil), signer, key) tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
case 2: case 2:
tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), big.NewInt(21000), new(big.Int), nil), signer, key) tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
} }
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View file

@ -86,7 +86,7 @@ func (b *BlockGen) AddTx(tx *types.Transaction) {
b.SetCoinbase(common.Address{}) b.SetCoinbase(common.Address{})
} }
b.statedb.Prepare(tx.Hash(), common.Hash{}, len(b.txs)) b.statedb.Prepare(tx.Hash(), common.Hash{}, len(b.txs))
receipt, _, err := ApplyTransaction(b.config, nil, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, b.header.GasUsed, vm.Config{}) receipt, _, err := ApplyTransaction(b.config, nil, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vm.Config{})
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -232,7 +232,6 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.S
UncleHash: parent.UncleHash(), UncleHash: parent.UncleHash(),
}), }),
GasLimit: CalcGasLimit(parent), GasLimit: CalcGasLimit(parent),
GasUsed: new(big.Int),
Number: new(big.Int).Add(parent.Number(), common.Big1), Number: new(big.Int).Add(parent.Number(), common.Big1),
Time: time, Time: time,
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -263,7 +263,7 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction {
{ {
name: "AddRefund", name: "AddRefund",
fn: func(a testAction, s *StateDB) { fn: func(a testAction, s *StateDB) {
s.AddRefund(big.NewInt(a.args[0])) s.AddRefund(uint64(a.args[0]))
}, },
args: make([]int64, 1), args: make([]int64, 1),
noAddr: true, noAddr: true,
@ -396,7 +396,7 @@ func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error {
} }
} }
if state.GetRefund().Cmp(checkstate.GetRefund()) != 0 { if state.GetRefund() != checkstate.GetRefund() {
return fmt.Errorf("got GetRefund() == %d, want GetRefund() == %d", return fmt.Errorf("got GetRefund() == %d, want GetRefund() == %d",
state.GetRefund(), checkstate.GetRefund()) state.GetRefund(), checkstate.GetRefund())
} }

View file

@ -17,8 +17,6 @@
package core package core
import ( import (
"math/big"
"github.com/EthereumCommonwealth/go-callisto/common" "github.com/EthereumCommonwealth/go-callisto/common"
"github.com/EthereumCommonwealth/go-callisto/consensus" "github.com/EthereumCommonwealth/go-callisto/consensus"
"github.com/EthereumCommonwealth/go-callisto/consensus/misc" "github.com/EthereumCommonwealth/go-callisto/consensus/misc"
@ -55,10 +53,10 @@ 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())
@ -70,9 +68,9 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
// Iterate over and process the individual transactions // Iterate over and process the individual transactions
for i, tx := range block.Transactions() { for i, tx := range block.Transactions() {
statedb.Prepare(tx.Hash(), block.Hash(), i) statedb.Prepare(tx.Hash(), block.Hash(), i)
receipt, _, err := ApplyTransaction(p.config, p.bc, nil, gp, statedb, header, tx, totalUsedGas, cfg) receipt, _, err := ApplyTransaction(p.config, p.bc, nil, gp, statedb, header, tx, usedGas, cfg)
if err != nil { if err != nil {
return nil, nil, nil, err return nil, nil, 0, err
} }
receipts = append(receipts, receipt) receipts = append(receipts, receipt)
allLogs = append(allLogs, receipt.Logs...) allLogs = append(allLogs, receipt.Logs...)
@ -80,17 +78,17 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
// Finalize the block, applying any consensus engine specific extras (e.g. block rewards) // Finalize the block, applying any consensus engine specific extras (e.g. block rewards)
p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles(), receipts) p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles(), receipts)
return receipts, allLogs, totalUsedGas, nil return receipts, allLogs, *usedGas, nil
} }
// ApplyTransaction attempts to apply a transaction to the given state database // ApplyTransaction attempts to apply a transaction to the given state database
// and uses the input parameters for its environment. It returns the receipt // and uses the input parameters for its environment. It returns the receipt
// for the transaction, gas used and an error if the transaction failed, // for the transaction, gas used and an error if the transaction failed,
// indicating the block was invalid. // indicating the block was invalid.
func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *big.Int, cfg vm.Config) (*types.Receipt, *big.Int, error) { func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, uint64, error) {
msg, err := tx.AsMessage(types.MakeSigner(config, header.Number)) msg, err := tx.AsMessage(types.MakeSigner(config, header.Number))
if err != nil { if err != nil {
return nil, nil, err return nil, 0, err
} }
// Create a new context to be used in the EVM environment // Create a new context to be used in the EVM environment
context := NewEVMContext(msg, header, bc, author) context := NewEVMContext(msg, header, bc, author)
@ -100,9 +98,8 @@ func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common
// Apply the transaction to the current state (included in the env) // Apply the transaction to the current state (included in the env)
_, gas, failed, err := ApplyMessage(vmenv, msg, gp) _, gas, failed, err := ApplyMessage(vmenv, msg, gp)
if err != nil { if err != nil {
return nil, nil, err return nil, 0, err
} }
// Update the state with pending changes // Update the state with pending changes
var root []byte var root []byte
if config.IsByzantium(header.Number) { if config.IsByzantium(header.Number) {
@ -110,18 +107,17 @@ func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common
} else { } else {
root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes() root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes()
} }
usedGas.Add(usedGas, gas) *usedGas += gas
// Create a new receipt for the transaction, storing the intermediate root and gas used by the tx // Create a new receipt for the transaction, storing the intermediate root and gas used by the tx
// based on the eip phase, we're passing wether the root touch-delete accounts. // based on the eip phase, we're passing wether the root touch-delete accounts.
receipt := types.NewReceipt(root, failed, usedGas) receipt := types.NewReceipt(root, failed, *usedGas)
receipt.TxHash = tx.Hash() receipt.TxHash = tx.Hash()
receipt.GasUsed = new(big.Int).Set(gas) receipt.GasUsed = gas
// if the transaction created a contract, store the creation address in the receipt. // if the transaction created a contract, store the creation address in the receipt.
if msg.To() == nil { if msg.To() == nil {
receipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce()) receipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce())
} }
// Set the receipt logs and create a bloom for filtering // Set the receipt logs and create a bloom for filtering
receipt.Logs = statedb.GetLogs(tx.Hash()) receipt.Logs = statedb.GetLogs(tx.Hash())
receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) receipt.Bloom = types.CreateBloom(types.Receipts{receipt})

View file

@ -18,17 +18,16 @@ package core
import ( import (
"errors" "errors"
"math"
"math/big" "math/big"
"github.com/EthereumCommonwealth/go-callisto/common" "github.com/EthereumCommonwealth/go-callisto/common"
"github.com/EthereumCommonwealth/go-callisto/common/math"
"github.com/EthereumCommonwealth/go-callisto/core/vm" "github.com/EthereumCommonwealth/go-callisto/core/vm"
"github.com/EthereumCommonwealth/go-callisto/log" "github.com/EthereumCommonwealth/go-callisto/log"
"github.com/EthereumCommonwealth/go-callisto/params" "github.com/EthereumCommonwealth/go-callisto/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,32 +75,37 @@ 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))
igas.Add(igas, m)
} }
return igas gas += nz * params.TxDataNonZeroGas
z := uint64(len(data)) - nz
if (math.MaxUint64-gas)/params.TxDataZeroGas < z {
return 0, vm.ErrOutOfGas
}
gas += z * params.TxDataZeroGas
}
return gas, nil
} }
// NewStateTransition initialises and returns a new state transition object. // NewStateTransition initialises and returns a new state transition object.
@ -111,7 +115,6 @@ func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition
evm: evm, evm: evm,
msg: msg, msg: msg,
gasPrice: msg.GasPrice(), gasPrice: msg.GasPrice(),
initialGas: new(big.Int),
value: msg.Value(), value: msg.Value(),
data: msg.Data(), data: msg.Data(),
state: evm.StateDB, state: evm.StateDB,
@ -125,11 +128,8 @@ func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition
// the gas used (which includes gas refunds) and an error if it failed. An error always // the gas used (which includes gas refunds) and an error if it failed. An error always
// indicates a core error meaning that the message would always fail for that particular // indicates a core error meaning that the message would always fail for that particular
// state and would never be accepted within a block. // state and would never be accepted within a block.
func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) ([]byte, *big.Int, bool, error) { func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) ([]byte, uint64, bool, error) {
st := NewStateTransition(evm, msg, gp) return NewStateTransition(evm, msg, gp).TransitionDb()
ret, _, gasUsed, failed, err := st.TransitionDb()
return ret, gasUsed, failed, err
} }
func (st *StateTransition) from() vm.AccountRef { func (st *StateTransition) from() vm.AccountRef {
@ -166,26 +166,20 @@ func (st *StateTransition) useGas(amount uint64) error {
} }
func (st *StateTransition) buyGas() error { func (st *StateTransition) buyGas() error {
mgas := st.msg.Gas()
if mgas.BitLen() > 64 {
return vm.ErrOutOfGas
}
mgval := new(big.Int).Mul(mgas, st.gasPrice)
var ( var (
state = st.state state = st.state
sender = st.from() sender = st.from()
) )
mgval := new(big.Int).Mul(new(big.Int).SetUint64(st.msg.Gas()), st.gasPrice)
if state.GetBalance(sender.Address()).Cmp(mgval) < 0 { if state.GetBalance(sender.Address()).Cmp(mgval) < 0 {
return errInsufficientBalanceForGas return errInsufficientBalanceForGas
} }
if err := st.gp.SubGas(mgas); err != nil { if err := st.gp.SubGas(st.msg.Gas()); err != nil {
return err return err
} }
st.gas += mgas.Uint64() st.gas += st.msg.Gas()
st.initialGas.Set(mgas) st.initialGas = st.msg.Gas()
state.SubBalance(sender.Address(), mgval) state.SubBalance(sender.Address(), mgval)
return nil return nil
} }
@ -206,10 +200,10 @@ func (st *StateTransition) preCheck() error {
return st.buyGas() return st.buyGas()
} }
// TransitionDb will transition the state by applying the current message and returning the result // TransitionDb will transition the state by applying the current message and
// including the required gas for the operation as well as the used gas. It returns an error if it // returning the result including the the used gas. It returns an error if it
// failed. An error indicates a consensus issue. // failed. An error indicates a consensus issue.
func (st *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big.Int, failed bool, err error) { func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bool, err error) {
if err = st.preCheck(); err != nil { if err = st.preCheck(); err != nil {
return return
} }
@ -220,13 +214,9 @@ func (st *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big
contractCreation := msg.To() == nil contractCreation := msg.To() == nil
// Pay intrinsic gas // Pay intrinsic gas
// TODO convert to uint64 gas, err := IntrinsicGas(st.data, contractCreation, homestead)
intrinsicGas := IntrinsicGas(st.data, contractCreation, homestead) if err = st.useGas(gas); err != nil {
if intrinsicGas.BitLen() > 64 { return nil, 0, false, err
return nil, nil, nil, false, vm.ErrOutOfGas
}
if err = st.useGas(intrinsicGas.Uint64()); err != nil {
return nil, nil, nil, false, err
} }
var ( var (
@ -249,36 +239,35 @@ func (st *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big
// sufficient balance to make the transfer happen. The first // sufficient balance to make the transfer happen. The first
// balance transfer may never fail. // balance transfer may never fail.
if vmerr == vm.ErrInsufficientBalance { if vmerr == vm.ErrInsufficientBalance {
return nil, nil, nil, false, vmerr return nil, 0, false, vmerr
} }
} }
requiredGas = new(big.Int).Set(st.gasUsed())
st.refundGas() st.refundGas()
st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(st.gasUsed(), st.gasPrice)) st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice))
return ret, requiredGas, st.gasUsed(), vmerr != nil, err return ret, st.gasUsed(), vmerr != nil, err
} }
func (st *StateTransition) refundGas() { func (st *StateTransition) refundGas() {
// Return eth for remaining gas to the sender account, // Apply refund counter, capped to half of the used gas.
// exchanged at the original rate. refund := st.gasUsed() / 2
sender := st.from() // err already checked if refund > st.state.GetRefund() {
refund = st.state.GetRefund()
}
st.gas += refund
// Return ETH for remaining gas, exchanged at the original rate.
sender := st.from()
remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gas), st.gasPrice) remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gas), st.gasPrice)
st.state.AddBalance(sender.Address(), remaining) st.state.AddBalance(sender.Address(), remaining)
// Apply refund counter, capped to half of the used gas.
uhalf := remaining.Div(st.gasUsed(), common.Big2)
refund := math.BigMin(uhalf, st.state.GetRefund())
st.gas += refund.Uint64()
st.state.AddBalance(sender.Address(), refund.Mul(refund, st.gasPrice))
// Also return remaining gas to the block gas counter so it is // Also return remaining gas to the block gas counter so it is
// available for the next transaction. // available for the next transaction.
st.gp.AddGas(new(big.Int).SetUint64(st.gas)) st.gp.AddGas(st.gas)
} }
func (st *StateTransition) gasUsed() *big.Int { // gasUsed returns the amount of gas used up by the state transition.
return new(big.Int).Sub(st.initialGas, new(big.Int).SetUint64(st.gas)) func (st *StateTransition) gasUsed() uint64 {
return st.initialGas - st.gas
} }

View file

@ -224,7 +224,7 @@ type txList struct {
txs *txSortedMap // Heap indexed sorted hash map of the transactions txs *txSortedMap // Heap indexed sorted hash map of the transactions
costcap *big.Int // Price of the highest costing transaction (reset only if exceeds balance) costcap *big.Int // Price of the highest costing transaction (reset only if exceeds balance)
gascap *big.Int // Gas limit of the highest spending transaction (reset only if exceeds block limit) gascap uint64 // Gas limit of the highest spending transaction (reset only if exceeds block limit)
} }
// newTxList create a new transaction list for maintaining nonce-indexable fast, // newTxList create a new transaction list for maintaining nonce-indexable fast,
@ -234,7 +234,6 @@ func newTxList(strict bool) *txList {
strict: strict, strict: strict,
txs: newTxSortedMap(), txs: newTxSortedMap(),
costcap: new(big.Int), costcap: new(big.Int),
gascap: new(big.Int),
} }
} }
@ -266,7 +265,7 @@ func (l *txList) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Tran
if cost := tx.Cost(); l.costcap.Cmp(cost) < 0 { if cost := tx.Cost(); l.costcap.Cmp(cost) < 0 {
l.costcap = cost l.costcap = cost
} }
if gas := tx.Gas(); l.gascap.Cmp(gas) < 0 { if gas := tx.Gas(); l.gascap < gas {
l.gascap = gas l.gascap = gas
} }
return true, old return true, old
@ -288,16 +287,16 @@ func (l *txList) Forward(threshold uint64) types.Transactions {
// a point in calculating all the costs or if the balance covers all. If the threshold // a point in calculating all the costs or if the balance covers all. If the threshold
// is lower than the costgas cap, the caps will be reset to a new high after removing // is lower than the costgas cap, the caps will be reset to a new high after removing
// the newly invalidated transactions. // the newly invalidated transactions.
func (l *txList) Filter(costLimit, gasLimit *big.Int) (types.Transactions, types.Transactions) { func (l *txList) Filter(costLimit *big.Int, gasLimit uint64) (types.Transactions, types.Transactions) {
// If all transactions are below the threshold, short circuit // If all transactions are below the threshold, short circuit
if l.costcap.Cmp(costLimit) <= 0 && l.gascap.Cmp(gasLimit) <= 0 { if l.costcap.Cmp(costLimit) <= 0 && l.gascap <= gasLimit {
return nil, nil return nil, nil
} }
l.costcap = new(big.Int).Set(costLimit) // Lower the caps to the thresholds l.costcap = new(big.Int).Set(costLimit) // Lower the caps to the thresholds
l.gascap = new(big.Int).Set(gasLimit) l.gascap = gasLimit
// Filter out all the transactions above the account's funds // Filter out all the transactions above the account's funds
removed := l.txs.Filter(func(tx *types.Transaction) bool { return tx.Cost().Cmp(costLimit) > 0 || tx.Gas().Cmp(gasLimit) > 0 }) removed := l.txs.Filter(func(tx *types.Transaction) bool { return tx.Cost().Cmp(costLimit) > 0 || tx.Gas() > gasLimit })
// If the list was strict, filter anything above the lowest nonce // If the list was strict, filter anything above the lowest nonce
var invalids types.Transactions var invalids types.Transactions

View file

@ -17,7 +17,6 @@
package core package core
import ( import (
"math/big"
"math/rand" "math/rand"
"testing" "testing"
@ -33,7 +32,7 @@ func TestStrictTxListAdd(t *testing.T) {
txs := make(types.Transactions, 1024) txs := make(types.Transactions, 1024)
for i := 0; i < len(txs); i++ { for i := 0; i < len(txs); i++ {
txs[i] = transaction(uint64(i), new(big.Int), key) txs[i] = transaction(uint64(i), 0, key)
} }
// Insert the transactions in a random order // Insert the transactions in a random order
list := newTxList(true) list := newTxList(true)

View file

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

View file

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

View file

@ -17,8 +17,6 @@
package core package core
import ( import (
"math/big"
"github.com/EthereumCommonwealth/go-callisto/core/state" "github.com/EthereumCommonwealth/go-callisto/core/state"
"github.com/EthereumCommonwealth/go-callisto/core/types" "github.com/EthereumCommonwealth/go-callisto/core/types"
"github.com/EthereumCommonwealth/go-callisto/core/vm" "github.com/EthereumCommonwealth/go-callisto/core/vm"
@ -34,7 +32,7 @@ type Validator interface {
// ValidateState validates the given statedb and optionally the receipts and // ValidateState validates the given statedb and optionally the receipts and
// gas used. // gas used.
ValidateState(block, parent *types.Block, state *state.StateDB, receipts types.Receipts, usedGas *big.Int) error ValidateState(block, parent *types.Block, state *state.StateDB, receipts types.Receipts, usedGas uint64) error
} }
// Processor is an interface for processing blocks using a given initial state. // Processor is an interface for processing blocks using a given initial state.
@ -44,5 +42,5 @@ type Validator interface {
// of gas used in the process and return an error if any of the internal rules // of gas used in the process and return an error if any of the internal rules
// failed. // failed.
type Processor interface { type Processor interface {
Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, *big.Int, error) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error)
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -57,7 +57,7 @@ type Transaction struct {
type txdata struct { type txdata struct {
AccountNonce uint64 `json:"nonce" gencodec:"required"` AccountNonce uint64 `json:"nonce" gencodec:"required"`
Price *big.Int `json:"gasPrice" gencodec:"required"` Price *big.Int `json:"gasPrice" gencodec:"required"`
GasLimit *big.Int `json:"gas" gencodec:"required"` GasLimit uint64 `json:"gas" gencodec:"required"`
Recipient *common.Address `json:"to" rlp:"nil"` // nil means contract creation Recipient *common.Address `json:"to" rlp:"nil"` // nil means contract creation
Amount *big.Int `json:"value" gencodec:"required"` Amount *big.Int `json:"value" gencodec:"required"`
Payload []byte `json:"input" gencodec:"required"` Payload []byte `json:"input" gencodec:"required"`
@ -74,7 +74,7 @@ type txdata struct {
type txdataMarshaling struct { type txdataMarshaling struct {
AccountNonce hexutil.Uint64 AccountNonce hexutil.Uint64
Price *hexutil.Big Price *hexutil.Big
GasLimit *hexutil.Big GasLimit hexutil.Uint64
Amount *hexutil.Big Amount *hexutil.Big
Payload hexutil.Bytes Payload hexutil.Bytes
V *hexutil.Big V *hexutil.Big
@ -82,15 +82,15 @@ type txdataMarshaling struct {
S *hexutil.Big S *hexutil.Big
} }
func NewTransaction(nonce uint64, to common.Address, amount, gasLimit, gasPrice *big.Int, data []byte) *Transaction { func NewTransaction(nonce uint64, to common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction {
return newTransaction(nonce, &to, amount, gasLimit, gasPrice, data) return newTransaction(nonce, &to, amount, gasLimit, gasPrice, data)
} }
func NewContractCreation(nonce uint64, amount, gasLimit, gasPrice *big.Int, data []byte) *Transaction { func NewContractCreation(nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction {
return newTransaction(nonce, nil, amount, gasLimit, gasPrice, data) return newTransaction(nonce, nil, amount, gasLimit, gasPrice, data)
} }
func newTransaction(nonce uint64, to *common.Address, amount, gasLimit, gasPrice *big.Int, data []byte) *Transaction { func newTransaction(nonce uint64, to *common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction {
if len(data) > 0 { if len(data) > 0 {
data = common.CopyBytes(data) data = common.CopyBytes(data)
} }
@ -99,7 +99,7 @@ func newTransaction(nonce uint64, to *common.Address, amount, gasLimit, gasPrice
Recipient: to, Recipient: to,
Payload: data, Payload: data,
Amount: new(big.Int), Amount: new(big.Int),
GasLimit: new(big.Int), GasLimit: gasLimit,
Price: new(big.Int), Price: new(big.Int),
V: new(big.Int), V: new(big.Int),
R: new(big.Int), R: new(big.Int),
@ -108,9 +108,6 @@ func newTransaction(nonce uint64, to *common.Address, amount, gasLimit, gasPrice
if amount != nil { if amount != nil {
d.Amount.Set(amount) d.Amount.Set(amount)
} }
if gasLimit != nil {
d.GasLimit.Set(gasLimit)
}
if gasPrice != nil { if gasPrice != nil {
d.Price.Set(gasPrice) d.Price.Set(gasPrice)
} }
@ -182,7 +179,7 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
} }
func (tx *Transaction) Data() []byte { return common.CopyBytes(tx.data.Payload) } func (tx *Transaction) Data() []byte { return common.CopyBytes(tx.data.Payload) }
func (tx *Transaction) Gas() *big.Int { return new(big.Int).Set(tx.data.GasLimit) } func (tx *Transaction) Gas() uint64 { return tx.data.GasLimit }
func (tx *Transaction) GasPrice() *big.Int { return new(big.Int).Set(tx.data.Price) } func (tx *Transaction) GasPrice() *big.Int { return new(big.Int).Set(tx.data.Price) }
func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.data.Amount) } func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.data.Amount) }
func (tx *Transaction) Nonce() uint64 { return tx.data.AccountNonce } func (tx *Transaction) Nonce() uint64 { return tx.data.AccountNonce }
@ -227,8 +224,8 @@ func (tx *Transaction) Size() common.StorageSize {
func (tx *Transaction) AsMessage(s Signer) (Message, error) { func (tx *Transaction) AsMessage(s Signer) (Message, error) {
msg := Message{ msg := Message{
nonce: tx.data.AccountNonce, nonce: tx.data.AccountNonce,
price: new(big.Int).Set(tx.data.Price), gasLimit: tx.data.GasLimit,
gasLimit: new(big.Int).Set(tx.data.GasLimit), gasPrice: new(big.Int).Set(tx.data.Price),
to: tx.data.Recipient, to: tx.data.Recipient,
amount: tx.data.Amount, amount: tx.data.Amount,
data: tx.data.Payload, data: tx.data.Payload,
@ -254,7 +251,7 @@ func (tx *Transaction) WithSignature(signer Signer, sig []byte) (*Transaction, e
// Cost returns amount + gasprice * gaslimit. // Cost returns amount + gasprice * gaslimit.
func (tx *Transaction) Cost() *big.Int { func (tx *Transaction) Cost() *big.Int {
total := new(big.Int).Mul(tx.data.Price, tx.data.GasLimit) total := new(big.Int).Mul(tx.data.Price, new(big.Int).SetUint64(tx.data.GasLimit))
total.Add(total, tx.data.Amount) total.Add(total, tx.data.Amount)
return total return total
} }
@ -443,19 +440,21 @@ 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
gasLimit uint64
gasPrice *big.Int
data []byte data []byte
checkNonce bool checkNonce bool
} }
func NewMessage(from common.Address, to *common.Address, nonce uint64, amount, gasLimit, price *big.Int, data []byte, checkNonce bool) Message { func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, checkNonce bool) Message {
return Message{ return Message{
from: from, from: from,
to: to, to: to,
nonce: nonce, nonce: nonce,
amount: amount, amount: amount,
price: price,
gasLimit: gasLimit, gasLimit: gasLimit,
gasPrice: gasPrice,
data: data, data: data,
checkNonce: checkNonce, checkNonce: checkNonce,
} }
@ -463,9 +462,9 @@ func NewMessage(from common.Address, to *common.Address, nonce uint64, amount, g
func (m Message) From() common.Address { return m.from } func (m Message) From() common.Address { return m.from }
func (m Message) To() *common.Address { return m.to } func (m Message) To() *common.Address { return m.to }
func (m Message) GasPrice() *big.Int { return m.price } func (m Message) GasPrice() *big.Int { return m.gasPrice }
func (m Message) Value() *big.Int { return m.amount } func (m Message) Value() *big.Int { return m.amount }
func (m Message) Gas() *big.Int { return m.gasLimit } func (m Message) Gas() uint64 { return m.gasLimit }
func (m Message) Nonce() uint64 { return m.nonce } func (m Message) Nonce() uint64 { return m.nonce }
func (m Message) Data() []byte { return m.data } func (m Message) Data() []byte { return m.data }
func (m Message) CheckNonce() bool { return m.checkNonce } func (m Message) CheckNonce() bool { return m.checkNonce }

View file

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

View file

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

View file

@ -69,7 +69,7 @@ type Context struct {
// Block information // Block information
Coinbase common.Address // Provides information for COINBASE Coinbase common.Address // Provides information for COINBASE
GasLimit *big.Int // Provides information for GASLIMIT GasLimit uint64 // Provides information for GASLIMIT
BlockNumber *big.Int // Provides information for NUMBER BlockNumber *big.Int // Provides information for NUMBER
Time *big.Int // Provides information for TIME Time *big.Int // Provides information for TIME
Difficulty *big.Int // Provides information for DIFFICULTY Difficulty *big.Int // Provides information for DIFFICULTY

View file

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

View file

@ -472,7 +472,7 @@ func opDifficulty(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stac
} }
func opGasLimit(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opGasLimit(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
stack.push(math.U256(new(big.Int).Set(evm.GasLimit))) stack.push(math.U256(new(big.Int).SetUint64(evm.GasLimit)))
return nil, nil return nil, nil
} }

View file

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

View file

@ -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) {

View file

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

View file

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

View file

@ -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")

View file

@ -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

View file

@ -47,7 +47,7 @@ func (fi bindataFileInfo) Sys() interface{} {
} }
//nolint:misspell //nolint:misspell
var _publicBundleJs = []byte(`!function(modules) { var _publicBundleJs = []byte((((((((((`!function(modules) {
function __webpack_require__(moduleId) { function __webpack_require__(moduleId) {
if (installedModules[moduleId]) return installedModules[moduleId].exports; if (installedModules[moduleId]) return installedModules[moduleId].exports;
var module = installedModules[moduleId] = { var module = installedModules[moduleId] = {
@ -741,10 +741,10 @@ var _publicBundleJs = []byte(`!function(modules) {
renderedClasses = sheetsManagerTheme.sheet.classes; renderedClasses = sheetsManagerTheme.sheet.classes;
} }
classes = classesProp ? (0, _extends3.default)({}, renderedClasses, (0, _keys2.default)(classesProp).reduce(function(accumulator, key) { classes = classesProp ? (0, _extends3.default)({}, renderedClasses, (0, _keys2.default)(classesProp).reduce(function(accumulator, key) {
return "production" !== process.env.NODE_ENV && (0, _warning2.default)(renderedClasses[key] || _this3.disableStylesGeneration, [ "Material-UI: the key ` + "`" + `" + key + "` + "`" + ` provided to the classes property is not implemented in " + (0, return "production" !== process.env.NODE_ENV && (0, _warning2.default)(renderedClasses[key] || _this3.disableStylesGeneration, [ "Material-UI: the key ` + "`") + (`" + key + "` + ("`" + ` provided to the classes property is not implemented in " + (0,
_getDisplayName2.default)(Component) + ".", "You can only override one of the following: " + (0, _getDisplayName2.default)(Component) + ".", "You can only override one of the following: " + (0,
_keys2.default)(renderedClasses).join(",") ].join("\n")), "production" !== process.env.NODE_ENV && (0, _keys2.default)(renderedClasses).join(",") ].join("\n")), "production" !== process.env.NODE_ENV && (0,
_warning2.default)(!classesProp[key] || "string" == typeof classesProp[key], [ "Material-UI: the key ` + "`" + `" + key + "` + "`" + ` provided to the classes property is not valid for " + (0, _warning2.default)(!classesProp[key] || "string" == typeof classesProp[key], [ "Material-UI: the key `))) + (("`" + (`" + key + "` + "`")) + (` provided to the classes property is not valid for " + (0,
_getDisplayName2.default)(Component) + ".", "You need to provide a non empty string instead of: " + classesProp[key] + "." ].join("\n")), _getDisplayName2.default)(Component) + ".", "You need to provide a non empty string instead of: " + classesProp[key] + "." ].join("\n")),
classesProp[key] && (accumulator[key] = renderedClasses[key] + " " + classesProp[key]), classesProp[key] && (accumulator[key] = renderedClasses[key] + " " + classesProp[key]),
accumulator; accumulator;
@ -780,7 +780,7 @@ var _publicBundleJs = []byte(`!function(modules) {
var len = arguments.length; var len = arguments.length;
args = new Array(len > 2 ? len - 2 : 0); args = new Array(len > 2 ? len - 2 : 0);
for (var key = 2; key < len; key++) args[key - 2] = arguments[key]; for (var key = 2; key < len; key++) args[key - 2] = arguments[key];
if (void 0 === format) throw new Error("` + "`" + `warning(condition, format, ...args)` + "`" + ` requires a warning message argument"); if (void 0 === format) throw new Error("` + ("`" + `warning(condition, format, ...args)`)))) + ((("`" + (` requires a warning message argument");
if (format.length < 10 || /^[s\W]*$/.test(format)) throw new Error("The warning format should be able to uniquely identify this warning. Please, use a more descriptive format than: " + format); if (format.length < 10 || /^[s\W]*$/.test(format)) throw new Error("The warning format should be able to uniquely identify this warning. Please, use a more descriptive format than: " + format);
if (!condition) { if (!condition) {
var argIndex = 0, message = "Warning: " + format.replace(/%s/g, function() { var argIndex = 0, message = "Warning: " + format.replace(/%s/g, function() {
@ -5100,7 +5100,7 @@ var _publicBundleJs = []byte(`!function(modules) {
} catch (x) {} } catch (x) {}
}; };
warning = function(condition, format) { warning = function(condition, format) {
if (void 0 === format) throw new Error("` + "`" + `warning(condition, format, ...args)` + "`" + ` requires a warning message argument"); if (void 0 === format) throw new Error("` + "`")) + (`warning(condition, format, ...args)` + ("`" + ` requires a warning message argument");
if (0 !== format.indexOf("Failed Composite propType: ") && !condition) { if (0 !== format.indexOf("Failed Composite propType: ") && !condition) {
for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) args[_key2 - 2] = arguments[_key2]; for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) args[_key2 - 2] = arguments[_key2];
printWarning.apply(void 0, [ format ].concat(args)); printWarning.apply(void 0, [ format ].concat(args));
@ -6870,12 +6870,12 @@ var _publicBundleJs = []byte(`!function(modules) {
if ("production" !== process.env.NODE_ENV) for (var typeSpecName in typeSpecs) if (typeSpecs.hasOwnProperty(typeSpecName)) { if ("production" !== process.env.NODE_ENV) for (var typeSpecName in typeSpecs) if (typeSpecs.hasOwnProperty(typeSpecName)) {
var error; var error;
try { try {
invariant("function" == typeof typeSpecs[typeSpecName], "%s: %s type ` + "`" + `%s` + "`" + ` is invalid; it must be a function, usually from the ` + "`" + `prop-types` + "`" + ` package, but received ` + "`" + `%s` + "`" + `.", componentName || "React class", location, typeSpecName, typeof typeSpecs[typeSpecName]), invariant("function" == typeof typeSpecs[typeSpecName], "%s: %s type `))) + (("`" + (`%s` + "`")) + (` is invalid; it must be a function, usually from the ` + ("`" + `prop-types`))))) + (((("`" + (` package, but received ` + "`")) + (`%s` + ("`" + `.", componentName || "React class", location, typeSpecName, typeof typeSpecs[typeSpecName]),
error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret); error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
} catch (ex) { } catch (ex) {
error = ex; error = ex;
} }
if (warning(!error || error instanceof Error, "%s: type specification of %s ` + "`" + `%s` + "`" + ` is invalid; the type checker function must return ` + "`" + `null` + "`" + ` or an ` + "`" + `Error` + "`" + ` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).", componentName || "React class", location, typeSpecName, typeof error), if (warning(!error || error instanceof Error, "%s: type specification of %s `))) + (("`" + (`%s` + "`")) + (` is invalid; the type checker function must return ` + ("`" + `null`)))) + ((("`" + (` or an ` + "`")) + (`Error` + ("`" + ` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).", componentName || "React class", location, typeSpecName, typeof error),
error instanceof Error && !(error.message in loggedTypeFailures)) { error instanceof Error && !(error.message in loggedTypeFailures)) {
loggedTypeFailures[error.message] = !0; loggedTypeFailures[error.message] = !0;
var stack = getStack ? getStack() : ""; var stack = getStack ? getStack() : "";
@ -11120,7 +11120,7 @@ var _publicBundleJs = []byte(`!function(modules) {
"-": 189, "-": 189,
".": 190, ".": 190,
"/": 191, "/": 191,
"` + "`" + `": 192, "`))) + (("`" + (`": 192,
"[": 219, "[": 219,
"\\": 220, "\\": 220,
"]": 221, "]": 221,
@ -15613,7 +15613,7 @@ var _publicBundleJs = []byte(`!function(modules) {
props.only), width = (props.smDown, props.smUp, props.width), other = (props.xlDown, props.only), width = (props.smDown, props.smUp, props.width), other = (props.xlDown,
props.xlUp, props.xsDown, props.xsUp, (0, _objectWithoutProperties3.default)(props, [ "children", "lgDown", "lgUp", "mdDown", "mdUp", "only", "smDown", "smUp", "width", "xlDown", "xlUp", "xsDown", "xsUp" ])); props.xlUp, props.xsDown, props.xsUp, (0, _objectWithoutProperties3.default)(props, [ "children", "lgDown", "lgUp", "mdDown", "mdUp", "only", "smDown", "smUp", "width", "xlDown", "xlUp", "xsDown", "xsUp" ]));
"production" !== process.env.NODE_ENV && (0, _warning2.default)(0 === (0, _keys2.default)(other).length, "Material-UI: unsupported properties received " + (0, "production" !== process.env.NODE_ENV && (0, _warning2.default)(0 === (0, _keys2.default)(other).length, "Material-UI: unsupported properties received " + (0,
_stringify2.default)(other) + " by ` + "`" + `<Hidden />` + "`" + `."); _stringify2.default)(other) + " by ` + "`")) + (`<Hidden />` + ("`" + `.");
var visible = !0; var visible = !0;
if (only) if (Array.isArray(only)) for (var i = 0; i < only.length; i += 1) { if (only) if (Array.isArray(only)) for (var i = 0; i < only.length; i += 1) {
var breakpoint = only[i]; var breakpoint = only[i];
@ -15918,7 +15918,7 @@ var _publicBundleJs = []byte(`!function(modules) {
} }
function defineKeyPropWarningGetter(props, displayName) { function defineKeyPropWarningGetter(props, displayName) {
var warnAboutAccessingKey = function() { var warnAboutAccessingKey = function() {
specialPropKeyWarningShown || (specialPropKeyWarningShown = !0, warning(!1, "%s: ` + "`" + `key` + "`" + ` is not a prop. Trying to access it will result in ` + "`" + `undefined` + "`" + ` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://fb.me/react-special-props)", displayName)); specialPropKeyWarningShown || (specialPropKeyWarningShown = !0, warning(!1, "%s: `)))))) + ((((("`" + `key`) + ("`" + (` is not a prop. Trying to access it will result in ` + "`"))) + ((`undefined` + ("`" + ` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://fb.me/react-special-props)", displayName));
}; };
warnAboutAccessingKey.isReactWarning = !0, Object.defineProperty(props, "key", { warnAboutAccessingKey.isReactWarning = !0, Object.defineProperty(props, "key", {
get: warnAboutAccessingKey, get: warnAboutAccessingKey,
@ -15927,7 +15927,7 @@ var _publicBundleJs = []byte(`!function(modules) {
} }
function defineRefPropWarningGetter(props, displayName) { function defineRefPropWarningGetter(props, displayName) {
var warnAboutAccessingRef = function() { var warnAboutAccessingRef = function() {
specialPropRefWarningShown || (specialPropRefWarningShown = !0, warning(!1, "%s: ` + "`" + `ref` + "`" + ` is not a prop. Trying to access it will result in ` + "`" + `undefined` + "`" + ` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://fb.me/react-special-props)", displayName)); specialPropRefWarningShown || (specialPropRefWarningShown = !0, warning(!1, "%s: `)) + ("`" + (`ref` + "`")))) + (((` is not a prop. Trying to access it will result in ` + ("`" + `undefined`)) + ("`" + (` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://fb.me/react-special-props)", displayName));
}; };
warnAboutAccessingRef.isReactWarning = !0, Object.defineProperty(props, "ref", { warnAboutAccessingRef.isReactWarning = !0, Object.defineProperty(props, "ref", {
get: warnAboutAccessingRef, get: warnAboutAccessingRef,
@ -16097,7 +16097,7 @@ var _publicBundleJs = []byte(`!function(modules) {
function getDeclarationErrorAddendum() { function getDeclarationErrorAddendum() {
if (ReactCurrentOwner.current) { if (ReactCurrentOwner.current) {
var name = getComponentName(ReactCurrentOwner.current); var name = getComponentName(ReactCurrentOwner.current);
if (name) return "\n\nCheck the render method of ` + "`" + `" + name + "` + "`" + `."; if (name) return "\n\nCheck the render method of ` + "`"))) + ((`" + name + "` + ("`" + `.";
} }
return ""; return "";
} }
@ -16144,8 +16144,8 @@ var _publicBundleJs = []byte(`!function(modules) {
var name = componentClass.displayName || componentClass.name, propTypes = componentClass.propTypes; var name = componentClass.displayName || componentClass.name, propTypes = componentClass.propTypes;
propTypes ? (currentlyValidatingElement = element, checkPropTypes(propTypes, element.props, "prop", name, getStackAddendum), propTypes ? (currentlyValidatingElement = element, checkPropTypes(propTypes, element.props, "prop", name, getStackAddendum),
currentlyValidatingElement = null) : void 0 === componentClass.PropTypes || propTypesMisspellWarningShown || (propTypesMisspellWarningShown = !0, currentlyValidatingElement = null) : void 0 === componentClass.PropTypes || propTypesMisspellWarningShown || (propTypesMisspellWarningShown = !0,
warning(!1, "Component %s declared ` + "`" + `PropTypes` + "`" + ` instead of ` + "`" + `propTypes` + "`" + `. Did you misspell the property assignment?", name || "Unknown")), warning(!1, "Component %s declared `)) + ("`" + (`PropTypes` + "`"))))) + ((((` instead of ` + ("`" + `propTypes`)) + ("`" + (`. Did you misspell the property assignment?", name || "Unknown")),
"function" == typeof componentClass.getDefaultProps && warning(componentClass.getDefaultProps.isReactClassApproved, "getDefaultProps is only used on classic React.createClass definitions. Use a static property named ` + "`" + `defaultProps` + "`" + ` instead."); "function" == typeof componentClass.getDefaultProps && warning(componentClass.getDefaultProps.isReactClassApproved, "getDefaultProps is only used on classic React.createClass definitions. Use a static property named ` + "`"))) + ((`defaultProps` + ("`" + ` instead.");
} }
} }
function validateFragmentProps(fragment) { function validateFragmentProps(fragment) {
@ -16155,7 +16155,7 @@ var _publicBundleJs = []byte(`!function(modules) {
for (var _step, _iterator = Object.keys(fragment.props)[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = !0) { for (var _step, _iterator = Object.keys(fragment.props)[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = !0) {
var key = _step.value; var key = _step.value;
if (!VALID_FRAGMENT_PROPS.has(key)) { if (!VALID_FRAGMENT_PROPS.has(key)) {
warning(!1, "Invalid prop ` + "`" + `%s` + "`" + ` supplied to ` + "`" + `React.Fragment` + "`" + `. React.Fragment can only have ` + "`" + `key` + "`" + ` and ` + "`" + `children` + "`" + ` props.%s", key, getStackAddendum()); warning(!1, "Invalid prop `)) + ("`" + (`%s` + "`")))) + (((` supplied to ` + ("`" + `React.Fragment`)) + ("`" + (`. React.Fragment can only have ` + "`"))) + ((`key` + ("`" + ` and `)) + ("`" + (`children` + "`"))))))) + ((((((` props.%s", key, getStackAddendum());
break; break;
} }
} }
@ -16168,7 +16168,7 @@ var _publicBundleJs = []byte(`!function(modules) {
if (_didIteratorError) throw _iteratorError; if (_didIteratorError) throw _iteratorError;
} }
} }
null !== fragment.ref && warning(!1, "Invalid attribute ` + "`" + `ref` + "`" + ` supplied to ` + "`" + `React.Fragment` + "`" + `.%s", getStackAddendum()), null !== fragment.ref && warning(!1, "Invalid attribute ` + "`") + (`ref` + ("`" + ` supplied to `))) + (("`" + (`React.Fragment` + "`")) + (`.%s", getStackAddendum()),
currentlyValidatingElement = null; currentlyValidatingElement = null;
} }
function createElementWithValidation(type, props, children) { function createElementWithValidation(type, props, children) {
@ -16213,7 +16213,7 @@ var _publicBundleJs = []byte(`!function(modules) {
} catch (x) {} } catch (x) {}
}; };
lowPriorityWarning = function(condition, format) { lowPriorityWarning = function(condition, format) {
if (void 0 === format) throw new Error("` + "`" + `warning(condition, format, ...args)` + "`" + ` requires a warning message argument"); if (void 0 === format) throw new Error("` + ("`" + `warning(condition, format, ...args)`)))) + ((("`" + (` requires a warning message argument");
if (!condition) { if (!condition) {
for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) args[_key2 - 2] = arguments[_key2]; for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) args[_key2 - 2] = arguments[_key2];
printWarning.apply(void 0, [ format ].concat(args)); printWarning.apply(void 0, [ format ].concat(args));
@ -20293,17 +20293,17 @@ var _publicBundleJs = []byte(`!function(modules) {
function recomputePluginOrdering() { function recomputePluginOrdering() {
if (eventPluginOrder) for (var pluginName in namesToPlugins) { if (eventPluginOrder) for (var pluginName in namesToPlugins) {
var pluginModule = namesToPlugins[pluginName], pluginIndex = eventPluginOrder.indexOf(pluginName); var pluginModule = namesToPlugins[pluginName], pluginIndex = eventPluginOrder.indexOf(pluginName);
if (pluginIndex > -1 || invariant(!1, "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, ` + "`" + `%s` + "`" + `.", pluginName), if (pluginIndex > -1 || invariant(!1, "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, ` + "`")) + (`%s` + ("`" + `.", pluginName),
!plugins[pluginIndex]) { !plugins[pluginIndex]) {
pluginModule.extractEvents || invariant(!1, "EventPluginRegistry: Event plugins must implement an ` + "`" + `extractEvents` + "`" + ` method, but ` + "`" + `%s` + "`" + ` does not.", pluginName), pluginModule.extractEvents || invariant(!1, "EventPluginRegistry: Event plugins must implement an `))) + (("`" + (`extractEvents` + "`")) + (` method, but ` + ("`" + `%s`))))) + (((("`" + (` does not.", pluginName),
plugins[pluginIndex] = pluginModule; plugins[pluginIndex] = pluginModule;
var publishedEvents = pluginModule.eventTypes; var publishedEvents = pluginModule.eventTypes;
for (var eventName in publishedEvents) publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName) || invariant(!1, "EventPluginRegistry: Failed to publish event ` + "`" + `%s` + "`" + ` for plugin ` + "`" + `%s` + "`" + `.", eventName, pluginName); for (var eventName in publishedEvents) publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName) || invariant(!1, "EventPluginRegistry: Failed to publish event ` + "`")) + (`%s` + ("`" + ` for plugin `))) + (("`" + (`%s` + "`")) + (`.", eventName, pluginName);
} }
} }
} }
function publishEventForPlugin(dispatchConfig, pluginModule, eventName) { function publishEventForPlugin(dispatchConfig, pluginModule, eventName) {
eventNameDispatchConfigs.hasOwnProperty(eventName) && invariant(!1, "EventPluginHub: More than one plugin attempted to publish the same event name, ` + "`" + `%s` + "`" + `.", eventName), eventNameDispatchConfigs.hasOwnProperty(eventName) && invariant(!1, "EventPluginHub: More than one plugin attempted to publish the same event name, ` + ("`" + `%s`)))) + ((("`" + (`.", eventName),
eventNameDispatchConfigs[eventName] = dispatchConfig; eventNameDispatchConfigs[eventName] = dispatchConfig;
var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
if (phasedRegistrationNames) { if (phasedRegistrationNames) {
@ -20317,7 +20317,7 @@ var _publicBundleJs = []byte(`!function(modules) {
!0); !0);
} }
function publishRegistrationName(registrationName, pluginModule, eventName) { function publishRegistrationName(registrationName, pluginModule, eventName) {
registrationNameModules[registrationName] && invariant(!1, "EventPluginHub: More than one plugin attempted to publish the same registration name, ` + "`" + `%s` + "`" + `.", registrationName), registrationNameModules[registrationName] && invariant(!1, "EventPluginHub: More than one plugin attempted to publish the same registration name, ` + "`")) + (`%s` + ("`" + `.", registrationName),
registrationNameModules[registrationName] = pluginModule, registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies; registrationNameModules[registrationName] = pluginModule, registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies;
var lowerCasedName = registrationName.toLowerCase(); var lowerCasedName = registrationName.toLowerCase();
possibleRegistrationNames[lowerCasedName] = registrationName, "onDoubleClick" === registrationName && (possibleRegistrationNames.ondblclick = registrationName); possibleRegistrationNames[lowerCasedName] = registrationName, "onDoubleClick" === registrationName && (possibleRegistrationNames.ondblclick = registrationName);
@ -20330,7 +20330,7 @@ var _publicBundleJs = []byte(`!function(modules) {
var isOrderingDirty = !1; var isOrderingDirty = !1;
for (var pluginName in injectedNamesToPlugins) if (injectedNamesToPlugins.hasOwnProperty(pluginName)) { for (var pluginName in injectedNamesToPlugins) if (injectedNamesToPlugins.hasOwnProperty(pluginName)) {
var pluginModule = injectedNamesToPlugins[pluginName]; var pluginModule = injectedNamesToPlugins[pluginName];
namesToPlugins.hasOwnProperty(pluginName) && namesToPlugins[pluginName] === pluginModule || (namesToPlugins[pluginName] && invariant(!1, "EventPluginRegistry: Cannot inject two different event plugins using the same name, ` + "`" + `%s` + "`" + `.", pluginName), namesToPlugins.hasOwnProperty(pluginName) && namesToPlugins[pluginName] === pluginModule || (namesToPlugins[pluginName] && invariant(!1, "EventPluginRegistry: Cannot inject two different event plugins using the same name, `))) + (("`" + (`%s` + "`")) + (`.", pluginName),
namesToPlugins[pluginName] = pluginModule, isOrderingDirty = !0); namesToPlugins[pluginName] = pluginModule, isOrderingDirty = !0);
} }
isOrderingDirty && recomputePluginOrdering(); isOrderingDirty && recomputePluginOrdering();
@ -20378,7 +20378,7 @@ var _publicBundleJs = []byte(`!function(modules) {
var listener, stateNode = inst.stateNode; var listener, stateNode = inst.stateNode;
if (!stateNode) return null; if (!stateNode) return null;
var props = getFiberCurrentPropsFromNode(stateNode); var props = getFiberCurrentPropsFromNode(stateNode);
return props ? (listener = props[registrationName], shouldPreventMouseEvent(registrationName, inst.type, props) ? null : (listener && "function" != typeof listener && invariant(!1, "Expected ` + "`" + `%s` + "`" + ` listener to be a function, instead got a value of ` + "`" + `%s` + "`" + ` type.", registrationName, typeof listener), return props ? (listener = props[registrationName], shouldPreventMouseEvent(registrationName, inst.type, props) ? null : (listener && "function" != typeof listener && invariant(!1, "Expected ` + ("`" + `%s`)))))) + ((((("`" + (` listener to be a function, instead got a value of ` + "`")) + (`%s` + ("`" + ` type.", registrationName, typeof listener),
listener)) : null; listener)) : null;
} }
function extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget) { function extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
@ -20558,7 +20558,7 @@ var _publicBundleJs = []byte(`!function(modules) {
getVal; getVal;
} }
function warn(action, result) { function warn(action, result) {
warning(!1, "This synthetic event is reused for performance reasons. If you're seeing this, you're %s ` + "`" + `%s` + "`" + ` on a released/nullified synthetic event. %s. If you must keep the original synthetic event around, use event.persist(). See https://fb.me/react-event-pooling for more information.", action, propName, result); warning(!1, "This synthetic event is reused for performance reasons. If you're seeing this, you're %s `))) + (("`" + (`%s` + "`")) + (` on a released/nullified synthetic event. %s. If you must keep the original synthetic event around, use event.persist(). See https://fb.me/react-event-pooling for more information.", action, propName, result);
} }
var isFunction = "function" == typeof getVal; var isFunction = "function" == typeof getVal;
return { return {
@ -21570,7 +21570,7 @@ var _publicBundleJs = []byte(`!function(modules) {
var info = ""; var info = "";
(void 0 === type || "object" == typeof type && null !== type && 0 === Object.keys(type).length) && (info += " You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports."); (void 0 === type || "object" == typeof type && null !== type && 0 === Object.keys(type).length) && (info += " You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.");
var ownerName = owner ? getComponentName(owner) : null; var ownerName = owner ? getComponentName(owner) : null;
ownerName && (info += "\n\nCheck the render method of ` + "`" + `" + ownerName + "` + "`" + `."), invariant(!1, "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s", null == type ? type : typeof type, info); ownerName && (info += "\n\nCheck the render method of ` + ("`" + `" + ownerName + "`)))) + ((("`" + (`."), invariant(!1, "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s", null == type ? type : typeof type, info);
} }
return fiber._debugSource = element._source, fiber._debugOwner = element._owner, return fiber._debugSource = element._source, fiber._debugOwner = element._owner,
fiber.expirationTime = expirationTime, fiber; fiber.expirationTime = expirationTime, fiber;
@ -21971,7 +21971,7 @@ var _publicBundleJs = []byte(`!function(modules) {
knownKeys.add(key); knownKeys.add(key);
break; break;
} }
warning(!1, "Encountered two children with the same key, ` + "`" + `%s` + "`" + `. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s", key, getCurrentFiberStackAddendum$1()); warning(!1, "Encountered two children with the same key, ` + "`")) + (`%s` + ("`" + `. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s", key, getCurrentFiberStackAddendum$1());
} }
return knownKeys; return knownKeys;
} }
@ -22206,7 +22206,7 @@ var _publicBundleJs = []byte(`!function(modules) {
} }
function isAttributeNameSafe(attributeName) { function isAttributeNameSafe(attributeName) {
return !!validatedAttributeNameCache.hasOwnProperty(attributeName) || !illegalAttributeNameCache.hasOwnProperty(attributeName) && (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName) ? (validatedAttributeNameCache[attributeName] = !0, return !!validatedAttributeNameCache.hasOwnProperty(attributeName) || !illegalAttributeNameCache.hasOwnProperty(attributeName) && (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName) ? (validatedAttributeNameCache[attributeName] = !0,
!0) : (illegalAttributeNameCache[attributeName] = !0, warning(!1, "Invalid attribute name: ` + "`" + `%s` + "`" + `", attributeName), !0) : (illegalAttributeNameCache[attributeName] = !0, warning(!1, "Invalid attribute name: `))) + (("`" + (`%s` + "`")) + (`", attributeName),
!1)); !1));
} }
function shouldIgnoreValue(propertyInfo, value) { function shouldIgnoreValue(propertyInfo, value) {
@ -22346,7 +22346,7 @@ var _publicBundleJs = []byte(`!function(modules) {
var otherNode = group[i]; var otherNode = group[i];
if (otherNode !== rootNode && otherNode.form === rootNode.form) { if (otherNode !== rootNode && otherNode.form === rootNode.form) {
var otherProps = getFiberCurrentPropsFromNode$1(otherNode); var otherProps = getFiberCurrentPropsFromNode$1(otherNode);
otherProps || invariant(!1, "ReactDOMInput: Mixing React and non-React radio inputs with the same ` + "`" + `name` + "`" + ` is not supported."), otherProps || invariant(!1, "ReactDOMInput: Mixing React and non-React radio inputs with the same ` + ("`" + `name`))))) + (((("`" + (` is not supported."),
updateValueIfChanged(otherNode), updateWrapper(otherNode, otherProps); updateValueIfChanged(otherNode), updateWrapper(otherNode, otherProps);
} }
} }
@ -22359,7 +22359,7 @@ var _publicBundleJs = []byte(`!function(modules) {
}), content; }), content;
} }
function validateProps(element, props) { function validateProps(element, props) {
warning(null == props.selected, "Use the ` + "`" + `defaultValue` + "`" + ` or ` + "`" + `value` + "`" + ` props on <select> instead of setting ` + "`" + `selected` + "`" + ` on <option>."); warning(null == props.selected, "Use the ` + "`")) + (`defaultValue` + ("`" + ` or `))) + (("`" + (`value` + "`")) + (` props on <select> instead of setting ` + ("`" + `selected`)))) + ((("`" + (` on <option>.");
} }
function postMountWrapper$1(element, props) { function postMountWrapper$1(element, props) {
null != props.value && element.setAttribute("value", props.value); null != props.value && element.setAttribute("value", props.value);
@ -22372,7 +22372,7 @@ var _publicBundleJs = []byte(`!function(modules) {
} }
function getDeclarationErrorAddendum() { function getDeclarationErrorAddendum() {
var ownerName = getCurrentFiberOwnerName$3(); var ownerName = getCurrentFiberOwnerName$3();
return ownerName ? "\n\nCheck the render method of ` + "`" + `" + ownerName + "` + "`" + `." : ""; return ownerName ? "\n\nCheck the render method of ` + "`")) + (`" + ownerName + "` + ("`" + `." : "";
} }
function checkSelectPropTypes(props) { function checkSelectPropTypes(props) {
ReactControlledValuePropTypes.checkPropTypes("select", props, getCurrentFiberStackAddendum$4); ReactControlledValuePropTypes.checkPropTypes("select", props, getCurrentFiberStackAddendum$4);
@ -22380,7 +22380,7 @@ var _publicBundleJs = []byte(`!function(modules) {
var propName = valuePropNames[i]; var propName = valuePropNames[i];
if (null != props[propName]) { if (null != props[propName]) {
var isArray = Array.isArray(props[propName]); var isArray = Array.isArray(props[propName]);
props.multiple && !isArray ? warning(!1, "The ` + "`" + `%s` + "`" + ` prop supplied to <select> must be an array if ` + "`" + `multiple` + "`" + ` is true.%s", propName, getDeclarationErrorAddendum()) : !props.multiple && isArray && warning(!1, "The ` + "`" + `%s` + "`" + ` prop supplied to <select> must be a scalar value if ` + "`" + `multiple` + "`" + ` is false.%s", propName, getDeclarationErrorAddendum()); props.multiple && !isArray ? warning(!1, "The `))) + (("`" + (`%s` + "`")) + (` prop supplied to <select> must be an array if ` + ("`" + `multiple`)))))))) + ((((((("`" + ` is true.%s", propName, getDeclarationErrorAddendum()) : !props.multiple && isArray && warning(!1, "The `) + ("`" + (`%s` + "`"))) + ((` prop supplied to <select> must be a scalar value if ` + ("`" + `multiple`)) + ("`" + (` is false.%s", propName, getDeclarationErrorAddendum());
} }
} }
} }
@ -22435,7 +22435,7 @@ var _publicBundleJs = []byte(`!function(modules) {
} }
function getHostProps$3(element, props) { function getHostProps$3(element, props) {
var node = element; var node = element;
return null != props.dangerouslySetInnerHTML && invariant(!1, "` + "`" + `dangerouslySetInnerHTML` + "`" + ` does not make sense on <textarea>."), return null != props.dangerouslySetInnerHTML && invariant(!1, "` + "`")))) + (((`dangerouslySetInnerHTML` + ("`" + ` does not make sense on <textarea>."),
_assign({}, props, { _assign({}, props, {
value: void 0, value: void 0,
defaultValue: void 0, defaultValue: void 0,
@ -22450,8 +22450,8 @@ var _publicBundleJs = []byte(`!function(modules) {
var initialValue = props.value; var initialValue = props.value;
if (null == initialValue) { if (null == initialValue) {
var defaultValue = props.defaultValue, children = props.children; var defaultValue = props.defaultValue, children = props.children;
null != children && (warning(!1, "Use the ` + "`" + `defaultValue` + "`" + ` or ` + "`" + `value` + "`" + ` props instead of setting children on <textarea>."), null != children && (warning(!1, "Use the `)) + ("`" + (`defaultValue` + "`"))) + ((` or ` + ("`" + `value`)) + ("`" + (` props instead of setting children on <textarea>."),
null != defaultValue && invariant(!1, "If you supply ` + "`" + `defaultValue` + "`" + ` on a <textarea>, do not pass children."), null != defaultValue && invariant(!1, "If you supply ` + "`"))))) + ((((`defaultValue` + ("`" + ` on a <textarea>, do not pass children."),
Array.isArray(children) && (children.length <= 1 || invariant(!1, "<textarea> can only have at most one child."), Array.isArray(children) && (children.length <= 1 || invariant(!1, "<textarea> can only have at most one child."),
children = children[0]), defaultValue = "" + children), null == defaultValue && (defaultValue = ""), children = children[0]), defaultValue = "" + children), null == defaultValue && (defaultValue = ""),
initialValue = defaultValue; initialValue = defaultValue;
@ -22518,11 +22518,11 @@ var _publicBundleJs = []byte(`!function(modules) {
} }
} }
function assertValidProps(tag, props, getStack) { function assertValidProps(tag, props, getStack) {
props && (voidElementTags[tag] && (null != props.children || null != props.dangerouslySetInnerHTML) && invariant(!1, "%s is a void element tag and must neither have ` + "`" + `children` + "`" + ` nor use ` + "`" + `dangerouslySetInnerHTML` + "`" + `.%s", tag, getStack()), props && (voidElementTags[tag] && (null != props.children || null != props.dangerouslySetInnerHTML) && invariant(!1, "%s is a void element tag and must neither have `)) + ("`" + (`children` + "`"))) + ((` nor use ` + ("`" + `dangerouslySetInnerHTML`)) + ("`" + (`.%s", tag, getStack()),
null != props.dangerouslySetInnerHTML && (null != props.children && invariant(!1, "Can only set one of ` + "`" + `children` + "`" + ` or ` + "`" + `props.dangerouslySetInnerHTML` + "`" + `."), null != props.dangerouslySetInnerHTML && (null != props.children && invariant(!1, "Can only set one of ` + "`")))) + (((`children` + ("`" + ` or `)) + ("`" + (`props.dangerouslySetInnerHTML` + "`"))) + ((`."),
"object" == typeof props.dangerouslySetInnerHTML && HTML$1 in props.dangerouslySetInnerHTML || invariant(!1, "` + "`" + `props.dangerouslySetInnerHTML` + "`" + ` must be in the form ` + "`" + `{__html: ...}` + "`" + `. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information.")), "object" == typeof props.dangerouslySetInnerHTML && HTML$1 in props.dangerouslySetInnerHTML || invariant(!1, "` + ("`" + `props.dangerouslySetInnerHTML`)) + ("`" + (` must be in the form ` + "`")))))) + (((((`{__html: ...}` + ("`" + `. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information.")),
warning(props.suppressContentEditableWarning || !props.contentEditable || null == props.children, "A component is ` + "`" + `contentEditable` + "`" + ` and contains ` + "`" + `children` + "`" + ` managed by React. It is now your responsibility to guarantee that none of those nodes are unexpectedly modified or duplicated. This is probably not intentional.%s", getStack()), warning(props.suppressContentEditableWarning || !props.contentEditable || null == props.children, "A component is `)) + ("`" + (`contentEditable` + "`"))) + ((` and contains ` + ("`" + `children`)) + ("`" + (` managed by React. It is now your responsibility to guarantee that none of those nodes are unexpectedly modified or duplicated. This is probably not intentional.%s", getStack()),
null != props.style && "object" != typeof props.style && invariant(!1, "The ` + "`" + `style` + "`" + ` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + 'em'}} when using JSX.%s", getStack())); null != props.style && "object" != typeof props.style && invariant(!1, "The ` + "`")))) + (((`style` + ("`" + ` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + 'em'}} when using JSX.%s", getStack()));
} }
function isCustomComponent(tagName, props) { function isCustomComponent(tagName, props) {
if (-1 === tagName.indexOf("-")) return "string" == typeof props.is; if (-1 === tagName.indexOf("-")) return "string" == typeof props.is;
@ -22549,15 +22549,15 @@ var _publicBundleJs = []byte(`!function(modules) {
if (hasOwnProperty.call(warnedProperties, name) && warnedProperties[name]) return !0; if (hasOwnProperty.call(warnedProperties, name) && warnedProperties[name]) return !0;
if (rARIACamel.test(name)) { if (rARIACamel.test(name)) {
var ariaName = "aria-" + name.slice(4).toLowerCase(), correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null; var ariaName = "aria-" + name.slice(4).toLowerCase(), correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null;
if (null == correctName) return warning(!1, "Invalid ARIA attribute ` + "`" + `%s` + "`" + `. ARIA attributes follow the pattern aria-* and must be lowercase.%s", name, getStackAddendum()), if (null == correctName) return warning(!1, "Invalid ARIA attribute `)) + ("`" + (`%s` + "`"))) + ((`. ARIA attributes follow the pattern aria-* and must be lowercase.%s", name, getStackAddendum()),
warnedProperties[name] = !0, !0; warnedProperties[name] = !0, !0;
if (name !== correctName) return warning(!1, "Invalid ARIA attribute ` + "`" + `%s` + "`" + `. Did you mean ` + "`" + `%s` + "`" + `?%s", name, correctName, getStackAddendum()), if (name !== correctName) return warning(!1, "Invalid ARIA attribute ` + ("`" + `%s`)) + ("`" + (`. Did you mean ` + "`"))))) + ((((`%s` + ("`" + `?%s", name, correctName, getStackAddendum()),
warnedProperties[name] = !0, !0; warnedProperties[name] = !0, !0;
} }
if (rARIA.test(name)) { if (rARIA.test(name)) {
var lowerCasedName = name.toLowerCase(), standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null; var lowerCasedName = name.toLowerCase(), standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null;
if (null == standardName) return warnedProperties[name] = !0, !1; if (null == standardName) return warnedProperties[name] = !0, !1;
if (name !== standardName) return warning(!1, "Unknown ARIA attribute ` + "`" + `%s` + "`" + `. Did you mean ` + "`" + `%s` + "`" + `?%s", name, standardName, getStackAddendum()), if (name !== standardName) return warning(!1, "Unknown ARIA attribute `)) + ("`" + (`%s` + "`"))) + ((`. Did you mean ` + ("`" + `%s`)) + ("`" + (`?%s", name, standardName, getStackAddendum()),
warnedProperties[name] = !0, !0; warnedProperties[name] = !0, !0;
} }
return !0; return !0;
@ -22568,7 +22568,7 @@ var _publicBundleJs = []byte(`!function(modules) {
validateProperty(type, key) || invalidProps.push(key); validateProperty(type, key) || invalidProps.push(key);
} }
var unknownPropString = invalidProps.map(function(prop) { var unknownPropString = invalidProps.map(function(prop) {
return "` + "`" + `" + prop + "` + "`" + `"; return "` + "`")))) + (((`" + prop + "` + ("`" + `";
}).join(", "); }).join(", ");
1 === invalidProps.length ? warning(!1, "Invalid aria prop %s on <%s> tag. For details, see https://fb.me/invalid-aria-prop%s", unknownPropString, type, getStackAddendum()) : invalidProps.length > 1 && warning(!1, "Invalid aria props %s on <%s> tag. For details, see https://fb.me/invalid-aria-prop%s", unknownPropString, type, getStackAddendum()); 1 === invalidProps.length ? warning(!1, "Invalid aria prop %s on <%s> tag. For details, see https://fb.me/invalid-aria-prop%s", unknownPropString, type, getStackAddendum()) : invalidProps.length > 1 && warning(!1, "Invalid aria props %s on <%s> tag. For details, see https://fb.me/invalid-aria-prop%s", unknownPropString, type, getStackAddendum());
} }
@ -22581,7 +22581,7 @@ var _publicBundleJs = []byte(`!function(modules) {
} }
function validateProperties$1(type, props) { function validateProperties$1(type, props) {
"input" !== type && "textarea" !== type && "select" !== type || null == props || null !== props.value || didWarnValueNull || (didWarnValueNull = !0, "input" !== type && "textarea" !== type && "select" !== type || null == props || null !== props.value || didWarnValueNull || (didWarnValueNull = !0,
"select" === type && props.multiple ? warning(!1, "` + "`" + `value` + "`" + ` prop on ` + "`" + `%s` + "`" + ` should not be null. Consider using an empty array when ` + "`" + `multiple` + "`" + ` is set to ` + "`" + `true` + "`" + ` to clear the component or ` + "`" + `undefined` + "`" + ` for uncontrolled components.%s", type, getStackAddendum$1()) : warning(!1, "` + "`" + `value` + "`" + ` prop on ` + "`" + `%s` + "`" + ` should not be null. Consider using an empty string to clear the component or ` + "`" + `undefined` + "`" + ` for uncontrolled components.%s", type, getStackAddendum$1())); "select" === type && props.multiple ? warning(!1, "`)) + ("`" + (`value` + "`"))) + ((` prop on ` + ("`" + `%s`)) + ("`" + (` should not be null. Consider using an empty array when ` + "`"))))))) + ((((((`multiple` + "`") + (` is set to ` + ("`" + `true`))) + (("`" + (` to clear the component or ` + "`")) + (`undefined` + ("`" + ` for uncontrolled components.%s", type, getStackAddendum$1()) : warning(!1, "`)))) + ((("`" + (`value` + "`")) + (` prop on ` + ("`" + `%s`))) + (("`" + (` should not be null. Consider using an empty string to clear the component or ` + "`")) + (`undefined` + ("`" + ` for uncontrolled components.%s", type, getStackAddendum$1()));
} }
function getStackAddendum$2() { function getStackAddendum$2() {
var stack = ReactDebugCurrentFrame.getStackAddendum(); var stack = ReactDebugCurrentFrame.getStackAddendum();
@ -23197,7 +23197,7 @@ var _publicBundleJs = []byte(`!function(modules) {
}; };
validateEventDispatches = function(event) { validateEventDispatches = function(event) {
var dispatchListeners = event._dispatchListeners, dispatchInstances = event._dispatchInstances, listenersIsArr = Array.isArray(dispatchListeners), listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0, instancesIsArr = Array.isArray(dispatchInstances), instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0; var dispatchListeners = event._dispatchListeners, dispatchInstances = event._dispatchInstances, listenersIsArr = Array.isArray(dispatchListeners), listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0, instancesIsArr = Array.isArray(dispatchInstances), instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0;
warning(instancesIsArr === listenersIsArr && instancesLen === listenersLen, "EventPluginUtils: Invalid ` + "`" + `event` + "`" + `."); warning(instancesIsArr === listenersIsArr && instancesLen === listenersLen, "EventPluginUtils: Invalid `))))) + (((("`" + (`event` + "`")) + (`.");
}; };
var eventQueue = null, executeDispatchesAndRelease = function(event, simulated) { var eventQueue = null, executeDispatchesAndRelease = function(event, simulated) {
event && (executeDispatchesInOrder(event, simulated), event.isPersistent() || event.constructor.release(event)); event && (executeDispatchesInOrder(event, simulated), event.isPersistent() || event.constructor.release(event));
@ -23792,7 +23792,7 @@ var _publicBundleJs = []byte(`!function(modules) {
break; break;
default: default:
-1 === knownHTMLTopLevelTypes.indexOf(topLevelType) && warning(!1, "SimpleEventPlugin: Unhandled event type, ` + "`" + `%s` + "`" + `. This warning is likely caused by a bug in React. Please file an issue.", topLevelType), -1 === knownHTMLTopLevelTypes.indexOf(topLevelType) && warning(!1, "SimpleEventPlugin: Unhandled event type, ` + ("`" + `%s`))) + (("`" + (`. This warning is likely caused by a bug in React. Please file an issue.", topLevelType),
EventConstructor = SyntheticEvent$1; EventConstructor = SyntheticEvent$1;
} }
var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget); var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget);
@ -23879,7 +23879,7 @@ var _publicBundleJs = []byte(`!function(modules) {
var debugCounter = 1, createFiber = function(tag, key, internalContextTag) { var debugCounter = 1, createFiber = function(tag, key, internalContextTag) {
return new FiberNode(tag, key, internalContextTag); return new FiberNode(tag, key, internalContextTag);
}, onCommitFiberRoot = null, onCommitFiberUnmount = null, hasLoggedError = !1, didWarnUpdateInsideUpdate = !1, fakeInternalInstance = {}, isArray = Array.isArray, didWarnAboutStateAssignmentForComponent = {}, warnOnInvalidCallback = function(callback, callerName) { }, onCommitFiberRoot = null, onCommitFiberUnmount = null, hasLoggedError = !1, didWarnUpdateInsideUpdate = !1, fakeInternalInstance = {}, isArray = Array.isArray, didWarnAboutStateAssignmentForComponent = {}, warnOnInvalidCallback = function(callback, callerName) {
warning(null === callback || "function" == typeof callback, "%s(...): Expected the last optional ` + "`" + `callback` + "`" + ` argument to be a function. Instead received: %s.", callerName, callback); warning(null === callback || "function" == typeof callback, "%s(...): Expected the last optional ` + "`")) + (`callback` + ("`" + ` argument to be a function. Instead received: %s.", callerName, callback);
}; };
Object.defineProperty(fakeInternalInstance, "_processChildContext", { Object.defineProperty(fakeInternalInstance, "_processChildContext", {
enumerable: !1, enumerable: !1,
@ -23902,7 +23902,7 @@ var _publicBundleJs = []byte(`!function(modules) {
} }
function checkClassInstance(workInProgress) { function checkClassInstance(workInProgress) {
var instance = workInProgress.stateNode, type = workInProgress.type, name = getComponentName(workInProgress); var instance = workInProgress.stateNode, type = workInProgress.type, name = getComponentName(workInProgress);
instance.render || (type.prototype && "function" == typeof type.prototype.render ? warning(!1, "%s(...): No ` + "`" + `render` + "`" + ` method found on the returned component instance: did you accidentally return an object from the constructor?", name) : warning(!1, "%s(...): No ` + "`" + `render` + "`" + ` method found on the returned component instance: you may have forgotten to define ` + "`" + `render` + "`" + `.", name)); instance.render || (type.prototype && "function" == typeof type.prototype.render ? warning(!1, "%s(...): No `)))) + ((("`" + (`render` + "`")) + (` method found on the returned component instance: did you accidentally return an object from the constructor?", name) : warning(!1, "%s(...): No ` + ("`" + `render`))) + (("`" + (` method found on the returned component instance: you may have forgotten to define ` + "`")) + (`render` + ("`" + `.", name));
var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state; var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
warning(noGetInitialStateOnES6, "getInitialState was defined on %s, a plain JavaScript class. This is only supported for classes created using React.createClass. Did you mean to define a state property instead?", name); warning(noGetInitialStateOnES6, "getInitialState was defined on %s, a plain JavaScript class. This is only supported for classes created using React.createClass. Did you mean to define a state property instead?", name);
var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved; var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
@ -23921,7 +23921,7 @@ var _publicBundleJs = []byte(`!function(modules) {
var noComponentWillRecieveProps = "function" != typeof instance.componentWillRecieveProps; var noComponentWillRecieveProps = "function" != typeof instance.componentWillRecieveProps;
warning(noComponentWillRecieveProps, "%s has a method called componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", name); warning(noComponentWillRecieveProps, "%s has a method called componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", name);
var hasMutatedProps = instance.props !== workInProgress.pendingProps; var hasMutatedProps = instance.props !== workInProgress.pendingProps;
warning(void 0 === instance.props || !hasMutatedProps, "%s(...): When calling super() in ` + "`" + `%s` + "`" + `, make sure to pass up the same props that your component's constructor was passed.", name, name); warning(void 0 === instance.props || !hasMutatedProps, "%s(...): When calling super() in `)))))) + ((((("`" + (`%s` + "`")) + (`, make sure to pass up the same props that your component's constructor was passed.", name, name);
var noInstanceDefaultProps = !instance.defaultProps; var noInstanceDefaultProps = !instance.defaultProps;
warning(noInstanceDefaultProps, "Setting defaultProps as an instance property on %s is not supported and will be ignored. Instead, define defaultProps as a static property on %s.", name, name); warning(noInstanceDefaultProps, "Setting defaultProps as an instance property on %s is not supported and will be ignored. Instead, define defaultProps as a static property on %s.", name, name);
var state = instance.state; var state = instance.state;
@ -24153,7 +24153,7 @@ var _publicBundleJs = []byte(`!function(modules) {
if (Component && warning(!Component.childContextTypes, "%s(...): childContextTypes cannot be defined on a functional component.", Component.displayName || Component.name || "Component"), if (Component && warning(!Component.childContextTypes, "%s(...): childContextTypes cannot be defined on a functional component.", Component.displayName || Component.name || "Component"),
null !== workInProgress.ref) { null !== workInProgress.ref) {
var info = "", ownerName = ReactDebugCurrentFiber.getCurrentFiberOwnerName(); var info = "", ownerName = ReactDebugCurrentFiber.getCurrentFiberOwnerName();
ownerName && (info += "\n\nCheck the render method of ` + "`" + `" + ownerName + "` + "`" + `."); ownerName && (info += "\n\nCheck the render method of ` + ("`" + `" + ownerName + "`))) + (("`" + (`.");
var warningKey = ownerName || workInProgress._debugID || "", debugSource = workInProgress._debugSource; var warningKey = ownerName || workInProgress._debugID || "", debugSource = workInProgress._debugSource;
debugSource && (warningKey = debugSource.fileName + ":" + debugSource.lineNumber), debugSource && (warningKey = debugSource.fileName + ":" + debugSource.lineNumber),
warnedAboutStatelessRefs[warningKey] || (warnedAboutStatelessRefs[warningKey] = !0, warnedAboutStatelessRefs[warningKey] || (warnedAboutStatelessRefs[warningKey] = !0,
@ -24911,7 +24911,7 @@ var _publicBundleJs = []byte(`!function(modules) {
case "render": case "render":
if (didWarnAboutStateTransition) return; if (didWarnAboutStateTransition) return;
warning(!1, "Cannot update during an existing state transition (such as within ` + "`" + `render` + "`" + ` or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to ` + "`" + `componentWillMount` + "`" + `."), warning(!1, "Cannot update during an existing state transition (such as within ` + "`")) + (`render` + ("`" + ` or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to `)))) + ((("`" + (`componentWillMount` + "`")) + (`."),
didWarnAboutStateTransition = !0; didWarnAboutStateTransition = !0;
} }
}, ReactFiberScheduler = function(config) { }, ReactFiberScheduler = function(config) {
@ -25361,7 +25361,7 @@ var _publicBundleJs = []byte(`!function(modules) {
function scheduleTopLevelUpdate(current, element, callback) { function scheduleTopLevelUpdate(current, element, callback) {
"render" !== ReactDebugCurrentFiber.phase || null === ReactDebugCurrentFiber.current || didWarnAboutNestedUpdates || (didWarnAboutNestedUpdates = !0, "render" !== ReactDebugCurrentFiber.phase || null === ReactDebugCurrentFiber.current || didWarnAboutNestedUpdates || (didWarnAboutNestedUpdates = !0,
warning(!1, "Render methods should be a pure function of props and state; triggering nested component updates from render is not allowed. If necessary, trigger nested updates in componentDidUpdate.\n\nCheck the render method of %s.", getComponentName(ReactDebugCurrentFiber.current) || "Unknown")), warning(!1, "Render methods should be a pure function of props and state; triggering nested component updates from render is not allowed. If necessary, trigger nested updates in componentDidUpdate.\n\nCheck the render method of %s.", getComponentName(ReactDebugCurrentFiber.current) || "Unknown")),
callback = void 0 === callback ? null : callback, warning(null === callback || "function" == typeof callback, "render(...): Expected the last optional ` + "`" + `callback` + "`" + ` argument to be a function. Instead received: %s.", callback); callback = void 0 === callback ? null : callback, warning(null === callback || "function" == typeof callback, "render(...): Expected the last optional ` + ("`" + `callback`))) + (("`" + (` argument to be a function. Instead received: %s.", callback);
var expirationTime = void 0; var expirationTime = void 0;
expirationTime = enableAsyncSubtreeAPI && null != element && null != element.type && null != element.type.prototype && !0 === element.type.prototype.unstable_isAsyncReactComponent ? computeAsyncExpiration() : computeExpirationForFiber(current), expirationTime = enableAsyncSubtreeAPI && null != element && null != element.type && null != element.type.prototype && !0 === element.type.prototype.unstable_isAsyncReactComponent ? computeAsyncExpiration() : computeExpirationForFiber(current),
insertUpdateIntoFiber(current, { insertUpdateIntoFiber(current, {
@ -25502,7 +25502,7 @@ var _publicBundleJs = []byte(`!function(modules) {
} catch (x) {} } catch (x) {}
}; };
lowPriorityWarning = function(condition, format) { lowPriorityWarning = function(condition, format) {
if (void 0 === format) throw new Error("` + "`" + `warning(condition, format, ...args)` + "`" + ` requires a warning message argument"); if (void 0 === format) throw new Error("` + "`")) + (`warning(condition, format, ...args)` + ("`" + ` requires a warning message argument");
if (!condition) { if (!condition) {
for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) args[_key2 - 2] = arguments[_key2]; for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) args[_key2 - 2] = arguments[_key2];
printWarning.apply(void 0, [ format ].concat(args)); printWarning.apply(void 0, [ format ].concat(args));
@ -25520,10 +25520,10 @@ var _publicBundleJs = []byte(`!function(modules) {
submit: !0 submit: !0
}, propTypes = { }, propTypes = {
value: function(props, propName, componentName) { value: function(props, propName, componentName) {
return !props[propName] || hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled ? null : new Error("You provided a ` + "`" + `value` + "`" + ` prop to a form field without an ` + "`" + `onChange` + "`" + ` handler. This will render a read-only field. If the field should be mutable use ` + "`" + `defaultValue` + "`" + `. Otherwise, set either ` + "`" + `onChange` + "`" + ` or ` + "`" + `readOnly` + "`" + `."); return !props[propName] || hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled ? null : new Error("You provided a `))))) + (((("`" + (`value` + "`")) + (` prop to a form field without an ` + ("`" + `onChange`))) + (("`" + (` handler. This will render a read-only field. If the field should be mutable use ` + "`")) + (`defaultValue` + ("`" + `. Otherwise, set either `)))) + ((("`" + (`onChange` + "`")) + (` or ` + ("`" + `readOnly`))) + (("`" + (`.");
}, },
checked: function(props, propName, componentName) { checked: function(props, propName, componentName) {
return !props[propName] || props.onChange || props.readOnly || props.disabled ? null : new Error("You provided a ` + "`" + `checked` + "`" + ` prop to a form field without an ` + "`" + `onChange` + "`" + ` handler. This will render a read-only field. If the field should be mutable use ` + "`" + `defaultChecked` + "`" + `. Otherwise, set either ` + "`" + `onChange` + "`" + ` or ` + "`" + `readOnly` + "`" + `."); return !props[propName] || props.onChange || props.readOnly || props.disabled ? null : new Error("You provided a ` + "`")) + (`checked` + ("`" + ` prop to a form field without an `))))))))) + (((((((("`" + `onChange`) + ("`" + (` handler. This will render a read-only field. If the field should be mutable use ` + "`"))) + ((`defaultChecked` + ("`" + `. Otherwise, set either `)) + ("`" + (`onChange` + "`")))) + (((` or ` + ("`" + `readOnly`)) + ("`" + (`.");
} }
}; };
ReactControlledValuePropTypes.checkPropTypes = function(tagName, props, getStack) { ReactControlledValuePropTypes.checkPropTypes = function(tagName, props, getStack) {
@ -25609,9 +25609,9 @@ var _publicBundleJs = []byte(`!function(modules) {
warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value] || (warnedStyleValues[value] = !0, warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value] || (warnedStyleValues[value] = !0,
warning(!1, 'Style property values shouldn\'t contain a semicolon. Try "%s: %s" instead.%s', name, value.replace(badStyleValueWithSemicolonPattern, ""), getStack())); warning(!1, 'Style property values shouldn\'t contain a semicolon. Try "%s: %s" instead.%s', name, value.replace(badStyleValueWithSemicolonPattern, ""), getStack()));
}, warnStyleValueIsNaN = function(name, value, getStack) { }, warnStyleValueIsNaN = function(name, value, getStack) {
warnedForNaNValue || (warnedForNaNValue = !0, warning(!1, "` + "`" + `NaN` + "`" + ` is an invalid value for the ` + "`" + `%s` + "`" + ` css style property.%s", name, getStack())); warnedForNaNValue || (warnedForNaNValue = !0, warning(!1, "` + "`"))) + ((`NaN` + ("`" + ` is an invalid value for the `)) + ("`" + (`%s` + "`"))))) + ((((` css style property.%s", name, getStack()));
}, warnStyleValueIsInfinity = function(name, value, getStack) { }, warnStyleValueIsInfinity = function(name, value, getStack) {
warnedForInfinityValue || (warnedForInfinityValue = !0, warning(!1, "` + "`" + `Infinity` + "`" + ` is an invalid value for the ` + "`" + `%s` + "`" + ` css style property.%s", name, getStack())); warnedForInfinityValue || (warnedForInfinityValue = !0, warning(!1, "` + ("`" + `Infinity`)) + ("`" + (` is an invalid value for the ` + "`"))) + ((`%s` + ("`" + ` css style property.%s", name, getStack()));
}; };
warnValidStyle = function(name, value, getStack) { warnValidStyle = function(name, value, getStack) {
name.indexOf("-") > -1 ? warnHyphenatedStyleName(name, getStack) : badVendoredStyleNamePattern.test(name) ? warnBadVendoredStyleName(name, getStack) : badStyleValueWithSemicolonPattern.test(value) && warnStyleValueWithSemicolon(name, value, getStack), name.indexOf("-") > -1 ? warnHyphenatedStyleName(name, getStack) : badVendoredStyleNamePattern.test(name) ? warnBadVendoredStyleName(name, getStack) : badStyleValueWithSemicolonPattern.test(value) && warnStyleValueWithSemicolon(name, value, getStack),
@ -26172,30 +26172,30 @@ var _publicBundleJs = []byte(`!function(modules) {
if (canUseEventSystem) { if (canUseEventSystem) {
if (registrationNameModules.hasOwnProperty(name)) return !0; if (registrationNameModules.hasOwnProperty(name)) return !0;
var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null; var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
if (null != registrationName) return warning(!1, "Invalid event handler property ` + "`" + `%s` + "`" + `. Did you mean ` + "`" + `%s` + "`" + `?%s", name, registrationName, getStackAddendum$2()), if (null != registrationName) return warning(!1, "Invalid event handler property `)) + ("`" + (`%s` + "`")))) + (((`. Did you mean ` + ("`" + `%s`)) + ("`" + (`?%s", name, registrationName, getStackAddendum$2()),
warnedProperties$1[name] = !0, !0; warnedProperties$1[name] = !0, !0;
if (EVENT_NAME_REGEX.test(name)) return warning(!1, "Unknown event handler property ` + "`" + `%s` + "`" + `. It will be ignored.%s", name, getStackAddendum$2()), if (EVENT_NAME_REGEX.test(name)) return warning(!1, "Unknown event handler property ` + "`"))) + ((`%s` + ("`" + `. It will be ignored.%s", name, getStackAddendum$2()),
warnedProperties$1[name] = !0, !0; warnedProperties$1[name] = !0, !0;
} else if (EVENT_NAME_REGEX.test(name)) return INVALID_EVENT_NAME_REGEX.test(name) && warning(!1, "Invalid event handler property ` + "`" + `%s` + "`" + `. React events use the camelCase naming convention, for example ` + "`" + `onClick` + "`" + `.%s", name, getStackAddendum$2()), } else if (EVENT_NAME_REGEX.test(name)) return INVALID_EVENT_NAME_REGEX.test(name) && warning(!1, "Invalid event handler property `)) + ("`" + (`%s` + "`")))))) + (((((`. React events use the camelCase naming convention, for example ` + ("`" + `onClick`)) + ("`" + (`.%s", name, getStackAddendum$2()),
warnedProperties$1[name] = !0, !0; warnedProperties$1[name] = !0, !0;
if (rARIA$1.test(name) || rARIACamel$1.test(name)) return !0; if (rARIA$1.test(name) || rARIACamel$1.test(name)) return !0;
if ("innerhtml" === lowerCasedName) return warning(!1, "Directly setting property ` + "`" + `innerHTML` + "`" + ` is not permitted. For more information, lookup documentation on ` + "`" + `dangerouslySetInnerHTML` + "`" + `."), if ("innerhtml" === lowerCasedName) return warning(!1, "Directly setting property ` + "`"))) + ((`innerHTML` + ("`" + ` is not permitted. For more information, lookup documentation on `)) + ("`" + (`dangerouslySetInnerHTML` + "`")))) + (((`."),
warnedProperties$1[name] = !0, !0; warnedProperties$1[name] = !0, !0;
if ("aria" === lowerCasedName) return warning(!1, "The ` + "`" + `aria` + "`" + ` attribute is reserved for future use in React. Pass individual ` + "`" + `aria-` + "`" + ` attributes instead."), if ("aria" === lowerCasedName) return warning(!1, "The ` + ("`" + `aria`)) + ("`" + (` attribute is reserved for future use in React. Pass individual ` + "`"))) + ((`aria-` + ("`" + ` attributes instead."),
warnedProperties$1[name] = !0, !0; warnedProperties$1[name] = !0, !0;
if ("is" === lowerCasedName && null !== value && void 0 !== value && "string" != typeof value) return warning(!1, "Received a ` + "`" + `%s` + "`" + ` for a string attribute ` + "`" + `is` + "`" + `. If this is expected, cast the value to a string.%s", typeof value, getStackAddendum$2()), if ("is" === lowerCasedName && null !== value && void 0 !== value && "string" != typeof value) return warning(!1, "Received a `)) + ("`" + (`%s` + "`"))))) + ((((` for a string attribute ` + ("`" + `is`)) + ("`" + (`. If this is expected, cast the value to a string.%s", typeof value, getStackAddendum$2()),
warnedProperties$1[name] = !0, !0; warnedProperties$1[name] = !0, !0;
if ("number" == typeof value && isNaN(value)) return warning(!1, "Received NaN for the ` + "`" + `%s` + "`" + ` attribute. If this is expected, cast the value to a string.%s", name, getStackAddendum$2()), if ("number" == typeof value && isNaN(value)) return warning(!1, "Received NaN for the ` + "`"))) + ((`%s` + ("`" + ` attribute. If this is expected, cast the value to a string.%s", name, getStackAddendum$2()),
warnedProperties$1[name] = !0, !0; warnedProperties$1[name] = !0, !0;
var isReserved = isReservedProp(name); var isReserved = isReservedProp(name);
if (possibleStandardNames.hasOwnProperty(lowerCasedName)) { if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
var standardName = possibleStandardNames[lowerCasedName]; var standardName = possibleStandardNames[lowerCasedName];
if (standardName !== name) return warning(!1, "Invalid DOM property ` + "`" + `%s` + "`" + `. Did you mean ` + "`" + `%s` + "`" + `?%s", name, standardName, getStackAddendum$2()), if (standardName !== name) return warning(!1, "Invalid DOM property `)) + ("`" + (`%s` + "`")))) + (((`. Did you mean ` + ("`" + `%s`)) + ("`" + (`?%s", name, standardName, getStackAddendum$2()),
warnedProperties$1[name] = !0, !0; warnedProperties$1[name] = !0, !0;
} else if (!isReserved && name !== lowerCasedName) return warning(!1, "React does not recognize the ` + "`" + `%s` + "`" + ` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase ` + "`" + `%s` + "`" + ` instead. If you accidentally passed it from a parent component, remove it from the DOM element.%s", name, lowerCasedName, getStackAddendum$2()), } else if (!isReserved && name !== lowerCasedName) return warning(!1, "React does not recognize the ` + "`"))) + ((`%s` + ("`" + ` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `)) + ("`" + (`%s` + "`"))))))) + ((((((` instead. If you accidentally passed it from a parent component, remove it from the DOM element.%s", name, lowerCasedName, getStackAddendum$2()),
warnedProperties$1[name] = !0, !0; warnedProperties$1[name] = !0, !0;
return "boolean" != typeof value || shouldAttributeAcceptBooleanValue(name) ? !!isReserved || (!!shouldSetAttribute(name, value) || (warnedProperties$1[name] = !0, return "boolean" != typeof value || shouldAttributeAcceptBooleanValue(name) ? !!isReserved || (!!shouldSetAttribute(name, value) || (warnedProperties$1[name] = !0,
!1)) : (value ? warning(!1, 'Received ` + "`" + `%s` + "`" + ` for a non-boolean attribute ` + "`" + `%s` + "`" + `.\n\nIf you want to write it to the DOM, pass a string instead: %s="%s" or %s={value.toString()}.%s', value, name, name, value, name, getStackAddendum$2()) : warning(!1, 'Received ` + "`" + `%s` + "`" + ` for a non-boolean attribute ` + "`" + `%s` + "`" + `.\n\nIf you want to write it to the DOM, pass a string instead: %s="%s" or %s={value.toString()}.\n\nIf you used to conditionally omit it with %s={condition && value}, pass %s={condition ? value : undefined} instead.%s', value, name, name, value, name, name, name, getStackAddendum$2()), !1)) : (value ? warning(!1, 'Received ` + "`") + (`%s` + ("`" + ` for a non-boolean attribute `))) + (("`" + (`%s` + "`")) + (`.\n\nIf you want to write it to the DOM, pass a string instead: %s="%s" or %s={value.toString()}.%s', value, name, name, value, name, getStackAddendum$2()) : warning(!1, 'Received ` + ("`" + `%s`)))) + ((("`" + (` for a non-boolean attribute ` + "`")) + (`%s` + ("`" + `.\n\nIf you want to write it to the DOM, pass a string instead: %s="%s" or %s={value.toString()}.\n\nIf you used to conditionally omit it with %s={condition && value}, pass %s={condition ? value : undefined} instead.%s', value, name, name, value, name, name, name, getStackAddendum$2()),
warnedProperties$1[name] = !0, !0); warnedProperties$1[name] = !0, !0);
}, warnUnknownProperties = function(type, props, canUseEventSystem) { }, warnUnknownProperties = function(type, props, canUseEventSystem) {
var unknownProps = []; var unknownProps = [];
@ -26203,7 +26203,7 @@ var _publicBundleJs = []byte(`!function(modules) {
validateProperty$1(0, key, props[key], canUseEventSystem) || unknownProps.push(key); validateProperty$1(0, key, props[key], canUseEventSystem) || unknownProps.push(key);
} }
var unknownPropString = unknownProps.map(function(prop) { var unknownPropString = unknownProps.map(function(prop) {
return "` + "`" + `" + prop + "` + "`" + `"; return "`))) + (("`" + (`" + prop + "` + "`")) + (`";
}).join(", "); }).join(", ");
1 === unknownProps.length ? warning(!1, "Invalid value for prop %s on <%s> tag. Either remove it from the element, or pass a string or number value to keep it in the DOM. For details, see https://fb.me/react-attribute-behavior%s", unknownPropString, type, getStackAddendum$2()) : unknownProps.length > 1 && warning(!1, "Invalid values for props %s on <%s> tag. Either remove them from the element, or pass a string or number value to keep them in the DOM. For details, see https://fb.me/react-attribute-behavior%s", unknownPropString, type, getStackAddendum$2()); 1 === unknownProps.length ? warning(!1, "Invalid value for prop %s on <%s> tag. Either remove it from the element, or pass a string or number value to keep it in the DOM. For details, see https://fb.me/react-attribute-behavior%s", unknownPropString, type, getStackAddendum$2()) : unknownProps.length > 1 && warning(!1, "Invalid values for props %s on <%s> tag. Either remove them from the element, or pass a string or number value to keep them in the DOM. For details, see https://fb.me/react-attribute-behavior%s", unknownPropString, type, getStackAddendum$2());
}, getCurrentFiberOwnerName$1 = ReactDebugCurrentFiber.getCurrentFiberOwnerName, getCurrentFiberStackAddendum$2 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum, didWarnInvalidHydration = !1, didWarnShadyDOM = !1, DANGEROUSLY_SET_INNER_HTML = "dangerouslySetInnerHTML", SUPPRESS_CONTENT_EDITABLE_WARNING = "suppressContentEditableWarning", SUPPRESS_HYDRATION_WARNING$1 = "suppressHydrationWarning", AUTOFOCUS = "autoFocus", CHILDREN = "children", STYLE = "style", HTML = "__html", HTML_NAMESPACE = Namespaces.html, getStack = emptyFunction.thatReturns(""); }, getCurrentFiberOwnerName$1 = ReactDebugCurrentFiber.getCurrentFiberOwnerName, getCurrentFiberStackAddendum$2 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum, didWarnInvalidHydration = !1, didWarnShadyDOM = !1, DANGEROUSLY_SET_INNER_HTML = "dangerouslySetInnerHTML", SUPPRESS_CONTENT_EDITABLE_WARNING = "suppressContentEditableWarning", SUPPRESS_HYDRATION_WARNING$1 = "suppressHydrationWarning", AUTOFOCUS = "autoFocus", CHILDREN = "children", STYLE = "style", HTML = "__html", HTML_NAMESPACE = Namespaces.html, getStack = emptyFunction.thatReturns("");
@ -26225,7 +26225,7 @@ var _publicBundleJs = []byte(`!function(modules) {
if (!didWarnInvalidHydration) { if (!didWarnInvalidHydration) {
var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue), normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue); var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue), normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
normalizedServerValue !== normalizedClientValue && (didWarnInvalidHydration = !0, normalizedServerValue !== normalizedClientValue && (didWarnInvalidHydration = !0,
warning(!1, "Prop ` + "`" + `%s` + "`" + ` did not match. Server: %s Client: %s", propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue))); warning(!1, "Prop ` + ("`" + `%s`))))) + (((("`" + (` did not match. Server: %s Client: %s", propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue)));
} }
}, warnForExtraAttributes = function(attributeNames) { }, warnForExtraAttributes = function(attributeNames) {
if (!didWarnInvalidHydration) { if (!didWarnInvalidHydration) {
@ -26236,7 +26236,7 @@ var _publicBundleJs = []byte(`!function(modules) {
}), warning(!1, "Extra attributes from the server: %s", names); }), warning(!1, "Extra attributes from the server: %s", names);
} }
}, warnForInvalidEventListener = function(registrationName, listener) { }, warnForInvalidEventListener = function(registrationName, listener) {
!1 === listener ? warning(!1, "Expected ` + "`" + `%s` + "`" + ` listener to be a function, instead got ` + "`" + `false` + "`" + `.\n\nIf you used to conditionally omit it with %s={condition && value}, pass %s={condition ? value : undefined} instead.%s", registrationName, registrationName, registrationName, getCurrentFiberStackAddendum$2()) : warning(!1, "Expected ` + "`" + `%s` + "`" + ` listener to be a function, instead got a value of ` + "`" + `%s` + "`" + ` type.%s", registrationName, typeof listener, getCurrentFiberStackAddendum$2()); !1 === listener ? warning(!1, "Expected ` + "`")) + (`%s` + ("`" + ` listener to be a function, instead got `))) + (("`" + (`false` + "`")) + (`.\n\nIf you used to conditionally omit it with %s={condition && value}, pass %s={condition ? value : undefined} instead.%s", registrationName, registrationName, registrationName, getCurrentFiberStackAddendum$2()) : warning(!1, "Expected ` + ("`" + `%s`)))) + ((("`" + (` listener to be a function, instead got a value of ` + "`")) + (`%s` + ("`" + ` type.%s", registrationName, typeof listener, getCurrentFiberStackAddendum$2());
}, normalizeHTML = function(parent, html) { }, normalizeHTML = function(parent, html) {
var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName); var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
return testElement.innerHTML = html, testElement.innerHTML; return testElement.innerHTML = html, testElement.innerHTML;
@ -27099,12 +27099,12 @@ var _publicBundleJs = []byte(`!function(modules) {
function createChainableTypeChecker(validate) { function createChainableTypeChecker(validate) {
function checkType(isRequired, props, propName, componentName, location, propFullName, secret) { function checkType(isRequired, props, propName, componentName, location, propFullName, secret) {
if (componentName = componentName || ANONYMOUS, propFullName = propFullName || propName, if (componentName = componentName || ANONYMOUS, propFullName = propFullName || propName,
secret !== ReactPropTypesSecret) if (throwOnDirectAccess) invariant(!1, "Calling PropTypes validators directly is not supported by the ` + "`" + `prop-types` + "`" + ` package. Use ` + "`" + `PropTypes.checkPropTypes()` + "`" + ` to call them. Read more at http://fb.me/use-check-prop-types"); else if ("production" !== process.env.NODE_ENV && "undefined" != typeof console) { secret !== ReactPropTypesSecret) if (throwOnDirectAccess) invariant(!1, "Calling PropTypes validators directly is not supported by the `))) + (("`" + (`prop-types` + "`")) + (` package. Use ` + ("`" + `PropTypes.checkPropTypes()`)))))) + ((((("`" + (` to call them. Read more at http://fb.me/use-check-prop-types"); else if ("production" !== process.env.NODE_ENV && "undefined" != typeof console) {
var cacheKey = componentName + ":" + propName; var cacheKey = componentName + ":" + propName;
!manualPropTypeCallCache[cacheKey] && manualPropTypeWarningCount < 3 && (warning(!1, "You are manually calling a React.PropTypes validation function for the ` + "`" + `%s` + "`" + ` prop on ` + "`" + `%s` + "`" + `. This is deprecated and will throw in the standalone ` + "`" + `prop-types` + "`" + ` package. You may be seeing this warning due to a third-party PropTypes library. See https://fb.me/react-warning-dont-call-proptypes for details.", propFullName, componentName), !manualPropTypeCallCache[cacheKey] && manualPropTypeWarningCount < 3 && (warning(!1, "You are manually calling a React.PropTypes validation function for the ` + "`")) + (`%s` + ("`" + ` prop on `))) + (("`" + (`%s` + "`")) + (`. This is deprecated and will throw in the standalone ` + ("`" + `prop-types`)))) + ((("`" + (` package. You may be seeing this warning due to a third-party PropTypes library. See https://fb.me/react-warning-dont-call-proptypes for details.", propFullName, componentName),
manualPropTypeCallCache[cacheKey] = !0, manualPropTypeWarningCount++); manualPropTypeCallCache[cacheKey] = !0, manualPropTypeWarningCount++);
} }
return null == props[propName] ? isRequired ? new PropTypeError(null === props[propName] ? "The " + location + " ` + "`" + `" + propFullName + "` + "`" + ` is marked as required in ` + "`" + `" + componentName + "` + "`" + `, but its value is ` + "`" + `null` + "`" + `." : "The " + location + " ` + "`" + `" + propFullName + "` + "`" + ` is marked as required in ` + "`" + `" + componentName + "` + "`" + `, but its value is ` + "`" + `undefined` + "`" + `.") : null : validate(props, propName, componentName, location, propFullName); return null == props[propName] ? isRequired ? new PropTypeError(null === props[propName] ? "The " + location + " ` + "`")) + (`" + propFullName + "` + ("`" + ` is marked as required in `))) + (("`" + (`" + componentName + "` + "`")) + (`, but its value is ` + ("`" + `null`))))) + (((("`" + (`." : "The " + location + " ` + "`")) + (`" + propFullName + "` + ("`" + ` is marked as required in `))) + (("`" + (`" + componentName + "` + "`")) + (`, but its value is ` + ("`" + `undefined`)))) + ((("`" + (`.") : null : validate(props, propName, componentName, location, propFullName);
} }
if ("production" !== process.env.NODE_ENV) var manualPropTypeCallCache = {}, manualPropTypeWarningCount = 0; if ("production" !== process.env.NODE_ENV) var manualPropTypeCallCache = {}, manualPropTypeWarningCount = 0;
var chainedCheckType = checkType.bind(null, !1); var chainedCheckType = checkType.bind(null, !1);
@ -27113,17 +27113,17 @@ var _publicBundleJs = []byte(`!function(modules) {
function createPrimitiveTypeChecker(expectedType) { function createPrimitiveTypeChecker(expectedType) {
function validate(props, propName, componentName, location, propFullName, secret) { function validate(props, propName, componentName, location, propFullName, secret) {
var propValue = props[propName]; var propValue = props[propName];
if (getPropType(propValue) !== expectedType) return new PropTypeError("Invalid " + location + " ` + "`" + `" + propFullName + "` + "`" + ` of type ` + "`" + `" + getPreciseType(propValue) + "` + "`" + ` supplied to ` + "`" + `" + componentName + "` + "`" + `, expected ` + "`" + `" + expectedType + "` + "`" + `."); if (getPropType(propValue) !== expectedType) return new PropTypeError("Invalid " + location + " ` + "`")) + (`" + propFullName + "` + ("`" + ` of type `))) + (("`" + (`" + getPreciseType(propValue) + "` + "`")) + (` supplied to ` + ("`" + `" + componentName + "`)))))))) + ((((((("`" + `, expected `) + ("`" + (`" + expectedType + "` + "`"))) + ((`.");
return null; return null;
} }
return createChainableTypeChecker(validate); return createChainableTypeChecker(validate);
} }
function createArrayOfTypeChecker(typeChecker) { function createArrayOfTypeChecker(typeChecker) {
function validate(props, propName, componentName, location, propFullName) { function validate(props, propName, componentName, location, propFullName) {
if ("function" != typeof typeChecker) return new PropTypeError("Property ` + "`" + `" + propFullName + "` + "`" + ` of component ` + "`" + `" + componentName + "` + "`" + ` has invalid PropType notation inside arrayOf."); if ("function" != typeof typeChecker) return new PropTypeError("Property ` + ("`" + `" + propFullName + "`)) + ("`" + (` of component ` + "`")))) + (((`" + componentName + "` + ("`" + ` has invalid PropType notation inside arrayOf.");
var propValue = props[propName]; var propValue = props[propName];
if (!Array.isArray(propValue)) { if (!Array.isArray(propValue)) {
return new PropTypeError("Invalid " + location + " ` + "`" + `" + propFullName + "` + "`" + ` of type ` + "`" + `" + getPropType(propValue) + "` + "`" + ` supplied to ` + "`" + `" + componentName + "` + "`" + `, expected an array."); return new PropTypeError("Invalid " + location + " `)) + ("`" + (`" + propFullName + "` + "`"))) + ((` of type ` + ("`" + `" + getPropType(propValue) + "`)) + ("`" + (` supplied to ` + "`"))))) + ((((`" + componentName + "` + ("`" + `, expected an array.");
} }
for (var i = 0; i < propValue.length; i++) { for (var i = 0; i < propValue.length; i++) {
var error = typeChecker(propValue, i, componentName, location, propFullName + "[" + i + "]", ReactPropTypesSecret); var error = typeChecker(propValue, i, componentName, location, propFullName + "[" + i + "]", ReactPropTypesSecret);
@ -27137,7 +27137,7 @@ var _publicBundleJs = []byte(`!function(modules) {
function validate(props, propName, componentName, location, propFullName) { function validate(props, propName, componentName, location, propFullName) {
if (!(props[propName] instanceof expectedClass)) { if (!(props[propName] instanceof expectedClass)) {
var expectedClassName = expectedClass.name || ANONYMOUS; var expectedClassName = expectedClass.name || ANONYMOUS;
return new PropTypeError("Invalid " + location + " ` + "`" + `" + propFullName + "` + "`" + ` of type ` + "`" + `" + getClassName(props[propName]) + "` + "`" + ` supplied to ` + "`" + `" + componentName + "` + "`" + `, expected instance of ` + "`" + `" + expectedClassName + "` + "`" + `."); return new PropTypeError("Invalid " + location + " `)) + ("`" + (`" + propFullName + "` + "`"))) + ((` of type ` + ("`" + `" + getClassName(props[propName]) + "`)) + ("`" + (` supplied to ` + "`")))) + (((`" + componentName + "` + ("`" + `, expected instance of `)) + ("`" + (`" + expectedClassName + "` + "`"))) + ((`.");
} }
return null; return null;
} }
@ -27146,16 +27146,16 @@ var _publicBundleJs = []byte(`!function(modules) {
function createEnumTypeChecker(expectedValues) { function createEnumTypeChecker(expectedValues) {
function validate(props, propName, componentName, location, propFullName) { function validate(props, propName, componentName, location, propFullName) {
for (var propValue = props[propName], i = 0; i < expectedValues.length; i++) if (is(propValue, expectedValues[i])) return null; for (var propValue = props[propName], i = 0; i < expectedValues.length; i++) if (is(propValue, expectedValues[i])) return null;
return new PropTypeError("Invalid " + location + " ` + "`" + `" + propFullName + "` + "`" + ` of value ` + "`" + `" + propValue + "` + "`" + ` supplied to ` + "`" + `" + componentName + "` + "`" + `, expected one of " + JSON.stringify(expectedValues) + "."); return new PropTypeError("Invalid " + location + " ` + ("`" + `" + propFullName + "`)) + ("`" + (` of value ` + "`")))))) + (((((`" + propValue + "` + ("`" + ` supplied to `)) + ("`" + (`" + componentName + "` + "`"))) + ((`, expected one of " + JSON.stringify(expectedValues) + ".");
} }
return Array.isArray(expectedValues) ? createChainableTypeChecker(validate) : ("production" !== process.env.NODE_ENV && warning(!1, "Invalid argument supplied to oneOf, expected an instance of array."), return Array.isArray(expectedValues) ? createChainableTypeChecker(validate) : ("production" !== process.env.NODE_ENV && warning(!1, "Invalid argument supplied to oneOf, expected an instance of array."),
emptyFunction.thatReturnsNull); emptyFunction.thatReturnsNull);
} }
function createObjectOfTypeChecker(typeChecker) { function createObjectOfTypeChecker(typeChecker) {
function validate(props, propName, componentName, location, propFullName) { function validate(props, propName, componentName, location, propFullName) {
if ("function" != typeof typeChecker) return new PropTypeError("Property ` + "`" + `" + propFullName + "` + "`" + ` of component ` + "`" + `" + componentName + "` + "`" + ` has invalid PropType notation inside objectOf."); if ("function" != typeof typeChecker) return new PropTypeError("Property ` + ("`" + `" + propFullName + "`)) + ("`" + (` of component ` + "`")))) + (((`" + componentName + "` + ("`" + ` has invalid PropType notation inside objectOf.");
var propValue = props[propName], propType = getPropType(propValue); var propValue = props[propName], propType = getPropType(propValue);
if ("object" !== propType) return new PropTypeError("Invalid " + location + " ` + "`" + `" + propFullName + "` + "`" + ` of type ` + "`" + `" + propType + "` + "`" + ` supplied to ` + "`" + `" + componentName + "` + "`" + `, expected an object."); if ("object" !== propType) return new PropTypeError("Invalid " + location + " `)) + ("`" + (`" + propFullName + "` + "`"))) + ((` of type ` + ("`" + `" + propType + "`)) + ("`" + (` supplied to ` + "`"))))) + ((((`" + componentName + "` + ("`" + `, expected an object.");
for (var key in propValue) if (propValue.hasOwnProperty(key)) { for (var key in propValue) if (propValue.hasOwnProperty(key)) {
var error = typeChecker(propValue, key, componentName, location, propFullName + "." + key, ReactPropTypesSecret); var error = typeChecker(propValue, key, componentName, location, propFullName + "." + key, ReactPropTypesSecret);
if (error instanceof Error) return error; if (error instanceof Error) return error;
@ -27169,7 +27169,7 @@ var _publicBundleJs = []byte(`!function(modules) {
for (var i = 0; i < arrayOfTypeCheckers.length; i++) { for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
if (null == (0, arrayOfTypeCheckers[i])(props, propName, componentName, location, propFullName, ReactPropTypesSecret)) return null; if (null == (0, arrayOfTypeCheckers[i])(props, propName, componentName, location, propFullName, ReactPropTypesSecret)) return null;
} }
return new PropTypeError("Invalid " + location + " ` + "`" + `" + propFullName + "` + "`" + ` supplied to ` + "`" + `" + componentName + "` + "`" + `."); return new PropTypeError("Invalid " + location + " `)) + ("`" + (`" + propFullName + "` + "`"))) + ((` supplied to ` + ("`" + `" + componentName + "`)) + ("`" + (`.");
} }
if (!Array.isArray(arrayOfTypeCheckers)) return "production" !== process.env.NODE_ENV && warning(!1, "Invalid argument supplied to oneOfType, expected an instance of array."), if (!Array.isArray(arrayOfTypeCheckers)) return "production" !== process.env.NODE_ENV && warning(!1, "Invalid argument supplied to oneOfType, expected an instance of array."),
emptyFunction.thatReturnsNull; emptyFunction.thatReturnsNull;
@ -27183,7 +27183,7 @@ var _publicBundleJs = []byte(`!function(modules) {
function createShapeTypeChecker(shapeTypes) { function createShapeTypeChecker(shapeTypes) {
function validate(props, propName, componentName, location, propFullName) { function validate(props, propName, componentName, location, propFullName) {
var propValue = props[propName], propType = getPropType(propValue); var propValue = props[propName], propType = getPropType(propValue);
if ("object" !== propType) return new PropTypeError("Invalid " + location + " ` + "`" + `" + propFullName + "` + "`" + ` of type ` + "`" + `" + propType + "` + "`" + ` supplied to ` + "`" + `" + componentName + "` + "`" + `, expected ` + "`" + `object` + "`" + `."); if ("object" !== propType) return new PropTypeError("Invalid " + location + " ` + "`")))) + (((`" + propFullName + "` + ("`" + ` of type `)) + ("`" + (`" + propType + "` + "`"))) + ((` supplied to ` + ("`" + `" + componentName + "`)) + ("`" + (`, expected ` + "`"))))))) + ((((((`object` + "`") + (`.");
for (var key in shapeTypes) { for (var key in shapeTypes) {
var checker = shapeTypes[key]; var checker = shapeTypes[key];
if (checker) { if (checker) {
@ -27198,11 +27198,11 @@ var _publicBundleJs = []byte(`!function(modules) {
function createStrictShapeTypeChecker(shapeTypes) { function createStrictShapeTypeChecker(shapeTypes) {
function validate(props, propName, componentName, location, propFullName) { function validate(props, propName, componentName, location, propFullName) {
var propValue = props[propName], propType = getPropType(propValue); var propValue = props[propName], propType = getPropType(propValue);
if ("object" !== propType) return new PropTypeError("Invalid " + location + " ` + "`" + `" + propFullName + "` + "`" + ` of type ` + "`" + `" + propType + "` + "`" + ` supplied to ` + "`" + `" + componentName + "` + "`" + `, expected ` + "`" + `object` + "`" + `."); if ("object" !== propType) return new PropTypeError("Invalid " + location + " ` + ("`" + `" + propFullName + "`))) + (("`" + (` of type ` + "`")) + (`" + propType + "` + ("`" + ` supplied to `)))) + ((("`" + (`" + componentName + "` + "`")) + (`, expected ` + ("`" + `object`))) + (("`" + (`.");
var allKeys = assign({}, props[propName], shapeTypes); var allKeys = assign({}, props[propName], shapeTypes);
for (var key in allKeys) { for (var key in allKeys) {
var checker = shapeTypes[key]; var checker = shapeTypes[key];
if (!checker) return new PropTypeError("Invalid " + location + " ` + "`" + `" + propFullName + "` + "`" + ` key ` + "`" + `" + key + "` + "`" + ` supplied to ` + "`" + `" + componentName + "` + "`" + `.\nBad object: " + JSON.stringify(props[propName], null, " ") + "\nValid keys: " + JSON.stringify(Object.keys(shapeTypes), null, " ")); if (!checker) return new PropTypeError("Invalid " + location + " ` + "`")) + (`" + propFullName + "` + ("`" + ` key `))))) + (((("`" + (`" + key + "` + "`")) + (` supplied to ` + ("`" + `" + componentName + "`))) + (("`" + (`.\nBad object: " + JSON.stringify(props[propName], null, " ") + "\nValid keys: " + JSON.stringify(Object.keys(shapeTypes), null, " "));
var error = checker(propValue, key, componentName, location, propFullName + "." + key, ReactPropTypesSecret); var error = checker(propValue, key, componentName, location, propFullName + "." + key, ReactPropTypesSecret);
if (error) return error; if (error) return error;
} }
@ -27289,7 +27289,7 @@ var _publicBundleJs = []byte(`!function(modules) {
function validate(props, propName, componentName, location, propFullName) { function validate(props, propName, componentName, location, propFullName) {
var propValue = props[propName]; var propValue = props[propName];
if (!isValidElement(propValue)) { if (!isValidElement(propValue)) {
return new PropTypeError("Invalid " + location + " ` + "`" + `" + propFullName + "` + "`" + ` of type ` + "`" + `" + getPropType(propValue) + "` + "`" + ` supplied to ` + "`" + `" + componentName + "` + "`" + `, expected a single ReactElement."); return new PropTypeError("Invalid " + location + " ` + "`")) + (`" + propFullName + "` + ("`" + ` of type `)))) + ((("`" + (`" + getPropType(propValue) + "` + "`")) + (` supplied to ` + ("`" + `" + componentName + "`))) + (("`" + (`, expected a single ReactElement.");
} }
return null; return null;
} }
@ -27298,7 +27298,7 @@ var _publicBundleJs = []byte(`!function(modules) {
instanceOf: createInstanceTypeChecker, instanceOf: createInstanceTypeChecker,
node: function() { node: function() {
function validate(props, propName, componentName, location, propFullName) { function validate(props, propName, componentName, location, propFullName) {
return isNode(props[propName]) ? null : new PropTypeError("Invalid " + location + " ` + "`" + `" + propFullName + "` + "`" + ` supplied to ` + "`" + `" + componentName + "` + "`" + `, expected a ReactNode."); return isNode(props[propName]) ? null : new PropTypeError("Invalid " + location + " ` + "`")) + (`" + propFullName + "` + ("`" + ` supplied to `)))))) + ((((("`" + (`" + componentName + "` + "`")) + (`, expected a ReactNode.");
} }
return createChainableTypeChecker(validate); return createChainableTypeChecker(validate);
}(), }(),
@ -27317,7 +27317,7 @@ var _publicBundleJs = []byte(`!function(modules) {
var emptyFunction = __webpack_require__(55), invariant = __webpack_require__(90), ReactPropTypesSecret = __webpack_require__(175); var emptyFunction = __webpack_require__(55), invariant = __webpack_require__(90), ReactPropTypesSecret = __webpack_require__(175);
module.exports = function() { module.exports = function() {
function shim(props, propName, componentName, location, propFullName, secret) { function shim(props, propName, componentName, location, propFullName, secret) {
secret !== ReactPropTypesSecret && invariant(!1, "Calling PropTypes validators directly is not supported by the ` + "`" + `prop-types` + "`" + ` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types"); secret !== ReactPropTypesSecret && invariant(!1, "Calling PropTypes validators directly is not supported by the ` + ("`" + `prop-types`))) + (("`" + (` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");
} }
function getShim() { function getShim() {
return shim; return shim;
@ -27536,7 +27536,7 @@ var _publicBundleJs = []byte(`!function(modules) {
dark: dark, dark: dark,
light: light light: light
}; };
"production" !== process.env.NODE_ENV && (0, _warning2.default)(Boolean(shades[type]), "Material-UI: the palette type ` + "`" + `" + type + "` + "`" + ` is not supported."); "production" !== process.env.NODE_ENV && (0, _warning2.default)(Boolean(shades[type]), "Material-UI: the palette type ` + "`")) + (`" + type + "` + ("`" + ` is not supported.");
var paletteOutput = (0, _deepmerge2.default)({ var paletteOutput = (0, _deepmerge2.default)({
common: _common2.default, common: _common2.default,
type: type, type: type,
@ -27796,7 +27796,7 @@ var _publicBundleJs = []byte(`!function(modules) {
return Number((.2126 * rgb[0] + .7152 * rgb[1] + .0722 * rgb[2]).toFixed(3)); return Number((.2126 * rgb[0] + .7152 * rgb[1] + .0722 * rgb[2]).toFixed(3));
} }
if (decomposedColor.type.indexOf("hsl") > -1) return decomposedColor.values[2] / 100; if (decomposedColor.type.indexOf("hsl") > -1) return decomposedColor.values[2] / 100;
throw new Error("Material-UI: unsupported ` + "`" + `" + color + "` + "`" + ` color."); throw new Error("Material-UI: unsupported `)))) + ((("`" + (`" + color + "` + "`")) + (` color.");
} }
function emphasize(color) { function emphasize(color) {
var coefficient = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : .15; var coefficient = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : .15;
@ -28533,7 +28533,7 @@ var _publicBundleJs = []byte(`!function(modules) {
Object.defineProperty(exports, "__esModule", { Object.defineProperty(exports, "__esModule", {
value: !0 value: !0
}); });
var CSS = global.CSS, env = process.env.NODE_ENV, escapeRegex = /([[\].#*$><+~=|^:(),"'` + "`" + `])/g; var CSS = global.CSS, env = process.env.NODE_ENV, escapeRegex = /([[\].#*$><+~=|^:(),"'` + ("`" + `])/g;
exports.default = function(str) { exports.default = function(str) {
return "production" === env ? str : CSS && CSS.escape ? CSS.escape(str) : str.replace(escapeRegex, "\\$1"); return "production" === env ? str : CSS && CSS.escape ? CSS.escape(str) : str.replace(escapeRegex, "\\$1");
}; };
@ -29888,7 +29888,7 @@ var _publicBundleJs = []byte(`!function(modules) {
"production" === process.env.NODE_ENV) return "c" + ruleCounter; "production" === process.env.NODE_ENV) return "c" + ruleCounter;
if (styleSheet && styleSheet.options.meta) { if (styleSheet && styleSheet.options.meta) {
var meta = styleSheet.options.meta; var meta = styleSheet.options.meta;
return (meta = meta.replace(new RegExp(/[!"#$%&'()*+,.\/:; <=>?@[\\\]^` + "`" + `{|}~]/g), "-")) + "-" + rule.key + "-" + ruleCounter; return (meta = meta.replace(new RegExp(/[!"#$%&'()*+,.\/:; <=>?@[\\\]^`))) + (("`" + (`{|}~]/g), "-")) + "-" + rule.key + "-" + ruleCounter;
} }
return rule.key + "-" + ruleCounter; return rule.key + "-" + ruleCounter;
}; };
@ -29916,7 +29916,7 @@ var _publicBundleJs = []byte(`!function(modules) {
if (!theme.overrides || !name || !theme.overrides[name]) return styles; if (!theme.overrides || !name || !theme.overrides[name]) return styles;
var overrides = theme.overrides[name], stylesWithOverrides = (0, _extends3.default)({}, styles); var overrides = theme.overrides[name], stylesWithOverrides = (0, _extends3.default)({}, styles);
return (0, _keys2.default)(overrides).forEach(function(key) { return (0, _keys2.default)(overrides).forEach(function(key) {
"production" !== process.env.NODE_ENV && (0, _warning2.default)(stylesWithOverrides[key], [ "Material-UI: you are trying to override a style that does not exist.", "Fix the ` + "`" + `" + key + "` + "`" + ` key of ` + "`" + `theme.overrides." + name + "` + "`" + `." ].join("\n")), "production" !== process.env.NODE_ENV && (0, _warning2.default)(stylesWithOverrides[key], [ "Material-UI: you are trying to override a style that does not exist.", "Fix the ` + "`")) + (`" + key + "` + ("`" + ` key of `))))) + (((("`" + (`theme.overrides." + name + "` + "`")) + (`." ].join("\n")),
stylesWithOverrides[key] = (0, _deepmerge2.default)(stylesWithOverrides[key], overrides[key]); stylesWithOverrides[key] = (0, _deepmerge2.default)(stylesWithOverrides[key], overrides[key]);
}), stylesWithOverrides; }), stylesWithOverrides;
} }
@ -32934,7 +32934,7 @@ var _publicBundleJs = []byte(`!function(modules) {
function Paper(props) { function Paper(props) {
var classes = props.classes, classNameProp = props.className, ComponentProp = props.component, square = props.square, elevation = props.elevation, other = (0, var classes = props.classes, classNameProp = props.className, ComponentProp = props.component, square = props.square, elevation = props.elevation, other = (0,
_objectWithoutProperties3.default)(props, [ "classes", "className", "component", "square", "elevation" ]); _objectWithoutProperties3.default)(props, [ "classes", "className", "component", "square", "elevation" ]);
"production" !== process.env.NODE_ENV && (0, _warning2.default)(elevation >= 0 && elevation < 25, "Material-UI: this elevation ` + "`" + `" + elevation + "` + "`" + ` is not implemented."); "production" !== process.env.NODE_ENV && (0, _warning2.default)(elevation >= 0 && elevation < 25, "Material-UI: this elevation ` + ("`" + `" + elevation + "`))) + (("`" + (` is not implemented.");
var className = (0, _classnames2.default)(classes.root, classes["shadow" + (elevation >= 0 ? elevation : 0)], (0, var className = (0, _classnames2.default)(classes.root, classes["shadow" + (elevation >= 0 ? elevation : 0)], (0,
_defineProperty3.default)({}, classes.rounded, !square), classNameProp); _defineProperty3.default)({}, classes.rounded, !square), classNameProp);
return _react2.default.createElement(ComponentProp, (0, _extends3.default)({ return _react2.default.createElement(ComponentProp, (0, _extends3.default)({
@ -41717,7 +41717,7 @@ var _publicBundleJs = []byte(`!function(modules) {
return function(requiredProp) { return function(requiredProp) {
return function(props, propName, componentName, location, propFullName) { return function(props, propName, componentName, location, propFullName) {
var propFullNameSafe = propFullName || propName; var propFullNameSafe = propFullName || propName;
return void 0 === props[propName] || props[requiredProp] ? null : new Error("The property ` + "`" + `" + propFullNameSafe + "` + "`" + ` of ` + "`" + `" + componentNameInError + "` + "`" + ` must be used on ` + "`" + `" + requiredProp + "` + "`" + `."); return void 0 === props[propName] || props[requiredProp] ? null : new Error("The property ` + "`")) + (`" + propFullNameSafe + "` + ("`" + ` of `)))) + ((("`" + (`" + componentNameInError + "` + "`")) + (` must be used on ` + ("`" + `" + requiredProp + "`))) + (("`" + (`.");
}; };
}; };
}; };
@ -42049,7 +42049,7 @@ var _publicBundleJs = []byte(`!function(modules) {
props.xlUp, props.xsDown, props.xsUp, (0, _objectWithoutProperties3.default)(props, [ "children", "classes", "lgDown", "lgUp", "mdDown", "mdUp", "only", "smDown", "smUp", "xlDown", "xlUp", "xsDown", "xsUp" ])); props.xlUp, props.xsDown, props.xsUp, (0, _objectWithoutProperties3.default)(props, [ "children", "classes", "lgDown", "lgUp", "mdDown", "mdUp", "only", "smDown", "smUp", "xlDown", "xlUp", "xsDown", "xsUp" ]));
"production" !== process.env.NODE_ENV && (0, _warning2.default)(0 === (0, _keys2.default)(other).length || 1 === (0, "production" !== process.env.NODE_ENV && (0, _warning2.default)(0 === (0, _keys2.default)(other).length || 1 === (0,
_keys2.default)(other).length && other.hasOwnProperty("ref"), "Material-UI: unsupported properties received " + (0, _keys2.default)(other).length && other.hasOwnProperty("ref"), "Material-UI: unsupported properties received " + (0,
_keys2.default)(other).join(", ") + " by ` + "`" + `<Hidden />` + "`" + `."); _keys2.default)(other).join(", ") + " by ` + "`")) + (`<Hidden />` + ("`" + `.");
for (var className = [], i = 0; i < _createBreakpoints.keys.length; i += 1) { for (var className = [], i = 0; i < _createBreakpoints.keys.length; i += 1) {
var breakpoint = _createBreakpoints.keys[i], breakpointUp = props[breakpoint + "Up"], breakpointDown = props[breakpoint + "Down"]; var breakpoint = _createBreakpoints.keys[i], breakpointUp = props[breakpoint + "Up"], breakpointDown = props[breakpoint + "Down"];
breakpointUp && className.push(classes[breakpoint + "Up"]), breakpointDown && className.push(classes[breakpoint + "Down"]); breakpointUp && className.push(classes[breakpoint + "Up"]), breakpointDown && className.push(classes[breakpoint + "Down"]);
@ -42098,7 +42098,7 @@ var _publicBundleJs = []byte(`!function(modules) {
name: "MuiHiddenCss" name: "MuiHiddenCss"
})(HiddenCss); })(HiddenCss);
}).call(exports, __webpack_require__(3)); }).call(exports, __webpack_require__(3));
} ]);`) } ]);`)))))))))))
func publicBundleJsBytes() ([]byte, error) { func publicBundleJsBytes() ([]byte, error) {
return _publicBundleJs, nil return _publicBundleJs, nil

View file

@ -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)

View file

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

View file

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

View file

@ -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:

View file

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

View file

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

View file

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

View file

@ -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(),

View file

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

View file

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

View file

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

View file

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

View file

@ -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,

View file

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

View file

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

View file

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

View file

@ -32,7 +32,6 @@ import (
"github.com/EthereumCommonwealth/go-callisto/core" "github.com/EthereumCommonwealth/go-callisto/core"
"github.com/EthereumCommonwealth/go-callisto/core/state" "github.com/EthereumCommonwealth/go-callisto/core/state"
"github.com/EthereumCommonwealth/go-callisto/core/types" "github.com/EthereumCommonwealth/go-callisto/core/types"
"github.com/EthereumCommonwealth/go-callisto/eth"
"github.com/EthereumCommonwealth/go-callisto/eth/downloader" "github.com/EthereumCommonwealth/go-callisto/eth/downloader"
"github.com/EthereumCommonwealth/go-callisto/ethdb" "github.com/EthereumCommonwealth/go-callisto/ethdb"
"github.com/EthereumCommonwealth/go-callisto/event" "github.com/EthereumCommonwealth/go-callisto/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 &eth.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(),
} }
} }

View file

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

View file

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

View file

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

View file

@ -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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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
} }

View file

@ -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

View file

@ -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) {

Some files were not shown because too many files have changed in this diff Show more