diff --git a/client/accounts/abi/bind/backend.go b/client/accounts/abi/bind/backend.go index d06b40138..c9f353150 100644 --- a/client/accounts/abi/bind/backend.go +++ b/client/accounts/abi/bind/backend.go @@ -55,15 +55,12 @@ type ContractTransactor interface { PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error) // PendingNonceAt retrieves the current pending nonce associated with an account. PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) - // SuggestGasPrice retrieves the currently suggested gas price to allow a timely - // execution of a transaction. - SuggestGasPrice(ctx context.Context) (*big.Int, error) - // EstimateGas tries to estimate the gas needed to execute a specific - // transaction based on 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, but it should provide a basis - // for setting a reasonable default. - EstimateGas(ctx context.Context, call kcoin.CallMsg) (gas uint64, err error) + // EstimateComputationalEffort tries to estimate the required computational + // effort to execute a specific transaction based on the current pending state of + // the backend blockchain. There is no guarantee that this is the true required + // effort as other transactions may be added or removed by miners, but it + // should provide a basis for setting a reasonable default. + EstimateComputationalEffort(ctx context.Context, call kcoin.CallMsg) (effort uint64, err error) // SendTransaction injects the transaction into the pending pool for execution. SendTransaction(ctx context.Context, tx *types.Transaction) error } diff --git a/client/accounts/abi/bind/backends/simulated.go b/client/accounts/abi/bind/backends/simulated.go index e5e970a31..285201391 100644 --- a/client/accounts/abi/bind/backends/simulated.go +++ b/client/accounts/abi/bind/backends/simulated.go @@ -21,14 +21,14 @@ import ( "github.com/kowala-tech/kcoin/client/event" "github.com/kowala-tech/kcoin/client/kcoindb" "github.com/kowala-tech/kcoin/client/knode/filters" - + "github.com/kowala-tech/kcoin/client/log" "github.com/kowala-tech/kcoin/client/params" + "github.com/kowala-tech/kcoin/client/params/effort" "github.com/kowala-tech/kcoin/client/rpc" - "github.com/kowala-tech/kcoin/client/log" ) var errBlockNumberUnsupported = errors.New("SimulatedBackend cannot access blocks other than the latest block") -var errGasEstimationFailed = errors.New("gas required exceeds allowance or always failing transaction") +var errCompEffortEstimationFailed = errors.New("required computational effort exceeds allowance or always failing transaction") // SimulatedBackend implements bind.ContractBackend, simulating a blockchain in // the background. Its main purpose is to allow easily testing contract bindings. @@ -189,34 +189,28 @@ func (b *SimulatedBackend) PendingNonceAt(ctx context.Context, account common.Ad return b.pendingState.GetOrNewStateObject(account).Nonce(), nil } -// SuggestGasPrice implements ContractTransactor.SuggestGasPrice. Since the simulated -// chain doens't have miners, we just return a gas price of 1 for any call. -func (b *SimulatedBackend) SuggestGasPrice(ctx context.Context) (*big.Int, error) { - return big.NewInt(1), nil -} - -// EstimateGas executes the requested code against the currently pending block/state and -// returns the used amount of gas. -func (b *SimulatedBackend) EstimateGas(ctx context.Context, call kowala.CallMsg) (uint64, error) { +// EstimateComputationalEffort executes the requested code against the currently pending block/state and +// returns the used amount of computational resources in compute units. +func (b *SimulatedBackend) EstimateComputationalEffort(ctx context.Context, call kowala.CallMsg) (uint64, error) { b.mu.Lock() defer b.mu.Unlock() - // Determine the lowest and highest possible gas limits to binary search in between + // Determine the lowest and highest possible effort limits to binary search in between var ( - lo uint64 = params.TxGas - 1 + lo uint64 = effort.Tx - 1 hi uint64 cap uint64 ) - if call.Gas >= params.TxGas { - hi = call.Gas + if call.ComputeLimit >= effort.Tx { + hi = call.ComputeLimit } else { - hi = b.pendingBlock.GasLimit() + hi = params.ComputeCapacity } cap = hi - // Create a helper to check if a gas allowance results in an executable transaction - executable := func(gas uint64) bool { - call.Gas = gas + // Create a helper to check if a computational resources allowance results in an executable transaction + executable := func(computeLimit uint64) bool { + call.ComputeLimit = computeLimit snapshot := b.pendingState.Snapshot() _, _, failed, err := b.callContract(ctx, call, b.pendingBlock, b.pendingState) @@ -224,14 +218,14 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call kowala.CallMsg) if err != nil || failed { if err != nil { - log.Error("can't estimate gas limit", "err", err) + log.Error("can't estimate computational effort", "err", err) } return false } return true } - // Execute the binary search and hone in on an executable gas limit + // Execute the binary search and hone in on an executable compute limit for lo+1 < hi { mid := (hi + lo) / 2 if !executable(mid) { @@ -243,7 +237,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call kowala.CallMsg) // Reject the transaction as invalid if it still fails at the highest allowance if hi == cap { if !executable(hi) { - return 0, errGasEstimationFailed + return 0, errCompEffortEstimationFailed } } return hi, nil @@ -253,11 +247,8 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call kowala.CallMsg) // state is modified during execution, make sure to copy it if necessary. func (b *SimulatedBackend) callContract(ctx context.Context, call kowala.CallMsg, block *types.Block, statedb *state.StateDB) ([]byte, uint64, bool, error) { // Ensure message is initialized properly. - if call.GasPrice == nil { - call.GasPrice = big.NewInt(1) - } - if call.Gas == 0 { - call.Gas = 50000000 + if call.ComputeLimit == 0 { + call.ComputeLimit = 50000000 } if call.Value == nil { call.Value = new(big.Int) @@ -268,13 +259,13 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call kowala.CallMsg // Execute the call. msg := callmsg{call} - evmContext := core.NewEVMContext(msg, block.Header(), b.BlockChain, nil) + vmContext := core.NewVMContext(msg, block.Header(), b.BlockChain, nil) // Create a new environment which holds all relevant information // about the transaction and calling mechanisms. - vmenv := vm.NewEVM(evmContext, statedb, b.config, vm.Config{}) - gaspool := new(core.GasPool).AddGas(math.MaxUint64) + vmenv := vm.New(vmContext, statedb, b.config, vm.Config{}) + crpool := new(core.ComputationalResourcePool).AddResource(math.MaxUint64) - return core.NewStateTransition(vmenv, msg, gaspool).TransitionDb() + return core.NewStateTransition(vmenv, msg, crpool).TransitionDb() } // SendTransaction updates the pending block to include the given transaction. @@ -394,8 +385,7 @@ func (m callmsg) From() common.Address { return m.CallMsg.From } func (m callmsg) Nonce() uint64 { return 0 } func (m callmsg) CheckNonce() bool { return false } func (m callmsg) To() *common.Address { return m.CallMsg.To } -func (m callmsg) GasPrice() *big.Int { return m.CallMsg.GasPrice } -func (m callmsg) Gas() uint64 { return m.CallMsg.Gas } +func (m callmsg) ComputeLimit() uint64 { return m.CallMsg.ComputeLimit } func (m callmsg) Value() *big.Int { return m.CallMsg.Value } func (m callmsg) Data() []byte { return m.CallMsg.Data } @@ -406,8 +396,8 @@ type filterBackend struct { bc *core.BlockChain } -func (fb *filterBackend) ChainDb() kcoindb.Database { return fb.db } -func (fb *filterBackend) EventMux() *event.TypeMux { panic("not supported") } +func (fb *filterBackend) ChainDb() kcoindb.Database { return fb.db } +func (fb *filterBackend) EventMux() *event.TypeMux { panic("not supported") } func (fb *filterBackend) HeaderByNumber(ctx context.Context, block rpc.BlockNumber) (*types.Header, error) { if block == rpc.LatestBlockNumber { diff --git a/client/accounts/abi/bind/base.go b/client/accounts/abi/bind/base.go index d0e84a348..5aa88832f 100644 --- a/client/accounts/abi/bind/base.go +++ b/client/accounts/abi/bind/base.go @@ -33,9 +33,8 @@ type TransactOpts struct { Nonce *big.Int // Nonce to use for the transaction execution (nil = use pending state) Signer SignerFn // Method to use for signing the transaction (mandatory) - 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) - GasLimit uint64 // Gas limit to set for the transaction execution (0 = estimate) + Value *big.Int // Funds to transfer along along the transaction (nil = 0 = no funds) + ComputeLimit uint64 // Compute limit to set for the transaction execution (0 = estimate) Context context.Context // Network context to support cancellation and timeouts (nil = no timeout) } @@ -183,17 +182,10 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i } else { nonce = opts.Nonce.Uint64() } - // Figure out the gas allowance and gas price values - gasPrice := opts.GasPrice - if gasPrice == nil { - gasPrice, err = c.transactor.SuggestGasPrice(ensureContext(opts.Context)) - if err != nil { - return nil, fmt.Errorf("failed to suggest gas price: %v", err) - } - } - gasLimit := opts.GasLimit - if gasLimit == 0 { - // Gas estimation cannot succeed without code for method invocations + + computeLimit := opts.ComputeLimit + if computeLimit == 0 { + // Computational effort estimation cannot succeed without code for method invocations if contract != nil { if code, err := c.transactor.PendingCodeAt(ensureContext(opts.Context), c.address); err != nil { return nil, err @@ -203,17 +195,17 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i } // If the contract surely has code (or code is not needed), estimate the transaction msg := kcoin.CallMsg{From: opts.From, To: contract, Value: value, Data: input} - gasLimit, err = c.transactor.EstimateGas(ensureContext(opts.Context), msg) + computeLimit, err = c.transactor.EstimateComputationalEffort(ensureContext(opts.Context), msg) if err != nil { - return nil, fmt.Errorf("failed to estimate gas needed: %v", err) + return nil, fmt.Errorf("failed to estimate required computational effort: %v", err) } } // Create the transaction, sign it and schedule it for execution var rawTx *types.Transaction if contract == nil { - rawTx = types.NewContractCreation(nonce, value, gasLimit, gasPrice, input) + rawTx = types.NewContractCreation(nonce, value, computeLimit, input) } else { - rawTx = types.NewTransaction(nonce, c.address, value, gasLimit, gasPrice, input) + rawTx = types.NewTransaction(nonce, c.address, value, computeLimit, input) } if opts.Signer == nil { return nil, errors.New("no signer to authorize the transaction with") diff --git a/client/accounts/abi/bind/bind_test.go b/client/accounts/abi/bind/bind_test.go deleted file mode 100644 index ef6209913..000000000 --- a/client/accounts/abi/bind/bind_test.go +++ /dev/null @@ -1,868 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package bind - -import ( - "fmt" - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "runtime" - "strings" - "testing" - - "github.com/kowala-tech/kcoin/client/common" - "golang.org/x/tools/imports" -) - -var bindTests = []struct { - name string - contract string - bytecode string - abi string - tester string -}{ - // Test that the binding is available in combined and separate forms too - { - `Empty`, - `contract NilContract {}`, - `606060405260068060106000396000f3606060405200`, - `[]`, - ` - if b, err := NewEmpty(common.Address{}, nil); b == nil || err != nil { - t.Fatalf("combined binding (%v) nil or error (%v) not nil", b, nil) - } - if b, err := NewEmptyCaller(common.Address{}, nil); b == nil || err != nil { - t.Fatalf("caller binding (%v) nil or error (%v) not nil", b, nil) - } - if b, err := NewEmptyTransactor(common.Address{}, nil); b == nil || err != nil { - t.Fatalf("transactor binding (%v) nil or error (%v) not nil", b, nil) - } - `, - }, - // Test that all the official sample contracts bind correctly - { - `Token`, - `https://ethereum.org/token`, - `60606040526040516107fd3803806107fd83398101604052805160805160a05160c051929391820192909101600160a060020a0333166000908152600360209081526040822086905581548551838052601f6002600019610100600186161502019093169290920482018390047f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56390810193919290918801908390106100e857805160ff19168380011785555b506101189291505b8082111561017157600081556001016100b4565b50506002805460ff19168317905550505050610658806101a56000396000f35b828001600101855582156100ac579182015b828111156100ac5782518260005055916020019190600101906100fa565b50508060016000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017557805160ff19168380011785555b506100c89291506100b4565b5090565b82800160010185558215610165579182015b8281111561016557825182600050559160200191906001019061018756606060405236156100775760e060020a600035046306fdde03811461007f57806323b872dd146100dc578063313ce5671461010e57806370a082311461011a57806395d89b4114610132578063a9059cbb1461018e578063cae9ca51146101bd578063dc3080f21461031c578063dd62ed3e14610341575b610365610002565b61036760008054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156104eb5780601f106104c0576101008083540402835291602001916104eb565b6103d5600435602435604435600160a060020a038316600090815260036020526040812054829010156104f357610002565b6103e760025460ff1681565b6103d560043560036020526000908152604090205481565b610367600180546020600282841615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156104eb5780601f106104c0576101008083540402835291602001916104eb565b610365600435602435600160a060020a033316600090815260036020526040902054819010156103f157610002565b60806020604435600481810135601f8101849004909302840160405260608381526103d5948235946024803595606494939101919081908382808284375094965050505050505060006000836004600050600033600160a060020a03168152602001908152602001600020600050600087600160a060020a031681526020019081526020016000206000508190555084905080600160a060020a0316638f4ffcb1338630876040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a03168152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156102f25780820380516001836020036101000a031916815260200191505b50955050505050506000604051808303816000876161da5a03f11561000257505050509392505050565b6005602090815260043560009081526040808220909252602435815220546103d59081565b60046020818152903560009081526040808220909252602435815220546103d59081565b005b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156103c75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60408051918252519081900360200190f35b6060908152602090f35b600160a060020a03821660009081526040902054808201101561041357610002565b806003600050600033600160a060020a03168152602001908152602001600020600082828250540392505081905550806003600050600084600160a060020a0316815260200190815260200160002060008282825054019250508190555081600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b820191906000526020600020905b8154815290600101906020018083116104ce57829003601f168201915b505050505081565b600160a060020a03831681526040812054808301101561051257610002565b600160a060020a0380851680835260046020908152604080852033949094168086529382528085205492855260058252808520938552929052908220548301111561055c57610002565b816003600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816003600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816005600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054019250508190555082600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3939250505056`, - `[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"},{"name":"_extraData","type":"bytes"}],"name":"approveAndCall","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"spentAllowance","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"inputs":[{"name":"initialSupply","type":"uint256"},{"name":"tokenName","type":"string"},{"name":"decimalUnits","type":"uint8"},{"name":"tokenSymbol","type":"string"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]`, - ` - if b, err := NewToken(common.Address{}, nil); b == nil || err != nil { - t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil) - } - `, - }, - { - `Crowdsale`, - `https://ethereum.org/crowdsale`, - `606060408190526007805460ff1916905560a0806105a883396101006040529051608051915160c05160e05160008054600160a060020a03199081169095178155670de0b6b3a7640000958602600155603c9093024201600355930260045560058054909216909217905561052f90819061007990396000f36060604052361561006c5760e060020a600035046301cb3b20811461008257806329dcb0cf1461014457806338af3eed1461014d5780636e66f6e91461015f5780637a3a0e84146101715780637b3e5e7b1461017a578063a035b1fe14610183578063dc0d3dff1461018c575b61020060075460009060ff161561032357610002565b61020060035460009042106103205760025460015490106103cb576002548154600160a060020a0316908290606082818181858883f150915460025460408051600160a060020a039390931683526020830191909152818101869052517fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf6945090819003909201919050a15b60405160008054600160a060020a039081169230909116319082818181858883f150506007805460ff1916600117905550505050565b6103a160035481565b6103ab600054600160a060020a031681565b6103ab600554600160a060020a031681565b6103a160015481565b6103a160025481565b6103a160045481565b6103be60043560068054829081101561000257506000526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f8101547ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d409190910154600160a060020a03919091169082565b005b505050815481101561000257906000526020600020906002020160005060008201518160000160006101000a815481600160a060020a030219169083021790555060208201518160010160005055905050806002600082828250540192505081905550600560009054906101000a9004600160a060020a0316600160a060020a031663a9059cbb3360046000505484046040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506000604051808303816000876161da5a03f11561000257505060408051600160a060020a03331681526020810184905260018183015290517fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf692509081900360600190a15b50565b5060a0604052336060908152346080819052600680546001810180835592939282908280158290116102025760020281600202836000526020600020918201910161020291905b8082111561039d57805473ffffffffffffffffffffffffffffffffffffffff19168155600060019190910190815561036a565b5090565b6060908152602090f35b600160a060020a03166060908152602090f35b6060918252608052604090f35b5b60065481101561010e576006805482908110156100025760009182526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0190600680549254600160a060020a0316928490811015610002576002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40015460405190915082818181858883f19350505050507fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf660066000508281548110156100025760008290526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01548154600160a060020a039190911691908490811015610002576002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40015460408051600160a060020a0394909416845260208401919091526000838201525191829003606001919050a16001016103cc56`, - `[{"constant":false,"inputs":[],"name":"checkGoalReached","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"deadline","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"beneficiary","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"tokenReward","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"fundingGoal","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"amountRaised","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"price","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"funders","outputs":[{"name":"addr","type":"address"},{"name":"amount","type":"uint256"}],"type":"function"},{"inputs":[{"name":"ifSuccessfulSendTo","type":"address"},{"name":"fundingGoalInEthers","type":"uint256"},{"name":"durationInMinutes","type":"uint256"},{"name":"etherCostOfEachToken","type":"uint256"},{"name":"addressOfTokenUsedAsReward","type":"address"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"backer","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"isContribution","type":"bool"}],"name":"FundTransfer","type":"event"}]`, - ` - if b, err := NewCrowdsale(common.Address{}, nil); b == nil || err != nil { - t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil) - } - `, - }, - { - `DAO`, - `https://ethereum.org/dao`, - `606060405260405160808061145f833960e06040529051905160a05160c05160008054600160a060020a03191633179055600184815560028490556003839055600780549182018082558280158290116100b8576003028160030283600052602060002091820191016100b891906101c8565b50506060919091015160029190910155600160a060020a0381166000146100a65760008054600160a060020a031916821790555b505050506111f18061026e6000396000f35b505060408051608081018252600080825260208281018290528351908101845281815292820192909252426060820152600780549194509250811015610002579081527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6889050815181546020848101517401000000000000000000000000000000000000000002600160a060020a03199290921690921760a060020a60ff021916178255604083015180516001848101805460008281528690209195600293821615610100026000190190911692909204601f9081018390048201949192919091019083901061023e57805160ff19168380011785555b50610072929150610226565b5050600060028201556001015b8082111561023a578054600160a860020a031916815560018181018054600080835592600290821615610100026000190190911604601f81901061020c57506101bb565b601f0160209004906000526020600020908101906101bb91905b8082111561023a5760008155600101610226565b5090565b828001600101855582156101af579182015b828111156101af57825182600050559160200191906001019061025056606060405236156100b95760e060020a6000350463013cf08b81146100bb578063237e9492146101285780633910682114610281578063400e3949146102995780635daf08ca146102a257806369bd34361461032f5780638160f0b5146103385780638da5cb5b146103415780639644fcbd14610353578063aa02a90f146103be578063b1050da5146103c7578063bcca1fd3146104b5578063d3c0715b146104dc578063eceb29451461058d578063f2fde38b1461067b575b005b61069c6004356004805482908110156100025790600052602060002090600a02016000506005810154815460018301546003840154600485015460068601546007870154600160a060020a03959095169750929560020194919360ff828116946101009093041692919089565b60408051602060248035600481810135601f81018590048502860185019096528585526107759581359591946044949293909201918190840183828082843750949650505050505050600060006004600050848154811015610002575090527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19e600a8402908101547f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b909101904210806101e65750600481015460ff165b8061026757508060000160009054906101000a9004600160a060020a03168160010160005054846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020816007016000505414155b8061027757506001546005820154105b1561109257610002565b61077560043560066020526000908152604090205481565b61077560055481565b61078760043560078054829081101561000257506000526003026000805160206111d18339815191528101547fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a820154600160a060020a0382169260a060020a90920460ff16917fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c689019084565b61077560025481565b61077560015481565b610830600054600160a060020a031681565b604080516020604435600481810135601f81018490048402850184019095528484526100b9948135946024803595939460649492939101918190840183828082843750949650505050505050600080548190600160a060020a03908116339091161461084d57610002565b61077560035481565b604080516020604435600481810135601f8101849004840285018401909552848452610775948135946024803595939460649492939101918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976084979196506024909101945090925082915084018382808284375094965050505050505033600160a060020a031660009081526006602052604081205481908114806104ab5750604081205460078054909190811015610002579082526003026000805160206111d1833981519152015460a060020a900460ff16155b15610ce557610002565b6100b960043560243560443560005433600160a060020a03908116911614610b1857610002565b604080516020604435600481810135601f810184900484028501840190955284845261077594813594602480359593946064949293910191819084018382808284375094965050505050505033600160a060020a031660009081526006602052604081205481908114806105835750604081205460078054909190811015610002579082526003026000805160206111d18339815191520181505460a060020a900460ff16155b15610f1d57610002565b604080516020606435600481810135601f81018490048402850184019095528484526107759481359460248035956044359560849492019190819084018382808284375094965050505050505060006000600460005086815481101561000257908252600a027f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b01815090508484846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160070160005054149150610cdc565b6100b960043560005433600160a060020a03908116911614610f0857610002565b604051808a600160a060020a031681526020018981526020018060200188815260200187815260200186815260200185815260200184815260200183815260200182810382528981815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561075e5780601f106107335761010080835404028352916020019161075e565b820191906000526020600020905b81548152906001019060200180831161074157829003601f168201915b50509a505050505050505050505060405180910390f35b60408051918252519081900360200190f35b60408051600160a060020a038616815260208101859052606081018390526080918101828152845460026001821615610100026000190190911604928201839052909160a08301908590801561081e5780601f106107f35761010080835404028352916020019161081e565b820191906000526020600020905b81548152906001019060200180831161080157829003601f168201915b50509550505050505060405180910390f35b60408051600160a060020a03929092168252519081900360200190f35b600160a060020a03851660009081526006602052604081205414156108a957604060002060078054918290556001820180825582801582901161095c5760030281600302836000526020600020918201910161095c9190610a4f565b600160a060020a03851660009081526006602052604090205460078054919350908390811015610002575060005250600381026000805160206111d183398151915201805474ff0000000000000000000000000000000000000000191660a060020a85021781555b60408051600160a060020a03871681526020810186905281517f27b022af4a8347100c7a041ce5ccf8e14d644ff05de696315196faae8cd50c9b929181900390910190a15050505050565b505050915081506080604051908101604052808681526020018581526020018481526020014281526020015060076000508381548110156100025790600052602060002090600302016000508151815460208481015160a060020a02600160a060020a03199290921690921774ff00000000000000000000000000000000000000001916178255604083015180516001848101805460008281528690209195600293821615610100026000190190911692909204601f90810183900482019491929190910190839010610ad357805160ff19168380011785555b50610b03929150610abb565b5050600060028201556001015b80821115610acf57805474ffffffffffffffffffffffffffffffffffffffffff1916815560018181018054600080835592600290821615610100026000190190911604601f819010610aa15750610a42565b601f016020900490600052602060002090810190610a4291905b80821115610acf5760008155600101610abb565b5090565b82800160010185558215610a36579182015b82811115610a36578251826000505591602001919060010190610ae5565b50506060919091015160029190910155610911565b600183905560028290556003819055604080518481526020810184905280820183905290517fa439d3fa452be5e0e1e24a8145e715f4fd8b9c08c96a42fd82a855a85e5d57de9181900360600190a1505050565b50508585846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160070160005081905550600260005054603c024201816003016000508190555060008160040160006101000a81548160ff0219169083021790555060008160040160016101000a81548160ff02191690830217905550600081600501600050819055507f646fec02522b41e7125cfc859a64fd4f4cefd5dc3b6237ca0abe251ded1fa881828787876040518085815260200184600160a060020a03168152602001838152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015610cc45780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a1600182016005555b50949350505050565b6004805460018101808355909190828015829011610d1c57600a0281600a028360005260206000209182019101610d1c9190610db8565b505060048054929450918491508110156100025790600052602060002090600a02016000508054600160a060020a031916871781556001818101879055855160028381018054600082815260209081902096975091959481161561010002600019011691909104601f90810182900484019391890190839010610ed857805160ff19168380011785555b50610b6c929150610abb565b50506001015b80821115610acf578054600160a060020a03191681556000600182810182905560028381018054848255909281161561010002600019011604601f819010610e9c57505b5060006003830181905560048301805461ffff191690556005830181905560068301819055600783018190556008830180548282559082526020909120610db2916002028101905b80821115610acf57805474ffffffffffffffffffffffffffffffffffffffffff1916815560018181018054600080835592600290821615610100026000190190911604601f819010610eba57505b5050600101610e44565b601f016020900490600052602060002090810190610dfc9190610abb565b601f016020900490600052602060002090810190610e929190610abb565b82800160010185558215610da6579182015b82811115610da6578251826000505591602001919060010190610eea565b60008054600160a060020a0319168217905550565b600480548690811015610002576000918252600a027f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b01905033600160a060020a0316600090815260098201602052604090205490915060ff1660011415610f8457610002565b33600160a060020a031660009081526009820160205260409020805460ff1916600190811790915560058201805490910190558315610fcd576006810180546001019055610fda565b6006810180546000190190555b7fc34f869b7ff431b034b7b9aea9822dac189a685e0b015c7d1be3add3f89128e8858533866040518085815260200184815260200183600160a060020a03168152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561107a5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a1509392505050565b6006810154600354901315611158578060000160009054906101000a9004600160a060020a0316600160a060020a03168160010160005054670de0b6b3a76400000284604051808280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156111225780820380516001836020036101000a031916815260200191505b5091505060006040518083038185876185025a03f15050505060048101805460ff191660011761ff00191661010017905561116d565b60048101805460ff191660011761ff00191690555b60068101546005820154600483015460408051888152602081019490945283810192909252610100900460ff166060830152517fd220b7272a8b6d0d7d6bcdace67b936a8f175e6d5c1b3ee438b72256b32ab3af9181900360800190a1509291505056a66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688`, - `[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"proposals","outputs":[{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"},{"name":"description","type":"string"},{"name":"votingDeadline","type":"uint256"},{"name":"executed","type":"bool"},{"name":"proposalPassed","type":"bool"},{"name":"numberOfVotes","type":"uint256"},{"name":"currentResult","type":"int256"},{"name":"proposalHash","type":"bytes32"}],"type":"function"},{"constant":false,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"transactionBytecode","type":"bytes"}],"name":"executeProposal","outputs":[{"name":"result","type":"int256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"memberId","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"numProposals","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"members","outputs":[{"name":"member","type":"address"},{"name":"canVote","type":"bool"},{"name":"name","type":"string"},{"name":"memberSince","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"debatingPeriodInMinutes","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"minimumQuorum","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"targetMember","type":"address"},{"name":"canVote","type":"bool"},{"name":"memberName","type":"string"}],"name":"changeMembership","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"majorityMargin","outputs":[{"name":"","type":"int256"}],"type":"function"},{"constant":false,"inputs":[{"name":"beneficiary","type":"address"},{"name":"etherAmount","type":"uint256"},{"name":"JobDescription","type":"string"},{"name":"transactionBytecode","type":"bytes"}],"name":"newProposal","outputs":[{"name":"proposalID","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"minimumQuorumForProposals","type":"uint256"},{"name":"minutesForDebate","type":"uint256"},{"name":"marginOfVotesForMajority","type":"int256"}],"name":"changeVotingRules","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"supportsProposal","type":"bool"},{"name":"justificationText","type":"string"}],"name":"vote","outputs":[{"name":"voteID","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"beneficiary","type":"address"},{"name":"etherAmount","type":"uint256"},{"name":"transactionBytecode","type":"bytes"}],"name":"checkProposalCode","outputs":[{"name":"codeChecksOut","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"type":"function"},{"inputs":[{"name":"minimumQuorumForProposals","type":"uint256"},{"name":"minutesForDebate","type":"uint256"},{"name":"marginOfVotesForMajority","type":"int256"},{"name":"congressLeader","type":"address"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"recipient","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"description","type":"string"}],"name":"ProposalAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"position","type":"bool"},{"indexed":false,"name":"voter","type":"address"},{"indexed":false,"name":"justification","type":"string"}],"name":"Voted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"result","type":"int256"},{"indexed":false,"name":"quorum","type":"uint256"},{"indexed":false,"name":"active","type":"bool"}],"name":"ProposalTallied","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"member","type":"address"},{"indexed":false,"name":"isMember","type":"bool"}],"name":"MembershipChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"minimumQuorum","type":"uint256"},{"indexed":false,"name":"debatingPeriodInMinutes","type":"uint256"},{"indexed":false,"name":"majorityMargin","type":"int256"}],"name":"ChangeOfRules","type":"event"}]`, - ` - if b, err := NewDAO(common.Address{}, nil); b == nil || err != nil { - t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil) - } - `, - }, - // Test that named and anonymous inputs are handled correctly - { - `InputChecker`, ``, ``, - ` - [ - {"type":"function","name":"noInput","constant":true,"inputs":[],"outputs":[]}, - {"type":"function","name":"namedInput","constant":true,"inputs":[{"name":"str","type":"string"}],"outputs":[]}, - {"type":"function","name":"anonInput","constant":true,"inputs":[{"name":"","type":"string"}],"outputs":[]}, - {"type":"function","name":"namedInputs","constant":true,"inputs":[{"name":"str1","type":"string"},{"name":"str2","type":"string"}],"outputs":[]}, - {"type":"function","name":"anonInputs","constant":true,"inputs":[{"name":"","type":"string"},{"name":"","type":"string"}],"outputs":[]}, - {"type":"function","name":"mixedInputs","constant":true,"inputs":[{"name":"","type":"string"},{"name":"str","type":"string"}],"outputs":[]} - ] - `, - `if b, err := NewInputChecker(common.Address{}, nil); b == nil || err != nil { - t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil) - } else if false { // Don't run, just compile and test types - var err error - - err = b.NoInput(nil) - err = b.NamedInput(nil, "") - err = b.AnonInput(nil, "") - err = b.NamedInputs(nil, "", "") - err = b.AnonInputs(nil, "", "") - err = b.MixedInputs(nil, "", "") - - fmt.Println(err) - }`, - }, - // Test that named and anonymous outputs are handled correctly - { - `OutputChecker`, ``, ``, - ` - [ - {"type":"function","name":"noOutput","constant":true,"inputs":[],"outputs":[]}, - {"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":"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":"mixedOutputs","constant":true,"inputs":[],"outputs":[{"name":"","type":"string"},{"name":"str","type":"string"}]} - ] - `, - `if b, err := NewOutputChecker(common.Address{}, nil); b == nil || err != nil { - t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil) - } else if false { // Don't run, just compile and test types - var str1, str2 string - var err error - - err = b.NoOutput(nil) - str1, err = b.NamedOutput(nil) - str1, err = b.AnonOutput(nil) - res, _ := b.NamedOutputs(nil) - str1, str2, err = b.CollidingOutputs(nil) - str1, str2, err = b.AnonOutputs(nil) - str1, str2, err = b.MixedOutputs(nil) - - fmt.Println(str1, str2, res.Str1, res.Str2, err) - }`, - }, - // Tests that named, anonymous and indexed events are handled correctly - { - `EventChecker`, ``, ``, - ` - [ - {"type":"event","name":"empty","inputs":[]}, - {"type":"event","name":"indexed","inputs":[{"name":"addr","type":"address","indexed":true},{"name":"num","type":"int256","indexed":true}]}, - {"type":"event","name":"mixed","inputs":[{"name":"addr","type":"address","indexed":true},{"name":"num","type":"int256"}]}, - {"type":"event","name":"anonymous","anonymous":true,"inputs":[]}, - {"type":"event","name":"dynamic","inputs":[{"name":"idxStr","type":"string","indexed":true},{"name":"idxDat","type":"bytes","indexed":true},{"name":"str","type":"string"},{"name":"dat","type":"bytes"}]} - ] - `, - `if e, err := NewEventChecker(common.Address{}, nil); e == nil || err != nil { - t.Fatalf("binding (%v) nil or error (%v) not nil", e, nil) - } else if false { // Don't run, just compile and test types - var ( - err error - res bool - str string - dat []byte - hash common.Hash - ) - _, err = e.FilterEmpty(nil) - _, err = e.FilterIndexed(nil, []common.Address{}, []*big.Int{}) - - mit, err := e.FilterMixed(nil, []common.Address{}) - - res = mit.Next() // Make sure the iterator has a Next method - err = mit.Error() // Make sure the iterator has an Error method - err = mit.Close() // Make sure the iterator has a Close method - - fmt.Println(mit.Event.Raw.BlockHash) // Make sure the raw log is contained within the results - fmt.Println(mit.Event.Num) // Make sure the unpacked non-indexed fields are present - fmt.Println(mit.Event.Addr) // Make sure the reconstructed indexed fields are present - - dit, err := e.FilterDynamic(nil, []string{}, [][]byte{}) - - str = dit.Event.Str // Make sure non-indexed strings retain their type - dat = dit.Event.Dat // Make sure non-indexed bytes retain their type - hash = dit.Event.IdxStr // Make sure indexed strings turn into hashes - hash = dit.Event.IdxDat // Make sure indexed bytes turn into hashes - - sink := make(chan *EventCheckerMixed) - sub, err := e.WatchMixed(nil, sink, []common.Address{}) - defer sub.Unsubscribe() - - event := <-sink - fmt.Println(event.Raw.BlockHash) // Make sure the raw log is contained within the results - fmt.Println(event.Num) // Make sure the unpacked non-indexed fields are present - fmt.Println(event.Addr) // Make sure the reconstructed indexed fields are present - - fmt.Println(res, str, dat, hash, err) - } - // Run a tiny reflection test to ensure disallowed methods don't appear - if _, ok := reflect.TypeOf(&EventChecker{}).MethodByName("FilterAnonymous"); ok { - t.Errorf("binding has disallowed method (FilterAnonymous)") - }`, - }, - // Test that contract interactions (deploy, transact and call) generate working code - { - `Interactor`, - ` - contract Interactor { - string public deployString; - string public transactString; - - function Interactor(string str) { - deployString = str; - } - - function transact(string str) { - transactString = str; - } - } - `, - `6060604052604051610328380380610328833981016040528051018060006000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10608d57805160ff19168380011785555b50607c9291505b8082111560ba57838155600101606b565b50505061026a806100be6000396000f35b828001600101855582156064579182015b828111156064578251826000505591602001919060010190609e565b509056606060405260e060020a60003504630d86a0e181146100315780636874e8091461008d578063d736c513146100ea575b005b610190600180546020600282841615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156102295780601f106101fe57610100808354040283529160200191610229565b61019060008054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156102295780601f106101fe57610100808354040283529160200191610229565b60206004803580820135601f81018490049093026080908101604052606084815261002f946024939192918401918190838280828437509496505050505050508060016000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061023157805160ff19168380011785555b506102619291505b808211156102665760008155830161017d565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156101f05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b820191906000526020600020905b81548152906001019060200180831161020c57829003601f168201915b505050505081565b82800160010185558215610175579182015b82811115610175578251826000505591602001919060010190610243565b505050565b509056`, - `[{"constant":true,"inputs":[],"name":"transactString","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":true,"inputs":[],"name":"deployString","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"str","type":"string"}],"name":"transact","outputs":[],"type":"function"},{"inputs":[{"name":"str","type":"string"}],"type":"constructor"}]`, - ` - // 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 an interaction tester contract and call a transaction on it - _, _, interactor, err := DeployInteractor(auth, sim, "Deploy string") - if err != nil { - t.Fatalf("Failed to deploy interactor contract: %v", err) - } - if _, err := interactor.Transact(auth, "Transact string"); err != nil { - t.Fatalf("Failed to transact with interactor contract: %v", err) - } - // Commit all pending transactions in the simulator and check the contract state - sim.Commit() - - if str, err := interactor.DeployString(nil); err != nil { - t.Fatalf("Failed to retrieve deploy string: %v", err) - } else if str != "Deploy string" { - t.Fatalf("Deploy string mismatch: have '%s', want 'Deploy string'", str) - } - if str, err := interactor.TransactString(nil); err != nil { - t.Fatalf("Failed to retrieve transact string: %v", err) - } else if str != "Transact string" { - t.Fatalf("Transact string mismatch: have '%s', want 'Transact string'", str) - } - `, - }, - // Tests that plain values can be properly returned and deserialized - { - `Getter`, - ` - contract Getter { - function getter() constant returns (string, int, bytes32) { - return ("Hi", 1, sha3("")); - } - } - `, - `606060405260dc8060106000396000f3606060405260e060020a6000350463993a04b78114601a575b005b600060605260c0604052600260809081527f486900000000000000000000000000000000000000000000000000000000000060a05260017fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060e0829052610100819052606060c0908152600261012081905281906101409060a09080838184600060046012f1505081517fffff000000000000000000000000000000000000000000000000000000000000169091525050604051610160819003945092505050f3`, - `[{"constant":true,"inputs":[],"name":"getter","outputs":[{"name":"","type":"string"},{"name":"","type":"int256"},{"name":"","type":"bytes32"}],"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 tuple tester contract and execute a structured call on it - _, _, getter, err := DeployGetter(auth, sim) - if err != nil { - t.Fatalf("Failed to deploy getter contract: %v", err) - } - sim.Commit() - - if str, num, _, err := getter.Getter(nil); err != nil { - t.Fatalf("Failed to call anonymous field retriever: %v", err) - } else if str != "Hi" || num.Cmp(big.NewInt(1)) != 0 { - t.Fatalf("Retrieved value mismatch: have %v/%v, want %v/%v", str, num, "Hi", 1) - } - `, - }, - // Tests that tuples can be properly returned and deserialized - { - `Tupler`, - ` - contract Tupler { - function tuple() constant returns (string a, int b, bytes32 c) { - return ("Hi", 1, sha3("")); - } - } - `, - `606060405260dc8060106000396000f3606060405260e060020a60003504633175aae28114601a575b005b600060605260c0604052600260809081527f486900000000000000000000000000000000000000000000000000000000000060a05260017fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060e0829052610100819052606060c0908152600261012081905281906101409060a09080838184600060046012f1505081517fffff000000000000000000000000000000000000000000000000000000000000169091525050604051610160819003945092505050f3`, - `[{"constant":true,"inputs":[],"name":"tuple","outputs":[{"name":"a","type":"string"},{"name":"b","type":"int256"},{"name":"c","type":"bytes32"}],"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 tuple tester contract and execute a structured call on it - _, _, tupler, err := DeployTupler(auth, sim) - if err != nil { - t.Fatalf("Failed to deploy tupler contract: %v", err) - } - sim.Commit() - - if res, err := tupler.Tuple(nil); err != nil { - t.Fatalf("Failed to call structure retriever: %v", err) - } else if res.A != "Hi" || res.B.Cmp(big.NewInt(1)) != 0 { - t.Fatalf("Retrieved value mismatch: have %v/%v, want %v/%v", res.A, res.B, "Hi", 1) - } - `, - }, - // Tests that arrays/slices can be properly returned and deserialized. - // Only addresses are tested, remainder just compiled to keep the test small. - { - `Slicer`, - ` - contract Slicer { - function echoAddresses(address[] input) constant returns (address[] output) { - return input; - } - function echoInts(int[] input) constant returns (int[] output) { - return input; - } - function echoFancyInts(uint24[23] input) constant returns (uint24[23] output) { - return input; - } - function echoBools(bool[] input) constant returns (bool[] output) { - return input; - } - } - `, - `606060405261015c806100126000396000f3606060405260e060020a6000350463be1127a3811461003c578063d88becc014610092578063e15a3db71461003c578063f637e5891461003c575b005b604080516020600480358082013583810285810185019096528085526100ee959294602494909392850192829185019084908082843750949650505050505050604080516020810190915260009052805b919050565b604080516102e0818101909252610138916004916102e491839060179083908390808284375090955050505050506102e0604051908101604052806017905b60008152602001906001900390816100d15790505081905061008d565b60405180806020018281038252838181518152602001915080519060200190602002808383829060006004602084601f0104600f02600301f1509050019250505060405180910390f35b60405180826102e0808381846000600461015cf15090500191505060405180910390f3`, - `[{"constant":true,"inputs":[{"name":"input","type":"address[]"}],"name":"echoAddresses","outputs":[{"name":"output","type":"address[]"}],"type":"function"},{"constant":true,"inputs":[{"name":"input","type":"uint24[23]"}],"name":"echoFancyInts","outputs":[{"name":"output","type":"uint24[23]"}],"type":"function"},{"constant":true,"inputs":[{"name":"input","type":"int256[]"}],"name":"echoInts","outputs":[{"name":"output","type":"int256[]"}],"type":"function"},{"constant":true,"inputs":[{"name":"input","type":"bool[]"}],"name":"echoBools","outputs":[{"name":"output","type":"bool[]"}],"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 slice tester contract and execute a n array call on it - _, _, slicer, err := DeploySlicer(auth, sim) - if err != nil { - t.Fatalf("Failed to deploy slicer contract: %v", err) - } - sim.Commit() - - if out, err := slicer.EchoAddresses(nil, []common.Address{auth.From, common.Address{}}); err != nil { - t.Fatalf("Failed to call slice echoer: %v", err) - } else if !reflect.DeepEqual(out, []common.Address{auth.From, common.Address{}}) { - t.Fatalf("Slice return mismatch: have %v, want %v", out, []common.Address{auth.From, common.Address{}}) - } - `, - }, - // Tests that anonymous default methods can be correctly invoked - { - `Defaulter`, - ` - contract Defaulter { - address public caller; - - function() { - caller = msg.sender; - } - } - `, - `6060604052606a8060106000396000f360606040523615601d5760e060020a6000350463fc9c8d3981146040575b605e6000805473ffffffffffffffffffffffffffffffffffffffff191633179055565b606060005473ffffffffffffffffffffffffffffffffffffffff1681565b005b6060908152602090f3`, - `[{"constant":true,"inputs":[],"name":"caller","outputs":[{"name":"","type":"address"}],"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 default method invoker contract and execute its default method - _, _, defaulter, err := DeployDefaulter(auth, sim) - if err != nil { - t.Fatalf("Failed to deploy defaulter contract: %v", err) - } - if _, err := (&DefaulterRaw{defaulter}).Transfer(auth); err != nil { - t.Fatalf("Failed to invoke default method: %v", err) - } - sim.Commit() - - if caller, err := defaulter.Caller(nil); err != nil { - t.Fatalf("Failed to call address retriever: %v", err) - } else if (caller != auth.From) { - t.Fatalf("Address mismatch: have %v, want %v", caller, auth.From) - } - `, - }, - // Tests that non-existent contracts are reported as such (though only simulator test) - { - `NonExistent`, - ` - contract NonExistent { - function String() constant returns(string) { - return "I don't exist"; - } - } - `, - `6060604052609f8060106000396000f3606060405260e060020a6000350463f97a60058114601a575b005b600060605260c0604052600d60809081527f4920646f6e27742065786973740000000000000000000000000000000000000060a052602060c0908152600d60e081905281906101009060a09080838184600060046012f15050815172ffffffffffffffffffffffffffffffffffffff1916909152505060405161012081900392509050f3`, - `[{"constant":true,"inputs":[],"name":"String","outputs":[{"name":"","type":"string"}],"type":"function"}]`, - ` - // Create a simulator and wrap a non-deployed contract - sim := backends.NewSimulatedBackend(nil) - - nonexistent, err := NewNonExistent(common.Address{}, sim) - if err != nil { - t.Fatalf("Failed to access non-existent contract: %v", err) - } - // Ensure that contract calls fail with the appropriate error - if res, err := nonexistent.String(nil); err == nil { - t.Fatalf("Call succeeded on non-existent contract: %v", res) - } else if (err != bind.ErrNoCode) { - t.Fatalf("Error mismatch: have %v, want %v", err, bind.ErrNoCode) - } - `, - }, - // Tests that gas estimation works for contracts with weird gas mechanics too. - { - `FunkyGasPattern`, - ` - contract FunkyGasPattern { - string public field; - - function SetField(string value) { - // This check will screw gas estimation! Good, good! - if (msg.gas < 100000) { - throw; - } - field = value; - } - } - `, - `606060405261021c806100126000396000f3606060405260e060020a600035046323fcf32a81146100265780634f28bf0e1461007b575b005b6040805160206004803580820135601f8101849004840285018401909552848452610024949193602493909291840191908190840183828082843750949650505050505050620186a05a101561014e57610002565b6100db60008054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281529291908301828280156102145780601f106101e957610100808354040283529160200191610214565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561013b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b505050565b8060006000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106101b557805160ff19168380011785555b506101499291505b808211156101e557600081556001016101a1565b82800160010185558215610199579182015b828111156101995782518260005055916020019190600101906101c7565b5090565b820191906000526020600020905b8154815290600101906020018083116101f757829003601f168201915b50505050508156`, - `[{"constant":false,"inputs":[{"name":"value","type":"string"}],"name":"SetField","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"field","outputs":[{"name":"","type":"string"}],"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 funky gas pattern contract - _, _, limiter, err := DeployFunkyGasPattern(auth, sim) - if err != nil { - t.Fatalf("Failed to deploy funky contract: %v", err) - } - sim.Commit() - - // Set the field with automatic estimation and check that it succeeds - if _, err := limiter.SetField(auth, "automatic"); err != nil { - t.Fatalf("Failed to call automatically gased transaction: %v", err) - } - sim.Commit() - - if field, _ := limiter.Field(nil); field != "automatic" { - t.Fatalf("Field mismatch: have %v, want %v", field, "automatic") - } - `, - }, - // Test that constant functions can be called from an (optional) specified address - { - `CallFrom`, - ` - contract CallFrom { - function callFrom() constant returns(address) { - return msg.sender; - } - } - `, `6060604052346000575b6086806100176000396000f300606060405263ffffffff60e060020a60003504166349f8e98281146022575b6000565b34600057602c6055565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b335b905600a165627a7a72305820aef6b7685c0fa24ba6027e4870404a57df701473fe4107741805c19f5138417c0029`, - `[{"constant":true,"inputs":[],"name":"callFrom","outputs":[{"name":"","type":"address"}],"payable":false,"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 sender tester contract and execute a structured call on it - _, _, callfrom, err := DeployCallFrom(auth, sim) - if err != nil { - t.Fatalf("Failed to deploy sender contract: %v", err) - } - sim.Commit() - - if res, err := callfrom.CallFrom(nil); err != nil { - t.Errorf("Failed to call constant function: %v", err) - } else if res != (common.Address{}) { - t.Errorf("Invalid address returned, want: %x, got: %x", (common.Address{}), res) - } - - for _, addr := range []common.Address{common.Address{}, common.Address{1}, common.Address{2}} { - if res, err := callfrom.CallFrom(&bind.CallOpts{From: addr}); err != nil { - t.Fatalf("Failed to call constant function: %v", err) - } else if res != addr { - t.Fatalf("Invalid address returned, want: %x, got: %x", addr, res) - } - } - `, - }, - // Tests that methods and returns with underscores inside work correctly. - { - `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); - } - function _under_scored_func() constant returns (int _int) { - return 0; - } - } - `, `6060604052341561000f57600080fd5b6103858061001e6000396000f30060606040526004361061008e576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806303a592131461009357806346546dbe146100c357806367e6633d146100ec5780639df4848514610181578063af7486ab146101b1578063b564b34d146101e1578063e02ab24d14610211578063e409ca4514610241575b600080fd5b341561009e57600080fd5b6100a6610271565b604051808381526020018281526020019250505060405180910390f35b34156100ce57600080fd5b6100d6610286565b6040518082815260200191505060405180910390f35b34156100f757600080fd5b6100ff61028e565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561014557808201518184015260208101905061012a565b50505050905090810190601f1680156101725780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b341561018c57600080fd5b6101946102dc565b604051808381526020018281526020019250505060405180910390f35b34156101bc57600080fd5b6101c46102f1565b604051808381526020018281526020019250505060405180910390f35b34156101ec57600080fd5b6101f4610306565b604051808381526020018281526020019250505060405180910390f35b341561021c57600080fd5b61022461031b565b604051808381526020018281526020019250505060405180910390f35b341561024c57600080fd5b610254610330565b604051808381526020018281526020019250505060405180910390f35b60008060016002819150809050915091509091565b600080905090565b6000610298610345565b61013a8090506040805190810160405280600281526020017f7069000000000000000000000000000000000000000000000000000000000000815250915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b6020604051908101604052806000815250905600a165627a7a72305820d1a53d9de9d1e3d55cb3dc591900b63c4f1ded79114f7b79b332684840e186a40029`, - `[{"constant":true,"inputs":[],"name":"LowerUpperCollision","outputs":[{"name":"_res","type":"int256"},{"name":"Res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_under_scored_func","outputs":[{"name":"_int","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) - a, _ = underscorer.UnderScoredFunc(nil) - - fmt.Println(a, b, err) - `, - }, - // Tests that logs can be successfully filtered and decoded. - { - `Eventer`, - ` - contract Eventer { - event SimpleEvent ( - address indexed Addr, - bytes32 indexed Id, - bool indexed Flag, - uint Value - ); - function raiseSimpleEvent(address addr, bytes32 id, bool flag, uint value) { - SimpleEvent(addr, id, flag, value); - } - - event NodataEvent ( - uint indexed Number, - int16 indexed Short, - uint32 indexed Long - ); - function raiseNodataEvent(uint number, int16 short, uint32 long) { - NodataEvent(number, short, long); - } - - event DynamicEvent ( - string indexed IndexedString, - bytes indexed IndexedBytes, - string NonIndexedString, - bytes NonIndexedBytes - ); - function raiseDynamicEvent(string str, bytes blob) { - DynamicEvent(str, blob, str, blob); - } - } - `, - `6060604052341561000f57600080fd5b61042c8061001e6000396000f300606060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063528300ff1461005c578063630c31e2146100fc578063c7d116dd14610156575b600080fd5b341561006757600080fd5b6100fa600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050610194565b005b341561010757600080fd5b610154600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035600019169060200190919080351515906020019091908035906020019091905050610367565b005b341561016157600080fd5b610192600480803590602001909190803560010b90602001909190803563ffffffff169060200190919050506103c3565b005b806040518082805190602001908083835b6020831015156101ca57805182526020820191506020810190506020830392506101a5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020826040518082805190602001908083835b60208310151561022d5780518252602082019150602081019050602083039250610208565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f3281fd4f5e152dd3385df49104a3f633706e21c9e80672e88d3bcddf33101f008484604051808060200180602001838103835285818151815260200191508051906020019080838360005b838110156102c15780820151818401526020810190506102a6565b50505050905090810190601f1680156102ee5780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b8381101561032757808201518184015260208101905061030c565b50505050905090810190601f1680156103545780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a35050565b81151583600019168573ffffffffffffffffffffffffffffffffffffffff167f1f097de4289df643bd9c11011cc61367aa12983405c021056e706eb5ba1250c8846040518082815260200191505060405180910390a450505050565b8063ffffffff168260010b847f3ca7f3a77e5e6e15e781850bc82e32adfa378a2a609370db24b4d0fae10da2c960405160405180910390a45050505600a165627a7a72305820d1f8a8bbddbc5bb29f285891d6ae1eef8420c52afdc05e1573f6114d8e1714710029`, - `[{"constant":false,"inputs":[{"name":"str","type":"string"},{"name":"blob","type":"bytes"}],"name":"raiseDynamicEvent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"},{"name":"id","type":"bytes32"},{"name":"flag","type":"bool"},{"name":"value","type":"uint256"}],"name":"raiseSimpleEvent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"number","type":"uint256"},{"name":"short","type":"int16"},{"name":"long","type":"uint32"}],"name":"raiseNodataEvent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"Addr","type":"address"},{"indexed":true,"name":"Id","type":"bytes32"},{"indexed":true,"name":"Flag","type":"bool"},{"indexed":false,"name":"Value","type":"uint256"}],"name":"SimpleEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"Number","type":"uint256"},{"indexed":true,"name":"Short","type":"int16"},{"indexed":true,"name":"Long","type":"uint32"}],"name":"NodataEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"IndexedString","type":"string"},{"indexed":true,"name":"IndexedBytes","type":"bytes"},{"indexed":false,"name":"NonIndexedString","type":"string"},{"indexed":false,"name":"NonIndexedBytes","type":"bytes"}],"name":"DynamicEvent","type":"event"}]`, - ` - // 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 an eventer contract - _, _, eventer, err := DeployEventer(auth, sim) - if err != nil { - t.Fatalf("Failed to deploy eventer contract: %v", err) - } - sim.Commit() - - // Inject a few events into the contract, gradually more in each block - for i := 1; i <= 3; i++ { - for j := 1; j <= i; j++ { - if _, err := eventer.RaiseSimpleEvent(auth, common.Address{byte(j)}, [32]byte{byte(j)}, true, big.NewInt(int64(10*i+j))); err != nil { - t.Fatalf("block %d, event %d: raise failed: %v", i, j, err) - } - } - sim.Commit() - } - // Test filtering for certain events and ensure they can be found - sit, err := eventer.FilterSimpleEvent(nil, []common.Address{common.Address{1}, common.Address{3}}, [][32]byte{{byte(1)}, {byte(2)}, {byte(3)}}, []bool{true}) - if err != nil { - t.Fatalf("failed to filter for simple events: %v", err) - } - defer sit.Close() - - sit.Next() - if sit.Event.Value.Uint64() != 11 || !sit.Event.Flag { - t.Errorf("simple log content mismatch: have %v, want {11, true}", sit.Event) - } - sit.Next() - if sit.Event.Value.Uint64() != 21 || !sit.Event.Flag { - t.Errorf("simple log content mismatch: have %v, want {21, true}", sit.Event) - } - sit.Next() - if sit.Event.Value.Uint64() != 31 || !sit.Event.Flag { - t.Errorf("simple log content mismatch: have %v, want {31, true}", sit.Event) - } - sit.Next() - if sit.Event.Value.Uint64() != 33 || !sit.Event.Flag { - t.Errorf("simple log content mismatch: have %v, want {33, true}", sit.Event) - } - - if sit.Next() { - t.Errorf("unexpected simple event found: %+v", sit.Event) - } - if err = sit.Error(); err != nil { - t.Fatalf("simple event iteration failed: %v", err) - } - // Test raising and filtering for an event with no data component - if _, err := eventer.RaiseNodataEvent(auth, big.NewInt(314), 141, 271); err != nil { - t.Fatalf("failed to raise nodata event: %v", err) - } - sim.Commit() - - nit, err := eventer.FilterNodataEvent(nil, []*big.Int{big.NewInt(314)}, []int16{140, 141, 142}, []uint32{271}) - if err != nil { - t.Fatalf("failed to filter for nodata events: %v", err) - } - defer nit.Close() - - if !nit.Next() { - t.Fatalf("nodata log not found: %v", nit.Error()) - } - if nit.Event.Number.Uint64() != 314 { - t.Errorf("nodata log content mismatch: have %v, want 314", nit.Event.Number) - } - if nit.Next() { - t.Errorf("unexpected nodata event found: %+v", nit.Event) - } - if err = nit.Error(); err != nil { - t.Fatalf("nodata event iteration failed: %v", err) - } - // Test raising and filtering for events with dynamic indexed components - if _, err := eventer.RaiseDynamicEvent(auth, "Hello", []byte("World")); err != nil { - t.Fatalf("failed to raise dynamic event: %v", err) - } - sim.Commit() - - dit, err := eventer.FilterDynamicEvent(nil, []string{"Hi", "Hello", "Bye"}, [][]byte{[]byte("World")}) - if err != nil { - t.Fatalf("failed to filter for dynamic events: %v", err) - } - defer dit.Close() - - if !dit.Next() { - t.Fatalf("dynamic log not found: %v", dit.Error()) - } - if dit.Event.NonIndexedString != "Hello" || string(dit.Event.NonIndexedBytes) != "World" || dit.Event.IndexedString != common.HexToHash("0x06b3dfaec148fb1bb2b066f10ec285e7c9bf402ab32aa78a5d38e34566810cd2") || dit.Event.IndexedBytes != common.HexToHash("0xf2208c967df089f60420785795c0a9ba8896b0f6f1867fa7f1f12ad6f79c1a18") { - t.Errorf("dynamic log content mismatch: have %v, want {'0x06b3dfaec148fb1bb2b066f10ec285e7c9bf402ab32aa78a5d38e34566810cd2, '0xf2208c967df089f60420785795c0a9ba8896b0f6f1867fa7f1f12ad6f79c1a18', 'Hello', 'World'}", dit.Event) - } - if dit.Next() { - t.Errorf("unexpected dynamic event found: %+v", dit.Event) - } - if err = dit.Error(); err != nil { - t.Fatalf("dynamic event iteration failed: %v", err) - } - // Test subscribing to an event and raising it afterwards - ch := make(chan *EventerSimpleEvent, 16) - sub, err := eventer.WatchSimpleEvent(nil, ch, nil, nil, nil) - if err != nil { - t.Fatalf("failed to subscribe to simple events: %v", err) - } - if _, err := eventer.RaiseSimpleEvent(auth, common.Address{255}, [32]byte{255}, true, big.NewInt(255)); err != nil { - t.Fatalf("failed to raise subscribed simple event: %v", err) - } - sim.Commit() - - select { - case event := <-ch: - if event.Value.Uint64() != 255 { - t.Errorf("simple log content mismatch: have %v, want 255", event) - } - case <-time.After(250 * time.Millisecond): - t.Fatalf("subscribed simple event didn't arrive") - } - // Unsubscribe from the event and make sure we're not delivered more - sub.Unsubscribe() - - if _, err := eventer.RaiseSimpleEvent(auth, common.Address{254}, [32]byte{254}, true, big.NewInt(254)); err != nil { - t.Fatalf("failed to raise subscribed simple event: %v", err) - } - sim.Commit() - - select { - case event := <-ch: - t.Fatalf("unsubscribed simple event arrived: %v", event) - case <-time.After(250 * time.Millisecond): - } - `, - }, - { - `DeeplyNestedArray`, - ` - contract DeeplyNestedArray { - uint64[3][4][5] public deepUint64Array; - function storeDeepUintArray(uint64[3][4][5] arr) public { - deepUint64Array = arr; - } - function retrieveDeepArray() public view returns (uint64[3][4][5]) { - return deepUint64Array; - } - } - `, - `6060604052341561000f57600080fd5b6106438061001e6000396000f300606060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063344248551461005c5780638ed4573a1461011457806398ed1856146101ab575b600080fd5b341561006757600080fd5b610112600480806107800190600580602002604051908101604052809291906000905b828210156101055783826101800201600480602002604051908101604052809291906000905b828210156100f25783826060020160038060200260405190810160405280929190826003602002808284378201915050505050815260200190600101906100b0565b505050508152602001906001019061008a565b5050505091905050610208565b005b341561011f57600080fd5b61012761021d565b604051808260056000925b8184101561019b578284602002015160046000925b8184101561018d5782846020020151600360200280838360005b8381101561017c578082015181840152602081019050610161565b505050509050019260010192610147565b925050509260010192610132565b9250505091505060405180910390f35b34156101b657600080fd5b6101de6004808035906020019091908035906020019091908035906020019091905050610309565b604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390f35b80600090600561021992919061035f565b5050565b6102256103b0565b6000600580602002604051908101604052809291906000905b8282101561030057838260040201600480602002604051908101604052809291906000905b828210156102ed578382016003806020026040519081016040528092919082600380156102d9576020028201916000905b82829054906101000a900467ffffffffffffffff1667ffffffffffffffff16815260200190600801906020826007010492830192600103820291508084116102945790505b505050505081526020019060010190610263565b505050508152602001906001019061023e565b50505050905090565b60008360058110151561031857fe5b600402018260048110151561032957fe5b018160038110151561033757fe5b6004918282040191900660080292509250509054906101000a900467ffffffffffffffff1681565b826005600402810192821561039f579160200282015b8281111561039e5782518290600461038e9291906103df565b5091602001919060040190610375565b5b5090506103ac919061042d565b5090565b610780604051908101604052806005905b6103c9610459565b8152602001906001900390816103c15790505090565b826004810192821561041c579160200282015b8281111561041b5782518290600361040b929190610488565b50916020019190600101906103f2565b5b5090506104299190610536565b5090565b61045691905b8082111561045257600081816104499190610562565b50600401610433565b5090565b90565b610180604051908101604052806004905b6104726105a7565b81526020019060019003908161046a5790505090565b82600380016004900481019282156105255791602002820160005b838211156104ef57835183826101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555092602001926008016020816007010492830192600103026104a3565b80156105235782816101000a81549067ffffffffffffffff02191690556008016020816007010492830192600103026104ef565b505b50905061053291906105d9565b5090565b61055f91905b8082111561055b57600081816105529190610610565b5060010161053c565b5090565b90565b50600081816105719190610610565b50600101600081816105839190610610565b50600101600081816105959190610610565b5060010160006105a59190610610565b565b6060604051908101604052806003905b600067ffffffffffffffff168152602001906001900390816105b75790505090565b61060d91905b8082111561060957600081816101000a81549067ffffffffffffffff0219169055506001016105df565b5090565b90565b50600090555600a165627a7a7230582087e5a43f6965ab6ef7a4ff056ab80ed78fd8c15cff57715a1bf34ec76a93661c0029`, - `[{"constant":false,"inputs":[{"name":"arr","type":"uint64[3][4][5]"}],"name":"storeDeepUintArray","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"retrieveDeepArray","outputs":[{"name":"","type":"uint64[3][4][5]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"name":"deepUint64Array","outputs":[{"name":"","type":"uint64"}],"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 the test contract - _, _, testContract, err := DeployDeeplyNestedArray(auth, sim) - if err != nil { - t.Fatalf("Failed to deploy test contract: %v", err) - } - - // Finish deploy. - sim.Commit() - - //Create coordinate-filled array, for testing purposes. - testArr := [5][4][3]uint64{} - for i := 0; i < 5; i++ { - testArr[i] = [4][3]uint64{} - for j := 0; j < 4; j++ { - testArr[i][j] = [3]uint64{} - for k := 0; k < 3; k++ { - //pack the coordinates, each array value will be unique, and can be validated easily. - testArr[i][j][k] = uint64(i) << 16 | uint64(j) << 8 | uint64(k) - } - } - } - - if _, err := testContract.StoreDeepUintArray(&bind.TransactOpts{ - From: auth.From, - Signer: auth.Signer, - }, testArr); err != nil { - t.Fatalf("Failed to store nested array in test contract: %v", err) - } - - sim.Commit() - - retrievedArr, err := testContract.RetrieveDeepArray(&bind.CallOpts{ - From: auth.From, - Pending: false, - }) - if err != nil { - t.Fatalf("Failed to retrieve nested array from test contract: %v", err) - } - - //quick check to see if contents were copied - // (See accounts/abi/unpack_test.go for more extensive testing) - if retrievedArr[4][3][2] != testArr[4][3][2] { - t.Fatalf("Retrieved value does not match expected value! got: %d, expected: %d. %v", retrievedArr[4][3][2], testArr[4][3][2], err) - } - `, - }, -} - -// Tests that packages generated by the binder can be successfully compiled and -// the requested tester run against it. -func TestBindings(t *testing.T) { - // Skip the test if no Go command can be found - gocmd := runtime.GOROOT() + "/bin/go" - if !common.FileExist(gocmd) { - t.Skip("go sdk not found for testing") - } - // Skip the test if the go-ethereum sources are symlinked (https://github.com/golang/go/issues/14845) - linkTestCode := fmt.Sprintf("package linktest\nfunc CheckSymlinks(){\nfmt.Println(backends.NewSimulatedBackend(nil))\n}") - linkTestDeps, err := imports.Process(os.TempDir(), []byte(linkTestCode), nil) - if err != nil { - t.Fatalf("failed check for goimports symlink bug: %v", err) - } - if !strings.Contains(string(linkTestDeps), "go-ethereum") { - t.Skip("symlinked environment doesn't support bind (https://github.com/golang/go/issues/14845)") - } - // Create a temporary workspace for the test suite - ws, err := ioutil.TempDir("", "") - if err != nil { - t.Fatalf("failed to create temporary workspace: %v", err) - } - defer os.RemoveAll(ws) - - pkg := filepath.Join(ws, "bindtest") - if err = os.MkdirAll(pkg, 0700); err != nil { - t.Fatalf("failed to create package: %v", err) - } - // Generate the test suite for all the contracts - for i, tt := range bindTests { - // Generate the binding and create a Go source file in the workspace - bind, err := Bind([]string{tt.name}, []string{tt.abi}, []string{tt.bytecode}, "bindtest", LangGo) - if err != nil { - t.Fatalf("test %d: failed to generate binding: %v", i, err) - } - if err = ioutil.WriteFile(filepath.Join(pkg, strings.ToLower(tt.name)+".go"), []byte(bind), 0600); err != nil { - t.Fatalf("test %d: failed to write binding: %v", i, err) - } - // Generate the test file with the injected test code - code := fmt.Sprintf("package bindtest\nimport \"testing\"\nfunc Test%s(t *testing.T){\n%s\n}", tt.name, tt.tester) - blob, err := imports.Process("", []byte(code), nil) - if err != nil { - t.Fatalf("test %d: failed to generate tests: %v", i, err) - } - if err := ioutil.WriteFile(filepath.Join(pkg, strings.ToLower(tt.name)+"_test.go"), blob, 0600); err != nil { - t.Fatalf("test %d: failed to write tests: %v", i, err) - } - } - // Test the entire package and report any failures - cmd := exec.Command(gocmd, "test", "-v") - cmd.Dir = pkg - if out, err := cmd.CombinedOutput(); err != nil { - t.Fatalf("failed to run binding test: %v\n%s", err, out) - } -} diff --git a/client/accounts/accounts.go b/client/accounts/accounts.go index 5aab4850a..58f405d93 100644 --- a/client/accounts/accounts.go +++ b/client/accounts/accounts.go @@ -126,9 +126,8 @@ type TransactOpts struct { Nonce *big.Int // Nonce to use for the transaction execution (nil = use pending state) Signer SignerFn // Method to use for signing the transaction (mandatory) - 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) - GasLimit *big.Int // Gas limit to set for the transaction execution (nil = estimate + 10%) + Value *big.Int // Funds to transfer along along the transaction (nil = 0 = no funds) + ComputeLimit *big.Int // Compute limit to set for the transaction execution (nil = estimate + 10%) Context context.Context // Network context to support cancellation and timeouts (nil = no timeout) } diff --git a/client/accounts/usbwallet/hub.go b/client/accounts/usbwallet/hub.go index a1ebe04dc..36cd9e7f1 100644 --- a/client/accounts/usbwallet/hub.go +++ b/client/accounts/usbwallet/hub.go @@ -55,11 +55,6 @@ func NewLedgerHub() (*Hub, error) { return newHub(LedgerScheme, 0x2c97, []uint16{0x0000 /* Ledger Blue */, 0x0001 /* Ledger Nano S */}, 0xffa0, 0, newLedgerDriver) } -// NewTrezorHub creates a new hardware wallet manager for Trezor devices. -func NewTrezorHub() (*Hub, error) { - return newHub(TrezorScheme, 0x534c, []uint16{0x0001 /* Trezor 1 */}, 0xff00, 0, newTrezorDriver) -} - // newHub creates a new hardware wallet manager for generic USB devices. func newHub(scheme string, vendorID uint16, productIDs []uint16, usageID uint16, endpointID int, makeDriver func(log.Logger) driver) (*Hub, error) { if !hid.Supported() { diff --git a/client/accounts/usbwallet/internal/trezor/messages.pb.go b/client/accounts/usbwallet/internal/trezor/messages.pb.go deleted file mode 100644 index 7297faecb..000000000 --- a/client/accounts/usbwallet/internal/trezor/messages.pb.go +++ /dev/null @@ -1,4626 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: messages.proto - -package trezor - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -// * -// Mapping between Trezor wire identifier (uint) and a protobuf message -type MessageType int32 - -const ( - MessageType_MessageType_Initialize MessageType = 0 - MessageType_MessageType_Ping MessageType = 1 - MessageType_MessageType_Success MessageType = 2 - MessageType_MessageType_Failure MessageType = 3 - MessageType_MessageType_ChangePin MessageType = 4 - MessageType_MessageType_WipeDevice MessageType = 5 - MessageType_MessageType_FirmwareErase MessageType = 6 - MessageType_MessageType_FirmwareUpload MessageType = 7 - MessageType_MessageType_FirmwareRequest MessageType = 8 - MessageType_MessageType_GetEntropy MessageType = 9 - MessageType_MessageType_Entropy MessageType = 10 - MessageType_MessageType_GetPublicKey MessageType = 11 - MessageType_MessageType_PublicKey MessageType = 12 - MessageType_MessageType_LoadDevice MessageType = 13 - MessageType_MessageType_ResetDevice MessageType = 14 - MessageType_MessageType_SignTx MessageType = 15 - MessageType_MessageType_SimpleSignTx MessageType = 16 // Deprecated: Do not use. - MessageType_MessageType_Features MessageType = 17 - MessageType_MessageType_PinMatrixRequest MessageType = 18 - MessageType_MessageType_PinMatrixAck MessageType = 19 - MessageType_MessageType_Cancel MessageType = 20 - MessageType_MessageType_TxRequest MessageType = 21 - MessageType_MessageType_TxAck MessageType = 22 - MessageType_MessageType_CipherKeyValue MessageType = 23 - MessageType_MessageType_ClearSession MessageType = 24 - MessageType_MessageType_ApplySettings MessageType = 25 - MessageType_MessageType_ButtonRequest MessageType = 26 - MessageType_MessageType_ButtonAck MessageType = 27 - MessageType_MessageType_ApplyFlags MessageType = 28 - MessageType_MessageType_GetAddress MessageType = 29 - MessageType_MessageType_Address MessageType = 30 - MessageType_MessageType_SelfTest MessageType = 32 - MessageType_MessageType_BackupDevice MessageType = 34 - MessageType_MessageType_EntropyRequest MessageType = 35 - MessageType_MessageType_EntropyAck MessageType = 36 - MessageType_MessageType_SignMessage MessageType = 38 - MessageType_MessageType_VerifyMessage MessageType = 39 - MessageType_MessageType_MessageSignature MessageType = 40 - MessageType_MessageType_PassphraseRequest MessageType = 41 - MessageType_MessageType_PassphraseAck MessageType = 42 - MessageType_MessageType_EstimateTxSize MessageType = 43 // Deprecated: Do not use. - MessageType_MessageType_TxSize MessageType = 44 // Deprecated: Do not use. - MessageType_MessageType_RecoveryDevice MessageType = 45 - MessageType_MessageType_WordRequest MessageType = 46 - MessageType_MessageType_WordAck MessageType = 47 - MessageType_MessageType_CipheredKeyValue MessageType = 48 - MessageType_MessageType_EncryptMessage MessageType = 49 // Deprecated: Do not use. - MessageType_MessageType_EncryptedMessage MessageType = 50 // Deprecated: Do not use. - MessageType_MessageType_DecryptMessage MessageType = 51 // Deprecated: Do not use. - MessageType_MessageType_DecryptedMessage MessageType = 52 // Deprecated: Do not use. - MessageType_MessageType_SignIdentity MessageType = 53 - MessageType_MessageType_SignedIdentity MessageType = 54 - MessageType_MessageType_GetFeatures MessageType = 55 - MessageType_MessageType_EthereumGetAddress MessageType = 56 - MessageType_MessageType_EthereumAddress MessageType = 57 - MessageType_MessageType_EthereumSignTx MessageType = 58 - MessageType_MessageType_EthereumTxRequest MessageType = 59 - MessageType_MessageType_EthereumTxAck MessageType = 60 - MessageType_MessageType_GetECDHSessionKey MessageType = 61 - MessageType_MessageType_ECDHSessionKey MessageType = 62 - MessageType_MessageType_SetU2FCounter MessageType = 63 - MessageType_MessageType_EthereumSignMessage MessageType = 64 - MessageType_MessageType_EthereumVerifyMessage MessageType = 65 - MessageType_MessageType_EthereumMessageSignature MessageType = 66 - MessageType_MessageType_DebugLinkDecision MessageType = 100 - MessageType_MessageType_DebugLinkGetState MessageType = 101 - MessageType_MessageType_DebugLinkState MessageType = 102 - MessageType_MessageType_DebugLinkStop MessageType = 103 - MessageType_MessageType_DebugLinkLog MessageType = 104 - MessageType_MessageType_DebugLinkMemoryRead MessageType = 110 - MessageType_MessageType_DebugLinkMemory MessageType = 111 - MessageType_MessageType_DebugLinkMemoryWrite MessageType = 112 - MessageType_MessageType_DebugLinkFlashErase MessageType = 113 -) - -var MessageType_name = map[int32]string{ - 0: "MessageType_Initialize", - 1: "MessageType_Ping", - 2: "MessageType_Success", - 3: "MessageType_Failure", - 4: "MessageType_ChangePin", - 5: "MessageType_WipeDevice", - 6: "MessageType_FirmwareErase", - 7: "MessageType_FirmwareUpload", - 8: "MessageType_FirmwareRequest", - 9: "MessageType_GetEntropy", - 10: "MessageType_Entropy", - 11: "MessageType_GetPublicKey", - 12: "MessageType_PublicKey", - 13: "MessageType_LoadDevice", - 14: "MessageType_ResetDevice", - 15: "MessageType_SignTx", - 16: "MessageType_SimpleSignTx", - 17: "MessageType_Features", - 18: "MessageType_PinMatrixRequest", - 19: "MessageType_PinMatrixAck", - 20: "MessageType_Cancel", - 21: "MessageType_TxRequest", - 22: "MessageType_TxAck", - 23: "MessageType_CipherKeyValue", - 24: "MessageType_ClearSession", - 25: "MessageType_ApplySettings", - 26: "MessageType_ButtonRequest", - 27: "MessageType_ButtonAck", - 28: "MessageType_ApplyFlags", - 29: "MessageType_GetAddress", - 30: "MessageType_Address", - 32: "MessageType_SelfTest", - 34: "MessageType_BackupDevice", - 35: "MessageType_EntropyRequest", - 36: "MessageType_EntropyAck", - 38: "MessageType_SignMessage", - 39: "MessageType_VerifyMessage", - 40: "MessageType_MessageSignature", - 41: "MessageType_PassphraseRequest", - 42: "MessageType_PassphraseAck", - 43: "MessageType_EstimateTxSize", - 44: "MessageType_TxSize", - 45: "MessageType_RecoveryDevice", - 46: "MessageType_WordRequest", - 47: "MessageType_WordAck", - 48: "MessageType_CipheredKeyValue", - 49: "MessageType_EncryptMessage", - 50: "MessageType_EncryptedMessage", - 51: "MessageType_DecryptMessage", - 52: "MessageType_DecryptedMessage", - 53: "MessageType_SignIdentity", - 54: "MessageType_SignedIdentity", - 55: "MessageType_GetFeatures", - 56: "MessageType_EthereumGetAddress", - 57: "MessageType_EthereumAddress", - 58: "MessageType_EthereumSignTx", - 59: "MessageType_EthereumTxRequest", - 60: "MessageType_EthereumTxAck", - 61: "MessageType_GetECDHSessionKey", - 62: "MessageType_ECDHSessionKey", - 63: "MessageType_SetU2FCounter", - 64: "MessageType_EthereumSignMessage", - 65: "MessageType_EthereumVerifyMessage", - 66: "MessageType_EthereumMessageSignature", - 100: "MessageType_DebugLinkDecision", - 101: "MessageType_DebugLinkGetState", - 102: "MessageType_DebugLinkState", - 103: "MessageType_DebugLinkStop", - 104: "MessageType_DebugLinkLog", - 110: "MessageType_DebugLinkMemoryRead", - 111: "MessageType_DebugLinkMemory", - 112: "MessageType_DebugLinkMemoryWrite", - 113: "MessageType_DebugLinkFlashErase", -} - -var MessageType_value = map[string]int32{ - "MessageType_Initialize": 0, - "MessageType_Ping": 1, - "MessageType_Success": 2, - "MessageType_Failure": 3, - "MessageType_ChangePin": 4, - "MessageType_WipeDevice": 5, - "MessageType_FirmwareErase": 6, - "MessageType_FirmwareUpload": 7, - "MessageType_FirmwareRequest": 8, - "MessageType_GetEntropy": 9, - "MessageType_Entropy": 10, - "MessageType_GetPublicKey": 11, - "MessageType_PublicKey": 12, - "MessageType_LoadDevice": 13, - "MessageType_ResetDevice": 14, - "MessageType_SignTx": 15, - "MessageType_SimpleSignTx": 16, - "MessageType_Features": 17, - "MessageType_PinMatrixRequest": 18, - "MessageType_PinMatrixAck": 19, - "MessageType_Cancel": 20, - "MessageType_TxRequest": 21, - "MessageType_TxAck": 22, - "MessageType_CipherKeyValue": 23, - "MessageType_ClearSession": 24, - "MessageType_ApplySettings": 25, - "MessageType_ButtonRequest": 26, - "MessageType_ButtonAck": 27, - "MessageType_ApplyFlags": 28, - "MessageType_GetAddress": 29, - "MessageType_Address": 30, - "MessageType_SelfTest": 32, - "MessageType_BackupDevice": 34, - "MessageType_EntropyRequest": 35, - "MessageType_EntropyAck": 36, - "MessageType_SignMessage": 38, - "MessageType_VerifyMessage": 39, - "MessageType_MessageSignature": 40, - "MessageType_PassphraseRequest": 41, - "MessageType_PassphraseAck": 42, - "MessageType_EstimateTxSize": 43, - "MessageType_TxSize": 44, - "MessageType_RecoveryDevice": 45, - "MessageType_WordRequest": 46, - "MessageType_WordAck": 47, - "MessageType_CipheredKeyValue": 48, - "MessageType_EncryptMessage": 49, - "MessageType_EncryptedMessage": 50, - "MessageType_DecryptMessage": 51, - "MessageType_DecryptedMessage": 52, - "MessageType_SignIdentity": 53, - "MessageType_SignedIdentity": 54, - "MessageType_GetFeatures": 55, - "MessageType_EthereumGetAddress": 56, - "MessageType_EthereumAddress": 57, - "MessageType_EthereumSignTx": 58, - "MessageType_EthereumTxRequest": 59, - "MessageType_EthereumTxAck": 60, - "MessageType_GetECDHSessionKey": 61, - "MessageType_ECDHSessionKey": 62, - "MessageType_SetU2FCounter": 63, - "MessageType_EthereumSignMessage": 64, - "MessageType_EthereumVerifyMessage": 65, - "MessageType_EthereumMessageSignature": 66, - "MessageType_DebugLinkDecision": 100, - "MessageType_DebugLinkGetState": 101, - "MessageType_DebugLinkState": 102, - "MessageType_DebugLinkStop": 103, - "MessageType_DebugLinkLog": 104, - "MessageType_DebugLinkMemoryRead": 110, - "MessageType_DebugLinkMemory": 111, - "MessageType_DebugLinkMemoryWrite": 112, - "MessageType_DebugLinkFlashErase": 113, -} - -func (x MessageType) Enum() *MessageType { - p := new(MessageType) - *p = x - return p -} - -func (x MessageType) String() string { - return proto.EnumName(MessageType_name, int32(x)) -} - -func (x *MessageType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(MessageType_value, data, "MessageType") - if err != nil { - return err - } - *x = MessageType(value) - return nil -} - -func (MessageType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{0} -} - -// * -// Request: Reset device to default state and ask for device details -// @next Features -type Initialize struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Initialize) Reset() { *m = Initialize{} } -func (m *Initialize) String() string { return proto.CompactTextString(m) } -func (*Initialize) ProtoMessage() {} -func (*Initialize) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{0} -} -func (m *Initialize) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Initialize.Unmarshal(m, b) -} -func (m *Initialize) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Initialize.Marshal(b, m, deterministic) -} -func (dst *Initialize) XXX_Merge(src proto.Message) { - xxx_messageInfo_Initialize.Merge(dst, src) -} -func (m *Initialize) XXX_Size() int { - return xxx_messageInfo_Initialize.Size(m) -} -func (m *Initialize) XXX_DiscardUnknown() { - xxx_messageInfo_Initialize.DiscardUnknown(m) -} - -var xxx_messageInfo_Initialize proto.InternalMessageInfo - -// * -// Request: Ask for device details (no device reset) -// @next Features -type GetFeatures struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *GetFeatures) Reset() { *m = GetFeatures{} } -func (m *GetFeatures) String() string { return proto.CompactTextString(m) } -func (*GetFeatures) ProtoMessage() {} -func (*GetFeatures) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{1} -} -func (m *GetFeatures) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_GetFeatures.Unmarshal(m, b) -} -func (m *GetFeatures) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_GetFeatures.Marshal(b, m, deterministic) -} -func (dst *GetFeatures) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetFeatures.Merge(dst, src) -} -func (m *GetFeatures) XXX_Size() int { - return xxx_messageInfo_GetFeatures.Size(m) -} -func (m *GetFeatures) XXX_DiscardUnknown() { - xxx_messageInfo_GetFeatures.DiscardUnknown(m) -} - -var xxx_messageInfo_GetFeatures proto.InternalMessageInfo - -// * -// Response: Reports various information about the device -// @prev Initialize -// @prev GetFeatures -type Features struct { - Vendor *string `protobuf:"bytes,1,opt,name=vendor" json:"vendor,omitempty"` - MajorVersion *uint32 `protobuf:"varint,2,opt,name=major_version,json=majorVersion" json:"major_version,omitempty"` - MinorVersion *uint32 `protobuf:"varint,3,opt,name=minor_version,json=minorVersion" json:"minor_version,omitempty"` - PatchVersion *uint32 `protobuf:"varint,4,opt,name=patch_version,json=patchVersion" json:"patch_version,omitempty"` - BootloaderMode *bool `protobuf:"varint,5,opt,name=bootloader_mode,json=bootloaderMode" json:"bootloader_mode,omitempty"` - DeviceId *string `protobuf:"bytes,6,opt,name=device_id,json=deviceId" json:"device_id,omitempty"` - PinProtection *bool `protobuf:"varint,7,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` - PassphraseProtection *bool `protobuf:"varint,8,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` - Language *string `protobuf:"bytes,9,opt,name=language" json:"language,omitempty"` - Label *string `protobuf:"bytes,10,opt,name=label" json:"label,omitempty"` - Coins []*CoinType `protobuf:"bytes,11,rep,name=coins" json:"coins,omitempty"` - Initialized *bool `protobuf:"varint,12,opt,name=initialized" json:"initialized,omitempty"` - Revision []byte `protobuf:"bytes,13,opt,name=revision" json:"revision,omitempty"` - BootloaderHash []byte `protobuf:"bytes,14,opt,name=bootloader_hash,json=bootloaderHash" json:"bootloader_hash,omitempty"` - Imported *bool `protobuf:"varint,15,opt,name=imported" json:"imported,omitempty"` - PinCached *bool `protobuf:"varint,16,opt,name=pin_cached,json=pinCached" json:"pin_cached,omitempty"` - PassphraseCached *bool `protobuf:"varint,17,opt,name=passphrase_cached,json=passphraseCached" json:"passphrase_cached,omitempty"` - FirmwarePresent *bool `protobuf:"varint,18,opt,name=firmware_present,json=firmwarePresent" json:"firmware_present,omitempty"` - NeedsBackup *bool `protobuf:"varint,19,opt,name=needs_backup,json=needsBackup" json:"needs_backup,omitempty"` - Flags *uint32 `protobuf:"varint,20,opt,name=flags" json:"flags,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Features) Reset() { *m = Features{} } -func (m *Features) String() string { return proto.CompactTextString(m) } -func (*Features) ProtoMessage() {} -func (*Features) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{2} -} -func (m *Features) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Features.Unmarshal(m, b) -} -func (m *Features) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Features.Marshal(b, m, deterministic) -} -func (dst *Features) XXX_Merge(src proto.Message) { - xxx_messageInfo_Features.Merge(dst, src) -} -func (m *Features) XXX_Size() int { - return xxx_messageInfo_Features.Size(m) -} -func (m *Features) XXX_DiscardUnknown() { - xxx_messageInfo_Features.DiscardUnknown(m) -} - -var xxx_messageInfo_Features proto.InternalMessageInfo - -func (m *Features) GetVendor() string { - if m != nil && m.Vendor != nil { - return *m.Vendor - } - return "" -} - -func (m *Features) GetMajorVersion() uint32 { - if m != nil && m.MajorVersion != nil { - return *m.MajorVersion - } - return 0 -} - -func (m *Features) GetMinorVersion() uint32 { - if m != nil && m.MinorVersion != nil { - return *m.MinorVersion - } - return 0 -} - -func (m *Features) GetPatchVersion() uint32 { - if m != nil && m.PatchVersion != nil { - return *m.PatchVersion - } - return 0 -} - -func (m *Features) GetBootloaderMode() bool { - if m != nil && m.BootloaderMode != nil { - return *m.BootloaderMode - } - return false -} - -func (m *Features) GetDeviceId() string { - if m != nil && m.DeviceId != nil { - return *m.DeviceId - } - return "" -} - -func (m *Features) GetPinProtection() bool { - if m != nil && m.PinProtection != nil { - return *m.PinProtection - } - return false -} - -func (m *Features) GetPassphraseProtection() bool { - if m != nil && m.PassphraseProtection != nil { - return *m.PassphraseProtection - } - return false -} - -func (m *Features) GetLanguage() string { - if m != nil && m.Language != nil { - return *m.Language - } - return "" -} - -func (m *Features) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label - } - return "" -} - -func (m *Features) GetCoins() []*CoinType { - if m != nil { - return m.Coins - } - return nil -} - -func (m *Features) GetInitialized() bool { - if m != nil && m.Initialized != nil { - return *m.Initialized - } - return false -} - -func (m *Features) GetRevision() []byte { - if m != nil { - return m.Revision - } - return nil -} - -func (m *Features) GetBootloaderHash() []byte { - if m != nil { - return m.BootloaderHash - } - return nil -} - -func (m *Features) GetImported() bool { - if m != nil && m.Imported != nil { - return *m.Imported - } - return false -} - -func (m *Features) GetPinCached() bool { - if m != nil && m.PinCached != nil { - return *m.PinCached - } - return false -} - -func (m *Features) GetPassphraseCached() bool { - if m != nil && m.PassphraseCached != nil { - return *m.PassphraseCached - } - return false -} - -func (m *Features) GetFirmwarePresent() bool { - if m != nil && m.FirmwarePresent != nil { - return *m.FirmwarePresent - } - return false -} - -func (m *Features) GetNeedsBackup() bool { - if m != nil && m.NeedsBackup != nil { - return *m.NeedsBackup - } - return false -} - -func (m *Features) GetFlags() uint32 { - if m != nil && m.Flags != nil { - return *m.Flags - } - return 0 -} - -// * -// Request: clear session (removes cached PIN, passphrase, etc). -// @next Success -type ClearSession struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ClearSession) Reset() { *m = ClearSession{} } -func (m *ClearSession) String() string { return proto.CompactTextString(m) } -func (*ClearSession) ProtoMessage() {} -func (*ClearSession) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{3} -} -func (m *ClearSession) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ClearSession.Unmarshal(m, b) -} -func (m *ClearSession) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ClearSession.Marshal(b, m, deterministic) -} -func (dst *ClearSession) XXX_Merge(src proto.Message) { - xxx_messageInfo_ClearSession.Merge(dst, src) -} -func (m *ClearSession) XXX_Size() int { - return xxx_messageInfo_ClearSession.Size(m) -} -func (m *ClearSession) XXX_DiscardUnknown() { - xxx_messageInfo_ClearSession.DiscardUnknown(m) -} - -var xxx_messageInfo_ClearSession proto.InternalMessageInfo - -// * -// Request: change language and/or label of the device -// @next Success -// @next Failure -// @next ButtonRequest -// @next PinMatrixRequest -type ApplySettings struct { - Language *string `protobuf:"bytes,1,opt,name=language" json:"language,omitempty"` - Label *string `protobuf:"bytes,2,opt,name=label" json:"label,omitempty"` - UsePassphrase *bool `protobuf:"varint,3,opt,name=use_passphrase,json=usePassphrase" json:"use_passphrase,omitempty"` - Homescreen []byte `protobuf:"bytes,4,opt,name=homescreen" json:"homescreen,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ApplySettings) Reset() { *m = ApplySettings{} } -func (m *ApplySettings) String() string { return proto.CompactTextString(m) } -func (*ApplySettings) ProtoMessage() {} -func (*ApplySettings) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{4} -} -func (m *ApplySettings) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ApplySettings.Unmarshal(m, b) -} -func (m *ApplySettings) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ApplySettings.Marshal(b, m, deterministic) -} -func (dst *ApplySettings) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplySettings.Merge(dst, src) -} -func (m *ApplySettings) XXX_Size() int { - return xxx_messageInfo_ApplySettings.Size(m) -} -func (m *ApplySettings) XXX_DiscardUnknown() { - xxx_messageInfo_ApplySettings.DiscardUnknown(m) -} - -var xxx_messageInfo_ApplySettings proto.InternalMessageInfo - -func (m *ApplySettings) GetLanguage() string { - if m != nil && m.Language != nil { - return *m.Language - } - return "" -} - -func (m *ApplySettings) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label - } - return "" -} - -func (m *ApplySettings) GetUsePassphrase() bool { - if m != nil && m.UsePassphrase != nil { - return *m.UsePassphrase - } - return false -} - -func (m *ApplySettings) GetHomescreen() []byte { - if m != nil { - return m.Homescreen - } - return nil -} - -// * -// Request: set flags of the device -// @next Success -// @next Failure -type ApplyFlags struct { - Flags *uint32 `protobuf:"varint,1,opt,name=flags" json:"flags,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ApplyFlags) Reset() { *m = ApplyFlags{} } -func (m *ApplyFlags) String() string { return proto.CompactTextString(m) } -func (*ApplyFlags) ProtoMessage() {} -func (*ApplyFlags) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{5} -} -func (m *ApplyFlags) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ApplyFlags.Unmarshal(m, b) -} -func (m *ApplyFlags) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ApplyFlags.Marshal(b, m, deterministic) -} -func (dst *ApplyFlags) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplyFlags.Merge(dst, src) -} -func (m *ApplyFlags) XXX_Size() int { - return xxx_messageInfo_ApplyFlags.Size(m) -} -func (m *ApplyFlags) XXX_DiscardUnknown() { - xxx_messageInfo_ApplyFlags.DiscardUnknown(m) -} - -var xxx_messageInfo_ApplyFlags proto.InternalMessageInfo - -func (m *ApplyFlags) GetFlags() uint32 { - if m != nil && m.Flags != nil { - return *m.Flags - } - return 0 -} - -// * -// Request: Starts workflow for setting/changing/removing the PIN -// @next ButtonRequest -// @next PinMatrixRequest -type ChangePin struct { - Remove *bool `protobuf:"varint,1,opt,name=remove" json:"remove,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ChangePin) Reset() { *m = ChangePin{} } -func (m *ChangePin) String() string { return proto.CompactTextString(m) } -func (*ChangePin) ProtoMessage() {} -func (*ChangePin) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{6} -} -func (m *ChangePin) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ChangePin.Unmarshal(m, b) -} -func (m *ChangePin) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ChangePin.Marshal(b, m, deterministic) -} -func (dst *ChangePin) XXX_Merge(src proto.Message) { - xxx_messageInfo_ChangePin.Merge(dst, src) -} -func (m *ChangePin) XXX_Size() int { - return xxx_messageInfo_ChangePin.Size(m) -} -func (m *ChangePin) XXX_DiscardUnknown() { - xxx_messageInfo_ChangePin.DiscardUnknown(m) -} - -var xxx_messageInfo_ChangePin proto.InternalMessageInfo - -func (m *ChangePin) GetRemove() bool { - if m != nil && m.Remove != nil { - return *m.Remove - } - return false -} - -// * -// Request: Test if the device is alive, device sends back the message in Success response -// @next Success -type Ping struct { - Message *string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` - ButtonProtection *bool `protobuf:"varint,2,opt,name=button_protection,json=buttonProtection" json:"button_protection,omitempty"` - PinProtection *bool `protobuf:"varint,3,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` - PassphraseProtection *bool `protobuf:"varint,4,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Ping) Reset() { *m = Ping{} } -func (m *Ping) String() string { return proto.CompactTextString(m) } -func (*Ping) ProtoMessage() {} -func (*Ping) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{7} -} -func (m *Ping) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Ping.Unmarshal(m, b) -} -func (m *Ping) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Ping.Marshal(b, m, deterministic) -} -func (dst *Ping) XXX_Merge(src proto.Message) { - xxx_messageInfo_Ping.Merge(dst, src) -} -func (m *Ping) XXX_Size() int { - return xxx_messageInfo_Ping.Size(m) -} -func (m *Ping) XXX_DiscardUnknown() { - xxx_messageInfo_Ping.DiscardUnknown(m) -} - -var xxx_messageInfo_Ping proto.InternalMessageInfo - -func (m *Ping) GetMessage() string { - if m != nil && m.Message != nil { - return *m.Message - } - return "" -} - -func (m *Ping) GetButtonProtection() bool { - if m != nil && m.ButtonProtection != nil { - return *m.ButtonProtection - } - return false -} - -func (m *Ping) GetPinProtection() bool { - if m != nil && m.PinProtection != nil { - return *m.PinProtection - } - return false -} - -func (m *Ping) GetPassphraseProtection() bool { - if m != nil && m.PassphraseProtection != nil { - return *m.PassphraseProtection - } - return false -} - -// * -// Response: Success of the previous request -type Success struct { - Message *string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Success) Reset() { *m = Success{} } -func (m *Success) String() string { return proto.CompactTextString(m) } -func (*Success) ProtoMessage() {} -func (*Success) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{8} -} -func (m *Success) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Success.Unmarshal(m, b) -} -func (m *Success) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Success.Marshal(b, m, deterministic) -} -func (dst *Success) XXX_Merge(src proto.Message) { - xxx_messageInfo_Success.Merge(dst, src) -} -func (m *Success) XXX_Size() int { - return xxx_messageInfo_Success.Size(m) -} -func (m *Success) XXX_DiscardUnknown() { - xxx_messageInfo_Success.DiscardUnknown(m) -} - -var xxx_messageInfo_Success proto.InternalMessageInfo - -func (m *Success) GetMessage() string { - if m != nil && m.Message != nil { - return *m.Message - } - return "" -} - -// * -// Response: Failure of the previous request -type Failure struct { - Code *FailureType `protobuf:"varint,1,opt,name=code,enum=FailureType" json:"code,omitempty"` - Message *string `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Failure) Reset() { *m = Failure{} } -func (m *Failure) String() string { return proto.CompactTextString(m) } -func (*Failure) ProtoMessage() {} -func (*Failure) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{9} -} -func (m *Failure) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Failure.Unmarshal(m, b) -} -func (m *Failure) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Failure.Marshal(b, m, deterministic) -} -func (dst *Failure) XXX_Merge(src proto.Message) { - xxx_messageInfo_Failure.Merge(dst, src) -} -func (m *Failure) XXX_Size() int { - return xxx_messageInfo_Failure.Size(m) -} -func (m *Failure) XXX_DiscardUnknown() { - xxx_messageInfo_Failure.DiscardUnknown(m) -} - -var xxx_messageInfo_Failure proto.InternalMessageInfo - -func (m *Failure) GetCode() FailureType { - if m != nil && m.Code != nil { - return *m.Code - } - return FailureType_Failure_UnexpectedMessage -} - -func (m *Failure) GetMessage() string { - if m != nil && m.Message != nil { - return *m.Message - } - return "" -} - -// * -// Response: Device is waiting for HW button press. -// @next ButtonAck -// @next Cancel -type ButtonRequest struct { - Code *ButtonRequestType `protobuf:"varint,1,opt,name=code,enum=ButtonRequestType" json:"code,omitempty"` - Data *string `protobuf:"bytes,2,opt,name=data" json:"data,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ButtonRequest) Reset() { *m = ButtonRequest{} } -func (m *ButtonRequest) String() string { return proto.CompactTextString(m) } -func (*ButtonRequest) ProtoMessage() {} -func (*ButtonRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{10} -} -func (m *ButtonRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ButtonRequest.Unmarshal(m, b) -} -func (m *ButtonRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ButtonRequest.Marshal(b, m, deterministic) -} -func (dst *ButtonRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ButtonRequest.Merge(dst, src) -} -func (m *ButtonRequest) XXX_Size() int { - return xxx_messageInfo_ButtonRequest.Size(m) -} -func (m *ButtonRequest) XXX_DiscardUnknown() { - xxx_messageInfo_ButtonRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_ButtonRequest proto.InternalMessageInfo - -func (m *ButtonRequest) GetCode() ButtonRequestType { - if m != nil && m.Code != nil { - return *m.Code - } - return ButtonRequestType_ButtonRequest_Other -} - -func (m *ButtonRequest) GetData() string { - if m != nil && m.Data != nil { - return *m.Data - } - return "" -} - -// * -// Request: Computer agrees to wait for HW button press -// @prev ButtonRequest -type ButtonAck struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ButtonAck) Reset() { *m = ButtonAck{} } -func (m *ButtonAck) String() string { return proto.CompactTextString(m) } -func (*ButtonAck) ProtoMessage() {} -func (*ButtonAck) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{11} -} -func (m *ButtonAck) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ButtonAck.Unmarshal(m, b) -} -func (m *ButtonAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ButtonAck.Marshal(b, m, deterministic) -} -func (dst *ButtonAck) XXX_Merge(src proto.Message) { - xxx_messageInfo_ButtonAck.Merge(dst, src) -} -func (m *ButtonAck) XXX_Size() int { - return xxx_messageInfo_ButtonAck.Size(m) -} -func (m *ButtonAck) XXX_DiscardUnknown() { - xxx_messageInfo_ButtonAck.DiscardUnknown(m) -} - -var xxx_messageInfo_ButtonAck proto.InternalMessageInfo - -// * -// Response: Device is asking computer to show PIN matrix and awaits PIN encoded using this matrix scheme -// @next PinMatrixAck -// @next Cancel -type PinMatrixRequest struct { - Type *PinMatrixRequestType `protobuf:"varint,1,opt,name=type,enum=PinMatrixRequestType" json:"type,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *PinMatrixRequest) Reset() { *m = PinMatrixRequest{} } -func (m *PinMatrixRequest) String() string { return proto.CompactTextString(m) } -func (*PinMatrixRequest) ProtoMessage() {} -func (*PinMatrixRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{12} -} -func (m *PinMatrixRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PinMatrixRequest.Unmarshal(m, b) -} -func (m *PinMatrixRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PinMatrixRequest.Marshal(b, m, deterministic) -} -func (dst *PinMatrixRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_PinMatrixRequest.Merge(dst, src) -} -func (m *PinMatrixRequest) XXX_Size() int { - return xxx_messageInfo_PinMatrixRequest.Size(m) -} -func (m *PinMatrixRequest) XXX_DiscardUnknown() { - xxx_messageInfo_PinMatrixRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_PinMatrixRequest proto.InternalMessageInfo - -func (m *PinMatrixRequest) GetType() PinMatrixRequestType { - if m != nil && m.Type != nil { - return *m.Type - } - return PinMatrixRequestType_PinMatrixRequestType_Current -} - -// * -// Request: Computer responds with encoded PIN -// @prev PinMatrixRequest -type PinMatrixAck struct { - Pin *string `protobuf:"bytes,1,req,name=pin" json:"pin,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *PinMatrixAck) Reset() { *m = PinMatrixAck{} } -func (m *PinMatrixAck) String() string { return proto.CompactTextString(m) } -func (*PinMatrixAck) ProtoMessage() {} -func (*PinMatrixAck) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{13} -} -func (m *PinMatrixAck) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PinMatrixAck.Unmarshal(m, b) -} -func (m *PinMatrixAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PinMatrixAck.Marshal(b, m, deterministic) -} -func (dst *PinMatrixAck) XXX_Merge(src proto.Message) { - xxx_messageInfo_PinMatrixAck.Merge(dst, src) -} -func (m *PinMatrixAck) XXX_Size() int { - return xxx_messageInfo_PinMatrixAck.Size(m) -} -func (m *PinMatrixAck) XXX_DiscardUnknown() { - xxx_messageInfo_PinMatrixAck.DiscardUnknown(m) -} - -var xxx_messageInfo_PinMatrixAck proto.InternalMessageInfo - -func (m *PinMatrixAck) GetPin() string { - if m != nil && m.Pin != nil { - return *m.Pin - } - return "" -} - -// * -// Request: Abort last operation that required user interaction -// @prev ButtonRequest -// @prev PinMatrixRequest -// @prev PassphraseRequest -type Cancel struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Cancel) Reset() { *m = Cancel{} } -func (m *Cancel) String() string { return proto.CompactTextString(m) } -func (*Cancel) ProtoMessage() {} -func (*Cancel) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{14} -} -func (m *Cancel) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Cancel.Unmarshal(m, b) -} -func (m *Cancel) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Cancel.Marshal(b, m, deterministic) -} -func (dst *Cancel) XXX_Merge(src proto.Message) { - xxx_messageInfo_Cancel.Merge(dst, src) -} -func (m *Cancel) XXX_Size() int { - return xxx_messageInfo_Cancel.Size(m) -} -func (m *Cancel) XXX_DiscardUnknown() { - xxx_messageInfo_Cancel.DiscardUnknown(m) -} - -var xxx_messageInfo_Cancel proto.InternalMessageInfo - -// * -// Response: Device awaits encryption passphrase -// @next PassphraseAck -// @next Cancel -type PassphraseRequest struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *PassphraseRequest) Reset() { *m = PassphraseRequest{} } -func (m *PassphraseRequest) String() string { return proto.CompactTextString(m) } -func (*PassphraseRequest) ProtoMessage() {} -func (*PassphraseRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{15} -} -func (m *PassphraseRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PassphraseRequest.Unmarshal(m, b) -} -func (m *PassphraseRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PassphraseRequest.Marshal(b, m, deterministic) -} -func (dst *PassphraseRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_PassphraseRequest.Merge(dst, src) -} -func (m *PassphraseRequest) XXX_Size() int { - return xxx_messageInfo_PassphraseRequest.Size(m) -} -func (m *PassphraseRequest) XXX_DiscardUnknown() { - xxx_messageInfo_PassphraseRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_PassphraseRequest proto.InternalMessageInfo - -// * -// Request: Send passphrase back -// @prev PassphraseRequest -type PassphraseAck struct { - Passphrase *string `protobuf:"bytes,1,req,name=passphrase" json:"passphrase,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *PassphraseAck) Reset() { *m = PassphraseAck{} } -func (m *PassphraseAck) String() string { return proto.CompactTextString(m) } -func (*PassphraseAck) ProtoMessage() {} -func (*PassphraseAck) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{16} -} -func (m *PassphraseAck) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PassphraseAck.Unmarshal(m, b) -} -func (m *PassphraseAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PassphraseAck.Marshal(b, m, deterministic) -} -func (dst *PassphraseAck) XXX_Merge(src proto.Message) { - xxx_messageInfo_PassphraseAck.Merge(dst, src) -} -func (m *PassphraseAck) XXX_Size() int { - return xxx_messageInfo_PassphraseAck.Size(m) -} -func (m *PassphraseAck) XXX_DiscardUnknown() { - xxx_messageInfo_PassphraseAck.DiscardUnknown(m) -} - -var xxx_messageInfo_PassphraseAck proto.InternalMessageInfo - -func (m *PassphraseAck) GetPassphrase() string { - if m != nil && m.Passphrase != nil { - return *m.Passphrase - } - return "" -} - -// * -// Request: Request a sample of random data generated by hardware RNG. May be used for testing. -// @next ButtonRequest -// @next Entropy -// @next Failure -type GetEntropy struct { - Size *uint32 `protobuf:"varint,1,req,name=size" json:"size,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *GetEntropy) Reset() { *m = GetEntropy{} } -func (m *GetEntropy) String() string { return proto.CompactTextString(m) } -func (*GetEntropy) ProtoMessage() {} -func (*GetEntropy) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{17} -} -func (m *GetEntropy) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_GetEntropy.Unmarshal(m, b) -} -func (m *GetEntropy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_GetEntropy.Marshal(b, m, deterministic) -} -func (dst *GetEntropy) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetEntropy.Merge(dst, src) -} -func (m *GetEntropy) XXX_Size() int { - return xxx_messageInfo_GetEntropy.Size(m) -} -func (m *GetEntropy) XXX_DiscardUnknown() { - xxx_messageInfo_GetEntropy.DiscardUnknown(m) -} - -var xxx_messageInfo_GetEntropy proto.InternalMessageInfo - -func (m *GetEntropy) GetSize() uint32 { - if m != nil && m.Size != nil { - return *m.Size - } - return 0 -} - -// * -// Response: Reply with random data generated by internal RNG -// @prev GetEntropy -type Entropy struct { - Entropy []byte `protobuf:"bytes,1,req,name=entropy" json:"entropy,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Entropy) Reset() { *m = Entropy{} } -func (m *Entropy) String() string { return proto.CompactTextString(m) } -func (*Entropy) ProtoMessage() {} -func (*Entropy) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{18} -} -func (m *Entropy) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Entropy.Unmarshal(m, b) -} -func (m *Entropy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Entropy.Marshal(b, m, deterministic) -} -func (dst *Entropy) XXX_Merge(src proto.Message) { - xxx_messageInfo_Entropy.Merge(dst, src) -} -func (m *Entropy) XXX_Size() int { - return xxx_messageInfo_Entropy.Size(m) -} -func (m *Entropy) XXX_DiscardUnknown() { - xxx_messageInfo_Entropy.DiscardUnknown(m) -} - -var xxx_messageInfo_Entropy proto.InternalMessageInfo - -func (m *Entropy) GetEntropy() []byte { - if m != nil { - return m.Entropy - } - return nil -} - -// * -// Request: Ask device for public key corresponding to address_n path -// @next PassphraseRequest -// @next PublicKey -// @next Failure -type GetPublicKey struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - EcdsaCurveName *string `protobuf:"bytes,2,opt,name=ecdsa_curve_name,json=ecdsaCurveName" json:"ecdsa_curve_name,omitempty"` - ShowDisplay *bool `protobuf:"varint,3,opt,name=show_display,json=showDisplay" json:"show_display,omitempty"` - CoinName *string `protobuf:"bytes,4,opt,name=coin_name,json=coinName,def=Bitcoin" json:"coin_name,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *GetPublicKey) Reset() { *m = GetPublicKey{} } -func (m *GetPublicKey) String() string { return proto.CompactTextString(m) } -func (*GetPublicKey) ProtoMessage() {} -func (*GetPublicKey) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{19} -} -func (m *GetPublicKey) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_GetPublicKey.Unmarshal(m, b) -} -func (m *GetPublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_GetPublicKey.Marshal(b, m, deterministic) -} -func (dst *GetPublicKey) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetPublicKey.Merge(dst, src) -} -func (m *GetPublicKey) XXX_Size() int { - return xxx_messageInfo_GetPublicKey.Size(m) -} -func (m *GetPublicKey) XXX_DiscardUnknown() { - xxx_messageInfo_GetPublicKey.DiscardUnknown(m) -} - -var xxx_messageInfo_GetPublicKey proto.InternalMessageInfo - -const Default_GetPublicKey_CoinName string = "Bitcoin" - -func (m *GetPublicKey) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -func (m *GetPublicKey) GetEcdsaCurveName() string { - if m != nil && m.EcdsaCurveName != nil { - return *m.EcdsaCurveName - } - return "" -} - -func (m *GetPublicKey) GetShowDisplay() bool { - if m != nil && m.ShowDisplay != nil { - return *m.ShowDisplay - } - return false -} - -func (m *GetPublicKey) GetCoinName() string { - if m != nil && m.CoinName != nil { - return *m.CoinName - } - return Default_GetPublicKey_CoinName -} - -// * -// Response: Contains public key derived from device private seed -// @prev GetPublicKey -type PublicKey struct { - Node *HDNodeType `protobuf:"bytes,1,req,name=node" json:"node,omitempty"` - Xpub *string `protobuf:"bytes,2,opt,name=xpub" json:"xpub,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *PublicKey) Reset() { *m = PublicKey{} } -func (m *PublicKey) String() string { return proto.CompactTextString(m) } -func (*PublicKey) ProtoMessage() {} -func (*PublicKey) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{20} -} -func (m *PublicKey) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PublicKey.Unmarshal(m, b) -} -func (m *PublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PublicKey.Marshal(b, m, deterministic) -} -func (dst *PublicKey) XXX_Merge(src proto.Message) { - xxx_messageInfo_PublicKey.Merge(dst, src) -} -func (m *PublicKey) XXX_Size() int { - return xxx_messageInfo_PublicKey.Size(m) -} -func (m *PublicKey) XXX_DiscardUnknown() { - xxx_messageInfo_PublicKey.DiscardUnknown(m) -} - -var xxx_messageInfo_PublicKey proto.InternalMessageInfo - -func (m *PublicKey) GetNode() *HDNodeType { - if m != nil { - return m.Node - } - return nil -} - -func (m *PublicKey) GetXpub() string { - if m != nil && m.Xpub != nil { - return *m.Xpub - } - return "" -} - -// * -// Request: Ask device for address corresponding to address_n path -// @next PassphraseRequest -// @next Address -// @next Failure -type GetAddress struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - CoinName *string `protobuf:"bytes,2,opt,name=coin_name,json=coinName,def=Bitcoin" json:"coin_name,omitempty"` - ShowDisplay *bool `protobuf:"varint,3,opt,name=show_display,json=showDisplay" json:"show_display,omitempty"` - Multisig *MultisigRedeemScriptType `protobuf:"bytes,4,opt,name=multisig" json:"multisig,omitempty"` - ScriptType *InputScriptType `protobuf:"varint,5,opt,name=script_type,json=scriptType,enum=InputScriptType,def=0" json:"script_type,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *GetAddress) Reset() { *m = GetAddress{} } -func (m *GetAddress) String() string { return proto.CompactTextString(m) } -func (*GetAddress) ProtoMessage() {} -func (*GetAddress) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{21} -} -func (m *GetAddress) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_GetAddress.Unmarshal(m, b) -} -func (m *GetAddress) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_GetAddress.Marshal(b, m, deterministic) -} -func (dst *GetAddress) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetAddress.Merge(dst, src) -} -func (m *GetAddress) XXX_Size() int { - return xxx_messageInfo_GetAddress.Size(m) -} -func (m *GetAddress) XXX_DiscardUnknown() { - xxx_messageInfo_GetAddress.DiscardUnknown(m) -} - -var xxx_messageInfo_GetAddress proto.InternalMessageInfo - -const Default_GetAddress_CoinName string = "Bitcoin" -const Default_GetAddress_ScriptType InputScriptType = InputScriptType_SPENDADDRESS - -func (m *GetAddress) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -func (m *GetAddress) GetCoinName() string { - if m != nil && m.CoinName != nil { - return *m.CoinName - } - return Default_GetAddress_CoinName -} - -func (m *GetAddress) GetShowDisplay() bool { - if m != nil && m.ShowDisplay != nil { - return *m.ShowDisplay - } - return false -} - -func (m *GetAddress) GetMultisig() *MultisigRedeemScriptType { - if m != nil { - return m.Multisig - } - return nil -} - -func (m *GetAddress) GetScriptType() InputScriptType { - if m != nil && m.ScriptType != nil { - return *m.ScriptType - } - return Default_GetAddress_ScriptType -} - -// * -// Request: Ask device for Ethereum address corresponding to address_n path -// @next PassphraseRequest -// @next EthereumAddress -// @next Failure -type EthereumGetAddress struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - ShowDisplay *bool `protobuf:"varint,2,opt,name=show_display,json=showDisplay" json:"show_display,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EthereumGetAddress) Reset() { *m = EthereumGetAddress{} } -func (m *EthereumGetAddress) String() string { return proto.CompactTextString(m) } -func (*EthereumGetAddress) ProtoMessage() {} -func (*EthereumGetAddress) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{22} -} -func (m *EthereumGetAddress) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumGetAddress.Unmarshal(m, b) -} -func (m *EthereumGetAddress) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumGetAddress.Marshal(b, m, deterministic) -} -func (dst *EthereumGetAddress) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumGetAddress.Merge(dst, src) -} -func (m *EthereumGetAddress) XXX_Size() int { - return xxx_messageInfo_EthereumGetAddress.Size(m) -} -func (m *EthereumGetAddress) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumGetAddress.DiscardUnknown(m) -} - -var xxx_messageInfo_EthereumGetAddress proto.InternalMessageInfo - -func (m *EthereumGetAddress) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -func (m *EthereumGetAddress) GetShowDisplay() bool { - if m != nil && m.ShowDisplay != nil { - return *m.ShowDisplay - } - return false -} - -// * -// Response: Contains address derived from device private seed -// @prev GetAddress -type Address struct { - Address *string `protobuf:"bytes,1,req,name=address" json:"address,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Address) Reset() { *m = Address{} } -func (m *Address) String() string { return proto.CompactTextString(m) } -func (*Address) ProtoMessage() {} -func (*Address) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{23} -} -func (m *Address) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Address.Unmarshal(m, b) -} -func (m *Address) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Address.Marshal(b, m, deterministic) -} -func (dst *Address) XXX_Merge(src proto.Message) { - xxx_messageInfo_Address.Merge(dst, src) -} -func (m *Address) XXX_Size() int { - return xxx_messageInfo_Address.Size(m) -} -func (m *Address) XXX_DiscardUnknown() { - xxx_messageInfo_Address.DiscardUnknown(m) -} - -var xxx_messageInfo_Address proto.InternalMessageInfo - -func (m *Address) GetAddress() string { - if m != nil && m.Address != nil { - return *m.Address - } - return "" -} - -// * -// Response: Contains an Ethereum address derived from device private seed -// @prev EthereumGetAddress -type EthereumAddress struct { - Address []byte `protobuf:"bytes,1,req,name=address" json:"address,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EthereumAddress) Reset() { *m = EthereumAddress{} } -func (m *EthereumAddress) String() string { return proto.CompactTextString(m) } -func (*EthereumAddress) ProtoMessage() {} -func (*EthereumAddress) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{24} -} -func (m *EthereumAddress) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumAddress.Unmarshal(m, b) -} -func (m *EthereumAddress) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumAddress.Marshal(b, m, deterministic) -} -func (dst *EthereumAddress) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumAddress.Merge(dst, src) -} -func (m *EthereumAddress) XXX_Size() int { - return xxx_messageInfo_EthereumAddress.Size(m) -} -func (m *EthereumAddress) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumAddress.DiscardUnknown(m) -} - -var xxx_messageInfo_EthereumAddress proto.InternalMessageInfo - -func (m *EthereumAddress) GetAddress() []byte { - if m != nil { - return m.Address - } - return nil -} - -// * -// Request: Request device to wipe all sensitive data and settings -// @next ButtonRequest -type WipeDevice struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *WipeDevice) Reset() { *m = WipeDevice{} } -func (m *WipeDevice) String() string { return proto.CompactTextString(m) } -func (*WipeDevice) ProtoMessage() {} -func (*WipeDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{25} -} -func (m *WipeDevice) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_WipeDevice.Unmarshal(m, b) -} -func (m *WipeDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_WipeDevice.Marshal(b, m, deterministic) -} -func (dst *WipeDevice) XXX_Merge(src proto.Message) { - xxx_messageInfo_WipeDevice.Merge(dst, src) -} -func (m *WipeDevice) XXX_Size() int { - return xxx_messageInfo_WipeDevice.Size(m) -} -func (m *WipeDevice) XXX_DiscardUnknown() { - xxx_messageInfo_WipeDevice.DiscardUnknown(m) -} - -var xxx_messageInfo_WipeDevice proto.InternalMessageInfo - -// * -// Request: Load seed and related internal settings from the computer -// @next ButtonRequest -// @next Success -// @next Failure -type LoadDevice struct { - Mnemonic *string `protobuf:"bytes,1,opt,name=mnemonic" json:"mnemonic,omitempty"` - Node *HDNodeType `protobuf:"bytes,2,opt,name=node" json:"node,omitempty"` - Pin *string `protobuf:"bytes,3,opt,name=pin" json:"pin,omitempty"` - PassphraseProtection *bool `protobuf:"varint,4,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` - Language *string `protobuf:"bytes,5,opt,name=language,def=english" json:"language,omitempty"` - Label *string `protobuf:"bytes,6,opt,name=label" json:"label,omitempty"` - SkipChecksum *bool `protobuf:"varint,7,opt,name=skip_checksum,json=skipChecksum" json:"skip_checksum,omitempty"` - U2FCounter *uint32 `protobuf:"varint,8,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *LoadDevice) Reset() { *m = LoadDevice{} } -func (m *LoadDevice) String() string { return proto.CompactTextString(m) } -func (*LoadDevice) ProtoMessage() {} -func (*LoadDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{26} -} -func (m *LoadDevice) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_LoadDevice.Unmarshal(m, b) -} -func (m *LoadDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_LoadDevice.Marshal(b, m, deterministic) -} -func (dst *LoadDevice) XXX_Merge(src proto.Message) { - xxx_messageInfo_LoadDevice.Merge(dst, src) -} -func (m *LoadDevice) XXX_Size() int { - return xxx_messageInfo_LoadDevice.Size(m) -} -func (m *LoadDevice) XXX_DiscardUnknown() { - xxx_messageInfo_LoadDevice.DiscardUnknown(m) -} - -var xxx_messageInfo_LoadDevice proto.InternalMessageInfo - -const Default_LoadDevice_Language string = "english" - -func (m *LoadDevice) GetMnemonic() string { - if m != nil && m.Mnemonic != nil { - return *m.Mnemonic - } - return "" -} - -func (m *LoadDevice) GetNode() *HDNodeType { - if m != nil { - return m.Node - } - return nil -} - -func (m *LoadDevice) GetPin() string { - if m != nil && m.Pin != nil { - return *m.Pin - } - return "" -} - -func (m *LoadDevice) GetPassphraseProtection() bool { - if m != nil && m.PassphraseProtection != nil { - return *m.PassphraseProtection - } - return false -} - -func (m *LoadDevice) GetLanguage() string { - if m != nil && m.Language != nil { - return *m.Language - } - return Default_LoadDevice_Language -} - -func (m *LoadDevice) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label - } - return "" -} - -func (m *LoadDevice) GetSkipChecksum() bool { - if m != nil && m.SkipChecksum != nil { - return *m.SkipChecksum - } - return false -} - -func (m *LoadDevice) GetU2FCounter() uint32 { - if m != nil && m.U2FCounter != nil { - return *m.U2FCounter - } - return 0 -} - -// * -// Request: Ask device to do initialization involving user interaction -// @next EntropyRequest -// @next Failure -type ResetDevice struct { - DisplayRandom *bool `protobuf:"varint,1,opt,name=display_random,json=displayRandom" json:"display_random,omitempty"` - Strength *uint32 `protobuf:"varint,2,opt,name=strength,def=256" json:"strength,omitempty"` - PassphraseProtection *bool `protobuf:"varint,3,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` - PinProtection *bool `protobuf:"varint,4,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` - Language *string `protobuf:"bytes,5,opt,name=language,def=english" json:"language,omitempty"` - Label *string `protobuf:"bytes,6,opt,name=label" json:"label,omitempty"` - U2FCounter *uint32 `protobuf:"varint,7,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` - SkipBackup *bool `protobuf:"varint,8,opt,name=skip_backup,json=skipBackup" json:"skip_backup,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ResetDevice) Reset() { *m = ResetDevice{} } -func (m *ResetDevice) String() string { return proto.CompactTextString(m) } -func (*ResetDevice) ProtoMessage() {} -func (*ResetDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{27} -} -func (m *ResetDevice) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ResetDevice.Unmarshal(m, b) -} -func (m *ResetDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ResetDevice.Marshal(b, m, deterministic) -} -func (dst *ResetDevice) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResetDevice.Merge(dst, src) -} -func (m *ResetDevice) XXX_Size() int { - return xxx_messageInfo_ResetDevice.Size(m) -} -func (m *ResetDevice) XXX_DiscardUnknown() { - xxx_messageInfo_ResetDevice.DiscardUnknown(m) -} - -var xxx_messageInfo_ResetDevice proto.InternalMessageInfo - -const Default_ResetDevice_Strength uint32 = 256 -const Default_ResetDevice_Language string = "english" - -func (m *ResetDevice) GetDisplayRandom() bool { - if m != nil && m.DisplayRandom != nil { - return *m.DisplayRandom - } - return false -} - -func (m *ResetDevice) GetStrength() uint32 { - if m != nil && m.Strength != nil { - return *m.Strength - } - return Default_ResetDevice_Strength -} - -func (m *ResetDevice) GetPassphraseProtection() bool { - if m != nil && m.PassphraseProtection != nil { - return *m.PassphraseProtection - } - return false -} - -func (m *ResetDevice) GetPinProtection() bool { - if m != nil && m.PinProtection != nil { - return *m.PinProtection - } - return false -} - -func (m *ResetDevice) GetLanguage() string { - if m != nil && m.Language != nil { - return *m.Language - } - return Default_ResetDevice_Language -} - -func (m *ResetDevice) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label - } - return "" -} - -func (m *ResetDevice) GetU2FCounter() uint32 { - if m != nil && m.U2FCounter != nil { - return *m.U2FCounter - } - return 0 -} - -func (m *ResetDevice) GetSkipBackup() bool { - if m != nil && m.SkipBackup != nil { - return *m.SkipBackup - } - return false -} - -// * -// Request: Perform backup of the device seed if not backed up using ResetDevice -// @next ButtonRequest -type BackupDevice struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *BackupDevice) Reset() { *m = BackupDevice{} } -func (m *BackupDevice) String() string { return proto.CompactTextString(m) } -func (*BackupDevice) ProtoMessage() {} -func (*BackupDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{28} -} -func (m *BackupDevice) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_BackupDevice.Unmarshal(m, b) -} -func (m *BackupDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_BackupDevice.Marshal(b, m, deterministic) -} -func (dst *BackupDevice) XXX_Merge(src proto.Message) { - xxx_messageInfo_BackupDevice.Merge(dst, src) -} -func (m *BackupDevice) XXX_Size() int { - return xxx_messageInfo_BackupDevice.Size(m) -} -func (m *BackupDevice) XXX_DiscardUnknown() { - xxx_messageInfo_BackupDevice.DiscardUnknown(m) -} - -var xxx_messageInfo_BackupDevice proto.InternalMessageInfo - -// * -// Response: Ask for additional entropy from host computer -// @prev ResetDevice -// @next EntropyAck -type EntropyRequest struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EntropyRequest) Reset() { *m = EntropyRequest{} } -func (m *EntropyRequest) String() string { return proto.CompactTextString(m) } -func (*EntropyRequest) ProtoMessage() {} -func (*EntropyRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{29} -} -func (m *EntropyRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EntropyRequest.Unmarshal(m, b) -} -func (m *EntropyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EntropyRequest.Marshal(b, m, deterministic) -} -func (dst *EntropyRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_EntropyRequest.Merge(dst, src) -} -func (m *EntropyRequest) XXX_Size() int { - return xxx_messageInfo_EntropyRequest.Size(m) -} -func (m *EntropyRequest) XXX_DiscardUnknown() { - xxx_messageInfo_EntropyRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_EntropyRequest proto.InternalMessageInfo - -// * -// Request: Provide additional entropy for seed generation function -// @prev EntropyRequest -// @next ButtonRequest -type EntropyAck struct { - Entropy []byte `protobuf:"bytes,1,opt,name=entropy" json:"entropy,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EntropyAck) Reset() { *m = EntropyAck{} } -func (m *EntropyAck) String() string { return proto.CompactTextString(m) } -func (*EntropyAck) ProtoMessage() {} -func (*EntropyAck) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{30} -} -func (m *EntropyAck) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EntropyAck.Unmarshal(m, b) -} -func (m *EntropyAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EntropyAck.Marshal(b, m, deterministic) -} -func (dst *EntropyAck) XXX_Merge(src proto.Message) { - xxx_messageInfo_EntropyAck.Merge(dst, src) -} -func (m *EntropyAck) XXX_Size() int { - return xxx_messageInfo_EntropyAck.Size(m) -} -func (m *EntropyAck) XXX_DiscardUnknown() { - xxx_messageInfo_EntropyAck.DiscardUnknown(m) -} - -var xxx_messageInfo_EntropyAck proto.InternalMessageInfo - -func (m *EntropyAck) GetEntropy() []byte { - if m != nil { - return m.Entropy - } - return nil -} - -// * -// Request: Start recovery workflow asking user for specific words of mnemonic -// Used to recovery device safely even on untrusted computer. -// @next WordRequest -type RecoveryDevice struct { - WordCount *uint32 `protobuf:"varint,1,opt,name=word_count,json=wordCount" json:"word_count,omitempty"` - PassphraseProtection *bool `protobuf:"varint,2,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` - PinProtection *bool `protobuf:"varint,3,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` - Language *string `protobuf:"bytes,4,opt,name=language,def=english" json:"language,omitempty"` - Label *string `protobuf:"bytes,5,opt,name=label" json:"label,omitempty"` - EnforceWordlist *bool `protobuf:"varint,6,opt,name=enforce_wordlist,json=enforceWordlist" json:"enforce_wordlist,omitempty"` - // 7 reserved for unused recovery method - Type *uint32 `protobuf:"varint,8,opt,name=type" json:"type,omitempty"` - U2FCounter *uint32 `protobuf:"varint,9,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` - DryRun *bool `protobuf:"varint,10,opt,name=dry_run,json=dryRun" json:"dry_run,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *RecoveryDevice) Reset() { *m = RecoveryDevice{} } -func (m *RecoveryDevice) String() string { return proto.CompactTextString(m) } -func (*RecoveryDevice) ProtoMessage() {} -func (*RecoveryDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{31} -} -func (m *RecoveryDevice) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_RecoveryDevice.Unmarshal(m, b) -} -func (m *RecoveryDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_RecoveryDevice.Marshal(b, m, deterministic) -} -func (dst *RecoveryDevice) XXX_Merge(src proto.Message) { - xxx_messageInfo_RecoveryDevice.Merge(dst, src) -} -func (m *RecoveryDevice) XXX_Size() int { - return xxx_messageInfo_RecoveryDevice.Size(m) -} -func (m *RecoveryDevice) XXX_DiscardUnknown() { - xxx_messageInfo_RecoveryDevice.DiscardUnknown(m) -} - -var xxx_messageInfo_RecoveryDevice proto.InternalMessageInfo - -const Default_RecoveryDevice_Language string = "english" - -func (m *RecoveryDevice) GetWordCount() uint32 { - if m != nil && m.WordCount != nil { - return *m.WordCount - } - return 0 -} - -func (m *RecoveryDevice) GetPassphraseProtection() bool { - if m != nil && m.PassphraseProtection != nil { - return *m.PassphraseProtection - } - return false -} - -func (m *RecoveryDevice) GetPinProtection() bool { - if m != nil && m.PinProtection != nil { - return *m.PinProtection - } - return false -} - -func (m *RecoveryDevice) GetLanguage() string { - if m != nil && m.Language != nil { - return *m.Language - } - return Default_RecoveryDevice_Language -} - -func (m *RecoveryDevice) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label - } - return "" -} - -func (m *RecoveryDevice) GetEnforceWordlist() bool { - if m != nil && m.EnforceWordlist != nil { - return *m.EnforceWordlist - } - return false -} - -func (m *RecoveryDevice) GetType() uint32 { - if m != nil && m.Type != nil { - return *m.Type - } - return 0 -} - -func (m *RecoveryDevice) GetU2FCounter() uint32 { - if m != nil && m.U2FCounter != nil { - return *m.U2FCounter - } - return 0 -} - -func (m *RecoveryDevice) GetDryRun() bool { - if m != nil && m.DryRun != nil { - return *m.DryRun - } - return false -} - -// * -// Response: Device is waiting for user to enter word of the mnemonic -// Its position is shown only on device's internal display. -// @prev RecoveryDevice -// @prev WordAck -type WordRequest struct { - Type *WordRequestType `protobuf:"varint,1,opt,name=type,enum=WordRequestType" json:"type,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *WordRequest) Reset() { *m = WordRequest{} } -func (m *WordRequest) String() string { return proto.CompactTextString(m) } -func (*WordRequest) ProtoMessage() {} -func (*WordRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{32} -} -func (m *WordRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_WordRequest.Unmarshal(m, b) -} -func (m *WordRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_WordRequest.Marshal(b, m, deterministic) -} -func (dst *WordRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_WordRequest.Merge(dst, src) -} -func (m *WordRequest) XXX_Size() int { - return xxx_messageInfo_WordRequest.Size(m) -} -func (m *WordRequest) XXX_DiscardUnknown() { - xxx_messageInfo_WordRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_WordRequest proto.InternalMessageInfo - -func (m *WordRequest) GetType() WordRequestType { - if m != nil && m.Type != nil { - return *m.Type - } - return WordRequestType_WordRequestType_Plain -} - -// * -// Request: Computer replies with word from the mnemonic -// @prev WordRequest -// @next WordRequest -// @next Success -// @next Failure -type WordAck struct { - Word *string `protobuf:"bytes,1,req,name=word" json:"word,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *WordAck) Reset() { *m = WordAck{} } -func (m *WordAck) String() string { return proto.CompactTextString(m) } -func (*WordAck) ProtoMessage() {} -func (*WordAck) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{33} -} -func (m *WordAck) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_WordAck.Unmarshal(m, b) -} -func (m *WordAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_WordAck.Marshal(b, m, deterministic) -} -func (dst *WordAck) XXX_Merge(src proto.Message) { - xxx_messageInfo_WordAck.Merge(dst, src) -} -func (m *WordAck) XXX_Size() int { - return xxx_messageInfo_WordAck.Size(m) -} -func (m *WordAck) XXX_DiscardUnknown() { - xxx_messageInfo_WordAck.DiscardUnknown(m) -} - -var xxx_messageInfo_WordAck proto.InternalMessageInfo - -func (m *WordAck) GetWord() string { - if m != nil && m.Word != nil { - return *m.Word - } - return "" -} - -// * -// Request: Ask device to sign message -// @next MessageSignature -// @next Failure -type SignMessage struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - Message []byte `protobuf:"bytes,2,req,name=message" json:"message,omitempty"` - CoinName *string `protobuf:"bytes,3,opt,name=coin_name,json=coinName,def=Bitcoin" json:"coin_name,omitempty"` - ScriptType *InputScriptType `protobuf:"varint,4,opt,name=script_type,json=scriptType,enum=InputScriptType,def=0" json:"script_type,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *SignMessage) Reset() { *m = SignMessage{} } -func (m *SignMessage) String() string { return proto.CompactTextString(m) } -func (*SignMessage) ProtoMessage() {} -func (*SignMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{34} -} -func (m *SignMessage) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SignMessage.Unmarshal(m, b) -} -func (m *SignMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SignMessage.Marshal(b, m, deterministic) -} -func (dst *SignMessage) XXX_Merge(src proto.Message) { - xxx_messageInfo_SignMessage.Merge(dst, src) -} -func (m *SignMessage) XXX_Size() int { - return xxx_messageInfo_SignMessage.Size(m) -} -func (m *SignMessage) XXX_DiscardUnknown() { - xxx_messageInfo_SignMessage.DiscardUnknown(m) -} - -var xxx_messageInfo_SignMessage proto.InternalMessageInfo - -const Default_SignMessage_CoinName string = "Bitcoin" -const Default_SignMessage_ScriptType InputScriptType = InputScriptType_SPENDADDRESS - -func (m *SignMessage) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -func (m *SignMessage) GetMessage() []byte { - if m != nil { - return m.Message - } - return nil -} - -func (m *SignMessage) GetCoinName() string { - if m != nil && m.CoinName != nil { - return *m.CoinName - } - return Default_SignMessage_CoinName -} - -func (m *SignMessage) GetScriptType() InputScriptType { - if m != nil && m.ScriptType != nil { - return *m.ScriptType - } - return Default_SignMessage_ScriptType -} - -// * -// Request: Ask device to verify message -// @next Success -// @next Failure -type VerifyMessage struct { - Address *string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` - Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` - Message []byte `protobuf:"bytes,3,opt,name=message" json:"message,omitempty"` - CoinName *string `protobuf:"bytes,4,opt,name=coin_name,json=coinName,def=Bitcoin" json:"coin_name,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *VerifyMessage) Reset() { *m = VerifyMessage{} } -func (m *VerifyMessage) String() string { return proto.CompactTextString(m) } -func (*VerifyMessage) ProtoMessage() {} -func (*VerifyMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{35} -} -func (m *VerifyMessage) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_VerifyMessage.Unmarshal(m, b) -} -func (m *VerifyMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_VerifyMessage.Marshal(b, m, deterministic) -} -func (dst *VerifyMessage) XXX_Merge(src proto.Message) { - xxx_messageInfo_VerifyMessage.Merge(dst, src) -} -func (m *VerifyMessage) XXX_Size() int { - return xxx_messageInfo_VerifyMessage.Size(m) -} -func (m *VerifyMessage) XXX_DiscardUnknown() { - xxx_messageInfo_VerifyMessage.DiscardUnknown(m) -} - -var xxx_messageInfo_VerifyMessage proto.InternalMessageInfo - -const Default_VerifyMessage_CoinName string = "Bitcoin" - -func (m *VerifyMessage) GetAddress() string { - if m != nil && m.Address != nil { - return *m.Address - } - return "" -} - -func (m *VerifyMessage) GetSignature() []byte { - if m != nil { - return m.Signature - } - return nil -} - -func (m *VerifyMessage) GetMessage() []byte { - if m != nil { - return m.Message - } - return nil -} - -func (m *VerifyMessage) GetCoinName() string { - if m != nil && m.CoinName != nil { - return *m.CoinName - } - return Default_VerifyMessage_CoinName -} - -// * -// Response: Signed message -// @prev SignMessage -type MessageSignature struct { - Address *string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` - Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *MessageSignature) Reset() { *m = MessageSignature{} } -func (m *MessageSignature) String() string { return proto.CompactTextString(m) } -func (*MessageSignature) ProtoMessage() {} -func (*MessageSignature) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{36} -} -func (m *MessageSignature) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_MessageSignature.Unmarshal(m, b) -} -func (m *MessageSignature) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_MessageSignature.Marshal(b, m, deterministic) -} -func (dst *MessageSignature) XXX_Merge(src proto.Message) { - xxx_messageInfo_MessageSignature.Merge(dst, src) -} -func (m *MessageSignature) XXX_Size() int { - return xxx_messageInfo_MessageSignature.Size(m) -} -func (m *MessageSignature) XXX_DiscardUnknown() { - xxx_messageInfo_MessageSignature.DiscardUnknown(m) -} - -var xxx_messageInfo_MessageSignature proto.InternalMessageInfo - -func (m *MessageSignature) GetAddress() string { - if m != nil && m.Address != nil { - return *m.Address - } - return "" -} - -func (m *MessageSignature) GetSignature() []byte { - if m != nil { - return m.Signature - } - return nil -} - -// * -// Request: Ask device to encrypt message -// @next EncryptedMessage -// @next Failure -type EncryptMessage struct { - Pubkey []byte `protobuf:"bytes,1,opt,name=pubkey" json:"pubkey,omitempty"` - Message []byte `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` - DisplayOnly *bool `protobuf:"varint,3,opt,name=display_only,json=displayOnly" json:"display_only,omitempty"` - AddressN []uint32 `protobuf:"varint,4,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - CoinName *string `protobuf:"bytes,5,opt,name=coin_name,json=coinName,def=Bitcoin" json:"coin_name,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EncryptMessage) Reset() { *m = EncryptMessage{} } -func (m *EncryptMessage) String() string { return proto.CompactTextString(m) } -func (*EncryptMessage) ProtoMessage() {} -func (*EncryptMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{37} -} -func (m *EncryptMessage) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EncryptMessage.Unmarshal(m, b) -} -func (m *EncryptMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EncryptMessage.Marshal(b, m, deterministic) -} -func (dst *EncryptMessage) XXX_Merge(src proto.Message) { - xxx_messageInfo_EncryptMessage.Merge(dst, src) -} -func (m *EncryptMessage) XXX_Size() int { - return xxx_messageInfo_EncryptMessage.Size(m) -} -func (m *EncryptMessage) XXX_DiscardUnknown() { - xxx_messageInfo_EncryptMessage.DiscardUnknown(m) -} - -var xxx_messageInfo_EncryptMessage proto.InternalMessageInfo - -const Default_EncryptMessage_CoinName string = "Bitcoin" - -func (m *EncryptMessage) GetPubkey() []byte { - if m != nil { - return m.Pubkey - } - return nil -} - -func (m *EncryptMessage) GetMessage() []byte { - if m != nil { - return m.Message - } - return nil -} - -func (m *EncryptMessage) GetDisplayOnly() bool { - if m != nil && m.DisplayOnly != nil { - return *m.DisplayOnly - } - return false -} - -func (m *EncryptMessage) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -func (m *EncryptMessage) GetCoinName() string { - if m != nil && m.CoinName != nil { - return *m.CoinName - } - return Default_EncryptMessage_CoinName -} - -// * -// Response: Encrypted message -// @prev EncryptMessage -type EncryptedMessage struct { - Nonce []byte `protobuf:"bytes,1,opt,name=nonce" json:"nonce,omitempty"` - Message []byte `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` - Hmac []byte `protobuf:"bytes,3,opt,name=hmac" json:"hmac,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EncryptedMessage) Reset() { *m = EncryptedMessage{} } -func (m *EncryptedMessage) String() string { return proto.CompactTextString(m) } -func (*EncryptedMessage) ProtoMessage() {} -func (*EncryptedMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{38} -} -func (m *EncryptedMessage) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EncryptedMessage.Unmarshal(m, b) -} -func (m *EncryptedMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EncryptedMessage.Marshal(b, m, deterministic) -} -func (dst *EncryptedMessage) XXX_Merge(src proto.Message) { - xxx_messageInfo_EncryptedMessage.Merge(dst, src) -} -func (m *EncryptedMessage) XXX_Size() int { - return xxx_messageInfo_EncryptedMessage.Size(m) -} -func (m *EncryptedMessage) XXX_DiscardUnknown() { - xxx_messageInfo_EncryptedMessage.DiscardUnknown(m) -} - -var xxx_messageInfo_EncryptedMessage proto.InternalMessageInfo - -func (m *EncryptedMessage) GetNonce() []byte { - if m != nil { - return m.Nonce - } - return nil -} - -func (m *EncryptedMessage) GetMessage() []byte { - if m != nil { - return m.Message - } - return nil -} - -func (m *EncryptedMessage) GetHmac() []byte { - if m != nil { - return m.Hmac - } - return nil -} - -// * -// Request: Ask device to decrypt message -// @next Success -// @next Failure -type DecryptMessage struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - Nonce []byte `protobuf:"bytes,2,opt,name=nonce" json:"nonce,omitempty"` - Message []byte `protobuf:"bytes,3,opt,name=message" json:"message,omitempty"` - Hmac []byte `protobuf:"bytes,4,opt,name=hmac" json:"hmac,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DecryptMessage) Reset() { *m = DecryptMessage{} } -func (m *DecryptMessage) String() string { return proto.CompactTextString(m) } -func (*DecryptMessage) ProtoMessage() {} -func (*DecryptMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{39} -} -func (m *DecryptMessage) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DecryptMessage.Unmarshal(m, b) -} -func (m *DecryptMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DecryptMessage.Marshal(b, m, deterministic) -} -func (dst *DecryptMessage) XXX_Merge(src proto.Message) { - xxx_messageInfo_DecryptMessage.Merge(dst, src) -} -func (m *DecryptMessage) XXX_Size() int { - return xxx_messageInfo_DecryptMessage.Size(m) -} -func (m *DecryptMessage) XXX_DiscardUnknown() { - xxx_messageInfo_DecryptMessage.DiscardUnknown(m) -} - -var xxx_messageInfo_DecryptMessage proto.InternalMessageInfo - -func (m *DecryptMessage) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -func (m *DecryptMessage) GetNonce() []byte { - if m != nil { - return m.Nonce - } - return nil -} - -func (m *DecryptMessage) GetMessage() []byte { - if m != nil { - return m.Message - } - return nil -} - -func (m *DecryptMessage) GetHmac() []byte { - if m != nil { - return m.Hmac - } - return nil -} - -// * -// Response: Decrypted message -// @prev DecryptedMessage -type DecryptedMessage struct { - Message []byte `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` - Address *string `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DecryptedMessage) Reset() { *m = DecryptedMessage{} } -func (m *DecryptedMessage) String() string { return proto.CompactTextString(m) } -func (*DecryptedMessage) ProtoMessage() {} -func (*DecryptedMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{40} -} -func (m *DecryptedMessage) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DecryptedMessage.Unmarshal(m, b) -} -func (m *DecryptedMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DecryptedMessage.Marshal(b, m, deterministic) -} -func (dst *DecryptedMessage) XXX_Merge(src proto.Message) { - xxx_messageInfo_DecryptedMessage.Merge(dst, src) -} -func (m *DecryptedMessage) XXX_Size() int { - return xxx_messageInfo_DecryptedMessage.Size(m) -} -func (m *DecryptedMessage) XXX_DiscardUnknown() { - xxx_messageInfo_DecryptedMessage.DiscardUnknown(m) -} - -var xxx_messageInfo_DecryptedMessage proto.InternalMessageInfo - -func (m *DecryptedMessage) GetMessage() []byte { - if m != nil { - return m.Message - } - return nil -} - -func (m *DecryptedMessage) GetAddress() string { - if m != nil && m.Address != nil { - return *m.Address - } - return "" -} - -// * -// Request: Ask device to encrypt or decrypt value of given key -// @next CipheredKeyValue -// @next Failure -type CipherKeyValue struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - Key *string `protobuf:"bytes,2,opt,name=key" json:"key,omitempty"` - Value []byte `protobuf:"bytes,3,opt,name=value" json:"value,omitempty"` - Encrypt *bool `protobuf:"varint,4,opt,name=encrypt" json:"encrypt,omitempty"` - AskOnEncrypt *bool `protobuf:"varint,5,opt,name=ask_on_encrypt,json=askOnEncrypt" json:"ask_on_encrypt,omitempty"` - AskOnDecrypt *bool `protobuf:"varint,6,opt,name=ask_on_decrypt,json=askOnDecrypt" json:"ask_on_decrypt,omitempty"` - Iv []byte `protobuf:"bytes,7,opt,name=iv" json:"iv,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CipherKeyValue) Reset() { *m = CipherKeyValue{} } -func (m *CipherKeyValue) String() string { return proto.CompactTextString(m) } -func (*CipherKeyValue) ProtoMessage() {} -func (*CipherKeyValue) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{41} -} -func (m *CipherKeyValue) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CipherKeyValue.Unmarshal(m, b) -} -func (m *CipherKeyValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CipherKeyValue.Marshal(b, m, deterministic) -} -func (dst *CipherKeyValue) XXX_Merge(src proto.Message) { - xxx_messageInfo_CipherKeyValue.Merge(dst, src) -} -func (m *CipherKeyValue) XXX_Size() int { - return xxx_messageInfo_CipherKeyValue.Size(m) -} -func (m *CipherKeyValue) XXX_DiscardUnknown() { - xxx_messageInfo_CipherKeyValue.DiscardUnknown(m) -} - -var xxx_messageInfo_CipherKeyValue proto.InternalMessageInfo - -func (m *CipherKeyValue) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -func (m *CipherKeyValue) GetKey() string { - if m != nil && m.Key != nil { - return *m.Key - } - return "" -} - -func (m *CipherKeyValue) GetValue() []byte { - if m != nil { - return m.Value - } - return nil -} - -func (m *CipherKeyValue) GetEncrypt() bool { - if m != nil && m.Encrypt != nil { - return *m.Encrypt - } - return false -} - -func (m *CipherKeyValue) GetAskOnEncrypt() bool { - if m != nil && m.AskOnEncrypt != nil { - return *m.AskOnEncrypt - } - return false -} - -func (m *CipherKeyValue) GetAskOnDecrypt() bool { - if m != nil && m.AskOnDecrypt != nil { - return *m.AskOnDecrypt - } - return false -} - -func (m *CipherKeyValue) GetIv() []byte { - if m != nil { - return m.Iv - } - return nil -} - -// * -// Response: Return ciphered/deciphered value -// @prev CipherKeyValue -type CipheredKeyValue struct { - Value []byte `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CipheredKeyValue) Reset() { *m = CipheredKeyValue{} } -func (m *CipheredKeyValue) String() string { return proto.CompactTextString(m) } -func (*CipheredKeyValue) ProtoMessage() {} -func (*CipheredKeyValue) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{42} -} -func (m *CipheredKeyValue) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CipheredKeyValue.Unmarshal(m, b) -} -func (m *CipheredKeyValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CipheredKeyValue.Marshal(b, m, deterministic) -} -func (dst *CipheredKeyValue) XXX_Merge(src proto.Message) { - xxx_messageInfo_CipheredKeyValue.Merge(dst, src) -} -func (m *CipheredKeyValue) XXX_Size() int { - return xxx_messageInfo_CipheredKeyValue.Size(m) -} -func (m *CipheredKeyValue) XXX_DiscardUnknown() { - xxx_messageInfo_CipheredKeyValue.DiscardUnknown(m) -} - -var xxx_messageInfo_CipheredKeyValue proto.InternalMessageInfo - -func (m *CipheredKeyValue) GetValue() []byte { - if m != nil { - return m.Value - } - return nil -} - -// * -// Request: Estimated size of the transaction -// This behaves exactly like SignTx, which means that it can ask using TxRequest -// This call is non-blocking (except possible PassphraseRequest to unlock the seed) -// @next TxSize -// @next Failure -type EstimateTxSize struct { - OutputsCount *uint32 `protobuf:"varint,1,req,name=outputs_count,json=outputsCount" json:"outputs_count,omitempty"` - InputsCount *uint32 `protobuf:"varint,2,req,name=inputs_count,json=inputsCount" json:"inputs_count,omitempty"` - CoinName *string `protobuf:"bytes,3,opt,name=coin_name,json=coinName,def=Bitcoin" json:"coin_name,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EstimateTxSize) Reset() { *m = EstimateTxSize{} } -func (m *EstimateTxSize) String() string { return proto.CompactTextString(m) } -func (*EstimateTxSize) ProtoMessage() {} -func (*EstimateTxSize) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{43} -} -func (m *EstimateTxSize) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EstimateTxSize.Unmarshal(m, b) -} -func (m *EstimateTxSize) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EstimateTxSize.Marshal(b, m, deterministic) -} -func (dst *EstimateTxSize) XXX_Merge(src proto.Message) { - xxx_messageInfo_EstimateTxSize.Merge(dst, src) -} -func (m *EstimateTxSize) XXX_Size() int { - return xxx_messageInfo_EstimateTxSize.Size(m) -} -func (m *EstimateTxSize) XXX_DiscardUnknown() { - xxx_messageInfo_EstimateTxSize.DiscardUnknown(m) -} - -var xxx_messageInfo_EstimateTxSize proto.InternalMessageInfo - -const Default_EstimateTxSize_CoinName string = "Bitcoin" - -func (m *EstimateTxSize) GetOutputsCount() uint32 { - if m != nil && m.OutputsCount != nil { - return *m.OutputsCount - } - return 0 -} - -func (m *EstimateTxSize) GetInputsCount() uint32 { - if m != nil && m.InputsCount != nil { - return *m.InputsCount - } - return 0 -} - -func (m *EstimateTxSize) GetCoinName() string { - if m != nil && m.CoinName != nil { - return *m.CoinName - } - return Default_EstimateTxSize_CoinName -} - -// * -// Response: Estimated size of the transaction -// @prev EstimateTxSize -type TxSize struct { - TxSize *uint32 `protobuf:"varint,1,opt,name=tx_size,json=txSize" json:"tx_size,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *TxSize) Reset() { *m = TxSize{} } -func (m *TxSize) String() string { return proto.CompactTextString(m) } -func (*TxSize) ProtoMessage() {} -func (*TxSize) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{44} -} -func (m *TxSize) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TxSize.Unmarshal(m, b) -} -func (m *TxSize) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TxSize.Marshal(b, m, deterministic) -} -func (dst *TxSize) XXX_Merge(src proto.Message) { - xxx_messageInfo_TxSize.Merge(dst, src) -} -func (m *TxSize) XXX_Size() int { - return xxx_messageInfo_TxSize.Size(m) -} -func (m *TxSize) XXX_DiscardUnknown() { - xxx_messageInfo_TxSize.DiscardUnknown(m) -} - -var xxx_messageInfo_TxSize proto.InternalMessageInfo - -func (m *TxSize) GetTxSize() uint32 { - if m != nil && m.TxSize != nil { - return *m.TxSize - } - return 0 -} - -// * -// Request: Ask device to sign transaction -// @next PassphraseRequest -// @next PinMatrixRequest -// @next TxRequest -// @next Failure -type SignTx struct { - OutputsCount *uint32 `protobuf:"varint,1,req,name=outputs_count,json=outputsCount" json:"outputs_count,omitempty"` - InputsCount *uint32 `protobuf:"varint,2,req,name=inputs_count,json=inputsCount" json:"inputs_count,omitempty"` - CoinName *string `protobuf:"bytes,3,opt,name=coin_name,json=coinName,def=Bitcoin" json:"coin_name,omitempty"` - Version *uint32 `protobuf:"varint,4,opt,name=version,def=1" json:"version,omitempty"` - LockTime *uint32 `protobuf:"varint,5,opt,name=lock_time,json=lockTime,def=0" json:"lock_time,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *SignTx) Reset() { *m = SignTx{} } -func (m *SignTx) String() string { return proto.CompactTextString(m) } -func (*SignTx) ProtoMessage() {} -func (*SignTx) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{45} -} -func (m *SignTx) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SignTx.Unmarshal(m, b) -} -func (m *SignTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SignTx.Marshal(b, m, deterministic) -} -func (dst *SignTx) XXX_Merge(src proto.Message) { - xxx_messageInfo_SignTx.Merge(dst, src) -} -func (m *SignTx) XXX_Size() int { - return xxx_messageInfo_SignTx.Size(m) -} -func (m *SignTx) XXX_DiscardUnknown() { - xxx_messageInfo_SignTx.DiscardUnknown(m) -} - -var xxx_messageInfo_SignTx proto.InternalMessageInfo - -const Default_SignTx_CoinName string = "Bitcoin" -const Default_SignTx_Version uint32 = 1 -const Default_SignTx_LockTime uint32 = 0 - -func (m *SignTx) GetOutputsCount() uint32 { - if m != nil && m.OutputsCount != nil { - return *m.OutputsCount - } - return 0 -} - -func (m *SignTx) GetInputsCount() uint32 { - if m != nil && m.InputsCount != nil { - return *m.InputsCount - } - return 0 -} - -func (m *SignTx) GetCoinName() string { - if m != nil && m.CoinName != nil { - return *m.CoinName - } - return Default_SignTx_CoinName -} - -func (m *SignTx) GetVersion() uint32 { - if m != nil && m.Version != nil { - return *m.Version - } - return Default_SignTx_Version -} - -func (m *SignTx) GetLockTime() uint32 { - if m != nil && m.LockTime != nil { - return *m.LockTime - } - return Default_SignTx_LockTime -} - -// * -// Request: Simplified transaction signing -// This method doesn't support streaming, so there are hardware limits in number of inputs and outputs. -// In case of success, the result is returned using TxRequest message. -// @next PassphraseRequest -// @next PinMatrixRequest -// @next TxRequest -// @next Failure -type SimpleSignTx struct { - Inputs []*TxInputType `protobuf:"bytes,1,rep,name=inputs" json:"inputs,omitempty"` - Outputs []*TxOutputType `protobuf:"bytes,2,rep,name=outputs" json:"outputs,omitempty"` - Transactions []*TransactionType `protobuf:"bytes,3,rep,name=transactions" json:"transactions,omitempty"` - CoinName *string `protobuf:"bytes,4,opt,name=coin_name,json=coinName,def=Bitcoin" json:"coin_name,omitempty"` - Version *uint32 `protobuf:"varint,5,opt,name=version,def=1" json:"version,omitempty"` - LockTime *uint32 `protobuf:"varint,6,opt,name=lock_time,json=lockTime,def=0" json:"lock_time,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *SimpleSignTx) Reset() { *m = SimpleSignTx{} } -func (m *SimpleSignTx) String() string { return proto.CompactTextString(m) } -func (*SimpleSignTx) ProtoMessage() {} -func (*SimpleSignTx) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{46} -} -func (m *SimpleSignTx) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SimpleSignTx.Unmarshal(m, b) -} -func (m *SimpleSignTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SimpleSignTx.Marshal(b, m, deterministic) -} -func (dst *SimpleSignTx) XXX_Merge(src proto.Message) { - xxx_messageInfo_SimpleSignTx.Merge(dst, src) -} -func (m *SimpleSignTx) XXX_Size() int { - return xxx_messageInfo_SimpleSignTx.Size(m) -} -func (m *SimpleSignTx) XXX_DiscardUnknown() { - xxx_messageInfo_SimpleSignTx.DiscardUnknown(m) -} - -var xxx_messageInfo_SimpleSignTx proto.InternalMessageInfo - -const Default_SimpleSignTx_CoinName string = "Bitcoin" -const Default_SimpleSignTx_Version uint32 = 1 -const Default_SimpleSignTx_LockTime uint32 = 0 - -func (m *SimpleSignTx) GetInputs() []*TxInputType { - if m != nil { - return m.Inputs - } - return nil -} - -func (m *SimpleSignTx) GetOutputs() []*TxOutputType { - if m != nil { - return m.Outputs - } - return nil -} - -func (m *SimpleSignTx) GetTransactions() []*TransactionType { - if m != nil { - return m.Transactions - } - return nil -} - -func (m *SimpleSignTx) GetCoinName() string { - if m != nil && m.CoinName != nil { - return *m.CoinName - } - return Default_SimpleSignTx_CoinName -} - -func (m *SimpleSignTx) GetVersion() uint32 { - if m != nil && m.Version != nil { - return *m.Version - } - return Default_SimpleSignTx_Version -} - -func (m *SimpleSignTx) GetLockTime() uint32 { - if m != nil && m.LockTime != nil { - return *m.LockTime - } - return Default_SimpleSignTx_LockTime -} - -// * -// Response: Device asks for information for signing transaction or returns the last result -// If request_index is set, device awaits TxAck message (with fields filled in according to request_type) -// If signature_index is set, 'signature' contains signed input of signature_index's input -// @prev SignTx -// @prev SimpleSignTx -// @prev TxAck -type TxRequest struct { - RequestType *RequestType `protobuf:"varint,1,opt,name=request_type,json=requestType,enum=RequestType" json:"request_type,omitempty"` - Details *TxRequestDetailsType `protobuf:"bytes,2,opt,name=details" json:"details,omitempty"` - Serialized *TxRequestSerializedType `protobuf:"bytes,3,opt,name=serialized" json:"serialized,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *TxRequest) Reset() { *m = TxRequest{} } -func (m *TxRequest) String() string { return proto.CompactTextString(m) } -func (*TxRequest) ProtoMessage() {} -func (*TxRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{47} -} -func (m *TxRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TxRequest.Unmarshal(m, b) -} -func (m *TxRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TxRequest.Marshal(b, m, deterministic) -} -func (dst *TxRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_TxRequest.Merge(dst, src) -} -func (m *TxRequest) XXX_Size() int { - return xxx_messageInfo_TxRequest.Size(m) -} -func (m *TxRequest) XXX_DiscardUnknown() { - xxx_messageInfo_TxRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_TxRequest proto.InternalMessageInfo - -func (m *TxRequest) GetRequestType() RequestType { - if m != nil && m.RequestType != nil { - return *m.RequestType - } - return RequestType_TXINPUT -} - -func (m *TxRequest) GetDetails() *TxRequestDetailsType { - if m != nil { - return m.Details - } - return nil -} - -func (m *TxRequest) GetSerialized() *TxRequestSerializedType { - if m != nil { - return m.Serialized - } - return nil -} - -// * -// Request: Reported transaction data -// @prev TxRequest -// @next TxRequest -type TxAck struct { - Tx *TransactionType `protobuf:"bytes,1,opt,name=tx" json:"tx,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *TxAck) Reset() { *m = TxAck{} } -func (m *TxAck) String() string { return proto.CompactTextString(m) } -func (*TxAck) ProtoMessage() {} -func (*TxAck) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{48} -} -func (m *TxAck) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TxAck.Unmarshal(m, b) -} -func (m *TxAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TxAck.Marshal(b, m, deterministic) -} -func (dst *TxAck) XXX_Merge(src proto.Message) { - xxx_messageInfo_TxAck.Merge(dst, src) -} -func (m *TxAck) XXX_Size() int { - return xxx_messageInfo_TxAck.Size(m) -} -func (m *TxAck) XXX_DiscardUnknown() { - xxx_messageInfo_TxAck.DiscardUnknown(m) -} - -var xxx_messageInfo_TxAck proto.InternalMessageInfo - -func (m *TxAck) GetTx() *TransactionType { - if m != nil { - return m.Tx - } - return nil -} - -// * -// Request: Ask device to sign transaction -// All fields are optional from the protocol's point of view. Each field defaults to value `0` if missing. -// Note: the first at most 1024 bytes of data MUST be transmitted as part of this message. -// @next PassphraseRequest -// @next PinMatrixRequest -// @next EthereumTxRequest -// @next Failure -type EthereumSignTx struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - Nonce []byte `protobuf:"bytes,2,opt,name=nonce" json:"nonce,omitempty"` - GasPrice []byte `protobuf:"bytes,3,opt,name=gas_price,json=gasPrice" json:"gas_price,omitempty"` - GasLimit []byte `protobuf:"bytes,4,opt,name=gas_limit,json=gasLimit" json:"gas_limit,omitempty"` - To []byte `protobuf:"bytes,5,opt,name=to" json:"to,omitempty"` - Value []byte `protobuf:"bytes,6,opt,name=value" json:"value,omitempty"` - DataInitialChunk []byte `protobuf:"bytes,7,opt,name=data_initial_chunk,json=dataInitialChunk" json:"data_initial_chunk,omitempty"` - DataLength *uint32 `protobuf:"varint,8,opt,name=data_length,json=dataLength" json:"data_length,omitempty"` - ChainId *uint32 `protobuf:"varint,9,opt,name=chain_id,json=chainId" json:"chain_id,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EthereumSignTx) Reset() { *m = EthereumSignTx{} } -func (m *EthereumSignTx) String() string { return proto.CompactTextString(m) } -func (*EthereumSignTx) ProtoMessage() {} -func (*EthereumSignTx) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{49} -} -func (m *EthereumSignTx) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumSignTx.Unmarshal(m, b) -} -func (m *EthereumSignTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumSignTx.Marshal(b, m, deterministic) -} -func (dst *EthereumSignTx) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumSignTx.Merge(dst, src) -} -func (m *EthereumSignTx) XXX_Size() int { - return xxx_messageInfo_EthereumSignTx.Size(m) -} -func (m *EthereumSignTx) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumSignTx.DiscardUnknown(m) -} - -var xxx_messageInfo_EthereumSignTx proto.InternalMessageInfo - -func (m *EthereumSignTx) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -func (m *EthereumSignTx) GetNonce() []byte { - if m != nil { - return m.Nonce - } - return nil -} - -func (m *EthereumSignTx) GetGasPrice() []byte { - if m != nil { - return m.GasPrice - } - return nil -} - -func (m *EthereumSignTx) GetGasLimit() []byte { - if m != nil { - return m.GasLimit - } - return nil -} - -func (m *EthereumSignTx) GetTo() []byte { - if m != nil { - return m.To - } - return nil -} - -func (m *EthereumSignTx) GetValue() []byte { - if m != nil { - return m.Value - } - return nil -} - -func (m *EthereumSignTx) GetDataInitialChunk() []byte { - if m != nil { - return m.DataInitialChunk - } - return nil -} - -func (m *EthereumSignTx) GetDataLength() uint32 { - if m != nil && m.DataLength != nil { - return *m.DataLength - } - return 0 -} - -func (m *EthereumSignTx) GetChainId() uint32 { - if m != nil && m.ChainId != nil { - return *m.ChainId - } - return 0 -} - -// * -// Response: Device asks for more data from transaction payload, or returns the signature. -// If data_length is set, device awaits that many more bytes of payload. -// Otherwise, the signature_* fields contain the computed transaction signature. All three fields will be present. -// @prev EthereumSignTx -// @next EthereumTxAck -type EthereumTxRequest struct { - DataLength *uint32 `protobuf:"varint,1,opt,name=data_length,json=dataLength" json:"data_length,omitempty"` - SignatureV *uint32 `protobuf:"varint,2,opt,name=signature_v,json=signatureV" json:"signature_v,omitempty"` - SignatureR []byte `protobuf:"bytes,3,opt,name=signature_r,json=signatureR" json:"signature_r,omitempty"` - SignatureS []byte `protobuf:"bytes,4,opt,name=signature_s,json=signatureS" json:"signature_s,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EthereumTxRequest) Reset() { *m = EthereumTxRequest{} } -func (m *EthereumTxRequest) String() string { return proto.CompactTextString(m) } -func (*EthereumTxRequest) ProtoMessage() {} -func (*EthereumTxRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{50} -} -func (m *EthereumTxRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumTxRequest.Unmarshal(m, b) -} -func (m *EthereumTxRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumTxRequest.Marshal(b, m, deterministic) -} -func (dst *EthereumTxRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumTxRequest.Merge(dst, src) -} -func (m *EthereumTxRequest) XXX_Size() int { - return xxx_messageInfo_EthereumTxRequest.Size(m) -} -func (m *EthereumTxRequest) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumTxRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_EthereumTxRequest proto.InternalMessageInfo - -func (m *EthereumTxRequest) GetDataLength() uint32 { - if m != nil && m.DataLength != nil { - return *m.DataLength - } - return 0 -} - -func (m *EthereumTxRequest) GetSignatureV() uint32 { - if m != nil && m.SignatureV != nil { - return *m.SignatureV - } - return 0 -} - -func (m *EthereumTxRequest) GetSignatureR() []byte { - if m != nil { - return m.SignatureR - } - return nil -} - -func (m *EthereumTxRequest) GetSignatureS() []byte { - if m != nil { - return m.SignatureS - } - return nil -} - -// * -// Request: Transaction payload data. -// @prev EthereumTxRequest -// @next EthereumTxRequest -type EthereumTxAck struct { - DataChunk []byte `protobuf:"bytes,1,opt,name=data_chunk,json=dataChunk" json:"data_chunk,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EthereumTxAck) Reset() { *m = EthereumTxAck{} } -func (m *EthereumTxAck) String() string { return proto.CompactTextString(m) } -func (*EthereumTxAck) ProtoMessage() {} -func (*EthereumTxAck) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{51} -} -func (m *EthereumTxAck) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumTxAck.Unmarshal(m, b) -} -func (m *EthereumTxAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumTxAck.Marshal(b, m, deterministic) -} -func (dst *EthereumTxAck) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumTxAck.Merge(dst, src) -} -func (m *EthereumTxAck) XXX_Size() int { - return xxx_messageInfo_EthereumTxAck.Size(m) -} -func (m *EthereumTxAck) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumTxAck.DiscardUnknown(m) -} - -var xxx_messageInfo_EthereumTxAck proto.InternalMessageInfo - -func (m *EthereumTxAck) GetDataChunk() []byte { - if m != nil { - return m.DataChunk - } - return nil -} - -// * -// Request: Ask device to sign message -// @next EthereumMessageSignature -// @next Failure -type EthereumSignMessage struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - Message []byte `protobuf:"bytes,2,req,name=message" json:"message,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EthereumSignMessage) Reset() { *m = EthereumSignMessage{} } -func (m *EthereumSignMessage) String() string { return proto.CompactTextString(m) } -func (*EthereumSignMessage) ProtoMessage() {} -func (*EthereumSignMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{52} -} -func (m *EthereumSignMessage) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumSignMessage.Unmarshal(m, b) -} -func (m *EthereumSignMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumSignMessage.Marshal(b, m, deterministic) -} -func (dst *EthereumSignMessage) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumSignMessage.Merge(dst, src) -} -func (m *EthereumSignMessage) XXX_Size() int { - return xxx_messageInfo_EthereumSignMessage.Size(m) -} -func (m *EthereumSignMessage) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumSignMessage.DiscardUnknown(m) -} - -var xxx_messageInfo_EthereumSignMessage proto.InternalMessageInfo - -func (m *EthereumSignMessage) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -func (m *EthereumSignMessage) GetMessage() []byte { - if m != nil { - return m.Message - } - return nil -} - -// * -// Request: Ask device to verify message -// @next Success -// @next Failure -type EthereumVerifyMessage struct { - Address []byte `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` - Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` - Message []byte `protobuf:"bytes,3,opt,name=message" json:"message,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EthereumVerifyMessage) Reset() { *m = EthereumVerifyMessage{} } -func (m *EthereumVerifyMessage) String() string { return proto.CompactTextString(m) } -func (*EthereumVerifyMessage) ProtoMessage() {} -func (*EthereumVerifyMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{53} -} -func (m *EthereumVerifyMessage) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumVerifyMessage.Unmarshal(m, b) -} -func (m *EthereumVerifyMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumVerifyMessage.Marshal(b, m, deterministic) -} -func (dst *EthereumVerifyMessage) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumVerifyMessage.Merge(dst, src) -} -func (m *EthereumVerifyMessage) XXX_Size() int { - return xxx_messageInfo_EthereumVerifyMessage.Size(m) -} -func (m *EthereumVerifyMessage) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumVerifyMessage.DiscardUnknown(m) -} - -var xxx_messageInfo_EthereumVerifyMessage proto.InternalMessageInfo - -func (m *EthereumVerifyMessage) GetAddress() []byte { - if m != nil { - return m.Address - } - return nil -} - -func (m *EthereumVerifyMessage) GetSignature() []byte { - if m != nil { - return m.Signature - } - return nil -} - -func (m *EthereumVerifyMessage) GetMessage() []byte { - if m != nil { - return m.Message - } - return nil -} - -// * -// Response: Signed message -// @prev EthereumSignMessage -type EthereumMessageSignature struct { - Address []byte `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` - Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EthereumMessageSignature) Reset() { *m = EthereumMessageSignature{} } -func (m *EthereumMessageSignature) String() string { return proto.CompactTextString(m) } -func (*EthereumMessageSignature) ProtoMessage() {} -func (*EthereumMessageSignature) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{54} -} -func (m *EthereumMessageSignature) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumMessageSignature.Unmarshal(m, b) -} -func (m *EthereumMessageSignature) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumMessageSignature.Marshal(b, m, deterministic) -} -func (dst *EthereumMessageSignature) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumMessageSignature.Merge(dst, src) -} -func (m *EthereumMessageSignature) XXX_Size() int { - return xxx_messageInfo_EthereumMessageSignature.Size(m) -} -func (m *EthereumMessageSignature) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumMessageSignature.DiscardUnknown(m) -} - -var xxx_messageInfo_EthereumMessageSignature proto.InternalMessageInfo - -func (m *EthereumMessageSignature) GetAddress() []byte { - if m != nil { - return m.Address - } - return nil -} - -func (m *EthereumMessageSignature) GetSignature() []byte { - if m != nil { - return m.Signature - } - return nil -} - -// * -// Request: Ask device to sign identity -// @next SignedIdentity -// @next Failure -type SignIdentity struct { - Identity *IdentityType `protobuf:"bytes,1,opt,name=identity" json:"identity,omitempty"` - ChallengeHidden []byte `protobuf:"bytes,2,opt,name=challenge_hidden,json=challengeHidden" json:"challenge_hidden,omitempty"` - ChallengeVisual *string `protobuf:"bytes,3,opt,name=challenge_visual,json=challengeVisual" json:"challenge_visual,omitempty"` - EcdsaCurveName *string `protobuf:"bytes,4,opt,name=ecdsa_curve_name,json=ecdsaCurveName" json:"ecdsa_curve_name,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *SignIdentity) Reset() { *m = SignIdentity{} } -func (m *SignIdentity) String() string { return proto.CompactTextString(m) } -func (*SignIdentity) ProtoMessage() {} -func (*SignIdentity) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{55} -} -func (m *SignIdentity) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SignIdentity.Unmarshal(m, b) -} -func (m *SignIdentity) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SignIdentity.Marshal(b, m, deterministic) -} -func (dst *SignIdentity) XXX_Merge(src proto.Message) { - xxx_messageInfo_SignIdentity.Merge(dst, src) -} -func (m *SignIdentity) XXX_Size() int { - return xxx_messageInfo_SignIdentity.Size(m) -} -func (m *SignIdentity) XXX_DiscardUnknown() { - xxx_messageInfo_SignIdentity.DiscardUnknown(m) -} - -var xxx_messageInfo_SignIdentity proto.InternalMessageInfo - -func (m *SignIdentity) GetIdentity() *IdentityType { - if m != nil { - return m.Identity - } - return nil -} - -func (m *SignIdentity) GetChallengeHidden() []byte { - if m != nil { - return m.ChallengeHidden - } - return nil -} - -func (m *SignIdentity) GetChallengeVisual() string { - if m != nil && m.ChallengeVisual != nil { - return *m.ChallengeVisual - } - return "" -} - -func (m *SignIdentity) GetEcdsaCurveName() string { - if m != nil && m.EcdsaCurveName != nil { - return *m.EcdsaCurveName - } - return "" -} - -// * -// Response: Device provides signed identity -// @prev SignIdentity -type SignedIdentity struct { - Address *string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` - PublicKey []byte `protobuf:"bytes,2,opt,name=public_key,json=publicKey" json:"public_key,omitempty"` - Signature []byte `protobuf:"bytes,3,opt,name=signature" json:"signature,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *SignedIdentity) Reset() { *m = SignedIdentity{} } -func (m *SignedIdentity) String() string { return proto.CompactTextString(m) } -func (*SignedIdentity) ProtoMessage() {} -func (*SignedIdentity) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{56} -} -func (m *SignedIdentity) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SignedIdentity.Unmarshal(m, b) -} -func (m *SignedIdentity) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SignedIdentity.Marshal(b, m, deterministic) -} -func (dst *SignedIdentity) XXX_Merge(src proto.Message) { - xxx_messageInfo_SignedIdentity.Merge(dst, src) -} -func (m *SignedIdentity) XXX_Size() int { - return xxx_messageInfo_SignedIdentity.Size(m) -} -func (m *SignedIdentity) XXX_DiscardUnknown() { - xxx_messageInfo_SignedIdentity.DiscardUnknown(m) -} - -var xxx_messageInfo_SignedIdentity proto.InternalMessageInfo - -func (m *SignedIdentity) GetAddress() string { - if m != nil && m.Address != nil { - return *m.Address - } - return "" -} - -func (m *SignedIdentity) GetPublicKey() []byte { - if m != nil { - return m.PublicKey - } - return nil -} - -func (m *SignedIdentity) GetSignature() []byte { - if m != nil { - return m.Signature - } - return nil -} - -// * -// Request: Ask device to generate ECDH session key -// @next ECDHSessionKey -// @next Failure -type GetECDHSessionKey struct { - Identity *IdentityType `protobuf:"bytes,1,opt,name=identity" json:"identity,omitempty"` - PeerPublicKey []byte `protobuf:"bytes,2,opt,name=peer_public_key,json=peerPublicKey" json:"peer_public_key,omitempty"` - EcdsaCurveName *string `protobuf:"bytes,3,opt,name=ecdsa_curve_name,json=ecdsaCurveName" json:"ecdsa_curve_name,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *GetECDHSessionKey) Reset() { *m = GetECDHSessionKey{} } -func (m *GetECDHSessionKey) String() string { return proto.CompactTextString(m) } -func (*GetECDHSessionKey) ProtoMessage() {} -func (*GetECDHSessionKey) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{57} -} -func (m *GetECDHSessionKey) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_GetECDHSessionKey.Unmarshal(m, b) -} -func (m *GetECDHSessionKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_GetECDHSessionKey.Marshal(b, m, deterministic) -} -func (dst *GetECDHSessionKey) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetECDHSessionKey.Merge(dst, src) -} -func (m *GetECDHSessionKey) XXX_Size() int { - return xxx_messageInfo_GetECDHSessionKey.Size(m) -} -func (m *GetECDHSessionKey) XXX_DiscardUnknown() { - xxx_messageInfo_GetECDHSessionKey.DiscardUnknown(m) -} - -var xxx_messageInfo_GetECDHSessionKey proto.InternalMessageInfo - -func (m *GetECDHSessionKey) GetIdentity() *IdentityType { - if m != nil { - return m.Identity - } - return nil -} - -func (m *GetECDHSessionKey) GetPeerPublicKey() []byte { - if m != nil { - return m.PeerPublicKey - } - return nil -} - -func (m *GetECDHSessionKey) GetEcdsaCurveName() string { - if m != nil && m.EcdsaCurveName != nil { - return *m.EcdsaCurveName - } - return "" -} - -// * -// Response: Device provides ECDH session key -// @prev GetECDHSessionKey -type ECDHSessionKey struct { - SessionKey []byte `protobuf:"bytes,1,opt,name=session_key,json=sessionKey" json:"session_key,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ECDHSessionKey) Reset() { *m = ECDHSessionKey{} } -func (m *ECDHSessionKey) String() string { return proto.CompactTextString(m) } -func (*ECDHSessionKey) ProtoMessage() {} -func (*ECDHSessionKey) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{58} -} -func (m *ECDHSessionKey) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ECDHSessionKey.Unmarshal(m, b) -} -func (m *ECDHSessionKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ECDHSessionKey.Marshal(b, m, deterministic) -} -func (dst *ECDHSessionKey) XXX_Merge(src proto.Message) { - xxx_messageInfo_ECDHSessionKey.Merge(dst, src) -} -func (m *ECDHSessionKey) XXX_Size() int { - return xxx_messageInfo_ECDHSessionKey.Size(m) -} -func (m *ECDHSessionKey) XXX_DiscardUnknown() { - xxx_messageInfo_ECDHSessionKey.DiscardUnknown(m) -} - -var xxx_messageInfo_ECDHSessionKey proto.InternalMessageInfo - -func (m *ECDHSessionKey) GetSessionKey() []byte { - if m != nil { - return m.SessionKey - } - return nil -} - -// * -// Request: Set U2F counter -// @next Success -type SetU2FCounter struct { - U2FCounter *uint32 `protobuf:"varint,1,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *SetU2FCounter) Reset() { *m = SetU2FCounter{} } -func (m *SetU2FCounter) String() string { return proto.CompactTextString(m) } -func (*SetU2FCounter) ProtoMessage() {} -func (*SetU2FCounter) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{59} -} -func (m *SetU2FCounter) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SetU2FCounter.Unmarshal(m, b) -} -func (m *SetU2FCounter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SetU2FCounter.Marshal(b, m, deterministic) -} -func (dst *SetU2FCounter) XXX_Merge(src proto.Message) { - xxx_messageInfo_SetU2FCounter.Merge(dst, src) -} -func (m *SetU2FCounter) XXX_Size() int { - return xxx_messageInfo_SetU2FCounter.Size(m) -} -func (m *SetU2FCounter) XXX_DiscardUnknown() { - xxx_messageInfo_SetU2FCounter.DiscardUnknown(m) -} - -var xxx_messageInfo_SetU2FCounter proto.InternalMessageInfo - -func (m *SetU2FCounter) GetU2FCounter() uint32 { - if m != nil && m.U2FCounter != nil { - return *m.U2FCounter - } - return 0 -} - -// * -// Request: Ask device to erase its firmware (so it can be replaced via FirmwareUpload) -// @next Success -// @next FirmwareRequest -// @next Failure -type FirmwareErase struct { - Length *uint32 `protobuf:"varint,1,opt,name=length" json:"length,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *FirmwareErase) Reset() { *m = FirmwareErase{} } -func (m *FirmwareErase) String() string { return proto.CompactTextString(m) } -func (*FirmwareErase) ProtoMessage() {} -func (*FirmwareErase) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{60} -} -func (m *FirmwareErase) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_FirmwareErase.Unmarshal(m, b) -} -func (m *FirmwareErase) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_FirmwareErase.Marshal(b, m, deterministic) -} -func (dst *FirmwareErase) XXX_Merge(src proto.Message) { - xxx_messageInfo_FirmwareErase.Merge(dst, src) -} -func (m *FirmwareErase) XXX_Size() int { - return xxx_messageInfo_FirmwareErase.Size(m) -} -func (m *FirmwareErase) XXX_DiscardUnknown() { - xxx_messageInfo_FirmwareErase.DiscardUnknown(m) -} - -var xxx_messageInfo_FirmwareErase proto.InternalMessageInfo - -func (m *FirmwareErase) GetLength() uint32 { - if m != nil && m.Length != nil { - return *m.Length - } - return 0 -} - -// * -// Response: Ask for firmware chunk -// @next FirmwareUpload -type FirmwareRequest struct { - Offset *uint32 `protobuf:"varint,1,opt,name=offset" json:"offset,omitempty"` - Length *uint32 `protobuf:"varint,2,opt,name=length" json:"length,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *FirmwareRequest) Reset() { *m = FirmwareRequest{} } -func (m *FirmwareRequest) String() string { return proto.CompactTextString(m) } -func (*FirmwareRequest) ProtoMessage() {} -func (*FirmwareRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{61} -} -func (m *FirmwareRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_FirmwareRequest.Unmarshal(m, b) -} -func (m *FirmwareRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_FirmwareRequest.Marshal(b, m, deterministic) -} -func (dst *FirmwareRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_FirmwareRequest.Merge(dst, src) -} -func (m *FirmwareRequest) XXX_Size() int { - return xxx_messageInfo_FirmwareRequest.Size(m) -} -func (m *FirmwareRequest) XXX_DiscardUnknown() { - xxx_messageInfo_FirmwareRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_FirmwareRequest proto.InternalMessageInfo - -func (m *FirmwareRequest) GetOffset() uint32 { - if m != nil && m.Offset != nil { - return *m.Offset - } - return 0 -} - -func (m *FirmwareRequest) GetLength() uint32 { - if m != nil && m.Length != nil { - return *m.Length - } - return 0 -} - -// * -// Request: Send firmware in binary form to the device -// @next Success -// @next Failure -type FirmwareUpload struct { - Payload []byte `protobuf:"bytes,1,req,name=payload" json:"payload,omitempty"` - Hash []byte `protobuf:"bytes,2,opt,name=hash" json:"hash,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *FirmwareUpload) Reset() { *m = FirmwareUpload{} } -func (m *FirmwareUpload) String() string { return proto.CompactTextString(m) } -func (*FirmwareUpload) ProtoMessage() {} -func (*FirmwareUpload) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{62} -} -func (m *FirmwareUpload) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_FirmwareUpload.Unmarshal(m, b) -} -func (m *FirmwareUpload) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_FirmwareUpload.Marshal(b, m, deterministic) -} -func (dst *FirmwareUpload) XXX_Merge(src proto.Message) { - xxx_messageInfo_FirmwareUpload.Merge(dst, src) -} -func (m *FirmwareUpload) XXX_Size() int { - return xxx_messageInfo_FirmwareUpload.Size(m) -} -func (m *FirmwareUpload) XXX_DiscardUnknown() { - xxx_messageInfo_FirmwareUpload.DiscardUnknown(m) -} - -var xxx_messageInfo_FirmwareUpload proto.InternalMessageInfo - -func (m *FirmwareUpload) GetPayload() []byte { - if m != nil { - return m.Payload - } - return nil -} - -func (m *FirmwareUpload) GetHash() []byte { - if m != nil { - return m.Hash - } - return nil -} - -// * -// Request: Perform a device self-test -// @next Success -// @next Failure -type SelfTest struct { - Payload []byte `protobuf:"bytes,1,opt,name=payload" json:"payload,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *SelfTest) Reset() { *m = SelfTest{} } -func (m *SelfTest) String() string { return proto.CompactTextString(m) } -func (*SelfTest) ProtoMessage() {} -func (*SelfTest) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{63} -} -func (m *SelfTest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SelfTest.Unmarshal(m, b) -} -func (m *SelfTest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SelfTest.Marshal(b, m, deterministic) -} -func (dst *SelfTest) XXX_Merge(src proto.Message) { - xxx_messageInfo_SelfTest.Merge(dst, src) -} -func (m *SelfTest) XXX_Size() int { - return xxx_messageInfo_SelfTest.Size(m) -} -func (m *SelfTest) XXX_DiscardUnknown() { - xxx_messageInfo_SelfTest.DiscardUnknown(m) -} - -var xxx_messageInfo_SelfTest proto.InternalMessageInfo - -func (m *SelfTest) GetPayload() []byte { - if m != nil { - return m.Payload - } - return nil -} - -// * -// Request: "Press" the button on the device -// @next Success -type DebugLinkDecision struct { - YesNo *bool `protobuf:"varint,1,req,name=yes_no,json=yesNo" json:"yes_no,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DebugLinkDecision) Reset() { *m = DebugLinkDecision{} } -func (m *DebugLinkDecision) String() string { return proto.CompactTextString(m) } -func (*DebugLinkDecision) ProtoMessage() {} -func (*DebugLinkDecision) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{64} -} -func (m *DebugLinkDecision) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DebugLinkDecision.Unmarshal(m, b) -} -func (m *DebugLinkDecision) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DebugLinkDecision.Marshal(b, m, deterministic) -} -func (dst *DebugLinkDecision) XXX_Merge(src proto.Message) { - xxx_messageInfo_DebugLinkDecision.Merge(dst, src) -} -func (m *DebugLinkDecision) XXX_Size() int { - return xxx_messageInfo_DebugLinkDecision.Size(m) -} -func (m *DebugLinkDecision) XXX_DiscardUnknown() { - xxx_messageInfo_DebugLinkDecision.DiscardUnknown(m) -} - -var xxx_messageInfo_DebugLinkDecision proto.InternalMessageInfo - -func (m *DebugLinkDecision) GetYesNo() bool { - if m != nil && m.YesNo != nil { - return *m.YesNo - } - return false -} - -// * -// Request: Computer asks for device state -// @next DebugLinkState -type DebugLinkGetState struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DebugLinkGetState) Reset() { *m = DebugLinkGetState{} } -func (m *DebugLinkGetState) String() string { return proto.CompactTextString(m) } -func (*DebugLinkGetState) ProtoMessage() {} -func (*DebugLinkGetState) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{65} -} -func (m *DebugLinkGetState) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DebugLinkGetState.Unmarshal(m, b) -} -func (m *DebugLinkGetState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DebugLinkGetState.Marshal(b, m, deterministic) -} -func (dst *DebugLinkGetState) XXX_Merge(src proto.Message) { - xxx_messageInfo_DebugLinkGetState.Merge(dst, src) -} -func (m *DebugLinkGetState) XXX_Size() int { - return xxx_messageInfo_DebugLinkGetState.Size(m) -} -func (m *DebugLinkGetState) XXX_DiscardUnknown() { - xxx_messageInfo_DebugLinkGetState.DiscardUnknown(m) -} - -var xxx_messageInfo_DebugLinkGetState proto.InternalMessageInfo - -// * -// Response: Device current state -// @prev DebugLinkGetState -type DebugLinkState struct { - Layout []byte `protobuf:"bytes,1,opt,name=layout" json:"layout,omitempty"` - Pin *string `protobuf:"bytes,2,opt,name=pin" json:"pin,omitempty"` - Matrix *string `protobuf:"bytes,3,opt,name=matrix" json:"matrix,omitempty"` - Mnemonic *string `protobuf:"bytes,4,opt,name=mnemonic" json:"mnemonic,omitempty"` - Node *HDNodeType `protobuf:"bytes,5,opt,name=node" json:"node,omitempty"` - PassphraseProtection *bool `protobuf:"varint,6,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` - ResetWord *string `protobuf:"bytes,7,opt,name=reset_word,json=resetWord" json:"reset_word,omitempty"` - ResetEntropy []byte `protobuf:"bytes,8,opt,name=reset_entropy,json=resetEntropy" json:"reset_entropy,omitempty"` - RecoveryFakeWord *string `protobuf:"bytes,9,opt,name=recovery_fake_word,json=recoveryFakeWord" json:"recovery_fake_word,omitempty"` - RecoveryWordPos *uint32 `protobuf:"varint,10,opt,name=recovery_word_pos,json=recoveryWordPos" json:"recovery_word_pos,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DebugLinkState) Reset() { *m = DebugLinkState{} } -func (m *DebugLinkState) String() string { return proto.CompactTextString(m) } -func (*DebugLinkState) ProtoMessage() {} -func (*DebugLinkState) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{66} -} -func (m *DebugLinkState) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DebugLinkState.Unmarshal(m, b) -} -func (m *DebugLinkState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DebugLinkState.Marshal(b, m, deterministic) -} -func (dst *DebugLinkState) XXX_Merge(src proto.Message) { - xxx_messageInfo_DebugLinkState.Merge(dst, src) -} -func (m *DebugLinkState) XXX_Size() int { - return xxx_messageInfo_DebugLinkState.Size(m) -} -func (m *DebugLinkState) XXX_DiscardUnknown() { - xxx_messageInfo_DebugLinkState.DiscardUnknown(m) -} - -var xxx_messageInfo_DebugLinkState proto.InternalMessageInfo - -func (m *DebugLinkState) GetLayout() []byte { - if m != nil { - return m.Layout - } - return nil -} - -func (m *DebugLinkState) GetPin() string { - if m != nil && m.Pin != nil { - return *m.Pin - } - return "" -} - -func (m *DebugLinkState) GetMatrix() string { - if m != nil && m.Matrix != nil { - return *m.Matrix - } - return "" -} - -func (m *DebugLinkState) GetMnemonic() string { - if m != nil && m.Mnemonic != nil { - return *m.Mnemonic - } - return "" -} - -func (m *DebugLinkState) GetNode() *HDNodeType { - if m != nil { - return m.Node - } - return nil -} - -func (m *DebugLinkState) GetPassphraseProtection() bool { - if m != nil && m.PassphraseProtection != nil { - return *m.PassphraseProtection - } - return false -} - -func (m *DebugLinkState) GetResetWord() string { - if m != nil && m.ResetWord != nil { - return *m.ResetWord - } - return "" -} - -func (m *DebugLinkState) GetResetEntropy() []byte { - if m != nil { - return m.ResetEntropy - } - return nil -} - -func (m *DebugLinkState) GetRecoveryFakeWord() string { - if m != nil && m.RecoveryFakeWord != nil { - return *m.RecoveryFakeWord - } - return "" -} - -func (m *DebugLinkState) GetRecoveryWordPos() uint32 { - if m != nil && m.RecoveryWordPos != nil { - return *m.RecoveryWordPos - } - return 0 -} - -// * -// Request: Ask device to restart -type DebugLinkStop struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DebugLinkStop) Reset() { *m = DebugLinkStop{} } -func (m *DebugLinkStop) String() string { return proto.CompactTextString(m) } -func (*DebugLinkStop) ProtoMessage() {} -func (*DebugLinkStop) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{67} -} -func (m *DebugLinkStop) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DebugLinkStop.Unmarshal(m, b) -} -func (m *DebugLinkStop) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DebugLinkStop.Marshal(b, m, deterministic) -} -func (dst *DebugLinkStop) XXX_Merge(src proto.Message) { - xxx_messageInfo_DebugLinkStop.Merge(dst, src) -} -func (m *DebugLinkStop) XXX_Size() int { - return xxx_messageInfo_DebugLinkStop.Size(m) -} -func (m *DebugLinkStop) XXX_DiscardUnknown() { - xxx_messageInfo_DebugLinkStop.DiscardUnknown(m) -} - -var xxx_messageInfo_DebugLinkStop proto.InternalMessageInfo - -// * -// Response: Device wants host to log event -type DebugLinkLog struct { - Level *uint32 `protobuf:"varint,1,opt,name=level" json:"level,omitempty"` - Bucket *string `protobuf:"bytes,2,opt,name=bucket" json:"bucket,omitempty"` - Text *string `protobuf:"bytes,3,opt,name=text" json:"text,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DebugLinkLog) Reset() { *m = DebugLinkLog{} } -func (m *DebugLinkLog) String() string { return proto.CompactTextString(m) } -func (*DebugLinkLog) ProtoMessage() {} -func (*DebugLinkLog) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{68} -} -func (m *DebugLinkLog) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DebugLinkLog.Unmarshal(m, b) -} -func (m *DebugLinkLog) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DebugLinkLog.Marshal(b, m, deterministic) -} -func (dst *DebugLinkLog) XXX_Merge(src proto.Message) { - xxx_messageInfo_DebugLinkLog.Merge(dst, src) -} -func (m *DebugLinkLog) XXX_Size() int { - return xxx_messageInfo_DebugLinkLog.Size(m) -} -func (m *DebugLinkLog) XXX_DiscardUnknown() { - xxx_messageInfo_DebugLinkLog.DiscardUnknown(m) -} - -var xxx_messageInfo_DebugLinkLog proto.InternalMessageInfo - -func (m *DebugLinkLog) GetLevel() uint32 { - if m != nil && m.Level != nil { - return *m.Level - } - return 0 -} - -func (m *DebugLinkLog) GetBucket() string { - if m != nil && m.Bucket != nil { - return *m.Bucket - } - return "" -} - -func (m *DebugLinkLog) GetText() string { - if m != nil && m.Text != nil { - return *m.Text - } - return "" -} - -// * -// Request: Read memory from device -// @next DebugLinkMemory -type DebugLinkMemoryRead struct { - Address *uint32 `protobuf:"varint,1,opt,name=address" json:"address,omitempty"` - Length *uint32 `protobuf:"varint,2,opt,name=length" json:"length,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DebugLinkMemoryRead) Reset() { *m = DebugLinkMemoryRead{} } -func (m *DebugLinkMemoryRead) String() string { return proto.CompactTextString(m) } -func (*DebugLinkMemoryRead) ProtoMessage() {} -func (*DebugLinkMemoryRead) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{69} -} -func (m *DebugLinkMemoryRead) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DebugLinkMemoryRead.Unmarshal(m, b) -} -func (m *DebugLinkMemoryRead) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DebugLinkMemoryRead.Marshal(b, m, deterministic) -} -func (dst *DebugLinkMemoryRead) XXX_Merge(src proto.Message) { - xxx_messageInfo_DebugLinkMemoryRead.Merge(dst, src) -} -func (m *DebugLinkMemoryRead) XXX_Size() int { - return xxx_messageInfo_DebugLinkMemoryRead.Size(m) -} -func (m *DebugLinkMemoryRead) XXX_DiscardUnknown() { - xxx_messageInfo_DebugLinkMemoryRead.DiscardUnknown(m) -} - -var xxx_messageInfo_DebugLinkMemoryRead proto.InternalMessageInfo - -func (m *DebugLinkMemoryRead) GetAddress() uint32 { - if m != nil && m.Address != nil { - return *m.Address - } - return 0 -} - -func (m *DebugLinkMemoryRead) GetLength() uint32 { - if m != nil && m.Length != nil { - return *m.Length - } - return 0 -} - -// * -// Response: Device sends memory back -// @prev DebugLinkMemoryRead -type DebugLinkMemory struct { - Memory []byte `protobuf:"bytes,1,opt,name=memory" json:"memory,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DebugLinkMemory) Reset() { *m = DebugLinkMemory{} } -func (m *DebugLinkMemory) String() string { return proto.CompactTextString(m) } -func (*DebugLinkMemory) ProtoMessage() {} -func (*DebugLinkMemory) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{70} -} -func (m *DebugLinkMemory) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DebugLinkMemory.Unmarshal(m, b) -} -func (m *DebugLinkMemory) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DebugLinkMemory.Marshal(b, m, deterministic) -} -func (dst *DebugLinkMemory) XXX_Merge(src proto.Message) { - xxx_messageInfo_DebugLinkMemory.Merge(dst, src) -} -func (m *DebugLinkMemory) XXX_Size() int { - return xxx_messageInfo_DebugLinkMemory.Size(m) -} -func (m *DebugLinkMemory) XXX_DiscardUnknown() { - xxx_messageInfo_DebugLinkMemory.DiscardUnknown(m) -} - -var xxx_messageInfo_DebugLinkMemory proto.InternalMessageInfo - -func (m *DebugLinkMemory) GetMemory() []byte { - if m != nil { - return m.Memory - } - return nil -} - -// * -// Request: Write memory to device. -// WARNING: Writing to the wrong location can irreparably break the device. -type DebugLinkMemoryWrite struct { - Address *uint32 `protobuf:"varint,1,opt,name=address" json:"address,omitempty"` - Memory []byte `protobuf:"bytes,2,opt,name=memory" json:"memory,omitempty"` - Flash *bool `protobuf:"varint,3,opt,name=flash" json:"flash,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DebugLinkMemoryWrite) Reset() { *m = DebugLinkMemoryWrite{} } -func (m *DebugLinkMemoryWrite) String() string { return proto.CompactTextString(m) } -func (*DebugLinkMemoryWrite) ProtoMessage() {} -func (*DebugLinkMemoryWrite) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{71} -} -func (m *DebugLinkMemoryWrite) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DebugLinkMemoryWrite.Unmarshal(m, b) -} -func (m *DebugLinkMemoryWrite) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DebugLinkMemoryWrite.Marshal(b, m, deterministic) -} -func (dst *DebugLinkMemoryWrite) XXX_Merge(src proto.Message) { - xxx_messageInfo_DebugLinkMemoryWrite.Merge(dst, src) -} -func (m *DebugLinkMemoryWrite) XXX_Size() int { - return xxx_messageInfo_DebugLinkMemoryWrite.Size(m) -} -func (m *DebugLinkMemoryWrite) XXX_DiscardUnknown() { - xxx_messageInfo_DebugLinkMemoryWrite.DiscardUnknown(m) -} - -var xxx_messageInfo_DebugLinkMemoryWrite proto.InternalMessageInfo - -func (m *DebugLinkMemoryWrite) GetAddress() uint32 { - if m != nil && m.Address != nil { - return *m.Address - } - return 0 -} - -func (m *DebugLinkMemoryWrite) GetMemory() []byte { - if m != nil { - return m.Memory - } - return nil -} - -func (m *DebugLinkMemoryWrite) GetFlash() bool { - if m != nil && m.Flash != nil { - return *m.Flash - } - return false -} - -// * -// Request: Erase block of flash on device -// WARNING: Writing to the wrong location can irreparably break the device. -type DebugLinkFlashErase struct { - Sector *uint32 `protobuf:"varint,1,opt,name=sector" json:"sector,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DebugLinkFlashErase) Reset() { *m = DebugLinkFlashErase{} } -func (m *DebugLinkFlashErase) String() string { return proto.CompactTextString(m) } -func (*DebugLinkFlashErase) ProtoMessage() {} -func (*DebugLinkFlashErase) Descriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{72} -} -func (m *DebugLinkFlashErase) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DebugLinkFlashErase.Unmarshal(m, b) -} -func (m *DebugLinkFlashErase) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DebugLinkFlashErase.Marshal(b, m, deterministic) -} -func (dst *DebugLinkFlashErase) XXX_Merge(src proto.Message) { - xxx_messageInfo_DebugLinkFlashErase.Merge(dst, src) -} -func (m *DebugLinkFlashErase) XXX_Size() int { - return xxx_messageInfo_DebugLinkFlashErase.Size(m) -} -func (m *DebugLinkFlashErase) XXX_DiscardUnknown() { - xxx_messageInfo_DebugLinkFlashErase.DiscardUnknown(m) -} - -var xxx_messageInfo_DebugLinkFlashErase proto.InternalMessageInfo - -func (m *DebugLinkFlashErase) GetSector() uint32 { - if m != nil && m.Sector != nil { - return *m.Sector - } - return 0 -} - -func init() { - proto.RegisterType((*Initialize)(nil), "Initialize") - proto.RegisterType((*GetFeatures)(nil), "GetFeatures") - proto.RegisterType((*Features)(nil), "Features") - proto.RegisterType((*ClearSession)(nil), "ClearSession") - proto.RegisterType((*ApplySettings)(nil), "ApplySettings") - proto.RegisterType((*ApplyFlags)(nil), "ApplyFlags") - proto.RegisterType((*ChangePin)(nil), "ChangePin") - proto.RegisterType((*Ping)(nil), "Ping") - proto.RegisterType((*Success)(nil), "Success") - proto.RegisterType((*Failure)(nil), "Failure") - proto.RegisterType((*ButtonRequest)(nil), "ButtonRequest") - proto.RegisterType((*ButtonAck)(nil), "ButtonAck") - proto.RegisterType((*PinMatrixRequest)(nil), "PinMatrixRequest") - proto.RegisterType((*PinMatrixAck)(nil), "PinMatrixAck") - proto.RegisterType((*Cancel)(nil), "Cancel") - proto.RegisterType((*PassphraseRequest)(nil), "PassphraseRequest") - proto.RegisterType((*PassphraseAck)(nil), "PassphraseAck") - proto.RegisterType((*GetEntropy)(nil), "GetEntropy") - proto.RegisterType((*Entropy)(nil), "Entropy") - proto.RegisterType((*GetPublicKey)(nil), "GetPublicKey") - proto.RegisterType((*PublicKey)(nil), "PublicKey") - proto.RegisterType((*GetAddress)(nil), "GetAddress") - proto.RegisterType((*EthereumGetAddress)(nil), "EthereumGetAddress") - proto.RegisterType((*Address)(nil), "Address") - proto.RegisterType((*EthereumAddress)(nil), "EthereumAddress") - proto.RegisterType((*WipeDevice)(nil), "WipeDevice") - proto.RegisterType((*LoadDevice)(nil), "LoadDevice") - proto.RegisterType((*ResetDevice)(nil), "ResetDevice") - proto.RegisterType((*BackupDevice)(nil), "BackupDevice") - proto.RegisterType((*EntropyRequest)(nil), "EntropyRequest") - proto.RegisterType((*EntropyAck)(nil), "EntropyAck") - proto.RegisterType((*RecoveryDevice)(nil), "RecoveryDevice") - proto.RegisterType((*WordRequest)(nil), "WordRequest") - proto.RegisterType((*WordAck)(nil), "WordAck") - proto.RegisterType((*SignMessage)(nil), "SignMessage") - proto.RegisterType((*VerifyMessage)(nil), "VerifyMessage") - proto.RegisterType((*MessageSignature)(nil), "MessageSignature") - proto.RegisterType((*EncryptMessage)(nil), "EncryptMessage") - proto.RegisterType((*EncryptedMessage)(nil), "EncryptedMessage") - proto.RegisterType((*DecryptMessage)(nil), "DecryptMessage") - proto.RegisterType((*DecryptedMessage)(nil), "DecryptedMessage") - proto.RegisterType((*CipherKeyValue)(nil), "CipherKeyValue") - proto.RegisterType((*CipheredKeyValue)(nil), "CipheredKeyValue") - proto.RegisterType((*EstimateTxSize)(nil), "EstimateTxSize") - proto.RegisterType((*TxSize)(nil), "TxSize") - proto.RegisterType((*SignTx)(nil), "SignTx") - proto.RegisterType((*SimpleSignTx)(nil), "SimpleSignTx") - proto.RegisterType((*TxRequest)(nil), "TxRequest") - proto.RegisterType((*TxAck)(nil), "TxAck") - proto.RegisterType((*EthereumSignTx)(nil), "EthereumSignTx") - proto.RegisterType((*EthereumTxRequest)(nil), "EthereumTxRequest") - proto.RegisterType((*EthereumTxAck)(nil), "EthereumTxAck") - proto.RegisterType((*EthereumSignMessage)(nil), "EthereumSignMessage") - proto.RegisterType((*EthereumVerifyMessage)(nil), "EthereumVerifyMessage") - proto.RegisterType((*EthereumMessageSignature)(nil), "EthereumMessageSignature") - proto.RegisterType((*SignIdentity)(nil), "SignIdentity") - proto.RegisterType((*SignedIdentity)(nil), "SignedIdentity") - proto.RegisterType((*GetECDHSessionKey)(nil), "GetECDHSessionKey") - proto.RegisterType((*ECDHSessionKey)(nil), "ECDHSessionKey") - proto.RegisterType((*SetU2FCounter)(nil), "SetU2FCounter") - proto.RegisterType((*FirmwareErase)(nil), "FirmwareErase") - proto.RegisterType((*FirmwareRequest)(nil), "FirmwareRequest") - proto.RegisterType((*FirmwareUpload)(nil), "FirmwareUpload") - proto.RegisterType((*SelfTest)(nil), "SelfTest") - proto.RegisterType((*DebugLinkDecision)(nil), "DebugLinkDecision") - proto.RegisterType((*DebugLinkGetState)(nil), "DebugLinkGetState") - proto.RegisterType((*DebugLinkState)(nil), "DebugLinkState") - proto.RegisterType((*DebugLinkStop)(nil), "DebugLinkStop") - proto.RegisterType((*DebugLinkLog)(nil), "DebugLinkLog") - proto.RegisterType((*DebugLinkMemoryRead)(nil), "DebugLinkMemoryRead") - proto.RegisterType((*DebugLinkMemory)(nil), "DebugLinkMemory") - proto.RegisterType((*DebugLinkMemoryWrite)(nil), "DebugLinkMemoryWrite") - proto.RegisterType((*DebugLinkFlashErase)(nil), "DebugLinkFlashErase") - proto.RegisterEnum("MessageType", MessageType_name, MessageType_value) -} - -func init() { proto.RegisterFile("messages.proto", fileDescriptor_4dc296cbfe5ffcd5) } - -var fileDescriptor_4dc296cbfe5ffcd5 = []byte{ - // 3424 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x5a, 0xcb, 0x6f, 0xdc, 0x46, - 0x9a, 0x5f, 0x76, 0xb7, 0xfa, 0xf1, 0x35, 0xbb, 0x55, 0xa2, 0x2d, 0xbb, 0x2d, 0x5b, 0xb6, 0x4c, - 0xc9, 0xb6, 0x64, 0x27, 0xed, 0x44, 0x79, 0x6c, 0xd6, 0xbb, 0x79, 0xc8, 0x7a, 0xd8, 0xde, 0xd8, - 0x8e, 0xc0, 0x56, 0x9c, 0xdb, 0x12, 0x14, 0x59, 0xea, 0xae, 0x55, 0x37, 0xc9, 0xf0, 0xa1, 0xa8, - 0x7d, 0xd8, 0xeb, 0xee, 0x65, 0x81, 0xec, 0x69, 0x73, 0x1a, 0xe4, 0x36, 0x19, 0x04, 0x18, 0x0c, - 0x30, 0x18, 0x60, 0x72, 0x9a, 0x3f, 0x60, 0xfe, 0x8b, 0x39, 0xce, 0x1f, 0x30, 0xe7, 0x41, 0x3d, - 0x48, 0x16, 0x29, 0xb6, 0x6c, 0x27, 0xc0, 0x5c, 0x04, 0xd6, 0x57, 0xbf, 0xfe, 0xea, 0x7b, 0xd5, - 0x57, 0x5f, 0x7d, 0x25, 0xe8, 0x4e, 0x70, 0x18, 0x5a, 0x43, 0x1c, 0xf6, 0xfd, 0xc0, 0x8b, 0xbc, - 0xa5, 0x76, 0x34, 0xf5, 0x93, 0x81, 0xae, 0x02, 0x3c, 0x71, 0x49, 0x44, 0xac, 0x31, 0x79, 0x89, - 0xf5, 0x0e, 0xb4, 0x1f, 0xe1, 0x68, 0x0f, 0x5b, 0x51, 0x1c, 0xe0, 0x50, 0xff, 0x69, 0x0e, 0x9a, - 0xc9, 0x40, 0xbb, 0x04, 0xf5, 0x13, 0xec, 0x3a, 0x5e, 0xd0, 0x53, 0x56, 0x94, 0xf5, 0x96, 0x21, - 0x46, 0xda, 0x2a, 0x74, 0x26, 0xd6, 0x7f, 0x7a, 0x81, 0x79, 0x82, 0x83, 0x90, 0x78, 0x6e, 0xaf, - 0xb2, 0xa2, 0xac, 0x77, 0x0c, 0x95, 0x11, 0x5f, 0x70, 0x1a, 0x03, 0x11, 0x57, 0x02, 0x55, 0x05, - 0x88, 0x12, 0x25, 0x90, 0x6f, 0x45, 0xf6, 0x28, 0x05, 0xd5, 0x38, 0x88, 0x11, 0x13, 0xd0, 0x1d, - 0x98, 0x3f, 0xf4, 0xbc, 0x68, 0xec, 0x59, 0x0e, 0x0e, 0xcc, 0x89, 0xe7, 0xe0, 0xde, 0xdc, 0x8a, - 0xb2, 0xde, 0x34, 0xba, 0x19, 0xf9, 0x99, 0xe7, 0x60, 0xed, 0x2a, 0xb4, 0x1c, 0x7c, 0x42, 0x6c, - 0x6c, 0x12, 0xa7, 0x57, 0x67, 0x22, 0x37, 0x39, 0xe1, 0x89, 0xa3, 0xdd, 0x82, 0xae, 0x4f, 0x5c, - 0x93, 0xda, 0x00, 0xdb, 0x11, 0x5d, 0xab, 0xc1, 0x98, 0x74, 0x7c, 0xe2, 0xee, 0xa7, 0x44, 0xed, - 0x3d, 0x58, 0xf4, 0xad, 0x30, 0xf4, 0x47, 0x81, 0x15, 0x62, 0x19, 0xdd, 0x64, 0xe8, 0x8b, 0xd9, - 0xa4, 0xf4, 0xa3, 0x25, 0x68, 0x8e, 0x2d, 0x77, 0x18, 0x5b, 0x43, 0xdc, 0x6b, 0xf1, 0x75, 0x93, - 0xb1, 0x76, 0x11, 0xe6, 0xc6, 0xd6, 0x21, 0x1e, 0xf7, 0x80, 0x4d, 0xf0, 0x81, 0x76, 0x03, 0xe6, - 0x6c, 0x8f, 0xb8, 0x61, 0xaf, 0xbd, 0x52, 0x5d, 0x6f, 0x6f, 0xb6, 0xfa, 0xdb, 0x1e, 0x71, 0x0f, - 0xa6, 0x3e, 0x36, 0x38, 0x5d, 0x5b, 0x81, 0x36, 0x49, 0xbd, 0xe4, 0xf4, 0x54, 0xb6, 0xba, 0x4c, - 0xa2, 0x8b, 0x06, 0xf8, 0x84, 0x30, 0xb3, 0x75, 0x56, 0x94, 0x75, 0xd5, 0x48, 0xc7, 0x05, 0x93, - 0x8d, 0xac, 0x70, 0xd4, 0xeb, 0x32, 0x88, 0x64, 0xb2, 0xc7, 0x56, 0x38, 0xa2, 0x4c, 0xc8, 0xc4, - 0xf7, 0x82, 0x08, 0x3b, 0xbd, 0x79, 0xb6, 0x46, 0x3a, 0xd6, 0x96, 0x01, 0xa8, 0xc5, 0x6c, 0xcb, - 0x1e, 0x61, 0xa7, 0x87, 0xd8, 0x6c, 0xcb, 0x27, 0xee, 0x36, 0x23, 0x68, 0xf7, 0x60, 0x41, 0xb2, - 0x94, 0x40, 0x2d, 0x30, 0x14, 0xca, 0x26, 0x04, 0x78, 0x03, 0xd0, 0x11, 0x09, 0x26, 0xdf, 0x58, - 0x01, 0x35, 0x2a, 0x0e, 0xb1, 0x1b, 0xf5, 0x34, 0x86, 0x9d, 0x4f, 0xe8, 0xfb, 0x9c, 0xac, 0xdd, - 0x04, 0xd5, 0xc5, 0xd8, 0x09, 0xcd, 0x43, 0xcb, 0x3e, 0x8e, 0xfd, 0xde, 0x05, 0xae, 0x3a, 0xa3, - 0x3d, 0x64, 0x24, 0x6a, 0xd3, 0xa3, 0xb1, 0x35, 0x0c, 0x7b, 0x17, 0x59, 0xb8, 0xf0, 0x81, 0xde, - 0x05, 0x75, 0x7b, 0x8c, 0xad, 0x60, 0x80, 0x43, 0x6a, 0x04, 0xfd, 0x7f, 0x14, 0xe8, 0x6c, 0xf9, - 0xfe, 0x78, 0x3a, 0xc0, 0x51, 0x44, 0xdc, 0x61, 0x98, 0xf3, 0x93, 0x32, 0xcb, 0x4f, 0x15, 0xd9, - 0x4f, 0xb7, 0xa0, 0x1b, 0xd3, 0x38, 0x48, 0xf5, 0x61, 0x61, 0xdc, 0x34, 0x3a, 0x71, 0x88, 0xf7, - 0x53, 0xa2, 0x76, 0x1d, 0x60, 0xe4, 0x4d, 0x70, 0x68, 0x07, 0x18, 0xf3, 0x20, 0x56, 0x0d, 0x89, - 0xa2, 0xeb, 0x00, 0x4c, 0x92, 0x3d, 0x2a, 0x68, 0x26, 0xbe, 0x22, 0x8b, 0xbf, 0x0a, 0xad, 0xed, - 0x91, 0xe5, 0x0e, 0xf1, 0x3e, 0x71, 0xe9, 0xd6, 0x0b, 0xf0, 0xc4, 0x3b, 0xe1, 0x72, 0x36, 0x0d, - 0x31, 0xd2, 0x7f, 0xa3, 0x40, 0x6d, 0x9f, 0xb8, 0x43, 0xad, 0x07, 0x0d, 0xb1, 0xc9, 0x85, 0x26, - 0xc9, 0x90, 0xfa, 0xe5, 0x30, 0x8e, 0x22, 0x2f, 0x17, 0xeb, 0x15, 0xee, 0x17, 0x3e, 0x21, 0x45, - 0xee, 0xd9, 0x5d, 0x51, 0x7d, 0xa3, 0x5d, 0x51, 0x9b, 0xbd, 0x2b, 0xf4, 0x55, 0x68, 0x0c, 0x62, - 0xdb, 0xc6, 0x61, 0x38, 0x5b, 0x5a, 0x7d, 0x17, 0x1a, 0x7b, 0x16, 0x19, 0xc7, 0x01, 0xd6, 0x56, - 0xa0, 0x66, 0xd3, 0xcd, 0x4d, 0x11, 0xdd, 0x4d, 0xb5, 0x2f, 0xe8, 0x6c, 0x57, 0xb0, 0x19, 0x99, - 0x4d, 0x25, 0xcf, 0xe6, 0x73, 0xe8, 0x3c, 0x64, 0xba, 0x19, 0xf8, 0xeb, 0x18, 0x87, 0x91, 0x76, - 0x3b, 0xc7, 0x4c, 0xeb, 0xe7, 0x66, 0x25, 0x96, 0x1a, 0xd4, 0x1c, 0x2b, 0xb2, 0x04, 0x3f, 0xf6, - 0xad, 0xb7, 0xa1, 0xc5, 0xe1, 0x5b, 0xf6, 0xb1, 0xfe, 0x31, 0xa0, 0x7d, 0xe2, 0x3e, 0xb3, 0xa2, - 0x80, 0x9c, 0x26, 0xcc, 0x37, 0xa0, 0x46, 0x33, 0xaa, 0x60, 0xbe, 0xd8, 0x2f, 0x02, 0x38, 0x7f, - 0x0a, 0xd1, 0x57, 0x40, 0x4d, 0x67, 0xb7, 0xec, 0x63, 0x0d, 0x41, 0xd5, 0x27, 0x6e, 0x4f, 0x59, - 0xa9, 0xac, 0xb7, 0x0c, 0xfa, 0xa9, 0x37, 0xa1, 0xbe, 0x6d, 0xb9, 0x36, 0x1e, 0xeb, 0x17, 0x60, - 0x21, 0x8b, 0x29, 0xc1, 0x4a, 0xbf, 0x0f, 0x9d, 0x8c, 0x48, 0x39, 0x5c, 0x07, 0x90, 0xc2, 0x91, - 0x33, 0x92, 0x28, 0xfa, 0x0a, 0xc0, 0x23, 0x1c, 0xed, 0xba, 0x51, 0xe0, 0xf9, 0x53, 0xaa, 0x5f, - 0x48, 0x5e, 0x72, 0x5c, 0xc7, 0x60, 0xdf, 0xd4, 0x31, 0xc9, 0x74, 0x0f, 0x1a, 0x98, 0x7f, 0x32, - 0x84, 0x6a, 0x24, 0x43, 0xfd, 0x57, 0x0a, 0xa8, 0x8f, 0x70, 0xb4, 0x1f, 0x1f, 0x8e, 0x89, 0xfd, - 0x39, 0x9e, 0xd2, 0xec, 0x6a, 0x39, 0x4e, 0x80, 0xc3, 0xd0, 0xa4, 0xf2, 0x57, 0xd7, 0x3b, 0x46, - 0x53, 0x10, 0x9e, 0x6b, 0xeb, 0x80, 0xb0, 0xed, 0x84, 0x96, 0x69, 0xc7, 0xc1, 0x09, 0x36, 0x5d, - 0x6b, 0x92, 0xb8, 0xa8, 0xcb, 0xe8, 0xdb, 0x94, 0xfc, 0xdc, 0x9a, 0x60, 0xba, 0xbd, 0xc3, 0x91, - 0xf7, 0x8d, 0xe9, 0x90, 0xd0, 0x1f, 0x5b, 0x53, 0x11, 0x6f, 0x6d, 0x4a, 0xdb, 0xe1, 0x24, 0x6d, - 0x0d, 0x5a, 0x34, 0x09, 0x72, 0x2e, 0x34, 0xc2, 0x5a, 0x0f, 0x1a, 0x0f, 0x49, 0x44, 0x69, 0x46, - 0x93, 0xfe, 0xa5, 0x8c, 0xf4, 0xcf, 0xa0, 0x95, 0x09, 0x77, 0x03, 0x6a, 0x2e, 0x77, 0x77, 0x65, - 0xbd, 0xbd, 0xd9, 0xee, 0x3f, 0xde, 0x79, 0xee, 0x39, 0x22, 0x74, 0x5c, 0xe1, 0xe7, 0x53, 0x3f, - 0x3e, 0x4c, 0xfc, 0x4c, 0xbf, 0xf5, 0xbf, 0x2a, 0xcc, 0x54, 0x5b, 0x5c, 0x89, 0xf3, 0x15, 0xcc, - 0xc9, 0x54, 0x99, 0x21, 0xd3, 0xeb, 0x28, 0xf7, 0x01, 0x34, 0x27, 0xf1, 0x38, 0x22, 0x21, 0x19, - 0x32, 0xdd, 0xda, 0x9b, 0x57, 0xfa, 0xcf, 0x04, 0xc1, 0xc0, 0x0e, 0xc6, 0x93, 0x81, 0x1d, 0x10, - 0x9f, 0xc7, 0x50, 0x0a, 0xd5, 0x3e, 0x85, 0x76, 0xc8, 0xe8, 0x26, 0x8b, 0xbc, 0x39, 0x16, 0x79, - 0xa8, 0xff, 0xc4, 0xf5, 0xe3, 0x28, 0xfb, 0xc1, 0x03, 0x75, 0xb0, 0xbf, 0xfb, 0x7c, 0x67, 0x6b, - 0x67, 0xc7, 0xd8, 0x1d, 0x0c, 0x0c, 0x08, 0xd3, 0x19, 0xfd, 0x00, 0xb4, 0xdd, 0x68, 0x84, 0x03, - 0x1c, 0x4f, 0x5e, 0x57, 0xe7, 0xa2, 0x36, 0x95, 0x33, 0xda, 0xd0, 0x50, 0x4a, 0x58, 0xf5, 0xa0, - 0x21, 0x7e, 0x29, 0x82, 0x32, 0x19, 0xea, 0xf7, 0x60, 0x3e, 0x59, 0x7a, 0x06, 0x58, 0xcd, 0xc0, - 0x2a, 0xc0, 0x57, 0xc4, 0xc7, 0x3b, 0xec, 0xdc, 0xd6, 0xff, 0xaf, 0x02, 0xf0, 0xd4, 0xb3, 0x1c, - 0x3e, 0xa4, 0x09, 0x7c, 0xe2, 0xe2, 0x89, 0xe7, 0x12, 0x3b, 0x49, 0xe0, 0xc9, 0x38, 0x0d, 0x81, - 0x0a, 0x33, 0x6a, 0x49, 0x08, 0x88, 0xad, 0x57, 0x65, 0xbf, 0xa3, 0x9f, 0x3f, 0x2b, 0xad, 0x69, - 0xab, 0xd2, 0x21, 0x32, 0xc7, 0x03, 0x01, 0xbb, 0xc3, 0x31, 0x09, 0x47, 0x65, 0xa7, 0x49, 0x5d, - 0x3e, 0x4d, 0x56, 0xa1, 0x13, 0x1e, 0x13, 0xdf, 0xb4, 0x47, 0xd8, 0x3e, 0x0e, 0xe3, 0x89, 0x28, - 0x41, 0x54, 0x4a, 0xdc, 0x16, 0x34, 0xed, 0x06, 0xb4, 0xe3, 0xcd, 0x23, 0xd3, 0xf6, 0x62, 0x37, - 0xc2, 0x01, 0xab, 0x3b, 0x3a, 0x06, 0xc4, 0x9b, 0x47, 0xdb, 0x9c, 0xa2, 0xff, 0xb6, 0x02, 0x6d, - 0x03, 0x87, 0x38, 0x12, 0x46, 0xb9, 0x05, 0x5d, 0xe1, 0x21, 0x33, 0xb0, 0x5c, 0xc7, 0x9b, 0x88, - 0x33, 0xa3, 0x23, 0xa8, 0x06, 0x23, 0x6a, 0x37, 0xa0, 0x19, 0x46, 0x01, 0x76, 0x87, 0xd1, 0x88, - 0x17, 0x6c, 0x0f, 0xaa, 0x9b, 0x1f, 0x7c, 0x68, 0xa4, 0xc4, 0xd9, 0xd6, 0xa8, 0x9e, 0x63, 0x8d, - 0xb3, 0x07, 0x48, 0xad, 0xec, 0x00, 0xf9, 0x05, 0x46, 0x2b, 0xd8, 0xa3, 0x51, 0xb4, 0x07, 0x05, - 0x30, 0xab, 0x8a, 0x7a, 0x81, 0x17, 0x6a, 0x40, 0x49, 0xbc, 0x5c, 0xa0, 0x85, 0x01, 0xff, 0x12, - 0x41, 0x85, 0xa0, 0x2b, 0xf2, 0x5f, 0x92, 0x64, 0x6f, 0x03, 0x08, 0x0a, 0xcd, 0xb0, 0xb9, 0xa4, - 0xa8, 0xc8, 0x49, 0xf1, 0x4f, 0x15, 0xe8, 0x1a, 0xd8, 0xf6, 0x4e, 0x70, 0x30, 0x15, 0xd6, 0x5f, - 0x06, 0xf8, 0xc6, 0x0b, 0x1c, 0x2e, 0x9f, 0x38, 0xd1, 0x5b, 0x94, 0xc2, 0xc4, 0x9b, 0x6d, 0xd4, - 0xca, 0x1b, 0x19, 0xb5, 0xfa, 0x2a, 0xa3, 0xd6, 0x5e, 0x69, 0xd4, 0x39, 0xd9, 0xa8, 0x1b, 0x80, - 0xb0, 0x7b, 0xe4, 0x05, 0x36, 0x36, 0xa9, 0xac, 0x63, 0x12, 0x46, 0xcc, 0xea, 0x4d, 0x63, 0x5e, - 0xd0, 0xbf, 0x12, 0x64, 0x9a, 0x39, 0x59, 0xca, 0xe1, 0x81, 0xc8, 0xbe, 0x8b, 0x3e, 0x69, 0x9d, - 0xf1, 0xc9, 0x65, 0x68, 0x38, 0xc1, 0xd4, 0x0c, 0x62, 0x97, 0xd5, 0xbd, 0x4d, 0xa3, 0xee, 0x04, - 0x53, 0x23, 0x76, 0xf5, 0xf7, 0xa0, 0x4d, 0x39, 0x27, 0x27, 0xe9, 0x5a, 0xee, 0x24, 0x45, 0x7d, - 0x69, 0x4e, 0x3a, 0x44, 0x97, 0xa1, 0x41, 0x27, 0xa8, 0x6f, 0x34, 0xa8, 0x51, 0x81, 0x45, 0x8a, - 0x61, 0xdf, 0xfa, 0x8f, 0x0a, 0xb4, 0x07, 0x64, 0xe8, 0x3e, 0x13, 0x15, 0xd0, 0xb9, 0x49, 0x2d, - 0x57, 0x43, 0xb0, 0xcc, 0x93, 0x14, 0x4e, 0xb9, 0x14, 0x5f, 0x9d, 0x95, 0xe2, 0x0b, 0x89, 0xb8, - 0xf6, 0xc6, 0x89, 0xf8, 0xbf, 0x15, 0xe8, 0xbc, 0xc0, 0x01, 0x39, 0x9a, 0x26, 0xf2, 0xe6, 0x92, - 0xa1, 0x22, 0x65, 0x4e, 0xed, 0x1a, 0xb4, 0x42, 0x32, 0x74, 0xd9, 0x7d, 0x8c, 0x45, 0x8c, 0x6a, - 0x64, 0x04, 0x59, 0x95, 0x2a, 0x8f, 0xd3, 0x52, 0x55, 0x66, 0x9e, 0xa0, 0xff, 0x0e, 0x48, 0x88, - 0x30, 0x90, 0x79, 0xfe, 0x1c, 0x59, 0xf4, 0x1f, 0x14, 0xba, 0xa9, 0xec, 0x60, 0xea, 0x47, 0x89, - 0x5a, 0x97, 0xa0, 0xee, 0xc7, 0x87, 0xc7, 0x38, 0xd9, 0x45, 0x62, 0x54, 0xac, 0xe2, 0x24, 0xb1, - 0x6f, 0x82, 0x9a, 0x64, 0x32, 0xcf, 0x1d, 0xa7, 0xc7, 0xa7, 0xa0, 0x7d, 0xe1, 0x8e, 0x0b, 0x55, - 0x48, 0xed, 0xbc, 0x43, 0x7a, 0x6e, 0x96, 0xda, 0x2f, 0x00, 0x09, 0x49, 0xb1, 0x93, 0xc8, 0x7a, - 0x11, 0xe6, 0x5c, 0xcf, 0xb5, 0xb1, 0x10, 0x95, 0x0f, 0xce, 0x91, 0x54, 0x83, 0xda, 0x68, 0x62, - 0xd9, 0xc2, 0xee, 0xec, 0x5b, 0xff, 0x1a, 0xba, 0x3b, 0x38, 0x67, 0x81, 0x73, 0x03, 0x31, 0x5d, - 0xb2, 0x32, 0x63, 0xc9, 0x6a, 0xf9, 0x92, 0x35, 0x69, 0xc9, 0x3d, 0x40, 0x62, 0xc9, 0x4c, 0x95, - 0x42, 0xad, 0x2d, 0x71, 0x90, 0x7c, 0x5b, 0xc9, 0xf9, 0x56, 0xff, 0xb3, 0x02, 0xdd, 0x6d, 0xe2, - 0x8f, 0x70, 0xf0, 0x39, 0x9e, 0xbe, 0xb0, 0xc6, 0xf1, 0x2b, 0x64, 0x47, 0x50, 0xa5, 0x7e, 0xe5, - 0x5c, 0xe8, 0x27, 0xd5, 0xe6, 0x84, 0xfe, 0x4e, 0x48, 0xcd, 0x07, 0x3c, 0x93, 0x32, 0xf9, 0xc4, - 0xb1, 0x90, 0x0c, 0xb5, 0x35, 0xe8, 0x5a, 0xe1, 0xb1, 0xe9, 0xb9, 0x66, 0x02, 0xe0, 0x77, 0x7a, - 0xd5, 0x0a, 0x8f, 0xbf, 0x70, 0x77, 0xcf, 0xa0, 0x1c, 0xae, 0xa6, 0x48, 0x52, 0x1c, 0x25, 0x54, - 0xd7, 0xba, 0x50, 0x21, 0x27, 0xec, 0x60, 0x50, 0x8d, 0x0a, 0x39, 0xd1, 0xd7, 0x01, 0x71, 0x65, - 0xb0, 0x93, 0xaa, 0x93, 0xca, 0xa7, 0x48, 0xf2, 0xe9, 0xff, 0x05, 0xdd, 0xdd, 0x30, 0x22, 0x13, - 0x2b, 0xc2, 0x07, 0xa7, 0x03, 0xf2, 0x12, 0xd3, 0x23, 0xda, 0x8b, 0x23, 0x3f, 0x8e, 0xc2, 0x34, - 0xa3, 0xd3, 0xc2, 0x59, 0x15, 0x44, 0x9e, 0xd4, 0x6f, 0x82, 0x4a, 0x5c, 0x09, 0x53, 0x61, 0x98, - 0x36, 0xa7, 0x71, 0xc8, 0x6b, 0x25, 0x13, 0xfd, 0x26, 0xd4, 0xc5, 0xba, 0x97, 0xa1, 0x11, 0x9d, - 0x9a, 0xa2, 0x54, 0xa7, 0xd9, 0xb4, 0x1e, 0xb1, 0x09, 0xfd, 0xf7, 0x0a, 0xd4, 0xe9, 0xf6, 0x3c, - 0x38, 0xfd, 0xc7, 0xca, 0xa6, 0x5d, 0x85, 0x46, 0xae, 0x2b, 0xf3, 0x40, 0x79, 0xd7, 0x48, 0x28, - 0xda, 0x75, 0x68, 0x8d, 0x3d, 0xfb, 0xd8, 0x8c, 0x88, 0xd8, 0x69, 0x9d, 0x07, 0xca, 0x3b, 0x46, - 0x93, 0xd2, 0x0e, 0xc8, 0x04, 0xeb, 0x7f, 0x53, 0x40, 0x1d, 0x90, 0x89, 0x3f, 0xc6, 0x42, 0xf6, - 0x35, 0xa8, 0x73, 0x11, 0x58, 0x2c, 0xb5, 0x37, 0xd5, 0xfe, 0xc1, 0x29, 0xcb, 0x99, 0x2c, 0xcd, - 0x8b, 0x39, 0xed, 0x0e, 0x34, 0x84, 0x32, 0xbd, 0x0a, 0x83, 0x75, 0xfa, 0x07, 0xa7, 0x5f, 0x30, - 0x0a, 0xc3, 0x25, 0xb3, 0xda, 0xfb, 0xa0, 0x46, 0x81, 0xe5, 0x86, 0x16, 0x3b, 0x09, 0xc3, 0x5e, - 0x95, 0xa1, 0x51, 0xff, 0x20, 0x23, 0xb2, 0x1f, 0xe4, 0x50, 0xaf, 0x97, 0x16, 0x65, 0xc5, 0xe7, - 0xce, 0x57, 0xbc, 0x7e, 0x56, 0xf1, 0x5f, 0x2b, 0xd0, 0x3a, 0x48, 0x2f, 0x8a, 0xf7, 0x41, 0x0d, - 0xf8, 0xa7, 0x29, 0x1d, 0x73, 0x6a, 0x5f, 0x3e, 0xe2, 0xda, 0x41, 0x36, 0xd0, 0xee, 0x43, 0xc3, - 0xc1, 0x91, 0x45, 0xc6, 0xa1, 0xa8, 0x63, 0x17, 0xfb, 0x29, 0xb7, 0x1d, 0x3e, 0xc1, 0x0d, 0x21, - 0x50, 0xda, 0x47, 0x00, 0x21, 0x0e, 0x92, 0x36, 0x51, 0x95, 0xfd, 0xa6, 0x97, 0xfd, 0x66, 0x90, - 0xce, 0xb1, 0x9f, 0x49, 0x58, 0x7d, 0x03, 0xe6, 0x0e, 0xd8, 0x95, 0x74, 0x05, 0x2a, 0xd1, 0x29, - 0x13, 0xad, 0xcc, 0x82, 0x95, 0xe8, 0x54, 0xff, 0xdf, 0x0a, 0x74, 0x93, 0x0a, 0x5e, 0xf8, 0xf3, - 0x67, 0xa4, 0xb6, 0xab, 0xd0, 0x1a, 0x5a, 0xa1, 0xe9, 0x07, 0xc4, 0x4e, 0xd2, 0x44, 0x73, 0x68, - 0x85, 0xfb, 0x74, 0x9c, 0x4c, 0x8e, 0xc9, 0x84, 0x44, 0x22, 0xc5, 0xd1, 0xc9, 0xa7, 0x74, 0x4c, - 0x37, 0x78, 0xe4, 0x31, 0x67, 0xa8, 0x46, 0x25, 0xf2, 0xb2, 0xcd, 0x5c, 0x97, 0x93, 0xcd, 0x5b, - 0xa0, 0xd1, 0xeb, 0xbb, 0x29, 0x9a, 0x64, 0xa6, 0x3d, 0x8a, 0xdd, 0x63, 0x91, 0x16, 0x10, 0x9d, - 0x11, 0x6d, 0xcf, 0x6d, 0x4a, 0xa7, 0x25, 0x0c, 0x43, 0x8f, 0x79, 0x45, 0x2c, 0xca, 0x6c, 0x4a, - 0x7a, 0xca, 0xcb, 0xe1, 0x2b, 0xd0, 0xb4, 0x47, 0x16, 0x71, 0x4d, 0xe2, 0x88, 0x02, 0xa7, 0xc1, - 0xc6, 0x4f, 0x1c, 0xfd, 0xff, 0x15, 0x58, 0x48, 0xec, 0x91, 0x39, 0xbb, 0xc0, 0x51, 0x39, 0xc3, - 0x91, 0x16, 0xaa, 0xc9, 0x81, 0x69, 0x9e, 0x88, 0xae, 0x29, 0xa4, 0xa4, 0x17, 0x79, 0x40, 0x20, - 0x6c, 0x94, 0x01, 0x8c, 0x3c, 0x20, 0x4c, 0x1a, 0x4d, 0x29, 0x69, 0xa0, 0xf7, 0xa1, 0x93, 0x09, - 0x46, 0x9d, 0xbb, 0x0c, 0x4c, 0x02, 0x61, 0x0c, 0x9e, 0xfc, 0x5a, 0x94, 0xc2, 0xac, 0xa0, 0x3f, - 0x85, 0x0b, 0xb2, 0x63, 0x7f, 0x59, 0x05, 0xa5, 0x13, 0x58, 0x4c, 0xb8, 0x9d, 0x5b, 0xe1, 0xa8, - 0xbf, 0xb8, 0xc2, 0xd1, 0x0d, 0xe8, 0x25, 0x4b, 0xbd, 0xaa, 0x86, 0x79, 0xdd, 0xd5, 0xf4, 0x9f, - 0x58, 0xd2, 0x1a, 0xba, 0x4f, 0x1c, 0xec, 0x46, 0x24, 0x9a, 0x6a, 0x1b, 0xd0, 0x24, 0xe2, 0x5b, - 0xec, 0x8f, 0x4e, 0x3f, 0x99, 0xe4, 0xf7, 0x73, 0x92, 0x41, 0x91, 0x3d, 0xb2, 0xc6, 0xd4, 0xf7, - 0xd8, 0x1c, 0x11, 0xc7, 0xc1, 0xae, 0x58, 0x60, 0x3e, 0xa5, 0x3f, 0x66, 0xe4, 0x3c, 0xf4, 0x84, - 0x84, 0xb1, 0x35, 0x16, 0x97, 0xd2, 0x0c, 0xfa, 0x82, 0x91, 0x4b, 0xdb, 0x2a, 0xb5, 0xb2, 0xb6, - 0x8a, 0x3e, 0x84, 0x2e, 0x15, 0x1d, 0x3b, 0xa9, 0xf0, 0xb3, 0x2b, 0xb9, 0x65, 0x00, 0x9f, 0x75, - 0x4e, 0xcc, 0xe4, 0x10, 0x57, 0x8d, 0x96, 0x9f, 0xf6, 0x52, 0x72, 0x46, 0xaa, 0x16, 0x8d, 0xf4, - 0xad, 0x02, 0x0b, 0x8f, 0x70, 0xb4, 0xbb, 0xbd, 0xf3, 0x58, 0x34, 0x5a, 0xe9, 0x6f, 0xde, 0xc0, - 0x52, 0xb7, 0x61, 0xde, 0xc7, 0x38, 0x30, 0xcf, 0x88, 0xd0, 0xa1, 0xe4, 0xac, 0xa5, 0x53, 0xa6, - 0x7b, 0xb5, 0x54, 0xf7, 0x77, 0xa1, 0x5b, 0x10, 0x87, 0xee, 0x13, 0x3e, 0x32, 0xb3, 0xfa, 0x13, - 0xc2, 0x14, 0xa0, 0xbf, 0x03, 0x9d, 0x01, 0x8e, 0xbe, 0xdc, 0xdc, 0x93, 0x2e, 0x91, 0xf2, 0x8d, - 0x46, 0x39, 0x73, 0xeb, 0xbe, 0x03, 0x9d, 0x3d, 0xd1, 0xa9, 0xde, 0x65, 0x3d, 0xdf, 0x4b, 0x50, - 0xcf, 0xed, 0x74, 0x31, 0xd2, 0xb7, 0x60, 0x3e, 0x01, 0x26, 0x99, 0xe1, 0x12, 0xd4, 0xbd, 0xa3, - 0xa3, 0x10, 0x27, 0xf7, 0x43, 0x31, 0x92, 0x58, 0x54, 0x72, 0x2c, 0x3e, 0x81, 0x6e, 0xc2, 0xe2, - 0x4b, 0x7f, 0xec, 0x59, 0x0e, 0x75, 0xa6, 0x6f, 0x4d, 0xe9, 0x67, 0xd2, 0x2f, 0x11, 0x43, 0x56, - 0x16, 0x5a, 0xe1, 0x48, 0xd8, 0x90, 0x7d, 0xeb, 0x6b, 0xd0, 0x1c, 0xe0, 0xf1, 0xd1, 0x01, 0x5d, - 0x3b, 0xf7, 0x4b, 0x45, 0xfa, 0xa5, 0x7e, 0x17, 0x16, 0x76, 0xf0, 0x61, 0x3c, 0x7c, 0x4a, 0xdc, - 0xe3, 0x1d, 0x6c, 0xf3, 0x97, 0x83, 0x45, 0xa8, 0x4f, 0x71, 0x68, 0xba, 0x1e, 0x5b, 0xa7, 0x69, - 0xcc, 0x4d, 0x71, 0xf8, 0xdc, 0xd3, 0x2f, 0x48, 0xd8, 0x47, 0x38, 0x1a, 0x44, 0x56, 0x84, 0xf5, - 0xbf, 0x54, 0x68, 0xc5, 0x2b, 0xa8, 0x8c, 0xc4, 0x34, 0xb2, 0xa6, 0x5e, 0x1c, 0x25, 0x35, 0x3f, - 0x1f, 0x25, 0xbd, 0x97, 0x4a, 0xd6, 0x7b, 0xb9, 0x04, 0xf5, 0x09, 0xeb, 0x8a, 0x0a, 0xa7, 0x8a, - 0x51, 0xae, 0xc5, 0x53, 0x9b, 0xd1, 0xe2, 0x99, 0x9b, 0xd5, 0xe2, 0x99, 0x79, 0xdb, 0xae, 0x9f, - 0x73, 0xdb, 0x5e, 0x06, 0x08, 0x70, 0x88, 0x23, 0x76, 0x13, 0x66, 0xe7, 0x45, 0xcb, 0x68, 0x31, - 0x0a, 0xbd, 0x74, 0xd2, 0xaa, 0x8b, 0x4f, 0x27, 0x3d, 0x81, 0x26, 0xd3, 0x4c, 0x65, 0xc4, 0xa4, - 0x8f, 0xfa, 0x16, 0x68, 0x81, 0xe8, 0x0b, 0x98, 0x47, 0xd6, 0x31, 0xbf, 0x55, 0x8b, 0xb7, 0x20, - 0x94, 0xcc, 0xec, 0x59, 0xc7, 0xec, 0x5a, 0xad, 0xdd, 0x85, 0x85, 0x14, 0xcd, 0x9a, 0x07, 0xbe, - 0x17, 0xb2, 0x7b, 0x72, 0xc7, 0x98, 0x4f, 0x26, 0x28, 0x70, 0xdf, 0x0b, 0xf5, 0x79, 0xe8, 0x48, - 0x36, 0xf6, 0x7c, 0x7d, 0x1f, 0xd4, 0x94, 0xf0, 0xd4, 0x1b, 0xb2, 0x0b, 0x3e, 0x3e, 0xc1, 0xe3, - 0xe4, 0x35, 0x81, 0x0d, 0xa8, 0x79, 0x0f, 0x63, 0xfb, 0x18, 0x47, 0xc2, 0xe6, 0x62, 0xc4, 0x6e, - 0xf3, 0xf8, 0x34, 0x12, 0x46, 0x67, 0xdf, 0xfa, 0x23, 0xb8, 0x90, 0x72, 0x7c, 0x86, 0x27, 0x5e, - 0x30, 0x35, 0x30, 0x8f, 0x39, 0x39, 0x81, 0x74, 0xb2, 0x04, 0x32, 0x2b, 0x6e, 0x37, 0x60, 0xbe, - 0xc0, 0x88, 0xb9, 0x99, 0x7d, 0x25, 0x01, 0xc1, 0x47, 0xfa, 0x7f, 0xc0, 0xc5, 0x02, 0xf4, 0xab, - 0x80, 0x44, 0xf8, 0xfc, 0x45, 0x05, 0xa7, 0x8a, 0xcc, 0x49, 0xbc, 0xa6, 0x84, 0x23, 0x71, 0x5b, - 0xe4, 0x03, 0xfd, 0x6d, 0x49, 0xa7, 0x3d, 0x4a, 0x49, 0x37, 0x6d, 0x88, 0xed, 0xc8, 0x4b, 0x76, - 0xb8, 0x18, 0xdd, 0xfd, 0x71, 0x11, 0xda, 0xe2, 0x1c, 0x61, 0x75, 0xd8, 0x0a, 0x5c, 0x92, 0x86, - 0x66, 0xf6, 0x60, 0x8a, 0xfe, 0x69, 0xa9, 0xf6, 0xed, 0x1f, 0x7a, 0x8a, 0xb6, 0x94, 0x5e, 0x9e, - 0x19, 0x62, 0x9f, 0xb8, 0x43, 0xa4, 0x88, 0xb9, 0x65, 0xb8, 0x20, 0xcf, 0x89, 0x57, 0x10, 0x54, - 0x59, 0xaa, 0x7d, 0x57, 0x32, 0x2d, 0xde, 0x39, 0x50, 0x55, 0x4c, 0xdf, 0x80, 0x45, 0x79, 0x3a, - 0x7d, 0x14, 0x42, 0x35, 0xc1, 0xbe, 0x20, 0x5c, 0xd6, 0x2e, 0x45, 0x73, 0x02, 0x71, 0x07, 0xae, - 0xe4, 0x56, 0x90, 0x13, 0x17, 0xaa, 0x2f, 0x35, 0x29, 0xe8, 0x8f, 0x14, 0xb8, 0x0e, 0x4b, 0x65, - 0x40, 0x9e, 0x75, 0x50, 0x43, 0x42, 0x6e, 0xc0, 0xd5, 0x32, 0xa4, 0x48, 0x71, 0xa8, 0xb9, 0xd4, - 0xfc, 0x2e, 0x81, 0x16, 0xe4, 0xcb, 0x5e, 0x23, 0x50, 0xab, 0xdc, 0x40, 0xc9, 0x34, 0x08, 0x0b, - 0xe8, 0xd0, 0x2b, 0x30, 0x48, 0x8f, 0x05, 0xd4, 0x16, 0x2c, 0x0a, 0x56, 0xca, 0x00, 0xaa, 0x60, - 0x52, 0x90, 0x22, 0xeb, 0x22, 0xa3, 0x8e, 0x60, 0x71, 0x13, 0x2e, 0xcb, 0x08, 0xa9, 0xa7, 0x8a, - 0xba, 0x02, 0x72, 0x0d, 0xb4, 0x9c, 0x27, 0x59, 0xf1, 0x8b, 0xe6, 0xc5, 0xec, 0x5a, 0x5e, 0x4e, - 0xf9, 0xc2, 0x83, 0xd0, 0x52, 0x9d, 0x62, 0x9a, 0x8a, 0x76, 0x1d, 0x2e, 0xe6, 0x2c, 0x27, 0x9e, - 0xd7, 0xd1, 0x82, 0x10, 0xf4, 0x36, 0x5c, 0x2b, 0x44, 0x52, 0xee, 0x31, 0x09, 0x69, 0x29, 0xae, - 0x57, 0x8a, 0xdb, 0xb2, 0x8f, 0xd1, 0x05, 0xee, 0xa9, 0xdf, 0x95, 0xc8, 0xcc, 0x1f, 0x97, 0xd0, - 0xc5, 0x72, 0xbb, 0xa5, 0xe5, 0x2b, 0x5a, 0x14, 0xcb, 0x5c, 0x85, 0x85, 0x3c, 0x80, 0xf2, 0xbf, - 0x94, 0x6a, 0x9c, 0x8b, 0x97, 0x7c, 0xcf, 0x00, 0x5d, 0x16, 0xa8, 0x82, 0xff, 0xe4, 0x57, 0x59, - 0xd4, 0x13, 0x98, 0xd5, 0x7c, 0x88, 0xe6, 0x1e, 0x6a, 0xd1, 0x95, 0x72, 0x50, 0xee, 0x11, 0x0f, - 0x2d, 0x09, 0x81, 0x57, 0xf3, 0x1a, 0xa5, 0x4f, 0x77, 0xe8, 0xaa, 0x64, 0x94, 0x42, 0x34, 0x64, - 0xaf, 0xb1, 0xe8, 0x5a, 0xf9, 0xae, 0xca, 0x1e, 0x49, 0xd0, 0x72, 0x79, 0xd4, 0x26, 0xd3, 0xd7, - 0xd3, 0xa8, 0xcd, 0xf9, 0x39, 0x39, 0x81, 0xd1, 0x8a, 0xb4, 0x8b, 0x0a, 0x96, 0x91, 0xdb, 0xd2, - 0x48, 0x2f, 0xb7, 0x71, 0xbe, 0x55, 0x8d, 0x56, 0xcb, 0xc3, 0x3b, 0x6b, 0x5f, 0xa3, 0xb5, 0xf2, - 0xf0, 0x96, 0xea, 0x7b, 0x74, 0xbb, 0xdc, 0xbe, 0xb9, 0xa2, 0x1d, 0xdd, 0x11, 0xa0, 0x42, 0x7c, - 0x16, 0xcb, 0x6d, 0xb4, 0x2e, 0x24, 0xba, 0x03, 0xcb, 0xb9, 0xf8, 0x2c, 0x3e, 0x65, 0xa2, 0x8d, - 0x14, 0x78, 0xa5, 0x1c, 0x48, 0xa5, 0xbf, 0x2b, 0x39, 0xed, 0x76, 0xc1, 0x12, 0xb9, 0x56, 0x0d, - 0xba, 0x27, 0xed, 0x30, 0x2d, 0x1f, 0xb2, 0x6c, 0xfe, 0xad, 0xa5, 0xfa, 0x77, 0x7c, 0xbe, 0x60, - 0xd1, 0x7c, 0x07, 0x1f, 0xbd, 0x5d, 0x6e, 0x2f, 0xa9, 0x15, 0x8d, 0xfa, 0xe5, 0x99, 0x5b, 0x34, - 0xa5, 0xd1, 0xfd, 0x72, 0x4b, 0x15, 0x9b, 0x50, 0xe8, 0x9d, 0x74, 0x27, 0x17, 0x3c, 0x2c, 0x77, - 0x0d, 0xd1, 0xbb, 0xa9, 0x5e, 0xeb, 0x79, 0x7e, 0xc5, 0xae, 0x25, 0xda, 0x4c, 0x35, 0x2c, 0x70, - 0xcc, 0xf7, 0x21, 0xd1, 0x7b, 0xb3, 0x38, 0x16, 0x9b, 0x87, 0xe8, 0xfd, 0x94, 0xa3, 0x5e, 0xcc, - 0x6d, 0xd9, 0xbd, 0x08, 0x7d, 0x50, 0x1e, 0xa9, 0xf9, 0x0b, 0x08, 0xfa, 0x50, 0x68, 0x5b, 0xb0, - 0xab, 0xf4, 0xef, 0x46, 0xe8, 0x9f, 0x05, 0xa3, 0x75, 0xb8, 0x9e, 0x53, 0xf4, 0xcc, 0x43, 0x25, - 0xfa, 0x48, 0x20, 0x6f, 0xe5, 0x8f, 0xa1, 0xc2, 0xbb, 0x22, 0xfa, 0x17, 0xb1, 0x66, 0x71, 0x0f, - 0xe5, 0x9a, 0x17, 0xe8, 0x41, 0x7a, 0x4c, 0x2e, 0x97, 0xa1, 0xb2, 0x9c, 0xf8, 0xaf, 0x69, 0x8a, - 0xb9, 0x52, 0x0e, 0xa4, 0xde, 0xff, 0xb7, 0x72, 0x6e, 0x67, 0x2e, 0x49, 0xe8, 0xe3, 0x19, 0x1b, - 0x3c, 0x8f, 0xfa, 0xa4, 0x7c, 0xcd, 0xdc, 0x75, 0x05, 0x7d, 0x2a, 0x58, 0x6d, 0xc0, 0x8d, 0x59, - 0x7a, 0x26, 0x2e, 0xfd, 0x4c, 0x40, 0xef, 0xc1, 0xcd, 0x32, 0x68, 0x7e, 0xcf, 0x6f, 0x09, 0x70, - 0x1f, 0xd6, 0xca, 0xc0, 0x67, 0xf6, 0xfe, 0x43, 0x21, 0xec, 0xbd, 0xbc, 0xee, 0x67, 0xee, 0x15, - 0xc8, 0x59, 0x6a, 0x7e, 0x9f, 0x6c, 0xeb, 0x3b, 0x33, 0xc0, 0xc9, 0xc5, 0x02, 0xe1, 0xa5, 0xda, - 0xf7, 0x25, 0x86, 0xca, 0xdf, 0x35, 0xd0, 0xd1, 0x52, 0xed, 0x87, 0x12, 0x43, 0xe5, 0xaa, 0x65, - 0x34, 0x14, 0xac, 0x0a, 0xe1, 0x2c, 0x57, 0xd0, 0x68, 0x24, 0x18, 0x15, 0x8c, 0x59, 0x52, 0x13, - 0x23, 0x57, 0xb0, 0x2b, 0x84, 0x61, 0x01, 0x8a, 0x3c, 0xc1, 0xf1, 0x2e, 0xac, 0x9c, 0x03, 0x63, - 0x15, 0x2f, 0xf2, 0x05, 0xcb, 0x59, 0xab, 0x67, 0xd5, 0x2b, 0xfa, 0x9a, 0x43, 0x1f, 0xbe, 0x0f, - 0xab, 0xb6, 0x37, 0xe9, 0x87, 0x56, 0xe4, 0x85, 0x23, 0x32, 0xb6, 0x0e, 0xc3, 0x7e, 0x14, 0xe0, - 0x97, 0x5e, 0xd0, 0x1f, 0x93, 0x43, 0xfe, 0x6f, 0x7e, 0x87, 0xf1, 0xd1, 0xc3, 0xce, 0x01, 0x23, - 0x0a, 0xae, 0x7f, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x2a, 0xe4, 0xc0, 0x85, 0x16, 0x28, 0x00, 0x00, -} diff --git a/client/accounts/usbwallet/internal/trezor/messages.proto b/client/accounts/usbwallet/internal/trezor/messages.proto deleted file mode 100644 index 8cb9c8cc2..000000000 --- a/client/accounts/usbwallet/internal/trezor/messages.proto +++ /dev/null @@ -1,905 +0,0 @@ -// This file originates from the SatoshiLabs Trezor `common` repository at: -// https://github.com/trezor/trezor-common/blob/master/protob/messages.proto -// dated 28.07.2017, commit dd8ec3231fb5f7992360aff9bdfe30bb58130f4b. - -syntax = "proto2"; - -/** - * Messages for TREZOR communication - */ - -// Sugar for easier handling in Java -option java_package = "com.satoshilabs.trezor.lib.protobuf"; -option java_outer_classname = "TrezorMessage"; - -import "types.proto"; - -/** - * Mapping between Trezor wire identifier (uint) and a protobuf message - */ -enum MessageType { - MessageType_Initialize = 0 [(wire_in) = true]; - MessageType_Ping = 1 [(wire_in) = true]; - MessageType_Success = 2 [(wire_out) = true]; - MessageType_Failure = 3 [(wire_out) = true]; - MessageType_ChangePin = 4 [(wire_in) = true]; - MessageType_WipeDevice = 5 [(wire_in) = true]; - MessageType_FirmwareErase = 6 [(wire_in) = true, (wire_bootloader) = true]; - MessageType_FirmwareUpload = 7 [(wire_in) = true, (wire_bootloader) = true]; - MessageType_FirmwareRequest = 8 [(wire_out) = true, (wire_bootloader) = true]; - MessageType_GetEntropy = 9 [(wire_in) = true]; - MessageType_Entropy = 10 [(wire_out) = true]; - MessageType_GetPublicKey = 11 [(wire_in) = true]; - MessageType_PublicKey = 12 [(wire_out) = true]; - MessageType_LoadDevice = 13 [(wire_in) = true]; - MessageType_ResetDevice = 14 [(wire_in) = true]; - MessageType_SignTx = 15 [(wire_in) = true]; - MessageType_SimpleSignTx = 16 [(wire_in) = true, deprecated = true]; - MessageType_Features = 17 [(wire_out) = true]; - MessageType_PinMatrixRequest = 18 [(wire_out) = true]; - MessageType_PinMatrixAck = 19 [(wire_in) = true, (wire_tiny) = true]; - MessageType_Cancel = 20 [(wire_in) = true]; - MessageType_TxRequest = 21 [(wire_out) = true]; - MessageType_TxAck = 22 [(wire_in) = true]; - MessageType_CipherKeyValue = 23 [(wire_in) = true]; - MessageType_ClearSession = 24 [(wire_in) = true]; - MessageType_ApplySettings = 25 [(wire_in) = true]; - MessageType_ButtonRequest = 26 [(wire_out) = true]; - MessageType_ButtonAck = 27 [(wire_in) = true, (wire_tiny) = true]; - MessageType_ApplyFlags = 28 [(wire_in) = true]; - MessageType_GetAddress = 29 [(wire_in) = true]; - MessageType_Address = 30 [(wire_out) = true]; - MessageType_SelfTest = 32 [(wire_in) = true, (wire_bootloader) = true]; - MessageType_BackupDevice = 34 [(wire_in) = true]; - MessageType_EntropyRequest = 35 [(wire_out) = true]; - MessageType_EntropyAck = 36 [(wire_in) = true]; - MessageType_SignMessage = 38 [(wire_in) = true]; - MessageType_VerifyMessage = 39 [(wire_in) = true]; - MessageType_MessageSignature = 40 [(wire_out) = true]; - MessageType_PassphraseRequest = 41 [(wire_out) = true]; - MessageType_PassphraseAck = 42 [(wire_in) = true, (wire_tiny) = true]; - MessageType_EstimateTxSize = 43 [(wire_in) = true, deprecated = true]; - MessageType_TxSize = 44 [(wire_out) = true, deprecated = true]; - MessageType_RecoveryDevice = 45 [(wire_in) = true]; - MessageType_WordRequest = 46 [(wire_out) = true]; - MessageType_WordAck = 47 [(wire_in) = true]; - MessageType_CipheredKeyValue = 48 [(wire_out) = true]; - MessageType_EncryptMessage = 49 [(wire_in) = true, deprecated = true]; - MessageType_EncryptedMessage = 50 [(wire_out) = true, deprecated = true]; - MessageType_DecryptMessage = 51 [(wire_in) = true, deprecated = true]; - MessageType_DecryptedMessage = 52 [(wire_out) = true, deprecated = true]; - MessageType_SignIdentity = 53 [(wire_in) = true]; - MessageType_SignedIdentity = 54 [(wire_out) = true]; - MessageType_GetFeatures = 55 [(wire_in) = true]; - MessageType_EthereumGetAddress = 56 [(wire_in) = true]; - MessageType_EthereumAddress = 57 [(wire_out) = true]; - MessageType_EthereumSignTx = 58 [(wire_in) = true]; - MessageType_EthereumTxRequest = 59 [(wire_out) = true]; - MessageType_EthereumTxAck = 60 [(wire_in) = true]; - MessageType_GetECDHSessionKey = 61 [(wire_in) = true]; - MessageType_ECDHSessionKey = 62 [(wire_out) = true]; - MessageType_SetU2FCounter = 63 [(wire_in) = true]; - MessageType_EthereumSignMessage = 64 [(wire_in) = true]; - MessageType_EthereumVerifyMessage = 65 [(wire_in) = true]; - MessageType_EthereumMessageSignature = 66 [(wire_out) = true]; - MessageType_DebugLinkDecision = 100 [(wire_debug_in) = true, (wire_tiny) = true]; - MessageType_DebugLinkGetState = 101 [(wire_debug_in) = true]; - MessageType_DebugLinkState = 102 [(wire_debug_out) = true]; - MessageType_DebugLinkStop = 103 [(wire_debug_in) = true]; - MessageType_DebugLinkLog = 104 [(wire_debug_out) = true]; - MessageType_DebugLinkMemoryRead = 110 [(wire_debug_in) = true]; - MessageType_DebugLinkMemory = 111 [(wire_debug_out) = true]; - MessageType_DebugLinkMemoryWrite = 112 [(wire_debug_in) = true]; - MessageType_DebugLinkFlashErase = 113 [(wire_debug_in) = true]; -} - -//////////////////// -// Basic messages // -//////////////////// - -/** - * Request: Reset device to default state and ask for device details - * @next Features - */ -message Initialize { -} - -/** - * Request: Ask for device details (no device reset) - * @next Features - */ -message GetFeatures { -} - -/** - * Response: Reports various information about the device - * @prev Initialize - * @prev GetFeatures - */ -message Features { - optional string vendor = 1; // name of the manufacturer, e.g. "bitcointrezor.com" - optional uint32 major_version = 2; // major version of the device, e.g. 1 - optional uint32 minor_version = 3; // minor version of the device, e.g. 0 - optional uint32 patch_version = 4; // patch version of the device, e.g. 0 - optional bool bootloader_mode = 5; // is device in bootloader mode? - optional string device_id = 6; // device's unique identifier - optional bool pin_protection = 7; // is device protected by PIN? - optional bool passphrase_protection = 8; // is node/mnemonic encrypted using passphrase? - optional string language = 9; // device language - optional string label = 10; // device description label - repeated CoinType coins = 11; // supported coins - optional bool initialized = 12; // does device contain seed? - optional bytes revision = 13; // SCM revision of firmware - optional bytes bootloader_hash = 14; // hash of the bootloader - optional bool imported = 15; // was storage imported from an external source? - optional bool pin_cached = 16; // is PIN already cached in session? - optional bool passphrase_cached = 17; // is passphrase already cached in session? - optional bool firmware_present = 18; // is valid firmware loaded? - optional bool needs_backup = 19; // does storage need backup? (equals to Storage.needs_backup) - optional uint32 flags = 20; // device flags (equals to Storage.flags) -} - -/** - * Request: clear session (removes cached PIN, passphrase, etc). - * @next Success - */ -message ClearSession { -} - -/** - * Request: change language and/or label of the device - * @next Success - * @next Failure - * @next ButtonRequest - * @next PinMatrixRequest - */ -message ApplySettings { - optional string language = 1; - optional string label = 2; - optional bool use_passphrase = 3; - optional bytes homescreen = 4; -} - -/** - * Request: set flags of the device - * @next Success - * @next Failure - */ -message ApplyFlags { - optional uint32 flags = 1; // bitmask, can only set bits, not unset -} - -/** - * Request: Starts workflow for setting/changing/removing the PIN - * @next ButtonRequest - * @next PinMatrixRequest - */ -message ChangePin { - optional bool remove = 1; // is PIN removal requested? -} - -/** - * Request: Test if the device is alive, device sends back the message in Success response - * @next Success - */ -message Ping { - optional string message = 1; // message to send back in Success message - optional bool button_protection = 2; // ask for button press - optional bool pin_protection = 3; // ask for PIN if set in device - optional bool passphrase_protection = 4; // ask for passphrase if set in device -} - -/** - * Response: Success of the previous request - */ -message Success { - optional string message = 1; // human readable description of action or request-specific payload -} - -/** - * Response: Failure of the previous request - */ -message Failure { - optional FailureType code = 1; // computer-readable definition of the error state - optional string message = 2; // human-readable message of the error state -} - -/** - * Response: Device is waiting for HW button press. - * @next ButtonAck - * @next Cancel - */ -message ButtonRequest { - optional ButtonRequestType code = 1; - optional string data = 2; -} - -/** - * Request: Computer agrees to wait for HW button press - * @prev ButtonRequest - */ -message ButtonAck { -} - -/** - * Response: Device is asking computer to show PIN matrix and awaits PIN encoded using this matrix scheme - * @next PinMatrixAck - * @next Cancel - */ -message PinMatrixRequest { - optional PinMatrixRequestType type = 1; -} - -/** - * Request: Computer responds with encoded PIN - * @prev PinMatrixRequest - */ -message PinMatrixAck { - required string pin = 1; // matrix encoded PIN entered by user -} - -/** - * Request: Abort last operation that required user interaction - * @prev ButtonRequest - * @prev PinMatrixRequest - * @prev PassphraseRequest - */ -message Cancel { -} - -/** - * Response: Device awaits encryption passphrase - * @next PassphraseAck - * @next Cancel - */ -message PassphraseRequest { -} - -/** - * Request: Send passphrase back - * @prev PassphraseRequest - */ -message PassphraseAck { - required string passphrase = 1; -} - -/** - * Request: Request a sample of random data generated by hardware RNG. May be used for testing. - * @next ButtonRequest - * @next Entropy - * @next Failure - */ -message GetEntropy { - required uint32 size = 1; // size of requested entropy -} - -/** - * Response: Reply with random data generated by internal RNG - * @prev GetEntropy - */ -message Entropy { - required bytes entropy = 1; // stream of random generated bytes -} - -/** - * Request: Ask device for public key corresponding to address_n path - * @next PassphraseRequest - * @next PublicKey - * @next Failure - */ -message GetPublicKey { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional string ecdsa_curve_name = 2; // ECDSA curve name to use - optional bool show_display = 3; // optionally show on display before sending the result - optional string coin_name = 4 [default='Bitcoin']; -} - -/** - * Response: Contains public key derived from device private seed - * @prev GetPublicKey - */ -message PublicKey { - required HDNodeType node = 1; // BIP32 public node - optional string xpub = 2; // serialized form of public node -} - -/** - * Request: Ask device for address corresponding to address_n path - * @next PassphraseRequest - * @next Address - * @next Failure - */ -message GetAddress { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional string coin_name = 2 [default='Bitcoin']; - optional bool show_display = 3 ; // optionally show on display before sending the result - optional MultisigRedeemScriptType multisig = 4; // filled if we are showing a multisig address - optional InputScriptType script_type = 5 [default=SPENDADDRESS]; // used to distinguish between various address formats (non-segwit, segwit, etc.) -} - -/** - * Request: Ask device for Ethereum address corresponding to address_n path - * @next PassphraseRequest - * @next EthereumAddress - * @next Failure - */ -message EthereumGetAddress { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional bool show_display = 2; // optionally show on display before sending the result -} - -/** - * Response: Contains address derived from device private seed - * @prev GetAddress - */ -message Address { - required string address = 1; // Coin address in Base58 encoding -} - -/** - * Response: Contains an Ethereum address derived from device private seed - * @prev EthereumGetAddress - */ -message EthereumAddress { - required bytes address = 1; // Coin address as an Ethereum 160 bit hash -} - -/** - * Request: Request device to wipe all sensitive data and settings - * @next ButtonRequest - */ -message WipeDevice { -} - -/** - * Request: Load seed and related internal settings from the computer - * @next ButtonRequest - * @next Success - * @next Failure - */ -message LoadDevice { - optional string mnemonic = 1; // seed encoded as BIP-39 mnemonic (12, 18 or 24 words) - optional HDNodeType node = 2; // BIP-32 node - optional string pin = 3; // set PIN protection - optional bool passphrase_protection = 4; // enable master node encryption using passphrase - optional string language = 5 [default='english']; // device language - optional string label = 6; // device label - optional bool skip_checksum = 7; // do not test mnemonic for valid BIP-39 checksum - optional uint32 u2f_counter = 8; // U2F counter -} - -/** - * Request: Ask device to do initialization involving user interaction - * @next EntropyRequest - * @next Failure - */ -message ResetDevice { - optional bool display_random = 1; // display entropy generated by the device before asking for additional entropy - optional uint32 strength = 2 [default=256]; // strength of seed in bits - optional bool passphrase_protection = 3; // enable master node encryption using passphrase - optional bool pin_protection = 4; // enable PIN protection - optional string language = 5 [default='english']; // device language - optional string label = 6; // device label - optional uint32 u2f_counter = 7; // U2F counter - optional bool skip_backup = 8; // postpone seed backup to BackupDevice workflow -} - -/** - * Request: Perform backup of the device seed if not backed up using ResetDevice - * @next ButtonRequest - */ -message BackupDevice { -} - -/** - * Response: Ask for additional entropy from host computer - * @prev ResetDevice - * @next EntropyAck - */ -message EntropyRequest { -} - -/** - * Request: Provide additional entropy for seed generation function - * @prev EntropyRequest - * @next ButtonRequest - */ -message EntropyAck { - optional bytes entropy = 1; // 256 bits (32 bytes) of random data -} - -/** - * Request: Start recovery workflow asking user for specific words of mnemonic - * Used to recovery device safely even on untrusted computer. - * @next WordRequest - */ -message RecoveryDevice { - optional uint32 word_count = 1; // number of words in BIP-39 mnemonic - optional bool passphrase_protection = 2; // enable master node encryption using passphrase - optional bool pin_protection = 3; // enable PIN protection - optional string language = 4 [default='english']; // device language - optional string label = 5; // device label - optional bool enforce_wordlist = 6; // enforce BIP-39 wordlist during the process - // 7 reserved for unused recovery method - optional uint32 type = 8; // supported recovery type (see RecoveryType) - optional uint32 u2f_counter = 9; // U2F counter - optional bool dry_run = 10; // perform dry-run recovery workflow (for safe mnemonic validation) -} - -/** - * Response: Device is waiting for user to enter word of the mnemonic - * Its position is shown only on device's internal display. - * @prev RecoveryDevice - * @prev WordAck - */ -message WordRequest { - optional WordRequestType type = 1; -} - -/** - * Request: Computer replies with word from the mnemonic - * @prev WordRequest - * @next WordRequest - * @next Success - * @next Failure - */ -message WordAck { - required string word = 1; // one word of mnemonic on asked position -} - -////////////////////////////// -// Message signing messages // -////////////////////////////// - -/** - * Request: Ask device to sign message - * @next MessageSignature - * @next Failure - */ -message SignMessage { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - required bytes message = 2; // message to be signed - optional string coin_name = 3 [default='Bitcoin']; // coin to use for signing - optional InputScriptType script_type = 4 [default=SPENDADDRESS]; // used to distinguish between various address formats (non-segwit, segwit, etc.) -} - -/** - * Request: Ask device to verify message - * @next Success - * @next Failure - */ -message VerifyMessage { - optional string address = 1; // address to verify - optional bytes signature = 2; // signature to verify - optional bytes message = 3; // message to verify - optional string coin_name = 4 [default='Bitcoin']; // coin to use for verifying -} - -/** - * Response: Signed message - * @prev SignMessage - */ -message MessageSignature { - optional string address = 1; // address used to sign the message - optional bytes signature = 2; // signature of the message -} - -/////////////////////////// -// Encryption/decryption // -/////////////////////////// - -/** - * Request: Ask device to encrypt message - * @next EncryptedMessage - * @next Failure - */ -message EncryptMessage { - optional bytes pubkey = 1; // public key - optional bytes message = 2; // message to encrypt - optional bool display_only = 3; // show just on display? (don't send back via wire) - repeated uint32 address_n = 4; // BIP-32 path to derive the signing key from master node - optional string coin_name = 5 [default='Bitcoin']; // coin to use for signing -} - -/** - * Response: Encrypted message - * @prev EncryptMessage - */ -message EncryptedMessage { - optional bytes nonce = 1; // nonce used during encryption - optional bytes message = 2; // encrypted message - optional bytes hmac = 3; // message hmac -} - -/** - * Request: Ask device to decrypt message - * @next Success - * @next Failure - */ -message DecryptMessage { - repeated uint32 address_n = 1; // BIP-32 path to derive the decryption key from master node - optional bytes nonce = 2; // nonce used during encryption - optional bytes message = 3; // message to decrypt - optional bytes hmac = 4; // message hmac -} - -/** - * Response: Decrypted message - * @prev DecryptedMessage - */ -message DecryptedMessage { - optional bytes message = 1; // decrypted message - optional string address = 2; // address used to sign the message (if used) -} - -/** - * Request: Ask device to encrypt or decrypt value of given key - * @next CipheredKeyValue - * @next Failure - */ -message CipherKeyValue { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional string key = 2; // key component of key:value - optional bytes value = 3; // value component of key:value - optional bool encrypt = 4; // are we encrypting (True) or decrypting (False)? - optional bool ask_on_encrypt = 5; // should we ask on encrypt operation? - optional bool ask_on_decrypt = 6; // should we ask on decrypt operation? - optional bytes iv = 7; // initialization vector (will be computed if not set) -} - -/** - * Response: Return ciphered/deciphered value - * @prev CipherKeyValue - */ -message CipheredKeyValue { - optional bytes value = 1; // ciphered/deciphered value -} - -////////////////////////////////// -// Transaction signing messages // -////////////////////////////////// - -/** - * Request: Estimated size of the transaction - * This behaves exactly like SignTx, which means that it can ask using TxRequest - * This call is non-blocking (except possible PassphraseRequest to unlock the seed) - * @next TxSize - * @next Failure - */ -message EstimateTxSize { - required uint32 outputs_count = 1; // number of transaction outputs - required uint32 inputs_count = 2; // number of transaction inputs - optional string coin_name = 3 [default='Bitcoin']; // coin to use -} - -/** - * Response: Estimated size of the transaction - * @prev EstimateTxSize - */ -message TxSize { - optional uint32 tx_size = 1; // estimated size of transaction in bytes -} - -/** - * Request: Ask device to sign transaction - * @next PassphraseRequest - * @next PinMatrixRequest - * @next TxRequest - * @next Failure - */ -message SignTx { - required uint32 outputs_count = 1; // number of transaction outputs - required uint32 inputs_count = 2; // number of transaction inputs - optional string coin_name = 3 [default='Bitcoin']; // coin to use - optional uint32 version = 4 [default=1]; // transaction version - optional uint32 lock_time = 5 [default=0]; // transaction lock_time -} - -/** - * Request: Simplified transaction signing - * This method doesn't support streaming, so there are hardware limits in number of inputs and outputs. - * In case of success, the result is returned using TxRequest message. - * @next PassphraseRequest - * @next PinMatrixRequest - * @next TxRequest - * @next Failure - */ -message SimpleSignTx { - repeated TxInputType inputs = 1; // transaction inputs - repeated TxOutputType outputs = 2; // transaction outputs - repeated TransactionType transactions = 3; // transactions whose outputs are used to build current inputs - optional string coin_name = 4 [default='Bitcoin']; // coin to use - optional uint32 version = 5 [default=1]; // transaction version - optional uint32 lock_time = 6 [default=0]; // transaction lock_time -} - -/** - * Response: Device asks for information for signing transaction or returns the last result - * If request_index is set, device awaits TxAck message (with fields filled in according to request_type) - * If signature_index is set, 'signature' contains signed input of signature_index's input - * @prev SignTx - * @prev SimpleSignTx - * @prev TxAck - */ -message TxRequest { - optional RequestType request_type = 1; // what should be filled in TxAck message? - optional TxRequestDetailsType details = 2; // request for tx details - optional TxRequestSerializedType serialized = 3; // serialized data and request for next -} - -/** - * Request: Reported transaction data - * @prev TxRequest - * @next TxRequest - */ -message TxAck { - optional TransactionType tx = 1; -} - -/** - * Request: Ask device to sign transaction - * All fields are optional from the protocol's point of view. Each field defaults to value `0` if missing. - * Note: the first at most 1024 bytes of data MUST be transmitted as part of this message. - * @next PassphraseRequest - * @next PinMatrixRequest - * @next EthereumTxRequest - * @next Failure - */ -message EthereumSignTx { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional bytes nonce = 2; // <=256 bit unsigned big endian - optional bytes gas_price = 3; // <=256 bit unsigned big endian (in wei) - optional bytes gas_limit = 4; // <=256 bit unsigned big endian - optional bytes to = 5; // 160 bit address hash - optional bytes value = 6; // <=256 bit unsigned big endian (in wei) - optional bytes data_initial_chunk = 7; // The initial data chunk (<= 1024 bytes) - optional uint32 data_length = 8; // Length of transaction payload - optional uint32 chain_id = 9; // Chain Id for EIP 155 -} - -/** - * Response: Device asks for more data from transaction payload, or returns the signature. - * If data_length is set, device awaits that many more bytes of payload. - * Otherwise, the signature_* fields contain the computed transaction signature. All three fields will be present. - * @prev EthereumSignTx - * @next EthereumTxAck - */ -message EthereumTxRequest { - optional uint32 data_length = 1; // Number of bytes being requested (<= 1024) - optional uint32 signature_v = 2; // Computed signature (recovery parameter, limited to 27 or 28) - optional bytes signature_r = 3; // Computed signature R component (256 bit) - optional bytes signature_s = 4; // Computed signature S component (256 bit) -} - -/** - * Request: Transaction payload data. - * @prev EthereumTxRequest - * @next EthereumTxRequest - */ -message EthereumTxAck { - optional bytes data_chunk = 1; // Bytes from transaction payload (<= 1024 bytes) -} - -//////////////////////////////////////// -// Ethereum: Message signing messages // -//////////////////////////////////////// - -/** - * Request: Ask device to sign message - * @next EthereumMessageSignature - * @next Failure - */ -message EthereumSignMessage { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - required bytes message = 2; // message to be signed -} - -/** - * Request: Ask device to verify message - * @next Success - * @next Failure - */ -message EthereumVerifyMessage { - optional bytes address = 1; // address to verify - optional bytes signature = 2; // signature to verify - optional bytes message = 3; // message to verify -} - -/** - * Response: Signed message - * @prev EthereumSignMessage - */ -message EthereumMessageSignature { - optional bytes address = 1; // address used to sign the message - optional bytes signature = 2; // signature of the message -} - -/////////////////////// -// Identity messages // -/////////////////////// - -/** - * Request: Ask device to sign identity - * @next SignedIdentity - * @next Failure - */ -message SignIdentity { - optional IdentityType identity = 1; // identity - optional bytes challenge_hidden = 2; // non-visible challenge - optional string challenge_visual = 3; // challenge shown on display (e.g. date+time) - optional string ecdsa_curve_name = 4; // ECDSA curve name to use -} - -/** - * Response: Device provides signed identity - * @prev SignIdentity - */ -message SignedIdentity { - optional string address = 1; // identity address - optional bytes public_key = 2; // identity public key - optional bytes signature = 3; // signature of the identity data -} - -/////////////////// -// ECDH messages // -/////////////////// - -/** - * Request: Ask device to generate ECDH session key - * @next ECDHSessionKey - * @next Failure - */ -message GetECDHSessionKey { - optional IdentityType identity = 1; // identity - optional bytes peer_public_key = 2; // peer's public key - optional string ecdsa_curve_name = 3; // ECDSA curve name to use -} - -/** - * Response: Device provides ECDH session key - * @prev GetECDHSessionKey - */ -message ECDHSessionKey { - optional bytes session_key = 1; // ECDH session key -} - -/////////////////// -// U2F messages // -/////////////////// - -/** - * Request: Set U2F counter - * @next Success - */ -message SetU2FCounter { - optional uint32 u2f_counter = 1; // counter -} - -///////////////////////// -// Bootloader messages // -///////////////////////// - -/** - * Request: Ask device to erase its firmware (so it can be replaced via FirmwareUpload) - * @next Success - * @next FirmwareRequest - * @next Failure - */ -message FirmwareErase { - optional uint32 length = 1; // length of new firmware -} - -/** - * Response: Ask for firmware chunk - * @next FirmwareUpload - */ -message FirmwareRequest { - optional uint32 offset = 1; // offset of requested firmware chunk - optional uint32 length = 2; // length of requested firmware chunk -} - -/** - * Request: Send firmware in binary form to the device - * @next Success - * @next Failure - */ -message FirmwareUpload { - required bytes payload = 1; // firmware to be loaded into device - optional bytes hash = 2; // hash of the payload -} - - -/** - * Request: Perform a device self-test - * @next Success - * @next Failure - */ -message SelfTest { - optional bytes payload = 1; // payload to be used in self-test -} - -///////////////////////////////////////////////////////////// -// Debug messages (only available if DebugLink is enabled) // -///////////////////////////////////////////////////////////// - -/** - * Request: "Press" the button on the device - * @next Success - */ -message DebugLinkDecision { - required bool yes_no = 1; // true for "Confirm", false for "Cancel" -} - -/** - * Request: Computer asks for device state - * @next DebugLinkState - */ -message DebugLinkGetState { -} - -/** - * Response: Device current state - * @prev DebugLinkGetState - */ -message DebugLinkState { - optional bytes layout = 1; // raw buffer of display - optional string pin = 2; // current PIN, blank if PIN is not set/enabled - optional string matrix = 3; // current PIN matrix - optional string mnemonic = 4; // current BIP-39 mnemonic - optional HDNodeType node = 5; // current BIP-32 node - optional bool passphrase_protection = 6; // is node/mnemonic encrypted using passphrase? - optional string reset_word = 7; // word on device display during ResetDevice workflow - optional bytes reset_entropy = 8; // current entropy during ResetDevice workflow - optional string recovery_fake_word = 9; // (fake) word on display during RecoveryDevice workflow - optional uint32 recovery_word_pos = 10; // index of mnemonic word the device is expecting during RecoveryDevice workflow -} - -/** - * Request: Ask device to restart - */ -message DebugLinkStop { -} - -/** - * Response: Device wants host to log event - */ -message DebugLinkLog { - optional uint32 level = 1; - optional string bucket = 2; - optional string text = 3; -} - -/** - * Request: Read memory from device - * @next DebugLinkMemory - */ -message DebugLinkMemoryRead { - optional uint32 address = 1; - optional uint32 length = 2; -} - -/** - * Response: Device sends memory back - * @prev DebugLinkMemoryRead - */ -message DebugLinkMemory { - optional bytes memory = 1; -} - -/** - * Request: Write memory to device. - * WARNING: Writing to the wrong location can irreparably break the device. - */ -message DebugLinkMemoryWrite { - optional uint32 address = 1; - optional bytes memory = 2; - optional bool flash = 3; -} - -/** - * Request: Erase block of flash on device - * WARNING: Writing to the wrong location can irreparably break the device. - */ -message DebugLinkFlashErase { - optional uint32 sector = 1; -} diff --git a/client/accounts/usbwallet/internal/trezor/trezor.go b/client/accounts/usbwallet/internal/trezor/trezor.go deleted file mode 100644 index 80cc75efc..000000000 --- a/client/accounts/usbwallet/internal/trezor/trezor.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// This file contains the implementation for interacting with the Trezor hardware -// wallets. The wire protocol spec can be found on the SatoshiLabs website: -// https://doc.satoshilabs.com/trezor-tech/api-protobuf.html - -//go:generate protoc --go_out=import_path=trezor:. types.proto messages.proto - -// Package trezor contains the wire protocol wrapper in Go. -package trezor - -import ( - "reflect" - - "github.com/golang/protobuf/proto" -) - -// Type returns the protocol buffer type number of a specific message. If the -// message is nil, this method panics! -func Type(msg proto.Message) uint16 { - return uint16(MessageType_value["MessageType_"+reflect.TypeOf(msg).Elem().Name()]) -} - -// Name returns the friendly message type name of a specific protocol buffer -// type number. -func Name(kind uint16) string { - name := MessageType_name[int32(kind)] - if len(name) < 12 { - return name - } - return name[12:] -} diff --git a/client/accounts/usbwallet/internal/trezor/types.pb.go b/client/accounts/usbwallet/internal/trezor/types.pb.go deleted file mode 100644 index 518d1e33b..000000000 --- a/client/accounts/usbwallet/internal/trezor/types.pb.go +++ /dev/null @@ -1,1519 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: types.proto - -package trezor - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -// * -// Type of failures returned by Failure message -// @used_in Failure -type FailureType int32 - -const ( - FailureType_Failure_UnexpectedMessage FailureType = 1 - FailureType_Failure_ButtonExpected FailureType = 2 - FailureType_Failure_DataError FailureType = 3 - FailureType_Failure_ActionCancelled FailureType = 4 - FailureType_Failure_PinExpected FailureType = 5 - FailureType_Failure_PinCancelled FailureType = 6 - FailureType_Failure_PinInvalid FailureType = 7 - FailureType_Failure_InvalidSignature FailureType = 8 - FailureType_Failure_ProcessError FailureType = 9 - FailureType_Failure_NotEnoughFunds FailureType = 10 - FailureType_Failure_NotInitialized FailureType = 11 - FailureType_Failure_FirmwareError FailureType = 99 -) - -var FailureType_name = map[int32]string{ - 1: "Failure_UnexpectedMessage", - 2: "Failure_ButtonExpected", - 3: "Failure_DataError", - 4: "Failure_ActionCancelled", - 5: "Failure_PinExpected", - 6: "Failure_PinCancelled", - 7: "Failure_PinInvalid", - 8: "Failure_InvalidSignature", - 9: "Failure_ProcessError", - 10: "Failure_NotEnoughFunds", - 11: "Failure_NotInitialized", - 99: "Failure_FirmwareError", -} - -var FailureType_value = map[string]int32{ - "Failure_UnexpectedMessage": 1, - "Failure_ButtonExpected": 2, - "Failure_DataError": 3, - "Failure_ActionCancelled": 4, - "Failure_PinExpected": 5, - "Failure_PinCancelled": 6, - "Failure_PinInvalid": 7, - "Failure_InvalidSignature": 8, - "Failure_ProcessError": 9, - "Failure_NotEnoughFunds": 10, - "Failure_NotInitialized": 11, - "Failure_FirmwareError": 99, -} - -func (x FailureType) Enum() *FailureType { - p := new(FailureType) - *p = x - return p -} - -func (x FailureType) String() string { - return proto.EnumName(FailureType_name, int32(x)) -} - -func (x *FailureType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(FailureType_value, data, "FailureType") - if err != nil { - return err - } - *x = FailureType(value) - return nil -} - -func (FailureType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{0} -} - -// * -// Type of script which will be used for transaction output -// @used_in TxOutputType -type OutputScriptType int32 - -const ( - OutputScriptType_PAYTOADDRESS OutputScriptType = 0 - OutputScriptType_PAYTOSCRIPTHASH OutputScriptType = 1 - OutputScriptType_PAYTOMULTISIG OutputScriptType = 2 - OutputScriptType_PAYTOOPRETURN OutputScriptType = 3 - OutputScriptType_PAYTOWITNESS OutputScriptType = 4 - OutputScriptType_PAYTOP2SHWITNESS OutputScriptType = 5 -) - -var OutputScriptType_name = map[int32]string{ - 0: "PAYTOADDRESS", - 1: "PAYTOSCRIPTHASH", - 2: "PAYTOMULTISIG", - 3: "PAYTOOPRETURN", - 4: "PAYTOWITNESS", - 5: "PAYTOP2SHWITNESS", -} - -var OutputScriptType_value = map[string]int32{ - "PAYTOADDRESS": 0, - "PAYTOSCRIPTHASH": 1, - "PAYTOMULTISIG": 2, - "PAYTOOPRETURN": 3, - "PAYTOWITNESS": 4, - "PAYTOP2SHWITNESS": 5, -} - -func (x OutputScriptType) Enum() *OutputScriptType { - p := new(OutputScriptType) - *p = x - return p -} - -func (x OutputScriptType) String() string { - return proto.EnumName(OutputScriptType_name, int32(x)) -} - -func (x *OutputScriptType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(OutputScriptType_value, data, "OutputScriptType") - if err != nil { - return err - } - *x = OutputScriptType(value) - return nil -} - -func (OutputScriptType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{1} -} - -// * -// Type of script which will be used for transaction output -// @used_in TxInputType -type InputScriptType int32 - -const ( - InputScriptType_SPENDADDRESS InputScriptType = 0 - InputScriptType_SPENDMULTISIG InputScriptType = 1 - InputScriptType_EXTERNAL InputScriptType = 2 - InputScriptType_SPENDWITNESS InputScriptType = 3 - InputScriptType_SPENDP2SHWITNESS InputScriptType = 4 -) - -var InputScriptType_name = map[int32]string{ - 0: "SPENDADDRESS", - 1: "SPENDMULTISIG", - 2: "EXTERNAL", - 3: "SPENDWITNESS", - 4: "SPENDP2SHWITNESS", -} - -var InputScriptType_value = map[string]int32{ - "SPENDADDRESS": 0, - "SPENDMULTISIG": 1, - "EXTERNAL": 2, - "SPENDWITNESS": 3, - "SPENDP2SHWITNESS": 4, -} - -func (x InputScriptType) Enum() *InputScriptType { - p := new(InputScriptType) - *p = x - return p -} - -func (x InputScriptType) String() string { - return proto.EnumName(InputScriptType_name, int32(x)) -} - -func (x *InputScriptType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(InputScriptType_value, data, "InputScriptType") - if err != nil { - return err - } - *x = InputScriptType(value) - return nil -} - -func (InputScriptType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{2} -} - -// * -// Type of information required by transaction signing process -// @used_in TxRequest -type RequestType int32 - -const ( - RequestType_TXINPUT RequestType = 0 - RequestType_TXOUTPUT RequestType = 1 - RequestType_TXMETA RequestType = 2 - RequestType_TXFINISHED RequestType = 3 - RequestType_TXEXTRADATA RequestType = 4 -) - -var RequestType_name = map[int32]string{ - 0: "TXINPUT", - 1: "TXOUTPUT", - 2: "TXMETA", - 3: "TXFINISHED", - 4: "TXEXTRADATA", -} - -var RequestType_value = map[string]int32{ - "TXINPUT": 0, - "TXOUTPUT": 1, - "TXMETA": 2, - "TXFINISHED": 3, - "TXEXTRADATA": 4, -} - -func (x RequestType) Enum() *RequestType { - p := new(RequestType) - *p = x - return p -} - -func (x RequestType) String() string { - return proto.EnumName(RequestType_name, int32(x)) -} - -func (x *RequestType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(RequestType_value, data, "RequestType") - if err != nil { - return err - } - *x = RequestType(value) - return nil -} - -func (RequestType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{3} -} - -// * -// Type of button request -// @used_in ButtonRequest -type ButtonRequestType int32 - -const ( - ButtonRequestType_ButtonRequest_Other ButtonRequestType = 1 - ButtonRequestType_ButtonRequest_FeeOverThreshold ButtonRequestType = 2 - ButtonRequestType_ButtonRequest_ConfirmOutput ButtonRequestType = 3 - ButtonRequestType_ButtonRequest_ResetDevice ButtonRequestType = 4 - ButtonRequestType_ButtonRequest_ConfirmWord ButtonRequestType = 5 - ButtonRequestType_ButtonRequest_WipeDevice ButtonRequestType = 6 - ButtonRequestType_ButtonRequest_ProtectCall ButtonRequestType = 7 - ButtonRequestType_ButtonRequest_SignTx ButtonRequestType = 8 - ButtonRequestType_ButtonRequest_FirmwareCheck ButtonRequestType = 9 - ButtonRequestType_ButtonRequest_Address ButtonRequestType = 10 - ButtonRequestType_ButtonRequest_PublicKey ButtonRequestType = 11 -) - -var ButtonRequestType_name = map[int32]string{ - 1: "ButtonRequest_Other", - 2: "ButtonRequest_FeeOverThreshold", - 3: "ButtonRequest_ConfirmOutput", - 4: "ButtonRequest_ResetDevice", - 5: "ButtonRequest_ConfirmWord", - 6: "ButtonRequest_WipeDevice", - 7: "ButtonRequest_ProtectCall", - 8: "ButtonRequest_SignTx", - 9: "ButtonRequest_FirmwareCheck", - 10: "ButtonRequest_Address", - 11: "ButtonRequest_PublicKey", -} - -var ButtonRequestType_value = map[string]int32{ - "ButtonRequest_Other": 1, - "ButtonRequest_FeeOverThreshold": 2, - "ButtonRequest_ConfirmOutput": 3, - "ButtonRequest_ResetDevice": 4, - "ButtonRequest_ConfirmWord": 5, - "ButtonRequest_WipeDevice": 6, - "ButtonRequest_ProtectCall": 7, - "ButtonRequest_SignTx": 8, - "ButtonRequest_FirmwareCheck": 9, - "ButtonRequest_Address": 10, - "ButtonRequest_PublicKey": 11, -} - -func (x ButtonRequestType) Enum() *ButtonRequestType { - p := new(ButtonRequestType) - *p = x - return p -} - -func (x ButtonRequestType) String() string { - return proto.EnumName(ButtonRequestType_name, int32(x)) -} - -func (x *ButtonRequestType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(ButtonRequestType_value, data, "ButtonRequestType") - if err != nil { - return err - } - *x = ButtonRequestType(value) - return nil -} - -func (ButtonRequestType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{4} -} - -// * -// Type of PIN request -// @used_in PinMatrixRequest -type PinMatrixRequestType int32 - -const ( - PinMatrixRequestType_PinMatrixRequestType_Current PinMatrixRequestType = 1 - PinMatrixRequestType_PinMatrixRequestType_NewFirst PinMatrixRequestType = 2 - PinMatrixRequestType_PinMatrixRequestType_NewSecond PinMatrixRequestType = 3 -) - -var PinMatrixRequestType_name = map[int32]string{ - 1: "PinMatrixRequestType_Current", - 2: "PinMatrixRequestType_NewFirst", - 3: "PinMatrixRequestType_NewSecond", -} - -var PinMatrixRequestType_value = map[string]int32{ - "PinMatrixRequestType_Current": 1, - "PinMatrixRequestType_NewFirst": 2, - "PinMatrixRequestType_NewSecond": 3, -} - -func (x PinMatrixRequestType) Enum() *PinMatrixRequestType { - p := new(PinMatrixRequestType) - *p = x - return p -} - -func (x PinMatrixRequestType) String() string { - return proto.EnumName(PinMatrixRequestType_name, int32(x)) -} - -func (x *PinMatrixRequestType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(PinMatrixRequestType_value, data, "PinMatrixRequestType") - if err != nil { - return err - } - *x = PinMatrixRequestType(value) - return nil -} - -func (PinMatrixRequestType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{5} -} - -// * -// Type of recovery procedure. These should be used as bitmask, e.g., -// `RecoveryDeviceType_ScrambledWords | RecoveryDeviceType_Matrix` -// listing every method supported by the host computer. -// -// Note that ScrambledWords must be supported by every implementation -// for backward compatibility; there is no way to not support it. -// -// @used_in RecoveryDevice -type RecoveryDeviceType int32 - -const ( - // use powers of two when extending this field - RecoveryDeviceType_RecoveryDeviceType_ScrambledWords RecoveryDeviceType = 0 - RecoveryDeviceType_RecoveryDeviceType_Matrix RecoveryDeviceType = 1 -) - -var RecoveryDeviceType_name = map[int32]string{ - 0: "RecoveryDeviceType_ScrambledWords", - 1: "RecoveryDeviceType_Matrix", -} - -var RecoveryDeviceType_value = map[string]int32{ - "RecoveryDeviceType_ScrambledWords": 0, - "RecoveryDeviceType_Matrix": 1, -} - -func (x RecoveryDeviceType) Enum() *RecoveryDeviceType { - p := new(RecoveryDeviceType) - *p = x - return p -} - -func (x RecoveryDeviceType) String() string { - return proto.EnumName(RecoveryDeviceType_name, int32(x)) -} - -func (x *RecoveryDeviceType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(RecoveryDeviceType_value, data, "RecoveryDeviceType") - if err != nil { - return err - } - *x = RecoveryDeviceType(value) - return nil -} - -func (RecoveryDeviceType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{6} -} - -// * -// Type of Recovery Word request -// @used_in WordRequest -type WordRequestType int32 - -const ( - WordRequestType_WordRequestType_Plain WordRequestType = 0 - WordRequestType_WordRequestType_Matrix9 WordRequestType = 1 - WordRequestType_WordRequestType_Matrix6 WordRequestType = 2 -) - -var WordRequestType_name = map[int32]string{ - 0: "WordRequestType_Plain", - 1: "WordRequestType_Matrix9", - 2: "WordRequestType_Matrix6", -} - -var WordRequestType_value = map[string]int32{ - "WordRequestType_Plain": 0, - "WordRequestType_Matrix9": 1, - "WordRequestType_Matrix6": 2, -} - -func (x WordRequestType) Enum() *WordRequestType { - p := new(WordRequestType) - *p = x - return p -} - -func (x WordRequestType) String() string { - return proto.EnumName(WordRequestType_name, int32(x)) -} - -func (x *WordRequestType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(WordRequestType_value, data, "WordRequestType") - if err != nil { - return err - } - *x = WordRequestType(value) - return nil -} - -func (WordRequestType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{7} -} - -// * -// Structure representing BIP32 (hierarchical deterministic) node -// Used for imports of private key into the device and exporting public key out of device -// @used_in PublicKey -// @used_in LoadDevice -// @used_in DebugLinkState -// @used_in Storage -type HDNodeType struct { - Depth *uint32 `protobuf:"varint,1,req,name=depth" json:"depth,omitempty"` - Fingerprint *uint32 `protobuf:"varint,2,req,name=fingerprint" json:"fingerprint,omitempty"` - ChildNum *uint32 `protobuf:"varint,3,req,name=child_num,json=childNum" json:"child_num,omitempty"` - ChainCode []byte `protobuf:"bytes,4,req,name=chain_code,json=chainCode" json:"chain_code,omitempty"` - PrivateKey []byte `protobuf:"bytes,5,opt,name=private_key,json=privateKey" json:"private_key,omitempty"` - PublicKey []byte `protobuf:"bytes,6,opt,name=public_key,json=publicKey" json:"public_key,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *HDNodeType) Reset() { *m = HDNodeType{} } -func (m *HDNodeType) String() string { return proto.CompactTextString(m) } -func (*HDNodeType) ProtoMessage() {} -func (*HDNodeType) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{0} -} -func (m *HDNodeType) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_HDNodeType.Unmarshal(m, b) -} -func (m *HDNodeType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_HDNodeType.Marshal(b, m, deterministic) -} -func (dst *HDNodeType) XXX_Merge(src proto.Message) { - xxx_messageInfo_HDNodeType.Merge(dst, src) -} -func (m *HDNodeType) XXX_Size() int { - return xxx_messageInfo_HDNodeType.Size(m) -} -func (m *HDNodeType) XXX_DiscardUnknown() { - xxx_messageInfo_HDNodeType.DiscardUnknown(m) -} - -var xxx_messageInfo_HDNodeType proto.InternalMessageInfo - -func (m *HDNodeType) GetDepth() uint32 { - if m != nil && m.Depth != nil { - return *m.Depth - } - return 0 -} - -func (m *HDNodeType) GetFingerprint() uint32 { - if m != nil && m.Fingerprint != nil { - return *m.Fingerprint - } - return 0 -} - -func (m *HDNodeType) GetChildNum() uint32 { - if m != nil && m.ChildNum != nil { - return *m.ChildNum - } - return 0 -} - -func (m *HDNodeType) GetChainCode() []byte { - if m != nil { - return m.ChainCode - } - return nil -} - -func (m *HDNodeType) GetPrivateKey() []byte { - if m != nil { - return m.PrivateKey - } - return nil -} - -func (m *HDNodeType) GetPublicKey() []byte { - if m != nil { - return m.PublicKey - } - return nil -} - -type HDNodePathType struct { - Node *HDNodeType `protobuf:"bytes,1,req,name=node" json:"node,omitempty"` - AddressN []uint32 `protobuf:"varint,2,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *HDNodePathType) Reset() { *m = HDNodePathType{} } -func (m *HDNodePathType) String() string { return proto.CompactTextString(m) } -func (*HDNodePathType) ProtoMessage() {} -func (*HDNodePathType) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{1} -} -func (m *HDNodePathType) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_HDNodePathType.Unmarshal(m, b) -} -func (m *HDNodePathType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_HDNodePathType.Marshal(b, m, deterministic) -} -func (dst *HDNodePathType) XXX_Merge(src proto.Message) { - xxx_messageInfo_HDNodePathType.Merge(dst, src) -} -func (m *HDNodePathType) XXX_Size() int { - return xxx_messageInfo_HDNodePathType.Size(m) -} -func (m *HDNodePathType) XXX_DiscardUnknown() { - xxx_messageInfo_HDNodePathType.DiscardUnknown(m) -} - -var xxx_messageInfo_HDNodePathType proto.InternalMessageInfo - -func (m *HDNodePathType) GetNode() *HDNodeType { - if m != nil { - return m.Node - } - return nil -} - -func (m *HDNodePathType) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -// * -// Structure representing Coin -// @used_in Features -type CoinType struct { - CoinName *string `protobuf:"bytes,1,opt,name=coin_name,json=coinName" json:"coin_name,omitempty"` - CoinShortcut *string `protobuf:"bytes,2,opt,name=coin_shortcut,json=coinShortcut" json:"coin_shortcut,omitempty"` - AddressType *uint32 `protobuf:"varint,3,opt,name=address_type,json=addressType,def=0" json:"address_type,omitempty"` - MaxfeeKb *uint64 `protobuf:"varint,4,opt,name=maxfee_kb,json=maxfeeKb" json:"maxfee_kb,omitempty"` - AddressTypeP2Sh *uint32 `protobuf:"varint,5,opt,name=address_type_p2sh,json=addressTypeP2sh,def=5" json:"address_type_p2sh,omitempty"` - SignedMessageHeader *string `protobuf:"bytes,8,opt,name=signed_message_header,json=signedMessageHeader" json:"signed_message_header,omitempty"` - XpubMagic *uint32 `protobuf:"varint,9,opt,name=xpub_magic,json=xpubMagic,def=76067358" json:"xpub_magic,omitempty"` - XprvMagic *uint32 `protobuf:"varint,10,opt,name=xprv_magic,json=xprvMagic,def=76066276" json:"xprv_magic,omitempty"` - Segwit *bool `protobuf:"varint,11,opt,name=segwit" json:"segwit,omitempty"` - Forkid *uint32 `protobuf:"varint,12,opt,name=forkid" json:"forkid,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CoinType) Reset() { *m = CoinType{} } -func (m *CoinType) String() string { return proto.CompactTextString(m) } -func (*CoinType) ProtoMessage() {} -func (*CoinType) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{2} -} -func (m *CoinType) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CoinType.Unmarshal(m, b) -} -func (m *CoinType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CoinType.Marshal(b, m, deterministic) -} -func (dst *CoinType) XXX_Merge(src proto.Message) { - xxx_messageInfo_CoinType.Merge(dst, src) -} -func (m *CoinType) XXX_Size() int { - return xxx_messageInfo_CoinType.Size(m) -} -func (m *CoinType) XXX_DiscardUnknown() { - xxx_messageInfo_CoinType.DiscardUnknown(m) -} - -var xxx_messageInfo_CoinType proto.InternalMessageInfo - -const Default_CoinType_AddressType uint32 = 0 -const Default_CoinType_AddressTypeP2Sh uint32 = 5 -const Default_CoinType_XpubMagic uint32 = 76067358 -const Default_CoinType_XprvMagic uint32 = 76066276 - -func (m *CoinType) GetCoinName() string { - if m != nil && m.CoinName != nil { - return *m.CoinName - } - return "" -} - -func (m *CoinType) GetCoinShortcut() string { - if m != nil && m.CoinShortcut != nil { - return *m.CoinShortcut - } - return "" -} - -func (m *CoinType) GetAddressType() uint32 { - if m != nil && m.AddressType != nil { - return *m.AddressType - } - return Default_CoinType_AddressType -} - -func (m *CoinType) GetMaxfeeKb() uint64 { - if m != nil && m.MaxfeeKb != nil { - return *m.MaxfeeKb - } - return 0 -} - -func (m *CoinType) GetAddressTypeP2Sh() uint32 { - if m != nil && m.AddressTypeP2Sh != nil { - return *m.AddressTypeP2Sh - } - return Default_CoinType_AddressTypeP2Sh -} - -func (m *CoinType) GetSignedMessageHeader() string { - if m != nil && m.SignedMessageHeader != nil { - return *m.SignedMessageHeader - } - return "" -} - -func (m *CoinType) GetXpubMagic() uint32 { - if m != nil && m.XpubMagic != nil { - return *m.XpubMagic - } - return Default_CoinType_XpubMagic -} - -func (m *CoinType) GetXprvMagic() uint32 { - if m != nil && m.XprvMagic != nil { - return *m.XprvMagic - } - return Default_CoinType_XprvMagic -} - -func (m *CoinType) GetSegwit() bool { - if m != nil && m.Segwit != nil { - return *m.Segwit - } - return false -} - -func (m *CoinType) GetForkid() uint32 { - if m != nil && m.Forkid != nil { - return *m.Forkid - } - return 0 -} - -// * -// Type of redeem script used in input -// @used_in TxInputType -type MultisigRedeemScriptType struct { - Pubkeys []*HDNodePathType `protobuf:"bytes,1,rep,name=pubkeys" json:"pubkeys,omitempty"` - Signatures [][]byte `protobuf:"bytes,2,rep,name=signatures" json:"signatures,omitempty"` - M *uint32 `protobuf:"varint,3,opt,name=m" json:"m,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *MultisigRedeemScriptType) Reset() { *m = MultisigRedeemScriptType{} } -func (m *MultisigRedeemScriptType) String() string { return proto.CompactTextString(m) } -func (*MultisigRedeemScriptType) ProtoMessage() {} -func (*MultisigRedeemScriptType) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{3} -} -func (m *MultisigRedeemScriptType) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_MultisigRedeemScriptType.Unmarshal(m, b) -} -func (m *MultisigRedeemScriptType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_MultisigRedeemScriptType.Marshal(b, m, deterministic) -} -func (dst *MultisigRedeemScriptType) XXX_Merge(src proto.Message) { - xxx_messageInfo_MultisigRedeemScriptType.Merge(dst, src) -} -func (m *MultisigRedeemScriptType) XXX_Size() int { - return xxx_messageInfo_MultisigRedeemScriptType.Size(m) -} -func (m *MultisigRedeemScriptType) XXX_DiscardUnknown() { - xxx_messageInfo_MultisigRedeemScriptType.DiscardUnknown(m) -} - -var xxx_messageInfo_MultisigRedeemScriptType proto.InternalMessageInfo - -func (m *MultisigRedeemScriptType) GetPubkeys() []*HDNodePathType { - if m != nil { - return m.Pubkeys - } - return nil -} - -func (m *MultisigRedeemScriptType) GetSignatures() [][]byte { - if m != nil { - return m.Signatures - } - return nil -} - -func (m *MultisigRedeemScriptType) GetM() uint32 { - if m != nil && m.M != nil { - return *m.M - } - return 0 -} - -// * -// Structure representing transaction input -// @used_in SimpleSignTx -// @used_in TransactionType -type TxInputType struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - PrevHash []byte `protobuf:"bytes,2,req,name=prev_hash,json=prevHash" json:"prev_hash,omitempty"` - PrevIndex *uint32 `protobuf:"varint,3,req,name=prev_index,json=prevIndex" json:"prev_index,omitempty"` - ScriptSig []byte `protobuf:"bytes,4,opt,name=script_sig,json=scriptSig" json:"script_sig,omitempty"` - Sequence *uint32 `protobuf:"varint,5,opt,name=sequence,def=4294967295" json:"sequence,omitempty"` - ScriptType *InputScriptType `protobuf:"varint,6,opt,name=script_type,json=scriptType,enum=InputScriptType,def=0" json:"script_type,omitempty"` - Multisig *MultisigRedeemScriptType `protobuf:"bytes,7,opt,name=multisig" json:"multisig,omitempty"` - Amount *uint64 `protobuf:"varint,8,opt,name=amount" json:"amount,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *TxInputType) Reset() { *m = TxInputType{} } -func (m *TxInputType) String() string { return proto.CompactTextString(m) } -func (*TxInputType) ProtoMessage() {} -func (*TxInputType) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{4} -} -func (m *TxInputType) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TxInputType.Unmarshal(m, b) -} -func (m *TxInputType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TxInputType.Marshal(b, m, deterministic) -} -func (dst *TxInputType) XXX_Merge(src proto.Message) { - xxx_messageInfo_TxInputType.Merge(dst, src) -} -func (m *TxInputType) XXX_Size() int { - return xxx_messageInfo_TxInputType.Size(m) -} -func (m *TxInputType) XXX_DiscardUnknown() { - xxx_messageInfo_TxInputType.DiscardUnknown(m) -} - -var xxx_messageInfo_TxInputType proto.InternalMessageInfo - -const Default_TxInputType_Sequence uint32 = 4294967295 -const Default_TxInputType_ScriptType InputScriptType = InputScriptType_SPENDADDRESS - -func (m *TxInputType) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -func (m *TxInputType) GetPrevHash() []byte { - if m != nil { - return m.PrevHash - } - return nil -} - -func (m *TxInputType) GetPrevIndex() uint32 { - if m != nil && m.PrevIndex != nil { - return *m.PrevIndex - } - return 0 -} - -func (m *TxInputType) GetScriptSig() []byte { - if m != nil { - return m.ScriptSig - } - return nil -} - -func (m *TxInputType) GetSequence() uint32 { - if m != nil && m.Sequence != nil { - return *m.Sequence - } - return Default_TxInputType_Sequence -} - -func (m *TxInputType) GetScriptType() InputScriptType { - if m != nil && m.ScriptType != nil { - return *m.ScriptType - } - return Default_TxInputType_ScriptType -} - -func (m *TxInputType) GetMultisig() *MultisigRedeemScriptType { - if m != nil { - return m.Multisig - } - return nil -} - -func (m *TxInputType) GetAmount() uint64 { - if m != nil && m.Amount != nil { - return *m.Amount - } - return 0 -} - -// * -// Structure representing transaction output -// @used_in SimpleSignTx -// @used_in TransactionType -type TxOutputType struct { - Address *string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` - AddressN []uint32 `protobuf:"varint,2,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - Amount *uint64 `protobuf:"varint,3,req,name=amount" json:"amount,omitempty"` - ScriptType *OutputScriptType `protobuf:"varint,4,req,name=script_type,json=scriptType,enum=OutputScriptType" json:"script_type,omitempty"` - Multisig *MultisigRedeemScriptType `protobuf:"bytes,5,opt,name=multisig" json:"multisig,omitempty"` - OpReturnData []byte `protobuf:"bytes,6,opt,name=op_return_data,json=opReturnData" json:"op_return_data,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *TxOutputType) Reset() { *m = TxOutputType{} } -func (m *TxOutputType) String() string { return proto.CompactTextString(m) } -func (*TxOutputType) ProtoMessage() {} -func (*TxOutputType) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{5} -} -func (m *TxOutputType) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TxOutputType.Unmarshal(m, b) -} -func (m *TxOutputType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TxOutputType.Marshal(b, m, deterministic) -} -func (dst *TxOutputType) XXX_Merge(src proto.Message) { - xxx_messageInfo_TxOutputType.Merge(dst, src) -} -func (m *TxOutputType) XXX_Size() int { - return xxx_messageInfo_TxOutputType.Size(m) -} -func (m *TxOutputType) XXX_DiscardUnknown() { - xxx_messageInfo_TxOutputType.DiscardUnknown(m) -} - -var xxx_messageInfo_TxOutputType proto.InternalMessageInfo - -func (m *TxOutputType) GetAddress() string { - if m != nil && m.Address != nil { - return *m.Address - } - return "" -} - -func (m *TxOutputType) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -func (m *TxOutputType) GetAmount() uint64 { - if m != nil && m.Amount != nil { - return *m.Amount - } - return 0 -} - -func (m *TxOutputType) GetScriptType() OutputScriptType { - if m != nil && m.ScriptType != nil { - return *m.ScriptType - } - return OutputScriptType_PAYTOADDRESS -} - -func (m *TxOutputType) GetMultisig() *MultisigRedeemScriptType { - if m != nil { - return m.Multisig - } - return nil -} - -func (m *TxOutputType) GetOpReturnData() []byte { - if m != nil { - return m.OpReturnData - } - return nil -} - -// * -// Structure representing compiled transaction output -// @used_in TransactionType -type TxOutputBinType struct { - Amount *uint64 `protobuf:"varint,1,req,name=amount" json:"amount,omitempty"` - ScriptPubkey []byte `protobuf:"bytes,2,req,name=script_pubkey,json=scriptPubkey" json:"script_pubkey,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *TxOutputBinType) Reset() { *m = TxOutputBinType{} } -func (m *TxOutputBinType) String() string { return proto.CompactTextString(m) } -func (*TxOutputBinType) ProtoMessage() {} -func (*TxOutputBinType) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{6} -} -func (m *TxOutputBinType) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TxOutputBinType.Unmarshal(m, b) -} -func (m *TxOutputBinType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TxOutputBinType.Marshal(b, m, deterministic) -} -func (dst *TxOutputBinType) XXX_Merge(src proto.Message) { - xxx_messageInfo_TxOutputBinType.Merge(dst, src) -} -func (m *TxOutputBinType) XXX_Size() int { - return xxx_messageInfo_TxOutputBinType.Size(m) -} -func (m *TxOutputBinType) XXX_DiscardUnknown() { - xxx_messageInfo_TxOutputBinType.DiscardUnknown(m) -} - -var xxx_messageInfo_TxOutputBinType proto.InternalMessageInfo - -func (m *TxOutputBinType) GetAmount() uint64 { - if m != nil && m.Amount != nil { - return *m.Amount - } - return 0 -} - -func (m *TxOutputBinType) GetScriptPubkey() []byte { - if m != nil { - return m.ScriptPubkey - } - return nil -} - -// * -// Structure representing transaction -// @used_in SimpleSignTx -type TransactionType struct { - Version *uint32 `protobuf:"varint,1,opt,name=version" json:"version,omitempty"` - Inputs []*TxInputType `protobuf:"bytes,2,rep,name=inputs" json:"inputs,omitempty"` - BinOutputs []*TxOutputBinType `protobuf:"bytes,3,rep,name=bin_outputs,json=binOutputs" json:"bin_outputs,omitempty"` - Outputs []*TxOutputType `protobuf:"bytes,5,rep,name=outputs" json:"outputs,omitempty"` - LockTime *uint32 `protobuf:"varint,4,opt,name=lock_time,json=lockTime" json:"lock_time,omitempty"` - InputsCnt *uint32 `protobuf:"varint,6,opt,name=inputs_cnt,json=inputsCnt" json:"inputs_cnt,omitempty"` - OutputsCnt *uint32 `protobuf:"varint,7,opt,name=outputs_cnt,json=outputsCnt" json:"outputs_cnt,omitempty"` - ExtraData []byte `protobuf:"bytes,8,opt,name=extra_data,json=extraData" json:"extra_data,omitempty"` - ExtraDataLen *uint32 `protobuf:"varint,9,opt,name=extra_data_len,json=extraDataLen" json:"extra_data_len,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *TransactionType) Reset() { *m = TransactionType{} } -func (m *TransactionType) String() string { return proto.CompactTextString(m) } -func (*TransactionType) ProtoMessage() {} -func (*TransactionType) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{7} -} -func (m *TransactionType) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TransactionType.Unmarshal(m, b) -} -func (m *TransactionType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TransactionType.Marshal(b, m, deterministic) -} -func (dst *TransactionType) XXX_Merge(src proto.Message) { - xxx_messageInfo_TransactionType.Merge(dst, src) -} -func (m *TransactionType) XXX_Size() int { - return xxx_messageInfo_TransactionType.Size(m) -} -func (m *TransactionType) XXX_DiscardUnknown() { - xxx_messageInfo_TransactionType.DiscardUnknown(m) -} - -var xxx_messageInfo_TransactionType proto.InternalMessageInfo - -func (m *TransactionType) GetVersion() uint32 { - if m != nil && m.Version != nil { - return *m.Version - } - return 0 -} - -func (m *TransactionType) GetInputs() []*TxInputType { - if m != nil { - return m.Inputs - } - return nil -} - -func (m *TransactionType) GetBinOutputs() []*TxOutputBinType { - if m != nil { - return m.BinOutputs - } - return nil -} - -func (m *TransactionType) GetOutputs() []*TxOutputType { - if m != nil { - return m.Outputs - } - return nil -} - -func (m *TransactionType) GetLockTime() uint32 { - if m != nil && m.LockTime != nil { - return *m.LockTime - } - return 0 -} - -func (m *TransactionType) GetInputsCnt() uint32 { - if m != nil && m.InputsCnt != nil { - return *m.InputsCnt - } - return 0 -} - -func (m *TransactionType) GetOutputsCnt() uint32 { - if m != nil && m.OutputsCnt != nil { - return *m.OutputsCnt - } - return 0 -} - -func (m *TransactionType) GetExtraData() []byte { - if m != nil { - return m.ExtraData - } - return nil -} - -func (m *TransactionType) GetExtraDataLen() uint32 { - if m != nil && m.ExtraDataLen != nil { - return *m.ExtraDataLen - } - return 0 -} - -// * -// Structure representing request details -// @used_in TxRequest -type TxRequestDetailsType struct { - RequestIndex *uint32 `protobuf:"varint,1,opt,name=request_index,json=requestIndex" json:"request_index,omitempty"` - TxHash []byte `protobuf:"bytes,2,opt,name=tx_hash,json=txHash" json:"tx_hash,omitempty"` - ExtraDataLen *uint32 `protobuf:"varint,3,opt,name=extra_data_len,json=extraDataLen" json:"extra_data_len,omitempty"` - ExtraDataOffset *uint32 `protobuf:"varint,4,opt,name=extra_data_offset,json=extraDataOffset" json:"extra_data_offset,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *TxRequestDetailsType) Reset() { *m = TxRequestDetailsType{} } -func (m *TxRequestDetailsType) String() string { return proto.CompactTextString(m) } -func (*TxRequestDetailsType) ProtoMessage() {} -func (*TxRequestDetailsType) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{8} -} -func (m *TxRequestDetailsType) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TxRequestDetailsType.Unmarshal(m, b) -} -func (m *TxRequestDetailsType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TxRequestDetailsType.Marshal(b, m, deterministic) -} -func (dst *TxRequestDetailsType) XXX_Merge(src proto.Message) { - xxx_messageInfo_TxRequestDetailsType.Merge(dst, src) -} -func (m *TxRequestDetailsType) XXX_Size() int { - return xxx_messageInfo_TxRequestDetailsType.Size(m) -} -func (m *TxRequestDetailsType) XXX_DiscardUnknown() { - xxx_messageInfo_TxRequestDetailsType.DiscardUnknown(m) -} - -var xxx_messageInfo_TxRequestDetailsType proto.InternalMessageInfo - -func (m *TxRequestDetailsType) GetRequestIndex() uint32 { - if m != nil && m.RequestIndex != nil { - return *m.RequestIndex - } - return 0 -} - -func (m *TxRequestDetailsType) GetTxHash() []byte { - if m != nil { - return m.TxHash - } - return nil -} - -func (m *TxRequestDetailsType) GetExtraDataLen() uint32 { - if m != nil && m.ExtraDataLen != nil { - return *m.ExtraDataLen - } - return 0 -} - -func (m *TxRequestDetailsType) GetExtraDataOffset() uint32 { - if m != nil && m.ExtraDataOffset != nil { - return *m.ExtraDataOffset - } - return 0 -} - -// * -// Structure representing serialized data -// @used_in TxRequest -type TxRequestSerializedType struct { - SignatureIndex *uint32 `protobuf:"varint,1,opt,name=signature_index,json=signatureIndex" json:"signature_index,omitempty"` - Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` - SerializedTx []byte `protobuf:"bytes,3,opt,name=serialized_tx,json=serializedTx" json:"serialized_tx,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *TxRequestSerializedType) Reset() { *m = TxRequestSerializedType{} } -func (m *TxRequestSerializedType) String() string { return proto.CompactTextString(m) } -func (*TxRequestSerializedType) ProtoMessage() {} -func (*TxRequestSerializedType) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{9} -} -func (m *TxRequestSerializedType) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TxRequestSerializedType.Unmarshal(m, b) -} -func (m *TxRequestSerializedType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TxRequestSerializedType.Marshal(b, m, deterministic) -} -func (dst *TxRequestSerializedType) XXX_Merge(src proto.Message) { - xxx_messageInfo_TxRequestSerializedType.Merge(dst, src) -} -func (m *TxRequestSerializedType) XXX_Size() int { - return xxx_messageInfo_TxRequestSerializedType.Size(m) -} -func (m *TxRequestSerializedType) XXX_DiscardUnknown() { - xxx_messageInfo_TxRequestSerializedType.DiscardUnknown(m) -} - -var xxx_messageInfo_TxRequestSerializedType proto.InternalMessageInfo - -func (m *TxRequestSerializedType) GetSignatureIndex() uint32 { - if m != nil && m.SignatureIndex != nil { - return *m.SignatureIndex - } - return 0 -} - -func (m *TxRequestSerializedType) GetSignature() []byte { - if m != nil { - return m.Signature - } - return nil -} - -func (m *TxRequestSerializedType) GetSerializedTx() []byte { - if m != nil { - return m.SerializedTx - } - return nil -} - -// * -// Structure representing identity data -// @used_in IdentityType -type IdentityType struct { - Proto *string `protobuf:"bytes,1,opt,name=proto" json:"proto,omitempty"` - User *string `protobuf:"bytes,2,opt,name=user" json:"user,omitempty"` - Host *string `protobuf:"bytes,3,opt,name=host" json:"host,omitempty"` - Port *string `protobuf:"bytes,4,opt,name=port" json:"port,omitempty"` - Path *string `protobuf:"bytes,5,opt,name=path" json:"path,omitempty"` - Index *uint32 `protobuf:"varint,6,opt,name=index,def=0" json:"index,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *IdentityType) Reset() { *m = IdentityType{} } -func (m *IdentityType) String() string { return proto.CompactTextString(m) } -func (*IdentityType) ProtoMessage() {} -func (*IdentityType) Descriptor() ([]byte, []int) { - return fileDescriptor_d938547f84707355, []int{10} -} -func (m *IdentityType) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_IdentityType.Unmarshal(m, b) -} -func (m *IdentityType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_IdentityType.Marshal(b, m, deterministic) -} -func (dst *IdentityType) XXX_Merge(src proto.Message) { - xxx_messageInfo_IdentityType.Merge(dst, src) -} -func (m *IdentityType) XXX_Size() int { - return xxx_messageInfo_IdentityType.Size(m) -} -func (m *IdentityType) XXX_DiscardUnknown() { - xxx_messageInfo_IdentityType.DiscardUnknown(m) -} - -var xxx_messageInfo_IdentityType proto.InternalMessageInfo - -const Default_IdentityType_Index uint32 = 0 - -func (m *IdentityType) GetProto() string { - if m != nil && m.Proto != nil { - return *m.Proto - } - return "" -} - -func (m *IdentityType) GetUser() string { - if m != nil && m.User != nil { - return *m.User - } - return "" -} - -func (m *IdentityType) GetHost() string { - if m != nil && m.Host != nil { - return *m.Host - } - return "" -} - -func (m *IdentityType) GetPort() string { - if m != nil && m.Port != nil { - return *m.Port - } - return "" -} - -func (m *IdentityType) GetPath() string { - if m != nil && m.Path != nil { - return *m.Path - } - return "" -} - -func (m *IdentityType) GetIndex() uint32 { - if m != nil && m.Index != nil { - return *m.Index - } - return Default_IdentityType_Index -} - -var E_WireIn = &proto.ExtensionDesc{ - ExtendedType: (*descriptor.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50002, - Name: "wire_in", - Tag: "varint,50002,opt,name=wire_in,json=wireIn", - Filename: "types.proto", -} - -var E_WireOut = &proto.ExtensionDesc{ - ExtendedType: (*descriptor.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50003, - Name: "wire_out", - Tag: "varint,50003,opt,name=wire_out,json=wireOut", - Filename: "types.proto", -} - -var E_WireDebugIn = &proto.ExtensionDesc{ - ExtendedType: (*descriptor.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50004, - Name: "wire_debug_in", - Tag: "varint,50004,opt,name=wire_debug_in,json=wireDebugIn", - Filename: "types.proto", -} - -var E_WireDebugOut = &proto.ExtensionDesc{ - ExtendedType: (*descriptor.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50005, - Name: "wire_debug_out", - Tag: "varint,50005,opt,name=wire_debug_out,json=wireDebugOut", - Filename: "types.proto", -} - -var E_WireTiny = &proto.ExtensionDesc{ - ExtendedType: (*descriptor.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50006, - Name: "wire_tiny", - Tag: "varint,50006,opt,name=wire_tiny,json=wireTiny", - Filename: "types.proto", -} - -var E_WireBootloader = &proto.ExtensionDesc{ - ExtendedType: (*descriptor.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50007, - Name: "wire_bootloader", - Tag: "varint,50007,opt,name=wire_bootloader,json=wireBootloader", - Filename: "types.proto", -} - -func init() { - proto.RegisterType((*HDNodeType)(nil), "HDNodeType") - proto.RegisterType((*HDNodePathType)(nil), "HDNodePathType") - proto.RegisterType((*CoinType)(nil), "CoinType") - proto.RegisterType((*MultisigRedeemScriptType)(nil), "MultisigRedeemScriptType") - proto.RegisterType((*TxInputType)(nil), "TxInputType") - proto.RegisterType((*TxOutputType)(nil), "TxOutputType") - proto.RegisterType((*TxOutputBinType)(nil), "TxOutputBinType") - proto.RegisterType((*TransactionType)(nil), "TransactionType") - proto.RegisterType((*TxRequestDetailsType)(nil), "TxRequestDetailsType") - proto.RegisterType((*TxRequestSerializedType)(nil), "TxRequestSerializedType") - proto.RegisterType((*IdentityType)(nil), "IdentityType") - proto.RegisterEnum("FailureType", FailureType_name, FailureType_value) - proto.RegisterEnum("OutputScriptType", OutputScriptType_name, OutputScriptType_value) - proto.RegisterEnum("InputScriptType", InputScriptType_name, InputScriptType_value) - proto.RegisterEnum("RequestType", RequestType_name, RequestType_value) - proto.RegisterEnum("ButtonRequestType", ButtonRequestType_name, ButtonRequestType_value) - proto.RegisterEnum("PinMatrixRequestType", PinMatrixRequestType_name, PinMatrixRequestType_value) - proto.RegisterEnum("RecoveryDeviceType", RecoveryDeviceType_name, RecoveryDeviceType_value) - proto.RegisterEnum("WordRequestType", WordRequestType_name, WordRequestType_value) - proto.RegisterExtension(E_WireIn) - proto.RegisterExtension(E_WireOut) - proto.RegisterExtension(E_WireDebugIn) - proto.RegisterExtension(E_WireDebugOut) - proto.RegisterExtension(E_WireTiny) - proto.RegisterExtension(E_WireBootloader) -} - -func init() { proto.RegisterFile("types.proto", fileDescriptor_d938547f84707355) } - -var fileDescriptor_d938547f84707355 = []byte{ - // 1899 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x57, 0xdb, 0x72, 0x1a, 0xc9, - 0x19, 0xf6, 0x00, 0x92, 0xe0, 0x07, 0xc4, 0xa8, 0x7d, 0xd0, 0x78, 0x6d, 0xaf, 0x31, 0x76, 0x62, - 0x45, 0x55, 0x61, 0x77, 0xc9, 0x5a, 0x8e, 0x55, 0xa9, 0x24, 0x3a, 0xa0, 0x15, 0x65, 0x0b, 0x51, - 0xc3, 0x28, 0x56, 0x72, 0x33, 0x35, 0xcc, 0xb4, 0xa0, 0x4b, 0x43, 0x37, 0xe9, 0xe9, 0x91, 0xd1, - 0xde, 0xe4, 0x2a, 0xc9, 0x55, 0x5e, 0x23, 0x6f, 0x91, 0xaa, 0xbc, 0x41, 0xaa, 0x36, 0xa7, 0xcb, - 0xbc, 0x41, 0xae, 0xf2, 0x00, 0xa9, 0x3e, 0x0c, 0x02, 0xc9, 0xde, 0xd2, 0x1d, 0xfd, 0x7d, 0xff, - 0xf9, 0xd0, 0x3d, 0x40, 0x59, 0x5c, 0x4e, 0x70, 0xd2, 0x9c, 0x70, 0x26, 0xd8, 0x67, 0xf5, 0x21, - 0x63, 0xc3, 0x18, 0x7f, 0xa1, 0x4e, 0x83, 0xf4, 0xec, 0x8b, 0x08, 0x27, 0x21, 0x27, 0x13, 0xc1, - 0xb8, 0x96, 0x68, 0xfc, 0xd5, 0x02, 0x38, 0xdc, 0xef, 0xb2, 0x08, 0x7b, 0x97, 0x13, 0x8c, 0xee, - 0xc1, 0x52, 0x84, 0x27, 0x62, 0xe4, 0x58, 0xf5, 0xdc, 0x46, 0xd5, 0xd5, 0x07, 0x54, 0x87, 0xf2, - 0x19, 0xa1, 0x43, 0xcc, 0x27, 0x9c, 0x50, 0xe1, 0xe4, 0x14, 0x37, 0x0f, 0xa1, 0x47, 0x50, 0x0a, - 0x47, 0x24, 0x8e, 0x7c, 0x9a, 0x8e, 0x9d, 0xbc, 0xe2, 0x8b, 0x0a, 0xe8, 0xa6, 0x63, 0xf4, 0x04, - 0x20, 0x1c, 0x05, 0x84, 0xfa, 0x21, 0x8b, 0xb0, 0x53, 0xa8, 0xe7, 0x36, 0x2a, 0x6e, 0x49, 0x21, - 0x7b, 0x2c, 0xc2, 0xe8, 0x29, 0x94, 0x27, 0x9c, 0x5c, 0x04, 0x02, 0xfb, 0xe7, 0xf8, 0xd2, 0x59, - 0xaa, 0x5b, 0x1b, 0x15, 0x17, 0x0c, 0xf4, 0x16, 0x5f, 0x4a, 0xfd, 0x49, 0x3a, 0x88, 0x49, 0xa8, - 0xf8, 0x65, 0xc5, 0x97, 0x34, 0xf2, 0x16, 0x5f, 0x36, 0xba, 0xb0, 0xaa, 0x33, 0xe8, 0x05, 0x62, - 0xa4, 0xb2, 0x78, 0x0a, 0x05, 0x2a, 0x5d, 0xc9, 0x24, 0xca, 0xad, 0x72, 0xf3, 0x2a, 0x41, 0x57, - 0x11, 0x32, 0xdc, 0x20, 0x8a, 0x38, 0x4e, 0x12, 0x9f, 0x3a, 0xb9, 0x7a, 0x5e, 0x86, 0x6b, 0x80, - 0x6e, 0xe3, 0x7f, 0x39, 0x28, 0xee, 0x31, 0x42, 0x95, 0x29, 0x99, 0x18, 0x23, 0xd4, 0xa7, 0xc1, - 0x58, 0xda, 0xb3, 0x36, 0x4a, 0x6e, 0x51, 0x02, 0xdd, 0x60, 0x8c, 0xd1, 0x73, 0xa8, 0x2a, 0x32, - 0x19, 0x31, 0x2e, 0xc2, 0x54, 0x56, 0x46, 0x0a, 0x54, 0x24, 0xd8, 0x37, 0x18, 0x7a, 0x01, 0x95, - 0xcc, 0x97, 0x6c, 0x8d, 0x93, 0xaf, 0x5b, 0x1b, 0xd5, 0x6d, 0xeb, 0x4b, 0xb7, 0x6c, 0xe0, 0xcc, - 0xcf, 0x38, 0x98, 0x9e, 0x61, 0xec, 0x9f, 0x0f, 0x9c, 0x42, 0xdd, 0xda, 0x28, 0xb8, 0x45, 0x0d, - 0xbc, 0x1d, 0xa0, 0x1f, 0xc3, 0xda, 0xbc, 0x09, 0x7f, 0xd2, 0x4a, 0x46, 0xaa, 0x4e, 0xd5, 0x6d, - 0xeb, 0x95, 0x5b, 0x9b, 0xb3, 0xd3, 0x6b, 0x25, 0x23, 0xd4, 0x82, 0xfb, 0x09, 0x19, 0x52, 0x1c, - 0xf9, 0x63, 0x9c, 0x24, 0xc1, 0x10, 0xfb, 0x23, 0x1c, 0x44, 0x98, 0x3b, 0x45, 0x15, 0xde, 0x5d, - 0x4d, 0x1e, 0x69, 0xee, 0x50, 0x51, 0xe8, 0x25, 0xc0, 0x74, 0x92, 0x0e, 0xfc, 0x71, 0x30, 0x24, - 0xa1, 0x53, 0x52, 0xb6, 0x8b, 0xaf, 0xb7, 0xbe, 0xdc, 0x7a, 0xfd, 0x93, 0x57, 0x3f, 0x75, 0x4b, - 0x92, 0x3b, 0x92, 0x94, 0x16, 0xe4, 0x17, 0x46, 0x10, 0xae, 0x04, 0xb7, 0x5a, 0xaf, 0xb7, 0xa4, - 0x20, 0xbf, 0xd0, 0x82, 0x0f, 0x60, 0x39, 0xc1, 0xc3, 0x0f, 0x44, 0x38, 0xe5, 0xba, 0xb5, 0x51, - 0x74, 0xcd, 0x49, 0xe2, 0x67, 0x8c, 0x9f, 0x93, 0xc8, 0xa9, 0x48, 0x65, 0xd7, 0x9c, 0x1a, 0x09, - 0x38, 0x47, 0x69, 0x2c, 0x48, 0x42, 0x86, 0x2e, 0x8e, 0x30, 0x1e, 0xf7, 0xd5, 0xa4, 0xaa, 0xea, - 0xfc, 0x08, 0x56, 0x26, 0xe9, 0xe0, 0x1c, 0x5f, 0x26, 0x8e, 0x55, 0xcf, 0x6f, 0x94, 0x5b, 0xb5, - 0xe6, 0x62, 0xcb, 0xdd, 0x8c, 0x47, 0x9f, 0x03, 0xc8, 0xfc, 0x02, 0x91, 0x72, 0x9c, 0xa8, 0xde, - 0x56, 0xdc, 0x39, 0x04, 0x55, 0xc0, 0x1a, 0xeb, 0x1e, 0xb8, 0xd6, 0xb8, 0xf1, 0x97, 0x1c, 0x94, - 0xbd, 0x69, 0x87, 0x4e, 0x52, 0x91, 0xb5, 0xe1, 0x6a, 0x30, 0xac, 0xc5, 0xc1, 0x90, 0xe4, 0x84, - 0xe3, 0x0b, 0x7f, 0x14, 0x24, 0x23, 0xb5, 0x04, 0x15, 0xb7, 0x28, 0x81, 0xc3, 0x20, 0x19, 0xa9, - 0x21, 0x95, 0x24, 0xa1, 0x11, 0x9e, 0x9a, 0x15, 0x50, 0xe2, 0x1d, 0x09, 0x48, 0x5a, 0x6f, 0x9e, - 0x9f, 0x90, 0xa1, 0x6a, 0x70, 0xc5, 0x2d, 0x69, 0xa4, 0x4f, 0x86, 0xe8, 0x87, 0x50, 0x4c, 0xf0, - 0x6f, 0x53, 0x4c, 0x43, 0x6c, 0x1a, 0x0b, 0x5f, 0xb7, 0xde, 0x7c, 0xfd, 0x66, 0xeb, 0x75, 0xeb, - 0xcd, 0x2b, 0x77, 0xc6, 0xa1, 0x5f, 0x40, 0xd9, 0x98, 0x51, 0xb3, 0x24, 0x77, 0x61, 0xb5, 0x65, - 0x37, 0x55, 0x02, 0x57, 0xf5, 0xda, 0xae, 0xf4, 0x7b, 0xed, 0xee, 0xfe, 0xce, 0xfe, 0xbe, 0xdb, - 0xee, 0xf7, 0x5d, 0xe3, 0x59, 0x25, 0xf8, 0x0a, 0x8a, 0x63, 0x53, 0x65, 0x67, 0xa5, 0x6e, 0x6d, - 0x94, 0x5b, 0x0f, 0x9b, 0x9f, 0x2a, 0xbb, 0x3b, 0x13, 0x95, 0x4d, 0x0b, 0xc6, 0x2c, 0xa5, 0x42, - 0xcd, 0x50, 0xc1, 0x35, 0xa7, 0xc6, 0x7f, 0x2d, 0xa8, 0x78, 0xd3, 0xe3, 0x54, 0x64, 0x05, 0x74, - 0x60, 0xc5, 0xd4, 0xcb, 0x6c, 0x4b, 0x76, 0xfc, 0xde, 0x9d, 0x9b, 0xb3, 0x2f, 0x2b, 0x37, 0xb3, - 0x8f, 0x5a, 0x8b, 0xf9, 0xca, 0xbb, 0x63, 0xb5, 0xb5, 0xd6, 0xd4, 0x0e, 0xe7, 0x22, 0xfd, 0x54, - 0x8a, 0x4b, 0xb7, 0x4f, 0xf1, 0x05, 0xac, 0xb2, 0x89, 0xcf, 0xb1, 0x48, 0x39, 0xf5, 0xa3, 0x40, - 0x04, 0xe6, 0xa6, 0xa9, 0xb0, 0x89, 0xab, 0xc0, 0xfd, 0x40, 0x04, 0x8d, 0x2e, 0xd4, 0xb2, 0x7c, - 0x77, 0xcd, 0x15, 0x71, 0x15, 0xbb, 0xb5, 0x10, 0xfb, 0x73, 0xa8, 0x9a, 0xd8, 0xf5, 0x6c, 0x9a, - 0x91, 0xa9, 0x68, 0xb0, 0xa7, 0xb0, 0xc6, 0xdf, 0x72, 0x50, 0xf3, 0x78, 0x40, 0x93, 0x20, 0x14, - 0x84, 0xd1, 0xac, 0x86, 0x17, 0x98, 0x27, 0x84, 0x51, 0x55, 0xc3, 0xaa, 0x9b, 0x1d, 0xd1, 0x0b, - 0x58, 0x26, 0xb2, 0xd5, 0x7a, 0xb0, 0xcb, 0xad, 0x4a, 0x73, 0x6e, 0x78, 0x5d, 0xc3, 0xa1, 0xaf, - 0xa0, 0x3c, 0x20, 0xd4, 0x67, 0x2a, 0xca, 0xc4, 0xc9, 0x2b, 0x51, 0xbb, 0x79, 0x2d, 0x6e, 0x17, - 0x06, 0x84, 0x6a, 0x24, 0x41, 0x2f, 0x61, 0x25, 0x13, 0x5f, 0x52, 0xe2, 0xd5, 0xe6, 0x7c, 0x5b, - 0xdd, 0x8c, 0x95, 0x5d, 0x8c, 0x59, 0x78, 0xee, 0x0b, 0x32, 0xc6, 0x6a, 0x8c, 0xab, 0x6e, 0x51, - 0x02, 0x1e, 0x19, 0x63, 0x39, 0xe4, 0x3a, 0x04, 0x3f, 0xa4, 0x42, 0x95, 0xaf, 0xea, 0x96, 0x34, - 0xb2, 0x47, 0x85, 0xbc, 0xe8, 0x8d, 0x19, 0xc5, 0xaf, 0x28, 0x1e, 0x0c, 0x24, 0x05, 0x9e, 0x00, - 0xe0, 0xa9, 0xe0, 0x81, 0x2e, 0x7f, 0x51, 0x2f, 0x89, 0x42, 0x64, 0xed, 0x65, 0x87, 0xae, 0x68, - 0x3f, 0xc6, 0x54, 0xdf, 0x53, 0x6e, 0x65, 0x26, 0xf2, 0x0e, 0xd3, 0xc6, 0x9f, 0x2d, 0xb8, 0xe7, - 0x4d, 0x5d, 0xb9, 0x31, 0x89, 0xd8, 0xc7, 0x22, 0x20, 0xb1, 0xbe, 0x62, 0x9f, 0x43, 0x95, 0x6b, - 0xd4, 0x2c, 0xa9, 0x2e, 0x6e, 0xc5, 0x80, 0x7a, 0x4f, 0xd7, 0x61, 0x45, 0x4c, 0xb3, 0x0d, 0x97, - 0xfe, 0x97, 0xc5, 0x54, 0xed, 0xf7, 0x4d, 0xe7, 0xf9, 0x9b, 0xce, 0xd1, 0x26, 0xac, 0xcd, 0x49, - 0xb1, 0xb3, 0xb3, 0x04, 0x0b, 0x53, 0xa6, 0xda, 0x4c, 0xf0, 0x58, 0xc1, 0x8d, 0xdf, 0x5b, 0xb0, - 0x3e, 0x0b, 0xb4, 0x8f, 0x39, 0x09, 0x62, 0xf2, 0x2d, 0x8e, 0x54, 0xac, 0x2f, 0xa1, 0x36, 0xbb, - 0xb3, 0x16, 0xa2, 0x5d, 0x9d, 0xc1, 0x3a, 0xde, 0xc7, 0x50, 0x9a, 0x21, 0x26, 0xe2, 0x2b, 0x40, - 0x8d, 0xe0, 0xcc, 0xb0, 0x2f, 0xa6, 0x2a, 0x66, 0x39, 0x82, 0x57, 0xde, 0xa6, 0x8d, 0x3f, 0x59, - 0x50, 0xe9, 0x44, 0x98, 0x0a, 0x22, 0x2e, 0xb3, 0x8f, 0x00, 0xf5, 0x71, 0x60, 0x36, 0x58, 0x1f, - 0x10, 0x82, 0x42, 0x9a, 0x60, 0x6e, 0xde, 0x38, 0xf5, 0x5b, 0x62, 0x23, 0x96, 0x08, 0x65, 0xb6, - 0xe4, 0xaa, 0xdf, 0x12, 0x9b, 0x30, 0xae, 0xb3, 0x2e, 0xb9, 0xea, 0xb7, 0xc2, 0x02, 0xa1, 0xdf, - 0x2c, 0x89, 0x05, 0x62, 0x84, 0xd6, 0x61, 0x49, 0x27, 0xb6, 0x9c, 0x3d, 0x88, 0xfa, 0xbc, 0xf9, - 0x5d, 0x0e, 0xca, 0x07, 0x01, 0x89, 0x53, 0xae, 0xbf, 0x49, 0x9e, 0xc0, 0x43, 0x73, 0xf4, 0x4f, - 0x28, 0x9e, 0x4e, 0x70, 0x28, 0x66, 0xaf, 0x97, 0x6d, 0xa1, 0xcf, 0xe0, 0x41, 0x46, 0xef, 0xa6, - 0x42, 0x30, 0xda, 0x36, 0x22, 0x76, 0x0e, 0xdd, 0x87, 0xb5, 0x8c, 0x93, 0x85, 0x6f, 0x73, 0xce, - 0xb8, 0x9d, 0x47, 0x8f, 0x60, 0x3d, 0x83, 0x77, 0xd4, 0xda, 0xed, 0x05, 0x34, 0xc4, 0x71, 0x8c, - 0x23, 0xbb, 0x80, 0xd6, 0xe1, 0x6e, 0x46, 0xf6, 0xc8, 0x95, 0xb1, 0x25, 0xe4, 0xc0, 0xbd, 0x39, - 0xe2, 0x4a, 0x65, 0x19, 0x3d, 0x00, 0x34, 0xc7, 0x74, 0xe8, 0x45, 0x10, 0x93, 0xc8, 0x5e, 0x41, - 0x8f, 0xc1, 0xc9, 0x70, 0x03, 0xf6, 0xb3, 0xd6, 0xd8, 0xc5, 0x05, 0x7b, 0x9c, 0x85, 0x38, 0x49, - 0x74, 0x7c, 0xa5, 0xf9, 0x94, 0xba, 0x4c, 0xb4, 0x29, 0x4b, 0x87, 0xa3, 0x83, 0x94, 0x46, 0x89, - 0x0d, 0xd7, 0xb8, 0x0e, 0x25, 0xc2, 0x74, 0xd2, 0x2e, 0xa3, 0x87, 0x70, 0x3f, 0xe3, 0x0e, 0x08, - 0x1f, 0x7f, 0x08, 0x38, 0xd6, 0x26, 0xc3, 0xcd, 0x3f, 0x5a, 0x60, 0x5f, 0xbf, 0x35, 0x91, 0x0d, - 0x95, 0xde, 0xce, 0xaf, 0xbd, 0x63, 0xf3, 0x50, 0xd8, 0x77, 0xd0, 0x5d, 0xa8, 0x29, 0xa4, 0xbf, - 0xe7, 0x76, 0x7a, 0xde, 0xe1, 0x4e, 0xff, 0xd0, 0xb6, 0xd0, 0x1a, 0x54, 0x15, 0x78, 0x74, 0xf2, - 0xce, 0xeb, 0xf4, 0x3b, 0xdf, 0xd8, 0xb9, 0x19, 0x74, 0xdc, 0x73, 0xdb, 0xde, 0x89, 0xdb, 0xb5, - 0xf3, 0x33, 0x63, 0xef, 0x3b, 0x5e, 0x57, 0x1a, 0x2b, 0xa0, 0x7b, 0x60, 0x2b, 0xa4, 0xd7, 0xea, - 0x1f, 0x66, 0xe8, 0xd2, 0x66, 0x0c, 0xb5, 0x6b, 0xcf, 0x95, 0x54, 0x9d, 0x7f, 0xb0, 0xec, 0x3b, - 0xd2, 0xbe, 0x42, 0x66, 0x2e, 0x2d, 0x54, 0x81, 0x62, 0xfb, 0xd4, 0x6b, 0xbb, 0xdd, 0x9d, 0x77, - 0x76, 0x6e, 0xa6, 0x92, 0xd9, 0xcd, 0x4b, 0x6f, 0x0a, 0x99, 0xf7, 0x56, 0xd8, 0x3c, 0x81, 0xb2, - 0xd9, 0x30, 0xe5, 0xa9, 0x0c, 0x2b, 0xde, 0x69, 0xa7, 0xdb, 0x3b, 0xf1, 0xec, 0x3b, 0xd2, 0xa2, - 0x77, 0x7a, 0x7c, 0xe2, 0xc9, 0x93, 0x85, 0x00, 0x96, 0xbd, 0xd3, 0xa3, 0xb6, 0xb7, 0x63, 0xe7, - 0xd0, 0x2a, 0x80, 0x77, 0x7a, 0xd0, 0xe9, 0x76, 0xfa, 0x87, 0xed, 0x7d, 0x3b, 0x8f, 0x6a, 0x50, - 0xf6, 0x4e, 0xdb, 0xa7, 0x9e, 0xbb, 0xb3, 0xbf, 0xe3, 0xed, 0xd8, 0x85, 0xcd, 0xff, 0xe4, 0x60, - 0x4d, 0x4f, 0xdb, 0xbc, 0xf5, 0x75, 0xb8, 0xbb, 0x00, 0xfa, 0xc7, 0x62, 0x84, 0xb9, 0x6d, 0xa1, - 0x06, 0x7c, 0xbe, 0x48, 0x1c, 0x60, 0x7c, 0x7c, 0x81, 0xb9, 0x37, 0xe2, 0x38, 0x19, 0xb1, 0x58, - 0xce, 0xea, 0x53, 0x78, 0xb4, 0x28, 0xb3, 0xc7, 0xe8, 0x19, 0xe1, 0x63, 0xdd, 0x35, 0x3b, 0x2f, - 0xf7, 0x60, 0x51, 0xc0, 0xc5, 0x09, 0x16, 0xfb, 0xf8, 0x82, 0x84, 0xd8, 0x2e, 0xdc, 0xa4, 0x8d, - 0xfe, 0x7b, 0xc6, 0xe5, 0xf4, 0x3e, 0x06, 0x67, 0x91, 0x7e, 0x4f, 0x26, 0xd8, 0x28, 0x2f, 0xdf, - 0x54, 0xee, 0x71, 0x26, 0x70, 0x28, 0xf6, 0x82, 0x38, 0xb6, 0x57, 0xe4, 0xa8, 0x2e, 0xd2, 0x72, - 0x8e, 0xbd, 0xa9, 0x5d, 0xbc, 0x19, 0x75, 0x36, 0x78, 0x7b, 0x23, 0x1c, 0x9e, 0xdb, 0x25, 0x39, - 0x93, 0x8b, 0x02, 0x3b, 0xfa, 0xcd, 0xb7, 0x41, 0xae, 0xe1, 0x35, 0xa7, 0xd9, 0x37, 0xbd, 0x5d, - 0xde, 0xfc, 0x1d, 0xdc, 0xeb, 0x11, 0x7a, 0x14, 0x08, 0x4e, 0xa6, 0xf3, 0x35, 0xae, 0xc3, 0xe3, - 0x8f, 0xe1, 0xfe, 0x5e, 0xca, 0x39, 0xa6, 0xc2, 0xb6, 0xd0, 0x33, 0x78, 0xf2, 0x51, 0x89, 0x2e, - 0xfe, 0x70, 0x40, 0x78, 0x22, 0xec, 0x9c, 0xec, 0xc7, 0xa7, 0x44, 0xfa, 0x38, 0x64, 0x34, 0xb2, - 0xf3, 0x9b, 0xbf, 0x01, 0xe4, 0xe2, 0x90, 0x5d, 0x60, 0x7e, 0xa9, 0xcb, 0xa4, 0xdc, 0xff, 0x00, - 0x9e, 0xdd, 0x44, 0xfd, 0x7e, 0xc8, 0x83, 0xf1, 0x20, 0xc6, 0x91, 0x2c, 0x76, 0x62, 0xdf, 0x91, - 0xf5, 0xfc, 0x88, 0x98, 0x76, 0x68, 0x5b, 0x9b, 0x67, 0x50, 0x93, 0x92, 0xf3, 0x79, 0x3d, 0x84, - 0xfb, 0xd7, 0x20, 0xbf, 0x17, 0x07, 0x84, 0xda, 0x77, 0x64, 0x9d, 0xae, 0x53, 0xda, 0xd2, 0x1b, - 0xdb, 0xfa, 0x34, 0xb9, 0x65, 0xe7, 0xb6, 0x7f, 0x06, 0x2b, 0x1f, 0x88, 0x7a, 0x41, 0xd0, 0xb3, - 0xa6, 0xfe, 0x2f, 0xd8, 0xcc, 0xfe, 0x0b, 0x36, 0xdb, 0x34, 0x1d, 0xff, 0x2a, 0x88, 0x53, 0x7c, - 0x3c, 0x91, 0x77, 0x60, 0xe2, 0x7c, 0xf7, 0x87, 0xbc, 0xfe, 0x52, 0x97, 0x3a, 0x1d, 0xba, 0xfd, - 0x73, 0x28, 0x2a, 0x6d, 0x96, 0x8a, 0xdb, 0xa8, 0xff, 0xdd, 0xa8, 0x2b, 0x97, 0xc7, 0xa9, 0xd8, - 0xfe, 0x06, 0xaa, 0x4a, 0x3f, 0xc2, 0x83, 0x74, 0x78, 0xcb, 0x18, 0xfe, 0x61, 0x8c, 0x94, 0xa5, - 0xe6, 0xbe, 0x54, 0xec, 0xd0, 0xed, 0x0e, 0xac, 0xce, 0x19, 0xba, 0x65, 0x38, 0xff, 0x34, 0x96, - 0x2a, 0x33, 0x4b, 0x32, 0xa6, 0x5f, 0x42, 0x49, 0x99, 0x12, 0x84, 0x5e, 0xde, 0xc6, 0xca, 0xbf, - 0x8c, 0x15, 0x55, 0x09, 0x8f, 0xd0, 0xcb, 0xed, 0x77, 0x50, 0x53, 0x16, 0x06, 0x8c, 0x89, 0x98, - 0xa9, 0x3f, 0x4f, 0xb7, 0xb0, 0xf3, 0x6f, 0x63, 0x47, 0x25, 0xb2, 0x3b, 0x53, 0xdd, 0xfd, 0x0a, - 0x9e, 0x87, 0x6c, 0xdc, 0x4c, 0x02, 0xc1, 0x92, 0x11, 0x89, 0x83, 0x41, 0xd2, 0x14, 0x1c, 0x7f, - 0xcb, 0x78, 0x33, 0x26, 0x83, 0x99, 0xbd, 0x5d, 0xf0, 0x14, 0x28, 0xdb, 0xfb, 0xff, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x70, 0x88, 0xcd, 0x71, 0xe2, 0x0f, 0x00, 0x00, -} diff --git a/client/accounts/usbwallet/internal/trezor/types.proto b/client/accounts/usbwallet/internal/trezor/types.proto deleted file mode 100644 index acbe79e3f..000000000 --- a/client/accounts/usbwallet/internal/trezor/types.proto +++ /dev/null @@ -1,278 +0,0 @@ -// This file originates from the SatoshiLabs Trezor `common` repository at: -// https://github.com/trezor/trezor-common/blob/master/protob/types.proto -// dated 28.07.2017, commit dd8ec3231fb5f7992360aff9bdfe30bb58130f4b. - -syntax = "proto2"; - -/** - * Types for TREZOR communication - * - * @author Marek Palatinus - * @version 1.2 - */ - -// Sugar for easier handling in Java -option java_package = "com.satoshilabs.trezor.lib.protobuf"; -option java_outer_classname = "TrezorType"; - -import "google/protobuf/descriptor.proto"; - -/** - * Options for specifying message direction and type of wire (normal/debug) - */ -extend google.protobuf.EnumValueOptions { - optional bool wire_in = 50002; // message can be transmitted via wire from PC to TREZOR - optional bool wire_out = 50003; // message can be transmitted via wire from TREZOR to PC - optional bool wire_debug_in = 50004; // message can be transmitted via debug wire from PC to TREZOR - optional bool wire_debug_out = 50005; // message can be transmitted via debug wire from TREZOR to PC - optional bool wire_tiny = 50006; // message is handled by TREZOR when the USB stack is in tiny mode - optional bool wire_bootloader = 50007; // message is only handled by TREZOR Bootloader -} - -/** - * Type of failures returned by Failure message - * @used_in Failure - */ -enum FailureType { - Failure_UnexpectedMessage = 1; - Failure_ButtonExpected = 2; - Failure_DataError = 3; - Failure_ActionCancelled = 4; - Failure_PinExpected = 5; - Failure_PinCancelled = 6; - Failure_PinInvalid = 7; - Failure_InvalidSignature = 8; - Failure_ProcessError = 9; - Failure_NotEnoughFunds = 10; - Failure_NotInitialized = 11; - Failure_FirmwareError = 99; -} - -/** - * Type of script which will be used for transaction output - * @used_in TxOutputType - */ -enum OutputScriptType { - PAYTOADDRESS = 0; // used for all addresses (bitcoin, p2sh, witness) - PAYTOSCRIPTHASH = 1; // p2sh address (deprecated; use PAYTOADDRESS) - PAYTOMULTISIG = 2; // only for change output - PAYTOOPRETURN = 3; // op_return - PAYTOWITNESS = 4; // only for change output - PAYTOP2SHWITNESS = 5; // only for change output -} - -/** - * Type of script which will be used for transaction output - * @used_in TxInputType - */ -enum InputScriptType { - SPENDADDRESS = 0; // standard p2pkh address - SPENDMULTISIG = 1; // p2sh multisig address - EXTERNAL = 2; // reserved for external inputs (coinjoin) - SPENDWITNESS = 3; // native segwit - SPENDP2SHWITNESS = 4; // segwit over p2sh (backward compatible) -} - -/** - * Type of information required by transaction signing process - * @used_in TxRequest - */ -enum RequestType { - TXINPUT = 0; - TXOUTPUT = 1; - TXMETA = 2; - TXFINISHED = 3; - TXEXTRADATA = 4; -} - -/** - * Type of button request - * @used_in ButtonRequest - */ -enum ButtonRequestType { - ButtonRequest_Other = 1; - ButtonRequest_FeeOverThreshold = 2; - ButtonRequest_ConfirmOutput = 3; - ButtonRequest_ResetDevice = 4; - ButtonRequest_ConfirmWord = 5; - ButtonRequest_WipeDevice = 6; - ButtonRequest_ProtectCall = 7; - ButtonRequest_SignTx = 8; - ButtonRequest_FirmwareCheck = 9; - ButtonRequest_Address = 10; - ButtonRequest_PublicKey = 11; -} - -/** - * Type of PIN request - * @used_in PinMatrixRequest - */ -enum PinMatrixRequestType { - PinMatrixRequestType_Current = 1; - PinMatrixRequestType_NewFirst = 2; - PinMatrixRequestType_NewSecond = 3; -} - -/** - * Type of recovery procedure. These should be used as bitmask, e.g., - * `RecoveryDeviceType_ScrambledWords | RecoveryDeviceType_Matrix` - * listing every method supported by the host computer. - * - * Note that ScrambledWords must be supported by every implementation - * for backward compatibility; there is no way to not support it. - * - * @used_in RecoveryDevice - */ -enum RecoveryDeviceType { - // use powers of two when extending this field - RecoveryDeviceType_ScrambledWords = 0; // words in scrambled order - RecoveryDeviceType_Matrix = 1; // matrix recovery type -} - -/** - * Type of Recovery Word request - * @used_in WordRequest - */ -enum WordRequestType { - WordRequestType_Plain = 0; - WordRequestType_Matrix9 = 1; - WordRequestType_Matrix6 = 2; -} - -/** - * Structure representing BIP32 (hierarchical deterministic) node - * Used for imports of private key into the device and exporting public key out of device - * @used_in PublicKey - * @used_in LoadDevice - * @used_in DebugLinkState - * @used_in Storage - */ -message HDNodeType { - required uint32 depth = 1; - required uint32 fingerprint = 2; - required uint32 child_num = 3; - required bytes chain_code = 4; - optional bytes private_key = 5; - optional bytes public_key = 6; -} - -message HDNodePathType { - required HDNodeType node = 1; // BIP-32 node in deserialized form - repeated uint32 address_n = 2; // BIP-32 path to derive the key from node -} - -/** - * Structure representing Coin - * @used_in Features - */ -message CoinType { - optional string coin_name = 1; - optional string coin_shortcut = 2; - optional uint32 address_type = 3 [default=0]; - optional uint64 maxfee_kb = 4; - optional uint32 address_type_p2sh = 5 [default=5]; - optional string signed_message_header = 8; - optional uint32 xpub_magic = 9 [default=76067358]; // default=0x0488b21e - optional uint32 xprv_magic = 10 [default=76066276]; // default=0x0488ade4 - optional bool segwit = 11; - optional uint32 forkid = 12; -} - -/** - * Type of redeem script used in input - * @used_in TxInputType - */ -message MultisigRedeemScriptType { - repeated HDNodePathType pubkeys = 1; // pubkeys from multisig address (sorted lexicographically) - repeated bytes signatures = 2; // existing signatures for partially signed input - optional uint32 m = 3; // "m" from n, how many valid signatures is necessary for spending -} - -/** - * Structure representing transaction input - * @used_in SimpleSignTx - * @used_in TransactionType - */ -message TxInputType { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - required bytes prev_hash = 2; // hash of previous transaction output to spend by this input - required uint32 prev_index = 3; // index of previous output to spend - optional bytes script_sig = 4; // script signature, unset for tx to sign - optional uint32 sequence = 5 [default=4294967295]; // sequence (default=0xffffffff) - optional InputScriptType script_type = 6 [default=SPENDADDRESS]; // defines template of input script - optional MultisigRedeemScriptType multisig = 7; // Filled if input is going to spend multisig tx - optional uint64 amount = 8; // amount of previous transaction output (for segwit only) -} - -/** - * Structure representing transaction output - * @used_in SimpleSignTx - * @used_in TransactionType - */ -message TxOutputType { - optional string address = 1; // target coin address in Base58 encoding - repeated uint32 address_n = 2; // BIP-32 path to derive the key from master node; has higher priority than "address" - required uint64 amount = 3; // amount to spend in satoshis - required OutputScriptType script_type = 4; // output script type - optional MultisigRedeemScriptType multisig = 5; // defines multisig address; script_type must be PAYTOMULTISIG - optional bytes op_return_data = 6; // defines op_return data; script_type must be PAYTOOPRETURN, amount must be 0 -} - -/** - * Structure representing compiled transaction output - * @used_in TransactionType - */ -message TxOutputBinType { - required uint64 amount = 1; - required bytes script_pubkey = 2; -} - -/** - * Structure representing transaction - * @used_in SimpleSignTx - */ -message TransactionType { - optional uint32 version = 1; - repeated TxInputType inputs = 2; - repeated TxOutputBinType bin_outputs = 3; - repeated TxOutputType outputs = 5; - optional uint32 lock_time = 4; - optional uint32 inputs_cnt = 6; - optional uint32 outputs_cnt = 7; - optional bytes extra_data = 8; - optional uint32 extra_data_len = 9; -} - -/** - * Structure representing request details - * @used_in TxRequest - */ -message TxRequestDetailsType { - optional uint32 request_index = 1; // device expects TxAck message from the computer - optional bytes tx_hash = 2; // tx_hash of requested transaction - optional uint32 extra_data_len = 3; // length of requested extra data - optional uint32 extra_data_offset = 4; // offset of requested extra data -} - -/** - * Structure representing serialized data - * @used_in TxRequest - */ -message TxRequestSerializedType { - optional uint32 signature_index = 1; // 'signature' field contains signed input of this index - optional bytes signature = 2; // signature of the signature_index input - optional bytes serialized_tx = 3; // part of serialized and signed transaction -} - -/** - * Structure representing identity data - * @used_in IdentityType - */ -message IdentityType { - optional string proto = 1; // proto part of URI - optional string user = 2; // user part of URI - optional string host = 3; // host part of URI - optional string port = 4; // port part of URI - optional string path = 5; // path part of URI - optional uint32 index = 6 [default=0]; // identity index -} diff --git a/client/accounts/usbwallet/ledger.go b/client/accounts/usbwallet/ledger.go index e168b64df..01ec9ddee 100644 --- a/client/accounts/usbwallet/ledger.go +++ b/client/accounts/usbwallet/ledger.go @@ -32,8 +32,8 @@ type ledgerParam1 byte type ledgerParam2 byte const ( - ledgerOpRetrieveAddress ledgerOpcode = 0x02 // Returns the public key and Ethereum address for a given BIP 32 path - ledgerOpSignTransaction ledgerOpcode = 0x04 // Signs an Ethereum transaction after having the user validate the parameters + ledgerOpRetrieveAddress ledgerOpcode = 0x02 // Returns the public key and Kowala address for a given BIP 32 path + ledgerOpSignTransaction ledgerOpcode = 0x04 // Signs a Kowala transaction after having the user validate the parameters ledgerOpGetConfiguration ledgerOpcode = 0x06 // Returns specific wallet application configuration ledgerP1DirectlyFetchAddress ledgerParam1 = 0x00 // Return address directly from the wallet @@ -74,15 +74,15 @@ func (w *ledgerDriver) Status() (string, error) { return fmt.Sprintf("Failed: %v", w.failure), w.failure } if w.browser { - return "Ethereum app in browser mode", w.failure + return "Kowala app in browser mode", w.failure } if w.offline() { - return "Ethereum app offline", w.failure + return "Kowala app offline", w.failure } - return fmt.Sprintf("Ethereum app v%d.%d.%d online", w.version[0], w.version[1], w.version[2]), w.failure + return fmt.Sprintf("Kowala app v%d.%d.%d online", w.version[0], w.version[1], w.version[2]), w.failure } -// offline returns whether the wallet and the Ethereum app is offline or not. +// offline returns whether the wallet and the Kowala app is offline or not. // // The method assumes that the state lock is held! func (w *ledgerDriver) offline() bool { @@ -97,13 +97,13 @@ func (w *ledgerDriver) Open(device io.ReadWriter, passphrase string) error { _, err := w.ledgerDerive(accounts.DefaultBaseDerivationPath) if err != nil { - // Ethereum app is not running or in browser mode, nothing more to do, return + // Kowala app is not running or in browser mode, nothing more to do, return if err == errLedgerReplyInvalidHeader { w.browser = true } return nil } - // Try to resolve the Ethereum app's version, will fail prior to v1.0.2 + // Try to resolve the Kowala app's version, will fail prior to v1.0.2 if w.version, err = w.ledgerVersion(); err != nil { w.version = [3]byte{1, 0, 0} // Assume worst case, can't verify if v1.0.0 or v1.0.1 } @@ -128,7 +128,7 @@ func (w *ledgerDriver) Heartbeat() error { } // Derive implements usbwallet.driver, sending a derivation request to the Ledger -// and returning the Ethereum address located on that derivation path. +// and returning the Kowala address located on that derivation path. func (w *ledgerDriver) Derive(path accounts.DerivationPath) (common.Address, error) { return w.ledgerDerive(path) } @@ -136,11 +136,11 @@ func (w *ledgerDriver) Derive(path accounts.DerivationPath) (common.Address, err // SignTx implements usbwallet.driver, sending the transaction to the Ledger and // waiting for the user to confirm or deny the transaction. // -// Note, if the version of the Ethereum application running on the Ledger wallet is +// Note, if the version of the Kowala application running on the Ledger wallet is // too old to sign EIP-155 transactions, but such is requested nonetheless, an error // will be returned opposed to silently signing in Homestead mode. func (w *ledgerDriver) SignTx(path accounts.DerivationPath, tx *types.Transaction, chainID *big.Int) (common.Address, *types.Transaction, error) { - // If the Ethereum app doesn't run, abort + // If the Kowala app doesn't run, abort if w.offline() { return common.Address{}, nil, accounts.ErrWalletClosed } @@ -152,7 +152,7 @@ func (w *ledgerDriver) SignTx(path accounts.DerivationPath, tx *types.Transactio return w.ledgerSign(path, tx, chainID) } -// ledgerVersion retrieves the current version of the Ethereum wallet app running +// ledgerVersion retrieves the current version of the Kowala wallet app running // on the Ledger wallet. // // The version retrieval protocol is defined as follows: @@ -184,7 +184,7 @@ func (w *ledgerDriver) ledgerVersion() ([3]byte, error) { return version, nil } -// ledgerDerive retrieves the currently active Ethereum address from a Ledger +// ledgerDerive retrieves the currently active Kowala address from a Ledger // wallet at the specified derivation path. // // The address derivation protocol is defined as follows: @@ -212,8 +212,8 @@ func (w *ledgerDriver) ledgerVersion() ([3]byte, error) { // ------------------------+------------------- // Public Key length | 1 byte // Uncompressed Public Key | arbitrary -// Ethereum address length | 1 byte -// Ethereum address | 40 bytes hex ascii +// Kowala address length | 1 byte +// Kowala address | 40 bytes hex ascii // Chain code if requested | 32 bytes func (w *ledgerDriver) ledgerDerive(derivationPath []uint32) (common.Address, error) { // Flatten the derivation path into the Ledger request @@ -233,13 +233,13 @@ func (w *ledgerDriver) ledgerDerive(derivationPath []uint32) (common.Address, er } reply = reply[1+int(reply[0]):] - // Extract the Ethereum hex address string + // Extract the Kowala hex address string if len(reply) < 1 || len(reply) < 1+int(reply[0]) { return common.Address{}, errors.New("reply lacks address entry") } hexstr := reply[1 : 1+int(reply[0])] - // Decode the hex sting into an Ethereum address and return + // Decode the hex sting into an Kowala address and return var address common.Address hex.Decode(address[:], hexstr) return address, nil @@ -286,20 +286,15 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction for i, component := range derivationPath { binary.BigEndian.PutUint32(path[1+4*i:], component) } - // Create the transaction RLP based on whether legacy or EIP155 signing was requested + var ( txrlp []byte err error ) - if chainID == nil { - if txrlp, err = rlp.EncodeToBytes([]interface{}{tx.Nonce(), tx.GasPrice(), tx.Gas(), tx.To(), tx.Value(), tx.Data()}); err != nil { - return common.Address{}, nil, err - } - } else { - if txrlp, err = rlp.EncodeToBytes([]interface{}{tx.Nonce(), tx.GasPrice(), tx.Gas(), tx.To(), tx.Value(), tx.Data(), chainID, big.NewInt(0), big.NewInt(0)}); err != nil { - return common.Address{}, nil, err - } + if txrlp, err = rlp.EncodeToBytes([]interface{}{tx.Nonce(), tx.ComputeLimit(), tx.To(), tx.Value(), tx.Data(), chainID, big.NewInt(0), big.NewInt(0)}); err != nil { + return common.Address{}, nil, err } + payload := append(path, txrlp...) // Send the request and wait for the response @@ -322,20 +317,14 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction payload = payload[chunk:] op = ledgerP1ContTransactionData } - // Extract the Ethereum signature and do a sanity validation + // Extract the Kowala signature and do a sanity validation if len(reply) != 65 { return common.Address{}, nil, errors.New("reply lacks signature") } signature := append(reply[1:], reply[0]) + signer := types.NewAndromedaSigner(chainID) + signature[64] = signature[64] - byte(chainID.Uint64()*2+35) - // Create the correct signer and signature transform based on the chain ID - var signer types.Signer - if chainID == nil { - signer = types.UnprotectedSigner{} - } else { - signer = types.NewAndromedaSigner(chainID) - signature[64] = signature[64] - byte(chainID.Uint64()*2+35) - } signed, err := tx.WithSignature(signer, signature) if err != nil { return common.Address{}, nil, err diff --git a/client/accounts/usbwallet/trezor.go b/client/accounts/usbwallet/trezor.go deleted file mode 100644 index e23e5ec73..000000000 --- a/client/accounts/usbwallet/trezor.go +++ /dev/null @@ -1,314 +0,0 @@ -// This file contains the implementation for interacting with the Trezor hardware -// wallets. The wire protocol spec can be found on the SatoshiLabs website: -// https://doc.satoshilabs.com/trezor-tech/api-protobuf.html - -package usbwallet - -import ( - "encoding/binary" - "errors" - "fmt" - "io" - "math/big" - - "github.com/golang/protobuf/proto" - "github.com/kowala-tech/kcoin/client/accounts" - "github.com/kowala-tech/kcoin/client/accounts/usbwallet/internal/trezor" - "github.com/kowala-tech/kcoin/client/common" - "github.com/kowala-tech/kcoin/client/common/hexutil" - "github.com/kowala-tech/kcoin/client/core/types" - "github.com/kowala-tech/kcoin/client/log" -) - -// ErrTrezorPINNeeded is returned if opening the trezor requires a PIN code. In -// this case, the calling application should display a pinpad and send back the -// encoded passphrase. -var ErrTrezorPINNeeded = errors.New("trezor: pin needed") - -// errTrezorReplyInvalidHeader is the error message returned by a Trezor data exchange -// if the device replies with a mismatching header. This usually means the device -// is in browser mode. -var errTrezorReplyInvalidHeader = errors.New("trezor: invalid reply header") - -// trezorDriver implements the communication with a Trezor hardware wallet. -type trezorDriver struct { - device io.ReadWriter // USB device connection to communicate through - version [3]uint32 // Current version of the Trezor firmware - label string // Current textual label of the Trezor device - pinwait bool // Flags whether the device is waiting for PIN entry - failure error // Any failure that would make the device unusable - log log.Logger // Contextual logger to tag the trezor with its id -} - -// newTrezorDriver creates a new instance of a Trezor USB protocol driver. -func newTrezorDriver(logger log.Logger) driver { - return &trezorDriver{ - log: logger, - } -} - -// Status implements accounts.Wallet, always whether the Trezor is opened, closed -// or whether the Ethereum app was not started on it. -func (w *trezorDriver) Status() (string, error) { - if w.failure != nil { - return fmt.Sprintf("Failed: %v", w.failure), w.failure - } - if w.device == nil { - return "Closed", w.failure - } - if w.pinwait { - return fmt.Sprintf("Trezor v%d.%d.%d '%s' waiting for PIN", w.version[0], w.version[1], w.version[2], w.label), w.failure - } - return fmt.Sprintf("Trezor v%d.%d.%d '%s' online", w.version[0], w.version[1], w.version[2], w.label), w.failure -} - -// Open implements usbwallet.driver, attempting to initialize the connection to -// the Trezor hardware wallet. Initializing the Trezor is a two phase operation: -// * The first phase is to initialize the connection and read the wallet's -// features. This phase is invoked is the provided passphrase is empty. The -// device will display the pinpad as a result and will return an appropriate -// error to notify the user that a second open phase is needed. -// * The second phase is to unlock access to the Trezor, which is done by the -// user actually providing a passphrase mapping a keyboard keypad to the pin -// number of the user (shuffled according to the pinpad displayed). -func (w *trezorDriver) Open(device io.ReadWriter, passphrase string) error { - w.device, w.failure = device, nil - - // If phase 1 is requested, init the connection and wait for user callback - if passphrase == "" { - // If we're already waiting for a PIN entry, insta-return - if w.pinwait { - return ErrTrezorPINNeeded - } - // Initialize a connection to the device - features := new(trezor.Features) - if _, err := w.trezorExchange(&trezor.Initialize{}, features); err != nil { - return err - } - w.version = [3]uint32{features.GetMajorVersion(), features.GetMinorVersion(), features.GetPatchVersion()} - w.label = features.GetLabel() - - // Do a manual ping, forcing the device to ask for its PIN - askPin := true - res, err := w.trezorExchange(&trezor.Ping{PinProtection: &askPin}, new(trezor.PinMatrixRequest), new(trezor.Success)) - if err != nil { - return err - } - // Only return the PIN request if the device wasn't unlocked until now - if res == 1 { - return nil // Device responded with trezor.Success - } - w.pinwait = true - return ErrTrezorPINNeeded - } - // Phase 2 requested with actual PIN entry - w.pinwait = false - - if _, err := w.trezorExchange(&trezor.PinMatrixAck{Pin: &passphrase}, new(trezor.Success)); err != nil { - w.failure = err - return err - } - return nil -} - -// Close implements usbwallet.driver, cleaning up and metadata maintained within -// the Trezor driver. -func (w *trezorDriver) Close() error { - w.version, w.label, w.pinwait = [3]uint32{}, "", false - return nil -} - -// Heartbeat implements usbwallet.driver, performing a sanity check against the -// Trezor to see if it's still online. -func (w *trezorDriver) Heartbeat() error { - if _, err := w.trezorExchange(&trezor.Ping{}, new(trezor.Success)); err != nil { - w.failure = err - return err - } - return nil -} - -// Derive implements usbwallet.driver, sending a derivation request to the Trezor -// and returning the Ethereum address located on that derivation path. -func (w *trezorDriver) Derive(path accounts.DerivationPath) (common.Address, error) { - return w.trezorDerive(path) -} - -// SignTx implements usbwallet.driver, sending the transaction to the Trezor and -// waiting for the user to confirm or deny the transaction. -func (w *trezorDriver) SignTx(path accounts.DerivationPath, tx *types.Transaction, chainID *big.Int) (common.Address, *types.Transaction, error) { - if w.device == nil { - return common.Address{}, nil, accounts.ErrWalletClosed - } - return w.trezorSign(path, tx, chainID) -} - -// trezorDerive sends a derivation request to the Trezor device and returns the -// Ethereum address located on that path. -func (w *trezorDriver) trezorDerive(derivationPath []uint32) (common.Address, error) { - address := new(trezor.EthereumAddress) - if _, err := w.trezorExchange(&trezor.EthereumGetAddress{AddressN: derivationPath}, address); err != nil { - return common.Address{}, err - } - return common.BytesToAddress(address.GetAddress()), nil -} - -// trezorSign sends the transaction to the Trezor wallet, and waits for the user -// to confirm or deny the transaction. -func (w *trezorDriver) trezorSign(derivationPath []uint32, tx *types.Transaction, chainID *big.Int) (common.Address, *types.Transaction, error) { - // Create the transaction initiation message - data := tx.Data() - length := uint32(len(data)) - - request := &trezor.EthereumSignTx{ - AddressN: derivationPath, - Nonce: new(big.Int).SetUint64(tx.Nonce()).Bytes(), - GasPrice: tx.GasPrice().Bytes(), - GasLimit: new(big.Int).SetUint64(tx.Gas()).Bytes(), - Value: tx.Value().Bytes(), - DataLength: &length, - } - if to := tx.To(); to != nil { - request.To = (*to)[:] // Non contract deploy, set recipient explicitly - } - if length > 1024 { // Send the data chunked if that was requested - request.DataInitialChunk, data = data[:1024], data[1024:] - } else { - request.DataInitialChunk, data = data, nil - } - if chainID != nil { // EIP-155 transaction, set chain ID explicitly (only 32 bit is supported!?) - id := uint32(chainID.Int64()) - request.ChainId = &id - } - // Send the initiation message and stream content until a signature is returned - response := new(trezor.EthereumTxRequest) - if _, err := w.trezorExchange(request, response); err != nil { - return common.Address{}, nil, err - } - for response.DataLength != nil && int(*response.DataLength) <= len(data) { - chunk := data[:*response.DataLength] - data = data[*response.DataLength:] - - if _, err := w.trezorExchange(&trezor.EthereumTxAck{DataChunk: chunk}, response); err != nil { - return common.Address{}, nil, err - } - } - // Extract the Ethereum signature and do a sanity validation - if len(response.GetSignatureR()) == 0 || len(response.GetSignatureS()) == 0 || response.GetSignatureV() == 0 { - return common.Address{}, nil, errors.New("reply lacks signature") - } - signature := append(append(response.GetSignatureR(), response.GetSignatureS()...), byte(response.GetSignatureV())) - - // Create the correct signer and signature transform based on the chain ID - var signer types.Signer - if chainID == nil { - signer = new(types.UnprotectedSigner) - } else { - signer = types.NewAndromedaSigner(chainID) - signature[64] = signature[64] - byte(chainID.Uint64()*2+35) - } - // Inject the final signature into the transaction and sanity check the sender - signed, err := tx.WithSignature(signer, signature) - if err != nil { - return common.Address{}, nil, err - } - sender, err := types.TxSender(signer, signed) - if err != nil { - return common.Address{}, nil, err - } - return sender, signed, nil -} - -// trezorExchange performs a data exchange with the Trezor wallet, sending it a -// message and retrieving the response. If multiple responses are possible, the -// method will also return the index of the destination object used. -func (w *trezorDriver) trezorExchange(req proto.Message, results ...proto.Message) (int, error) { - // Construct the original message payload to chunk up - data, err := proto.Marshal(req) - if err != nil { - return 0, err - } - payload := make([]byte, 8+len(data)) - copy(payload, []byte{0x23, 0x23}) - binary.BigEndian.PutUint16(payload[2:], trezor.Type(req)) - binary.BigEndian.PutUint32(payload[4:], uint32(len(data))) - copy(payload[8:], data) - - // Stream all the chunks to the device - chunk := make([]byte, 64) - chunk[0] = 0x3f // Report ID magic number - - for len(payload) > 0 { - // Construct the new message to stream, padding with zeroes if needed - if len(payload) > 63 { - copy(chunk[1:], payload[:63]) - payload = payload[63:] - } else { - copy(chunk[1:], payload) - copy(chunk[1+len(payload):], make([]byte, 63-len(payload))) - payload = nil - } - // Send over to the device - w.log.Trace("Data chunk sent to the Trezor", "chunk", hexutil.Bytes(chunk)) - if _, err := w.device.Write(chunk); err != nil { - return 0, err - } - } - // Stream the reply back from the wallet in 64 byte chunks - var ( - kind uint16 - reply []byte - ) - for { - // Read the next chunk from the Trezor wallet - if _, err := io.ReadFull(w.device, chunk); err != nil { - return 0, err - } - w.log.Trace("Data chunk received from the Trezor", "chunk", hexutil.Bytes(chunk)) - - // Make sure the transport header matches - if chunk[0] != 0x3f || (len(reply) == 0 && (chunk[1] != 0x23 || chunk[2] != 0x23)) { - return 0, errTrezorReplyInvalidHeader - } - // If it's the first chunk, retrieve the reply message type and total message length - var payload []byte - - if len(reply) == 0 { - kind = binary.BigEndian.Uint16(chunk[3:5]) - reply = make([]byte, 0, int(binary.BigEndian.Uint32(chunk[5:9]))) - payload = chunk[9:] - } else { - payload = chunk[1:] - } - // Append to the reply and stop when filled up - if left := cap(reply) - len(reply); left > len(payload) { - reply = append(reply, payload...) - } else { - reply = append(reply, payload[:left]...) - break - } - } - // Try to parse the reply into the requested reply message - if kind == uint16(trezor.MessageType_MessageType_Failure) { - // Trezor returned a failure, extract and return the message - failure := new(trezor.Failure) - if err := proto.Unmarshal(reply, failure); err != nil { - return 0, err - } - return 0, errors.New("trezor: " + failure.GetMessage()) - } - if kind == uint16(trezor.MessageType_MessageType_ButtonRequest) { - // Trezor is waiting for user confirmation, ack and wait for the next message - return w.trezorExchange(&trezor.ButtonAck{}, results...) - } - for i, res := range results { - if trezor.Type(res) == kind { - return i, proto.Unmarshal(reply, res) - } - } - expected := make([]string, len(results)) - for i, res := range results { - expected[i] = trezor.Name(trezor.Type(res)) - } - return 0, fmt.Errorf("trezor: expected reply types %s, got %s", expected, trezor.Name(kind)) -} diff --git a/client/cmd/faucet/faucet.go b/client/cmd/faucet/faucet.go index 7549e8d5d..e2ee8d6d0 100644 --- a/client/cmd/faucet/faucet.go +++ b/client/cmd/faucet/faucet.go @@ -42,6 +42,7 @@ import ( "github.com/kowala-tech/kcoin/client/p2p/discv5" "github.com/kowala-tech/kcoin/client/p2p/nat" "github.com/kowala-tech/kcoin/client/params" + "github.com/kowala-tech/kcoin/client/params/effort" "golang.org/x/net/websocket" ) @@ -227,7 +228,6 @@ type faucet struct { keystore *keystore.KeyStore // Keystore containing the single signer account accounts.Account // Account funding user faucet requests nonce uint64 // Current pending nonce of the faucet - price *big.Int // Current gas price to issue funds with conns []*websocket.Conn // Currently live websocket connections timeouts map[string]time.Time // History of users and their funding timeouts @@ -495,7 +495,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).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, 21000, f.price, nil) + tx := types.NewTransaction(f.nonce+uint64(len(f.reqs)), address, amount, effort.Tx, nil) signed, err := f.keystore.SignTx(f.account, tx, f.config.ChainID) if err != nil { f.lock.Unlock() @@ -564,16 +564,12 @@ func (f *faucet) loop() { var ( balance *big.Int nonce uint64 - price *big.Int err error ) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) balance, err = f.client.BalanceAt(ctx, f.account.Address, head.Number) if err == nil { nonce, err = f.client.NonceAt(ctx, f.account.Address, nil) - if err == nil { - price, err = f.client.SuggestGasPrice(ctx) - } } cancel() @@ -582,13 +578,13 @@ func (f *faucet) loop() { log.Warn("Failed to update faucet state", "block", head.Number, "hash", head.Hash(), "err", err) continue } else { - log.Info("Updated faucet state", "block", head.Number, "hash", head.Hash(), "balance", balance, "nonce", nonce, "price", price) + log.Info("Updated faucet state", "block", head.Number, "hash", head.Hash(), "balance", balance, "nonce", nonce) } // Faucet state retrieved, update locally and send to clients balance = new(big.Int).Div(balance, kcoin) f.lock.Lock() - f.price, f.nonce = price, nonce + f.nonce = nonce for len(f.reqs) > 0 && f.reqs[0].Tx.Nonce() < f.nonce { f.reqs = f.reqs[1:] } diff --git a/client/cmd/kcoin/chaincmd.go b/client/cmd/kcoin/chaincmd.go index 66914cb1d..eb9ab599b 100644 --- a/client/cmd/kcoin/chaincmd.go +++ b/client/cmd/kcoin/chaincmd.go @@ -32,7 +32,6 @@ var ( ArgsUsage: "", Flags: []cli.Flag{ utils.DataDirFlag, - utils.LightModeFlag, utils.TestnetFlag, utils.DevModeFlag, utils.CurrencyFlag, @@ -53,7 +52,6 @@ It expects the genesis file as argument.`, Flags: []cli.Flag{ utils.DataDirFlag, utils.CacheFlag, - utils.LightModeFlag, utils.GCModeFlag, utils.CacheDatabaseFlag, utils.CacheGCFlag, @@ -74,7 +72,6 @@ processing will proceed even if an individual RLP-file import failure occurs.`, Flags: []cli.Flag{ utils.DataDirFlag, utils.CacheFlag, - utils.LightModeFlag, }, Category: "BLOCKCHAIN COMMANDS", Description: ` @@ -91,7 +88,6 @@ if already existing.`, Flags: []cli.Flag{ utils.DataDirFlag, utils.CacheFlag, - utils.LightModeFlag, }, Category: "BLOCKCHAIN COMMANDS", Description: ` @@ -105,7 +101,6 @@ if already existing.`, Flags: []cli.Flag{ utils.DataDirFlag, utils.CacheFlag, - utils.LightModeFlag, }, Category: "BLOCKCHAIN COMMANDS", Description: ` @@ -133,7 +128,6 @@ The first argument must be the directory containing the blockchain to download f ArgsUsage: " ", Flags: []cli.Flag{ utils.DataDirFlag, - utils.LightModeFlag, }, Category: "BLOCKCHAIN COMMANDS", Description: ` @@ -147,7 +141,6 @@ Remove blockchain and state databases`, Flags: []cli.Flag{ utils.DataDirFlag, utils.CacheFlag, - utils.LightModeFlag, }, Category: "BLOCKCHAIN COMMANDS", Description: ` @@ -172,8 +165,7 @@ func initGenesis(ctx *cli.Context) error { // Open an initialise both full and light databases stack := makeFullNode(ctx) - // light chain data is used by the light client(not available) - for _, name := range []string{"chaindata" /*"lightchaindata"*/} { + for _, name := range []string{"chaindata"} { chaindb, err := stack.OpenDatabase(name, 0, 0) if err != nil { utils.Fatalf("Failed to open database: %v", err) diff --git a/client/cmd/kcoin/genesis_test.go b/client/cmd/kcoin/genesis_test.go deleted file mode 100644 index 6a458006e..000000000 --- a/client/cmd/kcoin/genesis_test.go +++ /dev/null @@ -1,96 +0,0 @@ -package main - -import ( - "io/ioutil" - "os" - "path/filepath" - "testing" -) - -// @TODO (rgeraldes) - review pow related elements - -var customGenesisTests = []struct { - genesis string - query string - result string -}{ - // Plain genesis file without anything extra - { - genesis: `{ - "alloc" : {}, - "coinbase" : "0x0000000000000000000000000000000000000000", - "difficulty" : "0x20000", - "extraData" : "", - "gasLimit" : "0x2fefd8", - "nonce" : "0x0000000000000042", - "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "timestamp" : "0x00" - }`, - query: "eth.getBlock(0).nonce", - result: "0x0000000000000042", - }, - // Genesis file with an empty chain configuration (ensure missing fields work) - { - genesis: `{ - "alloc" : {}, - "coinbase" : "0x0000000000000000000000000000000000000000", - "difficulty" : "0x20000", - "extraData" : "", - "gasLimit" : "0x2fefd8", - "nonce" : "0x0000000000000042", - "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "timestamp" : "0x00", - "config" : {} - }`, - query: "eth.getBlock(0).nonce", - result: "0x0000000000000042", - }, - // Genesis file with specific chain configurations - { - genesis: `{ - "alloc" : {}, - "coinbase" : "0x0000000000000000000000000000000000000000", - "difficulty" : "0x20000", - "extraData" : "", - "gasLimit" : "0x2fefd8", - "nonce" : "0x0000000000000042", - "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "timestamp" : "0x00", - "config" : { - "homesteadBlock" : 314, - "daoForkBlock" : 141, - "daoForkSupport" : true - } - }`, - query: "eth.getBlock(0).nonce", - result: "0x0000000000000042", - }, -} - -// Tests that initializing kcoin with a custom genesis block and chain definitions -// work properly. -func TestCustomGenesis(t *testing.T) { - for i, tt := range customGenesisTests { - // Create a temporary data directory to use and inspect later - datadir := tmpdir(t) - defer os.RemoveAll(datadir) - - // Initialize the data directory with the custom genesis block - json := filepath.Join(datadir, "genesis.json") - if err := ioutil.WriteFile(json, []byte(tt.genesis), 0600); err != nil { - t.Fatalf("test %d: failed to write genesis file: %v", i, err) - } - runKusd(t, "--datadir", datadir, "init", json).WaitExit() - - // Query the custom genesis block - kcoin := runKusd(t, - "--datadir", datadir, "--maxpeers", "0", "--port", "0", - "--nodiscover", "--nat", "none", "--ipcdisable", - "--exec", tt.query, "console") - kcoin.ExpectRegexp(tt.result) - kcoin.ExpectExit() - } -} diff --git a/client/cmd/kcoin/main.go b/client/cmd/kcoin/main.go index 1a978d436..9f28f584a 100644 --- a/client/cmd/kcoin/main.go +++ b/client/cmd/kcoin/main.go @@ -12,6 +12,7 @@ import ( "strings" "time" + "github.com/blang/semver" "github.com/elastic/gosigar" "github.com/kowala-tech/kcoin/client/accounts" "github.com/kowala-tech/kcoin/client/accounts/keystore" @@ -23,10 +24,9 @@ import ( "github.com/kowala-tech/kcoin/client/log" "github.com/kowala-tech/kcoin/client/metrics" "github.com/kowala-tech/kcoin/client/node" - "gopkg.in/urfave/cli.v1" - "github.com/kowala-tech/kcoin/client/version" - "github.com/blang/semver" "github.com/kowala-tech/kcoin/client/params" + "github.com/kowala-tech/kcoin/client/version" + "gopkg.in/urfave/cli.v1" ) const ( @@ -50,19 +50,14 @@ var ( utils.TxPoolNoLocalsFlag, utils.TxPoolJournalFlag, utils.TxPoolRejournalFlag, - utils.TxPoolPriceLimitFlag, - utils.TxPoolPriceBumpFlag, utils.TxPoolAccountSlotsFlag, utils.TxPoolGlobalSlotsFlag, utils.TxPoolAccountQueueFlag, utils.TxPoolGlobalQueueFlag, utils.TxPoolLifetimeFlag, utils.FastSyncFlag, - utils.LightModeFlag, utils.SyncModeFlag, utils.GCModeFlag, - utils.LightServFlag, - utils.LightPeersFlag, utils.LightKDFFlag, utils.VersionRepository, utils.SelfUpdateEnabledFlag, @@ -74,10 +69,8 @@ var ( utils.MaxPeersFlag, utils.MaxPendingPeersFlag, utils.CoinbaseFlag, - utils.GasPriceFlag, utils.ValidatorDepositFlag, utils.ValidationEnabledFlag, - utils.TargetGasLimitFlag, utils.NATFlag, utils.NoDiscoverFlag, utils.NetrestrictFlag, @@ -96,8 +89,6 @@ var ( utils.MetricsPrometheusAddressFlag, utils.MetricsPrometheusSubsystemFlag, utils.NoCompactionFlag, - utils.GpoBlocksFlag, - utils.GpoPercentileFlag, utils.ExtraDataFlag, configFileFlag, } @@ -196,7 +187,6 @@ func init() { go version.Checker(ctx.GlobalString(utils.VersionRepository.Name)) - utils.SetupNetwork(ctx) return nil } @@ -325,8 +315,7 @@ func startNode(ctx *cli.Context, stack *node.Node) { utils.Fatalf("kowala service not running: %v", err) } - // Set the gas price to the limits from the CLI and start mining - kowala.TxPool().SetGasPrice(utils.GlobalBig(ctx, utils.GasPriceFlag.Name)) + // start mining if err := kowala.StartValidating(); err != nil { utils.Fatalf("Failed to start validation: %v", err) } diff --git a/client/cmd/kcoin/sample-config.toml b/client/cmd/kcoin/sample-config.toml deleted file mode 100644 index b7e1f6528..000000000 --- a/client/cmd/kcoin/sample-config.toml +++ /dev/null @@ -1,39 +0,0 @@ -[Kowala] -NetworkId = 1 -SyncMode = "fast" -LightPeers = 20 -DatabaseCache = 128 -GasPrice = 25 -EnablePreimageRecording = false - - [Kowala.TxPool] - NoLocals = false - Journal = "transactions.rlp" - Rejournal = 3600000000000 - PriceLimit = 1 - PriceBump = 10 - AccountSlots = 16 - GlobalSlots = 4096 - AccountQueue = 64 - GlobalQueue = 1024 - Lifetime = 10800000000000 - - [Kowala.GPO] - Blocks = 10 - Percentile = 50 - -[Node] -DataDir = ".kowala" - - [Node.P2P] - MaxPeers = 25 - NoDiscovery = false - DiscoveryV5Addr = ":30304" - BootstrapNodes = ["enode://111929beaa10c4eef786996c79267ad041b919830d0c66587f213418d759e83416047df57c9dca9cb86af9b4f53b4491112a905ec7bc2540ec73f1fa066bfb8f@54.162.29.69:33445"] - # BootstrapNodesV5 = ["enode://bae38251dece370a6c99482364d433244f183ce74169ed148a57960e46b2ab36995c0ee15d54cdff2edfa92a423ab62faecdb8185a5c536c9090507284c87427@192.168.12.171:33445"] - StaticNodes = [] - TrustedNodes = [] - ListenAddr = ":30303" - -[Stats] -URL = "{{.Hostname}}:DVagynuHLdn9sK6c@testnet.kowala.io:80" diff --git a/client/cmd/kcoin/usage.go b/client/cmd/kcoin/usage.go index 205813cac..365882f9e 100644 --- a/client/cmd/kcoin/usage.go +++ b/client/cmd/kcoin/usage.go @@ -61,8 +61,6 @@ var AppHelpFlagGroups = []flagGroup{ utils.GCModeFlag, utils.KowalaStatsURLFlag, utils.IdentityFlag, - utils.LightServFlag, - utils.LightPeersFlag, utils.LightKDFFlag, utils.VersionRepository, }, @@ -73,8 +71,6 @@ var AppHelpFlagGroups = []flagGroup{ utils.TxPoolNoLocalsFlag, utils.TxPoolJournalFlag, utils.TxPoolRejournalFlag, - utils.TxPoolPriceLimitFlag, - utils.TxPoolPriceBumpFlag, utils.TxPoolAccountSlotsFlag, utils.TxPoolGlobalSlotsFlag, utils.TxPoolAccountQueueFlag, @@ -141,18 +137,9 @@ var AppHelpFlagGroups = []flagGroup{ utils.ValidationEnabledFlag, utils.ValidatorDepositFlag, utils.CoinbaseFlag, - utils.TargetGasLimitFlag, - utils.GasPriceFlag, utils.ExtraDataFlag, }, }, - { - Name: "GAS PRICE ORACLE", - Flags: []cli.Flag{ - utils.GpoBlocksFlag, - utils.GpoPercentileFlag, - }, - }, { Name: "VIRTUAL MACHINE", Flags: []cli.Flag{ @@ -182,7 +169,6 @@ var AppHelpFlagGroups = []flagGroup{ Name: "DEPRECATED", Flags: []cli.Flag{ utils.FastSyncFlag, - utils.LightModeFlag, }, }, { diff --git a/client/cmd/utils/flags.go b/client/cmd/utils/flags.go index fa2442662..0181bcb12 100644 --- a/client/cmd/utils/flags.go +++ b/client/cmd/utils/flags.go @@ -25,7 +25,6 @@ import ( "github.com/kowala-tech/kcoin/client/kcoindb" "github.com/kowala-tech/kcoin/client/knode" "github.com/kowala-tech/kcoin/client/knode/downloader" - "github.com/kowala-tech/kcoin/client/knode/gasprice" "github.com/kowala-tech/kcoin/client/log" "github.com/kowala-tech/kcoin/client/metrics" "github.com/kowala-tech/kcoin/client/metrics/influxdb" @@ -147,14 +146,10 @@ var ( Name: "fast", Usage: "Enable fast syncing through state downloads (replaced by --syncmode)", } - LightModeFlag = cli.BoolFlag{ - Name: "light", - Usage: "Enable light client mode (replaced by --syncmode)", - } defaultSyncMode = knode.DefaultConfig.SyncMode SyncModeFlag = TextMarshalerFlag{ Name: "syncmode", - Usage: `Blockchain sync mode ("fast", "full", or "light")`, + Usage: `Blockchain sync mode ("fast" or "full")`, Value: &defaultSyncMode, } GCModeFlag = cli.StringFlag{ @@ -162,16 +157,6 @@ var ( Usage: `Blockchain garbage collection mode ("full", "archive")`, Value: "full", } - LightServFlag = cli.IntFlag{ - Name: "lightserv", - Usage: "Maximum percentage of time allowed for serving LES requests (0-90)", - Value: 0, - } - LightPeersFlag = cli.IntFlag{ - Name: "lightpeers", - Usage: "Maximum number of LES client peers", - Value: 20, - } LightKDFFlag = cli.BoolFlag{ Name: "lightkdf", Usage: "Reduce key-derivation RAM & CPU usage at some expense of KDF strength", @@ -179,7 +164,7 @@ var ( // Transaction pool settings TxPoolNoLocalsFlag = cli.BoolFlag{ Name: "txpool.nolocals", - Usage: "Disables price exemptions for locally submitted transactions", + Usage: "Disables distinction between local and remote transactions", } TxPoolJournalFlag = cli.StringFlag{ Name: "txpool.journal", @@ -191,16 +176,6 @@ var ( Usage: "Time interval to regenerate the local transaction journal", Value: core.DefaultTxPoolConfig.Rejournal, } - TxPoolPriceLimitFlag = cli.Uint64Flag{ - Name: "txpool.pricelimit", - Usage: "Minimum gas price limit to enforce for acceptance into the pool", - Value: knode.DefaultConfig.TxPool.PriceLimit, - } - TxPoolPriceBumpFlag = cli.Uint64Flag{ - Name: "txpool.pricebump", - Usage: "Price bump percentage to replace an already existing transaction", - Value: knode.DefaultConfig.TxPool.PriceBump, - } TxPoolAccountSlotsFlag = cli.Uint64Flag{ Name: "txpool.accountslots", Usage: "Minimum number of executable transaction slots guaranteed per account", @@ -256,26 +231,14 @@ var ( ValidatorDepositFlag = cli.Uint64Flag{ Name: "deposit", Usage: "Deposit at stake", - // @TODO (rgeraldes) - default could be set to the minimum required } - TargetGasLimitFlag = cli.Uint64Flag{ - Name: "targetgaslimit", - Usage: "Target gas limit sets the artificial target gas floor for the blocks to mine", - Value: params.GenesisGasLimit, - } CoinbaseFlag = cli.StringFlag{ Name: "coinbase", Usage: "Public address for block validation rewards (default = first account created)", Value: "0", } - // @TODO(rgeraldes) - review - GasPriceFlag = BigFlag{ - Name: "gasprice", - Usage: "Minimal gas price to accept for mining a transactions", - Value: knode.DefaultConfig.GasPrice, - } ExtraDataFlag = cli.StringFlag{ Name: "extradata", Usage: "Block extra data set by the consensus validator (default = client version)", @@ -445,18 +408,6 @@ var ( Value: ".", } - // Gas price oracle settings - GpoBlocksFlag = cli.IntFlag{ - Name: "gpoblocks", - Usage: "Number of recent blocks to check for gas prices", - Value: knode.DefaultConfig.GPO.Blocks, - } - GpoPercentileFlag = cli.IntFlag{ - Name: "gpopercentile", - Usage: "Suggested gas price is the given percentile of a set of recent transaction gas prices", - Value: knode.DefaultConfig.GPO.Percentile, - } - MetricsEnabledFlag = cli.BoolFlag{ Name: metrics.MetricsEnabledFlag, Usage: "Enable metrics collection and reporting", @@ -816,7 +767,7 @@ func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) { if ctx.GlobalIsSet(MaxPendingPeersFlag.Name) { cfg.MaxPendingPeers = ctx.GlobalInt(MaxPendingPeersFlag.Name) } - if ctx.GlobalIsSet(NoDiscoverFlag.Name) || ctx.GlobalBool(LightModeFlag.Name) { + if ctx.GlobalIsSet(NoDiscoverFlag.Name) { cfg.NoDiscovery = true } @@ -860,15 +811,6 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config, kowalaCfg *knode.Config) cfg.DataDir = filepath.Join(cfg.DataDir, kowalaCfg.Currency) } -func setGPO(ctx *cli.Context, cfg *gasprice.Config) { - if ctx.GlobalIsSet(GpoBlocksFlag.Name) { - cfg.Blocks = ctx.GlobalInt(GpoBlocksFlag.Name) - } - if ctx.GlobalIsSet(GpoPercentileFlag.Name) { - cfg.Percentile = ctx.GlobalInt(GpoPercentileFlag.Name) - } -} - func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) { if ctx.GlobalIsSet(TxPoolNoLocalsFlag.Name) { cfg.NoLocals = ctx.GlobalBool(TxPoolNoLocalsFlag.Name) @@ -879,12 +821,6 @@ func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) { if ctx.GlobalIsSet(TxPoolRejournalFlag.Name) { cfg.Rejournal = ctx.GlobalDuration(TxPoolRejournalFlag.Name) } - if ctx.GlobalIsSet(TxPoolPriceLimitFlag.Name) { - cfg.PriceLimit = ctx.GlobalUint64(TxPoolPriceLimitFlag.Name) - } - if ctx.GlobalIsSet(TxPoolPriceBumpFlag.Name) { - cfg.PriceBump = ctx.GlobalUint64(TxPoolPriceBumpFlag.Name) - } if ctx.GlobalIsSet(TxPoolAccountSlotsFlag.Name) { cfg.AccountSlots = ctx.GlobalUint64(TxPoolAccountSlotsFlag.Name) } @@ -944,12 +880,11 @@ func checkExclusive(ctx *cli.Context, args ...interface{}) { func SetKowalaConfig(ctx *cli.Context, stack *node.Node, cfg *knode.Config) { // Avoid conflicting network flags checkExclusive(ctx, DevModeFlag, TestnetFlag) - checkExclusive(ctx, FastSyncFlag, LightModeFlag, SyncModeFlag) + checkExclusive(ctx, FastSyncFlag, SyncModeFlag) ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) setCoinbase(ctx, ks, cfg) setDeposit(ctx, cfg) - setGPO(ctx, &cfg.GPO) setTxPool(ctx, &cfg.TxPool) switch { @@ -957,15 +892,8 @@ func SetKowalaConfig(ctx *cli.Context, stack *node.Node, cfg *knode.Config) { cfg.SyncMode = *GlobalTextMarshaler(ctx, SyncModeFlag.Name).(*downloader.SyncMode) case ctx.GlobalBool(FastSyncFlag.Name): cfg.SyncMode = downloader.FastSync - case ctx.GlobalBool(LightModeFlag.Name): - cfg.SyncMode = downloader.LightSync - } - if ctx.GlobalIsSet(LightServFlag.Name) { - cfg.LightServ = ctx.GlobalInt(LightServFlag.Name) - } - if ctx.GlobalIsSet(LightPeersFlag.Name) { - cfg.LightPeers = ctx.GlobalInt(LightPeersFlag.Name) } + if ctx.GlobalIsSet(NetworkIdFlag.Name) { cfg.NetworkId = ctx.GlobalUint64(NetworkIdFlag.Name) } @@ -989,9 +917,6 @@ func SetKowalaConfig(ctx *cli.Context, stack *node.Node, cfg *knode.Config) { if ctx.GlobalIsSet(ExtraDataFlag.Name) { cfg.ExtraData = []byte(ctx.GlobalString(ExtraDataFlag.Name)) } - if ctx.GlobalIsSet(GasPriceFlag.Name) { - cfg.GasPrice = GlobalBig(ctx, GasPriceFlag.Name) - } if ctx.GlobalIsSet(VMEnableDebugFlag.Name) { // TODO(fjl): force-enable this in --dev mode cfg.EnablePreimageRecording = ctx.GlobalBool(VMEnableDebugFlag.Name) @@ -1039,12 +964,6 @@ func RegisterKowalaStatsService(stack *node.Node, url string) { } } -// SetupNetwork configures the system for either the main net or some test network. -func SetupNetwork(ctx *cli.Context) { - // TODO(fjl): move target gas limit into config - params.TargetGasLimit = ctx.GlobalUint64(TargetGasLimitFlag.Name) -} - func SetupMetrics(ctx *cli.Context) { if metrics.Enabled { log.Info("Enabling metrics collection") @@ -1073,9 +992,6 @@ func MakeChainDatabase(ctx *cli.Context, stack *node.Node) kcoindb.Database { handles = makeDatabaseHandles() ) name := "chaindata" - if ctx.GlobalBool(LightModeFlag.Name) { - name = "lightchaindata" - } chainDb, err := stack.OpenDatabase(name, cache, handles) if err != nil { Fatalf("Could not open database: %v", err) diff --git a/client/cmd/evm/compiler.go b/client/cmd/vm/compiler.go similarity index 95% rename from client/cmd/evm/compiler.go rename to client/cmd/vm/compiler.go index f37970833..72456d041 100644 --- a/client/cmd/evm/compiler.go +++ b/client/cmd/vm/compiler.go @@ -21,7 +21,7 @@ import ( "fmt" "io/ioutil" - "github.com/kowala-tech/kcoin/client/cmd/evm/internal/compiler" + "github.com/kowala-tech/kcoin/client/cmd/vm/internal/compiler" cli "gopkg.in/urfave/cli.v1" ) diff --git a/client/cmd/evm/disasm.go b/client/cmd/vm/disasm.go similarity index 100% rename from client/cmd/evm/disasm.go rename to client/cmd/vm/disasm.go diff --git a/client/cmd/evm/internal/compiler/compiler.go b/client/cmd/vm/internal/compiler/compiler.go similarity index 100% rename from client/cmd/evm/internal/compiler/compiler.go rename to client/cmd/vm/internal/compiler/compiler.go diff --git a/client/cmd/evm/json_logger.go b/client/cmd/vm/json_logger.go similarity index 61% rename from client/cmd/evm/json_logger.go rename to client/cmd/vm/json_logger.go index 7f9b3df2d..45ff14d27 100644 --- a/client/cmd/evm/json_logger.go +++ b/client/cmd/vm/json_logger.go @@ -32,27 +32,27 @@ type JSONLogger struct { cfg *vm.LogConfig } -// NewJSONLogger creates a new EVM tracer that prints execution steps as JSON objects +// NewJSONLogger creates a new VM tracer that prints execution steps as JSON objects // into the provided stream. func NewJSONLogger(cfg *vm.LogConfig, writer io.Writer) *JSONLogger { return &JSONLogger{json.NewEncoder(writer), cfg} } -func (l *JSONLogger) CaptureStart(from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) error { +func (l *JSONLogger) CaptureStart(from common.Address, to common.Address, create bool, input []byte, resource uint64, value *big.Int) error { return nil } // CaptureState outputs state information on the logger. -func (l *JSONLogger) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error { +func (l *JSONLogger) CaptureState(env *vm.VM, pc uint64, op vm.OpCode, resource, cost uint64, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error { log := vm.StructLog{ - Pc: pc, - Op: op, - Gas: gas, - GasCost: cost, - MemorySize: memory.Len(), - Storage: nil, - Depth: depth, - Err: err, + Pc: pc, + Op: op, + Resource: resource, + ComputeUnitPrice: cost, + MemorySize: memory.Len(), + Storage: nil, + Depth: depth, + Err: err, } if !l.cfg.DisableMemory { log.Memory = memory.Data() @@ -64,20 +64,20 @@ func (l *JSONLogger) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cos } // CaptureFault outputs state information on the logger. -func (l *JSONLogger) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error { +func (l *JSONLogger) CaptureFault(env *vm.VM, pc uint64, op vm.OpCode, resource, cost uint64, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error { return nil } // CaptureEnd is triggered at end of execution. -func (l *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error { +func (l *JSONLogger) CaptureEnd(output []byte, resourceUsage uint64, t time.Duration, err error) error { type endLog struct { - Output string `json:"output"` - GasUsed math.HexOrDecimal64 `json:"gasUsed"` - Time time.Duration `json:"time"` - Err string `json:"error,omitempty"` + Output string `json:"output"` + ResourceUsage math.HexOrDecimal64 `json:"resourceUsage"` + Time time.Duration `json:"time"` + Err string `json:"error,omitempty"` } if err != nil { - return l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t, err.Error()}) + return l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(resourceUsage), t, err.Error()}) } - return l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t, ""}) + return l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(resourceUsage), t, ""}) } diff --git a/client/cmd/evm/main.go b/client/cmd/vm/main.go similarity index 88% rename from client/cmd/evm/main.go rename to client/cmd/vm/main.go index 21f65d49f..61ba790e9 100644 --- a/client/cmd/evm/main.go +++ b/client/cmd/vm/main.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with go-ethereum. If not, see . -// evm executes EVM code snippets. +// vm executes VM code snippets. package main import ( @@ -27,7 +27,7 @@ import ( ) var ( - app = utils.NewApp(gitCommit, "the evm command line interface") + app = utils.NewApp(gitCommit, "the vm command line interface") DebugFlag = cli.BoolFlag{ Name: "debug", @@ -47,25 +47,25 @@ var ( } CodeFlag = cli.StringFlag{ Name: "code", - Usage: "EVM code", + Usage: "VM code", } CodeFileFlag = cli.StringFlag{ Name: "codefile", - Usage: "File containing EVM code. If '-' is specified, code is read from stdin ", + Usage: "File containing VM code. If '-' is specified, code is read from stdin ", } - GasFlag = cli.Uint64Flag{ - Name: "gas", - Usage: "gas limit for the evm", + ComputeLimitFlag = cli.Uint64Flag{ + Name: "limit", + Usage: "compute limit for the vm", Value: 10000000000, } PriceFlag = utils.BigFlag{ Name: "price", - Usage: "price set for the evm", + Usage: "price set for the vm", Value: new(big.Int), } ValueFlag = utils.BigFlag{ Name: "value", - Usage: "value set for the evm", + Usage: "value set for the vm", Value: new(big.Int), } DumpFlag = cli.BoolFlag{ @@ -74,7 +74,7 @@ var ( } InputFlag = cli.StringFlag{ Name: "input", - Usage: "input for the EVM", + Usage: "input for the VM", } VerbosityFlag = cli.IntFlag{ Name: "verbosity", @@ -117,7 +117,7 @@ func init() { VerbosityFlag, CodeFlag, CodeFileFlag, - GasFlag, + ComputeLimitFlag, PriceFlag, ValueFlag, DumpFlag, diff --git a/client/cmd/evm/runner.go b/client/cmd/vm/runner.go similarity index 85% rename from client/cmd/evm/runner.go rename to client/cmd/vm/runner.go index b5fef8901..9f61c6513 100644 --- a/client/cmd/evm/runner.go +++ b/client/cmd/vm/runner.go @@ -11,8 +11,8 @@ import ( "runtime/pprof" "time" - "github.com/kowala-tech/kcoin/client/cmd/evm/internal/compiler" "github.com/kowala-tech/kcoin/client/cmd/utils" + "github.com/kowala-tech/kcoin/client/cmd/vm/internal/compiler" "github.com/kowala-tech/kcoin/client/common" "github.com/kowala-tech/kcoin/client/core" "github.com/kowala-tech/kcoin/client/core/state" @@ -27,9 +27,9 @@ import ( var runCommand = cli.Command{ Action: runCmd, Name: "run", - Usage: "run arbitrary evm binary", + Usage: "run arbitrary vm binary", ArgsUsage: "", - Description: `The run command runs arbitrary EVM code.`, + Description: `The run command runs arbitrary VM code.`, } // readGenesis will read the given JSON format genesis file and return @@ -139,15 +139,15 @@ func runCmd(ctx *cli.Context) error { code = common.Hex2Bytes(bin) } - initialGas := ctx.GlobalUint64(GasFlag.Name) + initialResource := ctx.GlobalUint64(ComputeLimitFlag.Name) runtimeConfig := runtime.Config{ - Origin: sender, - State: statedb, - GasLimit: initialGas, - GasPrice: utils.GlobalBig(ctx, PriceFlag.Name), - Value: utils.GlobalBig(ctx, ValueFlag.Name), - BlockNumber: new(big.Int).SetUint64(blockNumber), - EVMConfig: vm.Config{ + Origin: sender, + State: statedb, + ComputeLimit: initialResource, + ComputeUnitPrice: utils.GlobalBig(ctx, PriceFlag.Name), + Value: utils.GlobalBig(ctx, ValueFlag.Name), + BlockNumber: new(big.Int).SetUint64(blockNumber), + VMConfig: vm.Config{ Tracer: tracer, Debug: ctx.GlobalBool(DebugFlag.Name) || ctx.GlobalBool(MachineFlag.Name), }, @@ -170,15 +170,15 @@ func runCmd(ctx *cli.Context) error { runtimeConfig.ChainConfig = chainConfig } tstart := time.Now() - var leftOverGas uint64 + var leftOverResource uint64 if ctx.GlobalBool(CreateFlag.Name) { input := append(code, common.Hex2Bytes(ctx.GlobalString(InputFlag.Name))...) - ret, _, leftOverGas, err = runtime.Create(input, &runtimeConfig) + ret, _, leftOverResource, err = runtime.Create(input, &runtimeConfig) } else { if len(code) > 0 { statedb.SetCode(receiver, code) } - ret, leftOverGas, err = runtime.Call(receiver, common.Hex2Bytes(ctx.GlobalString(InputFlag.Name)), &runtimeConfig) + ret, leftOverResource, err = runtime.Call(receiver, common.Hex2Bytes(ctx.GlobalString(InputFlag.Name)), &runtimeConfig) } execTime := time.Since(tstart) @@ -212,14 +212,14 @@ func runCmd(ctx *cli.Context) error { if ctx.GlobalBool(StatDumpFlag.Name) { var mem goruntime.MemStats goruntime.ReadMemStats(&mem) - fmt.Fprintf(os.Stderr, `evm execution time: %v -heap objects: %d -allocations: %d -total allocations: %d -GC calls: %d -Gas used: %d - -`, execTime, mem.HeapObjects, mem.Alloc, mem.TotalAlloc, mem.NumGC, initialGas-leftOverGas) + fmt.Fprintf(os.Stderr, `vm execution time: %v +heap objects: %d +allocations: %d +total allocations: %d +GC calls: %d +Computational Resource used: %d + +`, execTime, mem.HeapObjects, mem.Alloc, mem.TotalAlloc, mem.NumGC, initialResource-leftOverResource) } if tracer == nil { fmt.Printf("0x%x\n", ret) diff --git a/client/cmd/evm/staterunner.go b/client/cmd/vm/staterunner.go similarity index 100% rename from client/cmd/evm/staterunner.go rename to client/cmd/vm/staterunner.go diff --git a/client/cmd/evm/version.go b/client/cmd/vm/version.go similarity index 100% rename from client/cmd/evm/version.go rename to client/cmd/vm/version.go diff --git a/client/console/bridge.go b/client/console/bridge.go index c607c88e1..ab9305c54 100644 --- a/client/console/bridge.go +++ b/client/console/bridge.go @@ -7,7 +7,6 @@ import ( "strings" "time" - "github.com/kowala-tech/kcoin/client/accounts/usbwallet" "github.com/kowala-tech/kcoin/client/log" "github.com/kowala-tech/kcoin/client/rpc" "github.com/robertkrimen/otto" @@ -69,7 +68,7 @@ func (b *bridge) NewAccount(call otto.FunctionCall) (response otto.Value) { } // OpenWallet is a wrapper around personal.openWallet which can interpret and -// react to certain error messages, such as the Trezor PIN matrix request. +// react to certain error messages. func (b *bridge) OpenWallet(call otto.FunctionCall) (response otto.Value) { // Make sure we have a wallet specified to open if !call.Argument(0).IsString() { @@ -88,17 +87,23 @@ func (b *bridge) OpenWallet(call otto.FunctionCall) (response otto.Value) { if err == nil { return val } - // Wallet open failed, report error unless it's a PIN entry - if !strings.HasSuffix(err.Error(), usbwallet.ErrTrezorPINNeeded.Error()) { - throwJSException(err.Error()) - } - // Trezor PIN matrix input requested, display the matrix to the user and fetch the data - fmt.Fprintf(b.printer, "Look at the device for number positions\n\n") - fmt.Fprintf(b.printer, "7 | 8 | 9\n") - fmt.Fprintf(b.printer, "--+---+--\n") - fmt.Fprintf(b.printer, "4 | 5 | 6\n") - fmt.Fprintf(b.printer, "--+---+--\n") - fmt.Fprintf(b.printer, "1 | 2 | 3\n\n") + + /* + + // Wallet open failed, report error unless it's a PIN entry + if !strings.HasSuffix(err.Error(), usbwallet.ErrTrezorPINNeeded.Error()) { + throwJSException(err.Error()) + } + + // Trezor PIN matrix input requested, display the matrix to the user and fetch the data + fmt.Fprintf(b.printer, "Look at the device for number positions\n\n") + fmt.Fprintf(b.printer, "7 | 8 | 9\n") + fmt.Fprintf(b.printer, "--+---+--\n") + fmt.Fprintf(b.printer, "4 | 5 | 6\n") + fmt.Fprintf(b.printer, "--+---+--\n") + fmt.Fprintf(b.printer, "1 | 2 | 3\n\n") + + */ if input, err := b.prompter.PromptPassword("Please enter current PIN: "); err != nil { throwJSException(err.Error()) diff --git a/client/contracts/bindings/consensus/consensus.go b/client/contracts/bindings/consensus/consensus.go index a061d2c3e..3bf6344f4 100644 --- a/client/contracts/bindings/consensus/consensus.go +++ b/client/contracts/bindings/consensus/consensus.go @@ -69,15 +69,14 @@ func (tkn *mUSD) Mint(opts *accounts.TransactOpts, to common.Address, value *big func toBind(opts *accounts.TransactOpts) *bind.TransactOpts { bindOpts := &bind.TransactOpts{ - From: opts.From, - Nonce: opts.Nonce, - Value: opts.Value, - GasPrice: opts.GasPrice, - Context: opts.Context, - Signer: bind.SignerFn(opts.Signer), + From: opts.From, + Nonce: opts.Nonce, + Value: opts.Value, + Context: opts.Context, + Signer: bind.SignerFn(opts.Signer), } - if opts.GasLimit != nil { - bindOpts.GasLimit = opts.GasLimit.Uint64() + if opts.ComputeLimit != nil { + bindOpts.ComputeLimit = opts.ComputeLimit.Uint64() } return bindOpts } diff --git a/client/contracts/bindings/consensus/manager_test.go b/client/contracts/bindings/consensus/manager_test.go index 012bd7ae8..9b41edf06 100644 --- a/client/contracts/bindings/consensus/manager_test.go +++ b/client/contracts/bindings/consensus/manager_test.go @@ -277,7 +277,7 @@ func newVMTracer() *vmTracer { } } -func (vmt *vmTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error { +func (vmt *vmTracer) CaptureState(env *vm.VM, pc uint64, op vm.OpCode, resource, cost uint64, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error { if err != nil { return err } @@ -303,15 +303,15 @@ func (vmt *vmTracer) setAddrStorage(contractAddress common.Address, addrStorage vmt.data[contractAddress] = addrStorage } -func (vmt *vmTracer) CaptureStart(from common.Address, to common.Address, call bool, input []byte, gas uint64, value *big.Int) error { +func (vmt *vmTracer) CaptureStart(from common.Address, to common.Address, call bool, input []byte, resource uint64, value *big.Int) error { return nil } -func (vmt *vmTracer) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error { +func (vmt *vmTracer) CaptureEnd(output []byte, resourceUsage uint64, t time.Duration, err error) error { return nil } -func (vmt *vmTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error { +func (vmt *vmTracer) CaptureFault(env *vm.VM, pc uint64, op vm.OpCode, resource, cost uint64, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error { return nil } @@ -325,7 +325,7 @@ func (suite *ValidatorMgrSuite) TestIsGenesisValidator() { runtimeCfg := &runtime.Config{ State: sharedState, BlockNumber: common.Big0, - EVMConfig: vm.Config{ + VMConfig: vm.Config{ Debug: true, Tracer: newVMTracer(), }, @@ -426,12 +426,12 @@ func (suite *ValidatorMgrSuite) TestIsGenesisValidator() { backend := backends.NewSimulatedBackend(core.GenesisAlloc{ tokenAddr: core.GenesisAccount{ Code: tokenCode, - Storage: runtimeCfg.EVMConfig.Tracer.(*vmTracer).data[tokenAddr], + Storage: runtimeCfg.VMConfig.Tracer.(*vmTracer).data[tokenAddr], Balance: common.Big0, }, validatorMgrAddr: core.GenesisAccount{ Code: validatorMgrCode, - Storage: runtimeCfg.EVMConfig.Tracer.(*vmTracer).data[validatorMgrAddr], + Storage: runtimeCfg.VMConfig.Tracer.(*vmTracer).data[validatorMgrAddr], Balance: common.Big0, }, userAddr: core.GenesisAccount{ diff --git a/client/contracts/bindings/stability/stability_test.go b/client/contracts/bindings/stability/stability_test.go index 9ed509ddf..0cf106719 100644 --- a/client/contracts/bindings/stability/stability_test.go +++ b/client/contracts/bindings/stability/stability_test.go @@ -308,10 +308,10 @@ func (suite *StabilityContractSuite) TestUnsubscribe_Subscriber_PriceGreaterOrEq req.NoError(err) req.NotNil(unsubscribeReceipt) - priceProviderCost := new(big.Int).Mul(priceProviderTx.GasPrice(), new(big.Int).SetUint64(priceProviderReceipt.GasUsed)) - stabilityCost := new(big.Int).Mul(stabilityTx.GasPrice(), new(big.Int).SetUint64(stabilityReceipt.GasUsed)) - subscribeCost := new(big.Int).Mul(subscribeTx.GasPrice(), new(big.Int).SetUint64(subscribeReceipt.GasUsed)) - unsubscribeCost := new(big.Int).Mul(unsubscribeTx.GasPrice(), new(big.Int).SetUint64(unsubscribeReceipt.GasUsed)) + priceProviderCost := new(big.Int).Mul(params.ComputeUnitPrice, new(big.Int).SetUint64(priceProviderReceipt.ResourceUsage)) + stabilityCost := new(big.Int).Mul(params.ComputeUnitPrice, new(big.Int).SetUint64(stabilityReceipt.ResourceUsage)) + subscribeCost := new(big.Int).Mul(params.ComputeUnitPrice, new(big.Int).SetUint64(subscribeReceipt.ResourceUsage)) + unsubscribeCost := new(big.Int).Mul(params.ComputeUnitPrice, new(big.Int).SetUint64(unsubscribeReceipt.ResourceUsage)) finalBalance := new(big.Int).Sub(initialBalance, priceProviderCost) finalBalance.Sub(finalBalance, stabilityCost) diff --git a/client/core/block_validator.go b/client/core/block_validator.go index d90fa0b48..cfe077fb4 100644 --- a/client/core/block_validator.go +++ b/client/core/block_validator.go @@ -71,13 +71,13 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error { } // ValidateState validates the various changes that happen after a state -// transition, such as amount of used gas, the receipt roots and the state root +// transition, such as the computational resource usage, the receipt roots and the state root // itself. ValidateState returns a database batch if the validation was a success // otherwise nil and an error is returned. -func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *state.StateDB, receipts types.Receipts, usedGas uint64) error { +func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *state.StateDB, receipts types.Receipts, resourceUsage uint64) error { header := block.Header() - if block.GasUsed() != usedGas { - return fmt.Errorf("invalid gas used (remote: %d local: %d)", block.GasUsed(), usedGas) + if block.ResourceUsage() != resourceUsage { + return fmt.Errorf("invalid computational resources used (remote: %d local: %d)", block.ResourceUsage(), resourceUsage) } // Validate the received block's bloom with the one derived from the generated receipts. // For valid blocks this should always validate to true. @@ -97,34 +97,3 @@ func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *stat } return nil } - -// CalcGasLimit computes the gas limit of the next block after parent. -// This is miner strategy, not consensus protocol. -func CalcGasLimit(parent *types.Block) uint64 { - // contrib = (parentGasUsed * 3 / 2) / 1024 - contrib := (parent.GasUsed() + parent.GasUsed()/2) / params.GasLimitBoundDivisor - - // decay = parentGasLimit / 1024 -1 - decay := parent.GasLimit()/params.GasLimitBoundDivisor - 1 - - /* - strategy: gasLimit of block-to-mine is set based on parent's - gasUsed value. if parentGasUsed > parentGasLimit * (2/3) then we - increase it, otherwise lower it (or leave it unchanged if it's right - at that usage) the amount increased/decreased depends on how far away - from parentGasLimit * (2/3) parentGasUsed is. - */ - limit := parent.GasLimit() - decay + contrib - if limit < params.MinGasLimit { - limit = params.MinGasLimit - } - // however, if we're now below the target (TargetGasLimit) we increase the - // limit as much as we can (parentGasLimit / 1024 -1) - if limit < params.TargetGasLimit { - limit = parent.GasLimit() + decay - if limit > params.TargetGasLimit { - limit = params.TargetGasLimit - } - } - return limit -} diff --git a/client/core/blockchain.go b/client/core/blockchain.go index 03e8d5650..cea0c72e1 100644 --- a/client/core/blockchain.go +++ b/client/core/blockchain.go @@ -11,6 +11,7 @@ import ( "sync/atomic" "time" + "github.com/davecgh/go-spew/spew" "github.com/hashicorp/golang-lru" "github.com/kowala-tech/kcoin/client/common" "github.com/kowala-tech/kcoin/client/common/mclock" @@ -28,7 +29,6 @@ import ( "github.com/kowala-tech/kcoin/client/rlp" "github.com/kowala-tech/kcoin/client/trie" "gopkg.in/karalabe/cookiejar.v2/collections/prque" - "github.com/davecgh/go-spew/spew" ) var ( @@ -312,11 +312,6 @@ func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error { return nil } -// GasLimit returns the gas limit of the current HEAD block. -func (bc *BlockChain) GasLimit() uint64 { - return bc.CurrentBlock().GasLimit() -} - // CurrentBlock retrieves the current head block of the canonical chain. The // block is retrieved from the blockchain's internal cache. func (bc *BlockChain) CurrentBlock() *types.Block { @@ -718,11 +713,11 @@ func SetReceiptsData(config *params.ChainConfig, block *types.Block, receipts ty from, _ := types.TxSender(signer, transactions[j]) receipts[j].ContractAddress = crypto.CreateAddress(from, transactions[j].Nonce()) } - // The used gas can be calculated based on previous receipts + // The computational resource usage can be calculated based on previous receipts if j == 0 { - receipts[j].GasUsed = receipts[j].CumulativeGasUsed + receipts[j].ResourceUsage = receipts[j].CumulativeResourceUsage } else { - receipts[j].GasUsed = receipts[j].CumulativeGasUsed - receipts[j-1].CumulativeGasUsed + receipts[j].ResourceUsage = receipts[j].CumulativeResourceUsage - receipts[j-1].CumulativeResourceUsage } // The derived log fields can simply be set from the block and transaction for k := 0; k < len(receipts[j].Logs); k++ { @@ -1087,14 +1082,14 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty return i, events, coalescedLogs, err } // Process block using the parent state as reference point. - receipts, logs, usedGas, err := bc.processor.Process(block, state, bc.vmConfig) + receipts, logs, resourceUsage, err := bc.processor.Process(block, state, bc.vmConfig) if err != nil { log.Debug("insert chain error while bc.processor.Process of a block", "err", err.Error()) bc.reportBlock(block, receipts, err) return i, events, coalescedLogs, err } // Validate the state using the default validator - err = bc.Validator().ValidateState(block, parent, state, receipts, usedGas) + err = bc.Validator().ValidateState(block, parent, state, receipts, resourceUsage) if err != nil { log.Debug("insert chain error while bc.Validator().ValidateState of a block", "data", spew.Sdump( block.ReceivedFrom, @@ -1109,7 +1104,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty parent.Header().TxHash, parent.Header().ParentHash, parent.Header().Root, - usedGas)) + resourceUsage)) bc.reportBlock(block, receipts, err) return i, events, coalescedLogs, err @@ -1124,7 +1119,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty switch status { case CanonStatTy: log.Debug("Inserted new block", "number", block.Number(), "hash", block.Hash(), - "txs", len(block.Transactions()), "gas", block.GasUsed(), "elapsed", common.PrettyDuration(time.Since(bstart))) + "txs", len(block.Transactions()), "computational resource usage", block.ResourceUsage(), "elapsed", common.PrettyDuration(time.Since(bstart))) coalescedLogs = append(coalescedLogs, logs...) blockInsertTimer.UpdateSince(bstart) @@ -1136,13 +1131,13 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty case SideStatTy: log.Debug("Inserted forked block", "number", block.Number(), "hash", block.Hash(), "receipt", block.ReceiptHash(), "elapsed", - common.PrettyDuration(time.Since(bstart)), "txs", len(block.Transactions()), "gas", block.GasUsed()) + common.PrettyDuration(time.Since(bstart)), "txs", len(block.Transactions()), "computational resource usage", block.ResourceUsage()) blockInsertTimer.UpdateSince(bstart) events = append(events, ChainSideEvent{block}) } stats.processed++ - stats.usedGas += usedGas + stats.resourceUsage += resourceUsage cache, _ := bc.stateCache.TrieDB().Size() stats.report(chain, i, cache) @@ -1157,7 +1152,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty // insertStats tracks and reports on block insertion. type insertStats struct { queued, processed, ignored int - usedGas uint64 + resourceUsage uint64 lastIndex int startTime mclock.AbsTime } @@ -1181,8 +1176,8 @@ func (st *insertStats) report(chain []*types.Block, index int, cache common.Stor txs = countTransactions(chain[st.lastIndex : index+1]) ) context := []interface{}{ - "blocks", st.processed, "txs", txs, "mgas", float64(st.usedGas) / 1000000, - "elapsed", common.PrettyDuration(elapsed), "mgasps", float64(st.usedGas) * 1000 / float64(elapsed), + "blocks", st.processed, "txs", txs, "m computaional resource", float64(st.resourceUsage) / 1000000, + "elapsed", common.PrettyDuration(elapsed), "m computational resource ps", float64(st.resourceUsage) * 1000 / float64(elapsed), "number", end.Number(), "hash", end.Hash(), "cache", cache, } if st.queued > 0 { @@ -1526,4 +1521,4 @@ func (bc *BlockChain) SubscribeChainSideEvent(ch chan<- ChainSideEvent) event.Su // SubscribeLogsEvent registers a subscription of []*types.Log. func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription { return bc.scope.Track(bc.logsFeed.Subscribe(ch)) -} \ No newline at end of file +} diff --git a/client/core/blockchain_test.go b/client/core/blockchain_test.go deleted file mode 100644 index 1aa6994e6..000000000 --- a/client/core/blockchain_test.go +++ /dev/null @@ -1,1172 +0,0 @@ -package core - -// @TODO(rgeraldes) - review - -/* -// newTestBlockChain creates a blockchain without validation. -func newTestBlockChain(fake bool) *BlockChain { - db, _ := kcoindb.NewMemDatabase() - gspec := &Genesis{ - Config: params.TestChainConfig, - Difficulty: big.NewInt(1), - } - gspec.MustCommit(db) - engine := ethash.NewFullFaker() - if !fake { - engine = ethash.NewTester() - } - blockchain, err := NewBlockChain(db, gspec.Config, engine, vm.Config{}) - if err != nil { - panic(err) - } - blockchain.SetValidator(bproc{}) - return blockchain -} - -// Test fork of length N starting from block i -func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, comparator func(td1, td2 *big.Int)) { - // Copy old chain up to #i into a new db - db, blockchain2, err := newCanonical(i, full) - if err != nil { - t.Fatal("could not make new canonical in testFork", err) - } - defer blockchain2.Stop() - - // Assert the chains have the same header/block at #i - var hash1, hash2 common.Hash - if full { - hash1 = blockchain.GetBlockByNumber(uint64(i)).Hash() - hash2 = blockchain2.GetBlockByNumber(uint64(i)).Hash() - } else { - hash1 = blockchain.GetHeaderByNumber(uint64(i)).Hash() - hash2 = blockchain2.GetHeaderByNumber(uint64(i)).Hash() - } - if hash1 != hash2 { - t.Errorf("chain content mismatch at %d: have hash %v, want hash %v", i, hash2, hash1) - } - // Extend the newly created chain - var ( - blockChainB []*types.Block - headerChainB []*types.Header - ) - if full { - blockChainB = makeBlockChain(blockchain2.CurrentBlock(), n, db, forkSeed) - if _, err := blockchain2.InsertChain(blockChainB); err != nil { - t.Fatalf("failed to insert forking chain: %v", err) - } - } else { - headerChainB = makeHeaderChain(blockchain2.CurrentHeader(), n, db, forkSeed) - if _, err := blockchain2.InsertHeaderChain(headerChainB, 1); err != nil { - t.Fatalf("failed to insert forking chain: %v", err) - } - } - // Sanity check that the forked chain can be imported into the original - var tdPre, tdPost *big.Int - - if full { - tdPre = blockchain.GetTdByHash(blockchain.CurrentBlock().Hash()) - if err := testBlockChainImport(blockChainB, blockchain); err != nil { - t.Fatalf("failed to import forked block chain: %v", err) - } - tdPost = blockchain.GetTdByHash(blockChainB[len(blockChainB)-1].Hash()) - } else { - tdPre = blockchain.GetTdByHash(blockchain.CurrentHeader().Hash()) - if err := testHeaderChainImport(headerChainB, blockchain); err != nil { - t.Fatalf("failed to import forked header chain: %v", err) - } - tdPost = blockchain.GetTdByHash(headerChainB[len(headerChainB)-1].Hash()) - } - // Compare the total difficulties of the chains - comparator(tdPre, tdPost) -} - -func printChain(bc *BlockChain) { - for i := bc.CurrentBlock().Number().Uint64(); i > 0; i-- { - b := bc.GetBlockByNumber(uint64(i)) - fmt.Printf("\t%x %v\n", b.Hash(), b.Difficulty()) - } -} - -// testBlockChainImport tries to process a chain of blocks, writing them into -// the database if successful. -func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error { - for _, block := range chain { - // Try and process the block - err := blockchain.engine.VerifyHeader(blockchain, block.Header(), true) - if err == nil { - err = blockchain.validator.ValidateBody(block) - } - if err != nil { - if err == ErrKnownBlock { - continue - } - return err - } - statedb, err := state.New(blockchain.GetBlockByHash(block.ParentHash()).Root(), blockchain.stateCache) - if err != nil { - return err - } - receipts, _, usedGas, err := blockchain.Processor().Process(block, statedb, vm.Config{}) - if err != nil { - blockchain.reportBlock(block, receipts, err) - return err - } - err = blockchain.validator.ValidateState(block, blockchain.GetBlockByHash(block.ParentHash()), statedb, receipts, usedGas) - if err != nil { - blockchain.reportBlock(block, receipts, err) - return err - } - blockchain.mu.Lock() - WriteTd(blockchain.chainDb, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTdByHash(block.ParentHash()))) - WriteBlock(blockchain.chainDb, block) - statedb.CommitTo(blockchain.chainDb, false) - blockchain.mu.Unlock() - } - return nil -} - -// testHeaderChainImport tries to process a chain of header, writing them into -// the database if successful. -func testHeaderChainImport(chain []*types.Header, blockchain *BlockChain) error { - for _, header := range chain { - // Try and validate the header - if err := blockchain.engine.VerifyHeader(blockchain, header, false); err != nil { - return err - } - // Manually insert the header into the database, but don't reorganise (allows subsequent testing) - blockchain.mu.Lock() - WriteTd(blockchain.chainDb, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, blockchain.GetTdByHash(header.ParentHash))) - WriteHeader(blockchain.chainDb, header) - blockchain.mu.Unlock() - } - return nil -} - -func insertChain(done chan bool, blockchain *BlockChain, chain types.Blocks, t *testing.T) { - _, err := blockchain.InsertChain(chain) - if err != nil { - fmt.Println(err) - t.FailNow() - } - done <- true -} - -func TestLastBlock(t *testing.T) { - bchain := newTestBlockChain(false) - defer bchain.Stop() - - block := makeBlockChain(bchain.CurrentBlock(), 1, bchain.chainDb, 0)[0] - bchain.insert(block) - if block.Hash() != GetHeadBlockHash(bchain.chainDb) { - t.Errorf("Write/Get HeadBlockHash failed") - } -} - -// Tests that given a starting canonical chain of a given size, it can be extended -// with various length chains. -func TestExtendCanonicalHeaders(t *testing.T) { testExtendCanonical(t, false) } -func TestExtendCanonicalBlocks(t *testing.T) { testExtendCanonical(t, true) } - -func testExtendCanonical(t *testing.T, full bool) { - length := 5 - - // Make first chain starting from genesis - _, processor, err := newCanonical(length, full) - if err != nil { - t.Fatalf("failed to make new canonical chain: %v", err) - } - defer processor.Stop() - - // Define the difficulty comparator - better := func(td1, td2 *big.Int) { - if td2.Cmp(td1) <= 0 { - t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1) - } - } - // Start fork from current height - testFork(t, processor, length, 1, full, better) - testFork(t, processor, length, 2, full, better) - testFork(t, processor, length, 5, full, better) - testFork(t, processor, length, 10, full, better) -} - -// Tests that given a starting canonical chain of a given size, creating shorter -// forks do not take canonical ownership. -func TestShorterForkHeaders(t *testing.T) { testShorterFork(t, false) } -func TestShorterForkBlocks(t *testing.T) { testShorterFork(t, true) } - -func testShorterFork(t *testing.T, full bool) { - length := 10 - - // Make first chain starting from genesis - _, processor, err := newCanonical(length, full) - if err != nil { - t.Fatalf("failed to make new canonical chain: %v", err) - } - defer processor.Stop() - - // Define the difficulty comparator - worse := func(td1, td2 *big.Int) { - if td2.Cmp(td1) >= 0 { - t.Errorf("total difficulty mismatch: have %v, expected less than %v", td2, td1) - } - } - // Sum of numbers must be less than `length` for this to be a shorter fork - testFork(t, processor, 0, 3, full, worse) - testFork(t, processor, 0, 7, full, worse) - testFork(t, processor, 1, 1, full, worse) - testFork(t, processor, 1, 7, full, worse) - testFork(t, processor, 5, 3, full, worse) - testFork(t, processor, 5, 4, full, worse) -} - -// Tests that given a starting canonical chain of a given size, creating longer -// forks do take canonical ownership. -func TestLongerForkHeaders(t *testing.T) { testLongerFork(t, false) } -func TestLongerForkBlocks(t *testing.T) { testLongerFork(t, true) } - -func testLongerFork(t *testing.T, full bool) { - length := 10 - - // Make first chain starting from genesis - _, processor, err := newCanonical(length, full) - if err != nil { - t.Fatalf("failed to make new canonical chain: %v", err) - } - defer processor.Stop() - - // Define the difficulty comparator - better := func(td1, td2 *big.Int) { - if td2.Cmp(td1) <= 0 { - t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1) - } - } - // Sum of numbers must be greater than `length` for this to be a longer fork - testFork(t, processor, 0, 11, full, better) - testFork(t, processor, 0, 15, full, better) - testFork(t, processor, 1, 10, full, better) - testFork(t, processor, 1, 12, full, better) - testFork(t, processor, 5, 6, full, better) - testFork(t, processor, 5, 8, full, better) -} - -// Tests that given a starting canonical chain of a given size, creating equal -// forks do take canonical ownership. -func TestEqualForkHeaders(t *testing.T) { testEqualFork(t, false) } -func TestEqualForkBlocks(t *testing.T) { testEqualFork(t, true) } - -func testEqualFork(t *testing.T, full bool) { - length := 10 - - // Make first chain starting from genesis - _, processor, err := newCanonical(length, full) - if err != nil { - t.Fatalf("failed to make new canonical chain: %v", err) - } - defer processor.Stop() - - // Define the difficulty comparator - equal := func(td1, td2 *big.Int) { - if td2.Cmp(td1) != 0 { - t.Errorf("total difficulty mismatch: have %v, want %v", td2, td1) - } - } - // Sum of numbers must be equal to `length` for this to be an equal fork - testFork(t, processor, 0, 10, full, equal) - testFork(t, processor, 1, 9, full, equal) - testFork(t, processor, 2, 8, full, equal) - testFork(t, processor, 5, 5, full, equal) - testFork(t, processor, 6, 4, full, equal) - testFork(t, processor, 9, 1, full, equal) -} - -// Tests that chains missing links do not get accepted by the processor. -func TestBrokenHeaderChain(t *testing.T) { testBrokenChain(t, false) } -func TestBrokenBlockChain(t *testing.T) { testBrokenChain(t, true) } - -func testBrokenChain(t *testing.T, full bool) { - // Make chain starting from genesis - db, blockchain, err := newCanonical(10, full) - if err != nil { - t.Fatalf("failed to make new canonical chain: %v", err) - } - defer blockchain.Stop() - - // Create a forked chain, and try to insert with a missing link - if full { - chain := makeBlockChain(blockchain.CurrentBlock(), 5, db, forkSeed)[1:] - if err := testBlockChainImport(chain, blockchain); err == nil { - t.Errorf("broken block chain not reported") - } - } else { - chain := makeHeaderChain(blockchain.CurrentHeader(), 5, db, forkSeed)[1:] - if err := testHeaderChainImport(chain, blockchain); err == nil { - t.Errorf("broken header chain not reported") - } - } -} - -type bproc struct{} - -func (bproc) ValidateBody(*types.Block) error { return nil } -func (bproc) ValidateState(block, parent *types.Block, state *state.StateDB, receipts types.Receipts, usedGas *big.Int) error { - return nil -} -func (bproc) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, *big.Int, error) { - return nil, nil, new(big.Int), nil -} - -func makeHeaderChainWithDiff(genesis *types.Block, d []int, seed byte) []*types.Header { - blocks := makeBlockChainWithDiff(genesis, d, seed) - headers := make([]*types.Header, len(blocks)) - for i, block := range blocks { - headers[i] = block.Header() - } - return headers -} - -func makeBlockChainWithDiff(genesis *types.Block, d []int, seed byte) []*types.Block { - var chain []*types.Block - for i, difficulty := range d { - header := &types.Header{ - Coinbase: common.Address{seed}, - Number: big.NewInt(int64(i + 1)), - Difficulty: big.NewInt(int64(difficulty)), - UncleHash: types.EmptyUncleHash, - TxHash: types.EmptyRootHash, - ReceiptHash: types.EmptyRootHash, - Time: big.NewInt(int64(i) + 1), - } - if i == 0 { - header.ParentHash = genesis.Hash() - } else { - header.ParentHash = chain[i-1].Hash() - } - block := types.NewBlockWithHeader(header) - chain = append(chain, block) - } - return chain -} - -// Tests that reorganising a long difficult chain after a short easy one -// overwrites the canonical numbers and links in the database. -func TestReorgLongHeaders(t *testing.T) { testReorgLong(t, false) } -func TestReorgLongBlocks(t *testing.T) { testReorgLong(t, true) } - -func testReorgLong(t *testing.T, full bool) { - testReorg(t, []int{1, 2, 4}, []int{1, 2, 3, 4}, 10, full) -} - -// Tests that reorganising a short difficult chain after a long easy one -// overwrites the canonical numbers and links in the database. -func TestReorgShortHeaders(t *testing.T) { testReorgShort(t, false) } -func TestReorgShortBlocks(t *testing.T) { testReorgShort(t, true) } - -func testReorgShort(t *testing.T, full bool) { - testReorg(t, []int{1, 2, 3, 4}, []int{1, 10}, 11, full) -} - -func testReorg(t *testing.T, first, second []int, td int64, full bool) { - bc := newTestBlockChain(true) - defer bc.Stop() - - // Insert an easy and a difficult chain afterwards - if full { - bc.InsertChain(makeBlockChainWithDiff(bc.genesisBlock, first, 11)) - bc.InsertChain(makeBlockChainWithDiff(bc.genesisBlock, second, 22)) - } else { - bc.InsertHeaderChain(makeHeaderChainWithDiff(bc.genesisBlock, first, 11), 1) - bc.InsertHeaderChain(makeHeaderChainWithDiff(bc.genesisBlock, second, 22), 1) - } - // Check that the chain is valid number and link wise - if full { - prev := bc.CurrentBlock() - for block := bc.GetBlockByNumber(bc.CurrentBlock().NumberU64() - 1); block.NumberU64() != 0; prev, block = block, bc.GetBlockByNumber(block.NumberU64()-1) { - if prev.ParentHash() != block.Hash() { - t.Errorf("parent block hash mismatch: have %x, want %x", prev.ParentHash(), block.Hash()) - } - } - } else { - prev := bc.CurrentHeader() - for header := bc.GetHeaderByNumber(bc.CurrentHeader().Number.Uint64() - 1); header.Number.Uint64() != 0; prev, header = header, bc.GetHeaderByNumber(header.Number.Uint64()-1) { - if prev.ParentHash != header.Hash() { - t.Errorf("parent header hash mismatch: have %x, want %x", prev.ParentHash, header.Hash()) - } - } - } - // Make sure the chain total difficulty is the correct one - want := new(big.Int).Add(bc.genesisBlock.Difficulty(), big.NewInt(td)) - if full { - if have := bc.GetTdByHash(bc.CurrentBlock().Hash()); have.Cmp(want) != 0 { - t.Errorf("total difficulty mismatch: have %v, want %v", have, want) - } - } else { - if have := bc.GetTdByHash(bc.CurrentHeader().Hash()); have.Cmp(want) != 0 { - t.Errorf("total difficulty mismatch: have %v, want %v", have, want) - } - } -} - -// Tests that the insertion functions detect banned hashes. -func TestBadHeaderHashes(t *testing.T) { testBadHashes(t, false) } -func TestBadBlockHashes(t *testing.T) { testBadHashes(t, true) } - -func testBadHashes(t *testing.T, full bool) { - bc := newTestBlockChain(true) - defer bc.Stop() - - // Create a chain, ban a hash and try to import - var err error - if full { - blocks := makeBlockChainWithDiff(bc.genesisBlock, []int{1, 2, 4}, 10) - BadHashes[blocks[2].Header().Hash()] = true - _, err = bc.InsertChain(blocks) - } else { - headers := makeHeaderChainWithDiff(bc.genesisBlock, []int{1, 2, 4}, 10) - BadHashes[headers[2].Hash()] = true - _, err = bc.InsertHeaderChain(headers, 1) - } - if err != ErrBlacklistedHash { - t.Errorf("error mismatch: have: %v, want: %v", err, ErrBlacklistedHash) - } -} - -// Tests that bad hashes are detected on boot, and the chain rolled back to a -// good state prior to the bad hash. -func TestReorgBadHeaderHashes(t *testing.T) { testReorgBadHashes(t, false) } -func TestReorgBadBlockHashes(t *testing.T) { testReorgBadHashes(t, true) } - -func testReorgBadHashes(t *testing.T, full bool) { - bc := newTestBlockChain(true) - defer bc.Stop() - - // Create a chain, import and ban afterwards - headers := makeHeaderChainWithDiff(bc.genesisBlock, []int{1, 2, 3, 4}, 10) - blocks := makeBlockChainWithDiff(bc.genesisBlock, []int{1, 2, 3, 4}, 10) - - if full { - if _, err := bc.InsertChain(blocks); err != nil { - t.Fatalf("failed to import blocks: %v", err) - } - if bc.CurrentBlock().Hash() != blocks[3].Hash() { - t.Errorf("last block hash mismatch: have: %x, want %x", bc.CurrentBlock().Hash(), blocks[3].Header().Hash()) - } - BadHashes[blocks[3].Header().Hash()] = true - defer func() { delete(BadHashes, blocks[3].Header().Hash()) }() - } else { - if _, err := bc.InsertHeaderChain(headers, 1); err != nil { - t.Fatalf("failed to import headers: %v", err) - } - if bc.CurrentHeader().Hash() != headers[3].Hash() { - t.Errorf("last header hash mismatch: have: %x, want %x", bc.CurrentHeader().Hash(), headers[3].Hash()) - } - BadHashes[headers[3].Hash()] = true - defer func() { delete(BadHashes, headers[3].Hash()) }() - } - - // Create a new BlockChain and check that it rolled back the state. - ncm, err := NewBlockChain(bc.chainDb, bc.config, ethash.NewFaker(), vm.Config{}) - if err != nil { - t.Fatalf("failed to create new chain manager: %v", err) - } - defer ncm.Stop() - - if full { - if ncm.CurrentBlock().Hash() != blocks[2].Header().Hash() { - t.Errorf("last block hash mismatch: have: %x, want %x", ncm.CurrentBlock().Hash(), blocks[2].Header().Hash()) - } - if blocks[2].Header().GasLimit.Cmp(ncm.GasLimit()) != 0 { - t.Errorf("last block gasLimit mismatch: have: %x, want %x", ncm.GasLimit(), blocks[2].Header().GasLimit) - } - } else { - if ncm.CurrentHeader().Hash() != headers[2].Hash() { - t.Errorf("last header hash mismatch: have: %x, want %x", ncm.CurrentHeader().Hash(), headers[2].Hash()) - } - } -} - -// Tests chain insertions in the face of one entity containing an invalid nonce. -func TestHeadersInsertNonceError(t *testing.T) { testInsertNonceError(t, false) } -func TestBlocksInsertNonceError(t *testing.T) { testInsertNonceError(t, true) } - -func testInsertNonceError(t *testing.T, full bool) { - for i := 1; i < 25 && !t.Failed(); i++ { - // Create a pristine chain and database - db, blockchain, err := newCanonical(0, full) - if err != nil { - t.Fatalf("failed to create pristine chain: %v", err) - } - defer blockchain.Stop() - - // Create and insert a chain with a failing nonce - var ( - failAt int - failRes int - failNum uint64 - ) - if full { - blocks := makeBlockChain(blockchain.CurrentBlock(), i, db, 0) - - failAt = rand.Int() % len(blocks) - failNum = blocks[failAt].NumberU64() - - blockchain.engine = ethash.NewFakeFailer(failNum) - failRes, err = blockchain.InsertChain(blocks) - } else { - headers := makeHeaderChain(blockchain.CurrentHeader(), i, db, 0) - - failAt = rand.Int() % len(headers) - failNum = headers[failAt].Number.Uint64() - - blockchain.engine = ethash.NewFakeFailer(failNum) - blockchain.hc.engine = blockchain.engine - failRes, err = blockchain.InsertHeaderChain(headers, 1) - } - // Check that the returned error indicates the failure. - if failRes != failAt { - t.Errorf("test %d: failure index mismatch: have %d, want %d", i, failRes, failAt) - } - // Check that all no blocks after the failing block have been inserted. - for j := 0; j < i-failAt; j++ { - if full { - if block := blockchain.GetBlockByNumber(failNum + uint64(j)); block != nil { - t.Errorf("test %d: invalid block in chain: %v", i, block) - } - } else { - if header := blockchain.GetHeaderByNumber(failNum + uint64(j)); header != nil { - t.Errorf("test %d: invalid header in chain: %v", i, header) - } - } - } - } -} - -// Tests that fast importing a block chain produces the same chain data as the -// classical full block processing. -func TestFastVsFullChains(t *testing.T) { - // Configure and generate a sample block chain - var ( - gendb, _ = kcoindb.NewMemDatabase() - key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - address = crypto.PubkeyToAddress(key.PublicKey) - funds = big.NewInt(1000000000) - gspec = &Genesis{ - Config: params.TestChainConfig, - Alloc: GenesisAlloc{address: {Balance: funds}}, - } - genesis = gspec.MustCommit(gendb) - signer = types.NewEIP155Signer(gspec.Config.ChainId) - ) - blocks, receipts := GenerateChain(gspec.Config, genesis, gendb, 1024, func(i int, block *BlockGen) { - block.SetCoinbase(common.Address{0x00}) - - // If the block number is multiple of 3, send a few bonus transactions to the miner - if i%3 == 2 { - for j := 0; j < i%4+1; j++ { - tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), bigTxGas, nil, nil), signer, key) - if err != nil { - panic(err) - } - block.AddTx(tx) - } - } - // If the block number is a multiple of 5, add a few bonus uncles to the block - if i%5 == 5 { - block.AddUncle(&types.Header{ParentHash: block.PrevBlock(i - 1).Hash(), Number: big.NewInt(int64(i - 1))}) - } - }) - // Import the chain as an archive node for the comparison baseline - archiveDb, _ := kcoindb.NewMemDatabase() - gspec.MustCommit(archiveDb) - archive, _ := NewBlockChain(archiveDb, gspec.Config, ethash.NewFaker(), vm.Config{}) - defer archive.Stop() - - if n, err := archive.InsertChain(blocks); err != nil { - t.Fatalf("failed to process block %d: %v", n, err) - } - - // Fast import the chain as a non-archive node to test - fastDb, _ := kcoindb.NewMemDatabase() - gspec.MustCommit(fastDb) - fast, _ := NewBlockChain(fastDb, gspec.Config, ethash.NewFaker(), vm.Config{}) - defer fast.Stop() - - headers := make([]*types.Header, len(blocks)) - for i, block := range blocks { - headers[i] = block.Header() - } - if n, err := fast.InsertHeaderChain(headers, 1); err != nil { - t.Fatalf("failed to insert header %d: %v", n, err) - } - if n, err := fast.InsertReceiptChain(blocks, receipts); err != nil { - t.Fatalf("failed to insert receipt %d: %v", n, err) - } - // Iterate over all chain data components, and cross reference - for i := 0; i < len(blocks); i++ { - num, hash := blocks[i].NumberU64(), blocks[i].Hash() - - if ftd, atd := fast.GetTdByHash(hash), archive.GetTdByHash(hash); ftd.Cmp(atd) != 0 { - t.Errorf("block #%d [%x]: td mismatch: have %v, want %v", num, hash, ftd, atd) - } - if fheader, aheader := fast.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); fheader.Hash() != aheader.Hash() { - t.Errorf("block #%d [%x]: header mismatch: have %v, want %v", num, hash, fheader, aheader) - } - if fblock, ablock := fast.GetBlockByHash(hash), archive.GetBlockByHash(hash); fblock.Hash() != ablock.Hash() { - t.Errorf("block #%d [%x]: block mismatch: have %v, want %v", num, hash, fblock, ablock) - } else if types.DeriveSha(fblock.Transactions()) != types.DeriveSha(ablock.Transactions()) { - t.Errorf("block #%d [%x]: transactions mismatch: have %v, want %v", num, hash, fblock.Transactions(), ablock.Transactions()) - } else if types.CalcUncleHash(fblock.Uncles()) != types.CalcUncleHash(ablock.Uncles()) { - t.Errorf("block #%d [%x]: uncles mismatch: have %v, want %v", num, hash, fblock.Uncles(), ablock.Uncles()) - } - if freceipts, areceipts := GetBlockReceipts(fastDb, hash, GetBlockNumber(fastDb, hash)), GetBlockReceipts(archiveDb, hash, GetBlockNumber(archiveDb, hash)); types.DeriveSha(freceipts) != types.DeriveSha(areceipts) { - t.Errorf("block #%d [%x]: receipts mismatch: have %v, want %v", num, hash, freceipts, areceipts) - } - } - // Check that the canonical chains are the same between the databases - for i := 0; i < len(blocks)+1; i++ { - if fhash, ahash := GetCanonicalHash(fastDb, uint64(i)), GetCanonicalHash(archiveDb, uint64(i)); fhash != ahash { - t.Errorf("block #%d: canonical hash mismatch: have %v, want %v", i, fhash, ahash) - } - } -} - -// Tests that various import methods move the chain head pointers to the correct -// positions. -func TestLightVsFastVsFullChainHeads(t *testing.T) { - // Configure and generate a sample block chain - var ( - gendb, _ = kcoindb.NewMemDatabase() - key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - address = crypto.PubkeyToAddress(key.PublicKey) - funds = big.NewInt(1000000000) - gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}} - genesis = gspec.MustCommit(gendb) - ) - height := uint64(1024) - blocks, receipts := GenerateChain(gspec.Config, genesis, gendb, int(height), nil) - - // Configure a subchain to roll back - remove := []common.Hash{} - for _, block := range blocks[height/2:] { - remove = append(remove, block.Hash()) - } - // Create a small assertion method to check the three heads - assert := func(t *testing.T, kind string, chain *BlockChain, header uint64, fast uint64, block uint64) { - if num := chain.CurrentBlock().NumberU64(); num != block { - t.Errorf("%s head block mismatch: have #%v, want #%v", kind, num, block) - } - if num := chain.CurrentFastBlock().NumberU64(); num != fast { - t.Errorf("%s head fast-block mismatch: have #%v, want #%v", kind, num, fast) - } - if num := chain.CurrentHeader().Number.Uint64(); num != header { - t.Errorf("%s head header mismatch: have #%v, want #%v", kind, num, header) - } - } - // Import the chain as an archive node and ensure all pointers are updated - archiveDb, _ := kcoindb.NewMemDatabase() - gspec.MustCommit(archiveDb) - - archive, _ := NewBlockChain(archiveDb, gspec.Config, ethash.NewFaker(), new(event.TypeMux), vm.Config{}) - if n, err := archive.InsertChain(blocks); err != nil { - t.Fatalf("failed to process block %d: %v", n, err) - } - defer archive.Stop() - - assert(t, "archive", archive, height, height, height) - archive.Rollback(remove) - assert(t, "archive", archive, height/2, height/2, height/2) - - // Import the chain as a non-archive node and ensure all pointers are updated - fastDb, _ := kcoindb.NewMemDatabase() - gspec.MustCommit(fastDb) - fast, _ := NewBlockChain(fastDb, gspec.Config, ethash.NewFaker(), vm.Config{}) - defer fast.Stop() - - headers := make([]*types.Header, len(blocks)) - for i, block := range blocks { - headers[i] = block.Header() - } - if n, err := fast.InsertHeaderChain(headers, 1); err != nil { - t.Fatalf("failed to insert header %d: %v", n, err) - } - if n, err := fast.InsertReceiptChain(blocks, receipts); err != nil { - t.Fatalf("failed to insert receipt %d: %v", n, err) - } - assert(t, "fast", fast, height, height, 0) - fast.Rollback(remove) - assert(t, "fast", fast, height/2, height/2, 0) - - // Import the chain as a light node and ensure all pointers are updated - lightDb, _ := kcoindb.NewMemDatabase() - gspec.MustCommit(lightDb) - - light, _ := NewBlockChain(lightDb, gspec.Config, ethash.NewFaker(), new(event.TypeMux), vm.Config{}) - if n, err := light.InsertHeaderChain(headers, 1); err != nil { - t.Fatalf("failed to insert header %d: %v", n, err) - } - defer light.Stop() - - assert(t, "light", light, height, 0, 0) - light.Rollback(remove) - assert(t, "light", light, height/2, 0, 0) -} - -// Tests that chain reorganisations handle transaction removals and reinsertions. -func TestChainTxReorgs(t *testing.T) { - var ( - key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") - key3, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee") - addr1 = crypto.PubkeyToAddress(key1.PublicKey) - addr2 = crypto.PubkeyToAddress(key2.PublicKey) - addr3 = crypto.PubkeyToAddress(key3.PublicKey) - db, _ = kcoindb.NewMemDatabase() - gspec = &Genesis{ - Config: params.TestChainConfig, - GasLimit: 3141592, - Alloc: GenesisAlloc{ - addr1: {Balance: big.NewInt(1000000)}, - addr2: {Balance: big.NewInt(1000000)}, - addr3: {Balance: big.NewInt(1000000)}, - }, - } - genesis = gspec.MustCommit(db) - signer = types.NewEIP155Signer(gspec.Config.ChainId) - ) - - // Create two transactions shared between the chains: - // - postponed: transaction included at a later block in the forked chain - // - swapped: transaction included at the same block number in the forked chain - postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), bigTxGas, nil, nil), signer, key1) - swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), bigTxGas, nil, nil), signer, key1) - - // Create two transactions that will be dropped by the forked chain: - // - pastDrop: transaction dropped retroactively from a past block - // - freshDrop: transaction dropped exactly at the block where the reorg is detected - var pastDrop, freshDrop *types.Transaction - - // Create three transactions that will be added in the forked chain: - // - pastAdd: transaction added before the reorganization is detected - // - freshAdd: transaction added at the exact block the reorg is detected - // - futureAdd: transaction added after the reorg has already finished - var pastAdd, freshAdd, futureAdd *types.Transaction - - chain, _ := GenerateChain(gspec.Config, genesis, db, 3, func(i int, gen *BlockGen) { - switch i { - case 0: - pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), bigTxGas, nil, nil), signer, key2) - - gen.AddTx(pastDrop) // This transaction will be dropped in the fork from below the split point - gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork - - case 2: - freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), bigTxGas, nil, nil), signer, key2) - - 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.OffsetTime(9) // Lower the block difficulty to simulate a weaker chain - } - }) - // Import the chain. This runs all block validation rules. - blockchain, _ := NewBlockChain(db, gspec.Config, ethash.NewFaker(), vm.Config{}) - if i, err := blockchain.InsertChain(chain); err != nil { - t.Fatalf("failed to insert original chain[%d]: %v", i, err) - } - defer blockchain.Stop() - - // overwrite the old chain - chain, _ = GenerateChain(gspec.Config, genesis, db, 5, func(i int, gen *BlockGen) { - switch i { - case 0: - pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), bigTxGas, nil, nil), signer, key3) - gen.AddTx(pastAdd) // This transaction needs to be injected during reorg - - case 2: - gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain - gen.AddTx(swapped) // This transaction was swapped from the exact current spot in the original chain - - freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), bigTxGas, nil, nil), signer, key3) - gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time - - case 3: - futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), bigTxGas, nil, nil), signer, key3) - gen.AddTx(futureAdd) // This transaction will be added after a full reorg - } - }) - if _, err := blockchain.InsertChain(chain); err != nil { - t.Fatalf("failed to insert forked chain: %v", err) - } - - // removed tx - for i, tx := range (types.Transactions{pastDrop, freshDrop}) { - if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn != nil { - t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn) - } - if rcpt, _, _, _ := GetReceipt(db, tx.Hash()); rcpt != nil { - t.Errorf("drop %d: receipt %v found while shouldn't have been", i, rcpt) - } - } - // added tx - for i, tx := range (types.Transactions{pastAdd, freshAdd, futureAdd}) { - if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn == nil { - t.Errorf("add %d: expected tx to be found", i) - } - if rcpt, _, _, _ := GetReceipt(db, tx.Hash()); rcpt == nil { - t.Errorf("add %d: expected receipt to be found", i) - } - } - // shared tx - for i, tx := range (types.Transactions{postponed, swapped}) { - if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn == nil { - t.Errorf("share %d: expected tx to be found", i) - } - if rcpt, _, _, _ := GetReceipt(db, tx.Hash()); rcpt == nil { - t.Errorf("share %d: expected receipt to be found", i) - } - } -} - -func TestLogReorgs(t *testing.T) { - - var ( - key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - addr1 = crypto.PubkeyToAddress(key1.PublicKey) - db, _ = kcoindb.NewMemDatabase() - // this code generates a log - code = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00") - gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}} - genesis = gspec.MustCommit(db) - signer = types.NewEIP155Signer(gspec.Config.ChainId) - ) - - blockchain, _ := NewBlockChain(db, gspec.Config, ethash.NewFaker(), vm.Config{}) - defer blockchain.Stop() - - rmLogsCh := make(chan RemovedLogsEvent) - blockchain.SubscribeRemovedLogsEvent(rmLogsCh) - chain, _ := GenerateChain(params.TestChainConfig, genesis, db, 2, func(i int, gen *BlockGen) { - if i == 1 { - tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), big.NewInt(1000000), new(big.Int), code), signer, key1) - if err != nil { - t.Fatalf("failed to create tx: %v", err) - } - gen.AddTx(tx) - } - }) - if _, err := blockchain.InsertChain(chain); err != nil { - t.Fatalf("failed to insert chain: %v", err) - } - - chain, _ = GenerateChain(params.TestChainConfig, genesis, db, 3, func(i int, gen *BlockGen) {}) - if _, err := blockchain.InsertChain(chain); err != nil { - t.Fatalf("failed to insert forked chain: %v", err) - } - - timeout := time.NewTimer(1 * time.Second) - select { - case ev := <-rmLogsCh: - if len(ev.Logs) == 0 { - t.Error("expected logs") - } - case <-timeout.C: - t.Fatal("Timeout. There is no RemovedLogsEvent has been sent.") - } -} - -func TestReorgSideEvent(t *testing.T) { - var ( - db, _ = kcoindb.NewMemDatabase() - key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - addr1 = crypto.PubkeyToAddress(key1.PublicKey) - gspec = &Genesis{ - Config: params.TestChainConfig, - Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}, - } - genesis = gspec.MustCommit(db) - signer = types.NewEIP155Signer(gspec.Config.ChainId) - ) - - blockchain, _ := NewBlockChain(db, gspec.Config, ethash.NewFaker(), vm.Config{}) - defer blockchain.Stop() - - chain, _ := GenerateChain(gspec.Config, genesis, db, 3, func(i int, gen *BlockGen) {}) - if _, err := blockchain.InsertChain(chain); err != nil { - t.Fatalf("failed to insert chain: %v", err) - } - - replacementBlocks, _ := GenerateChain(gspec.Config, genesis, 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) - if i == 2 { - gen.OffsetTime(-9) - } - if err != nil { - t.Fatalf("failed to create tx: %v", err) - } - gen.AddTx(tx) - }) - chainSideCh := make(chan ChainSideEvent, 64) - blockchain.SubscribeChainSideEvent(chainSideCh) - if _, err := blockchain.InsertChain(replacementBlocks); err != nil { - t.Fatalf("failed to insert chain: %v", err) - } - - // first two block of the secondary chain are for a brief moment considered - // side chains because up to that point the first one is considered the - // heavier chain. - expectedSideHashes := map[common.Hash]bool{ - replacementBlocks[0].Hash(): true, - replacementBlocks[1].Hash(): true, - chain[0].Hash(): true, - chain[1].Hash(): true, - chain[2].Hash(): true, - } - - i := 0 - - const timeoutDura = 10 * time.Second - timeout := time.NewTimer(timeoutDura) -done: - for { - select { - case ev := <-chainSideCh: - block := ev.Block - if _, ok := expectedSideHashes[block.Hash()]; !ok { - t.Errorf("%d: didn't expect %x to be in side chain", i, block.Hash()) - } - i++ - - if i == len(expectedSideHashes) { - timeout.Stop() - - break done - } - timeout.Reset(timeoutDura) - - case <-timeout.C: - t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent") - } - } - - // make sure no more events are fired - select { - case e := <-chainSideCh: - t.Errorf("unexpected event fired: %v", e) - case <-time.After(250 * time.Millisecond): - } - -} - -// Tests if the canonical block can be fetched from the database during chain insertion. -func TestCanonicalBlockRetrieval(t *testing.T) { - bc := newTestBlockChain(true) - defer bc.Stop() - - chain, _ := GenerateChain(bc.config, bc.genesisBlock, bc.chainDb, 10, func(i int, gen *BlockGen) {}) - - var pend sync.WaitGroup - pend.Add(len(chain)) - - for i := range chain { - go func(block *types.Block) { - defer pend.Done() - - // try to retrieve a block by its canonical hash and see if the block data can be retrieved. - for { - ch := GetCanonicalHash(bc.chainDb, block.NumberU64()) - if ch == (common.Hash{}) { - continue // busy wait for canonical hash to be written - } - if ch != block.Hash() { - t.Fatalf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex()) - } - fb := GetBlock(bc.chainDb, ch, block.NumberU64()) - if fb == nil { - t.Fatalf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex()) - } - if fb.Hash() != block.Hash() { - t.Fatalf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex()) - } - return - } - }(chain[i]) - - if _, err := bc.InsertChain(types.Blocks{chain[i]}); err != nil { - t.Fatalf("failed to insert block %d: %v", i, err) - } - } - pend.Wait() -} - -func TestEIP155Transition(t *testing.T) { - // Configure and generate a sample block chain - var ( - db, _ = kcoindb.NewMemDatabase() - key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - address = crypto.PubkeyToAddress(key.PublicKey) - funds = big.NewInt(1000000000) - deleteAddr = common.Address{1} - gspec = &Genesis{ - Config: ¶ms.ChainConfig{ChainId: big.NewInt(1), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}, - Alloc: GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}}, - } - genesis = gspec.MustCommit(db) - mux event.TypeMux - ) - - blockchain, _ := NewBlockChain(db, gspec.Config, ethash.NewFaker(), vm.Config{}) - defer blockchain.Stop() - - blocks, _ := GenerateChain(gspec.Config, genesis, db, 4, func(i int, block *BlockGen) { - var ( - tx *types.Transaction - err error - basicTx = func(signer types.Signer) (*types.Transaction, error) { - return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), big.NewInt(21000), new(big.Int), nil), signer, key) - } - ) - switch i { - case 0: - tx, err = basicTx(types.HomesteadSigner{}) - if err != nil { - t.Fatal(err) - } - block.AddTx(tx) - case 2: - tx, err = basicTx(types.HomesteadSigner{}) - if err != nil { - t.Fatal(err) - } - block.AddTx(tx) - - tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainId)) - if err != nil { - t.Fatal(err) - } - block.AddTx(tx) - case 3: - tx, err = basicTx(types.HomesteadSigner{}) - if err != nil { - t.Fatal(err) - } - block.AddTx(tx) - - tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainId)) - if err != nil { - t.Fatal(err) - } - block.AddTx(tx) - } - }) - - if _, err := blockchain.InsertChain(blocks); err != nil { - t.Fatal(err) - } - block := blockchain.GetBlockByNumber(1) - if block.Transactions()[0].Protected() { - t.Error("Expected block[0].txs[0] to not be replay protected") - } - - block = blockchain.GetBlockByNumber(3) - if block.Transactions()[0].Protected() { - t.Error("Expected block[3].txs[0] to not be replay protected") - } - if !block.Transactions()[1].Protected() { - t.Error("Expected block[3].txs[1] to be replay protected") - } - if _, err := blockchain.InsertChain(blocks[4:]); err != nil { - t.Fatal(err) - } - - // generate an invalid chain id transaction - config := ¶ms.ChainConfig{ChainId: big.NewInt(2), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)} - blocks, _ = GenerateChain(config, blocks[len(blocks)-1], db, 4, func(i int, block *BlockGen) { - var ( - tx *types.Transaction - err error - basicTx = func(signer types.Signer) (*types.Transaction, error) { - return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), big.NewInt(21000), new(big.Int), nil), signer, key) - } - ) - switch i { - case 0: - tx, err = basicTx(types.NewEIP155Signer(big.NewInt(2))) - if err != nil { - t.Fatal(err) - } - block.AddTx(tx) - } - }) - _, err := blockchain.InsertChain(blocks) - if err != types.ErrInvalidChainId { - t.Error("expected error:", types.ErrInvalidChainId) - } -} - -func TestEIP161AccountRemoval(t *testing.T) { - // Configure and generate a sample block chain - var ( - db, _ = kcoindb.NewMemDatabase() - key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - address = crypto.PubkeyToAddress(key.PublicKey) - funds = big.NewInt(1000000000) - theAddr = common.Address{1} - gspec = &Genesis{ - Config: ¶ms.ChainConfig{ - ChainId: big.NewInt(1), - HomesteadBlock: new(big.Int), - EIP155Block: new(big.Int), - EIP158Block: big.NewInt(2), - }, - Alloc: GenesisAlloc{address: {Balance: funds}}, - } - genesis = gspec.MustCommit(db) - ) - blockchain, _ := NewBlockChain(db, gspec.Config, ethash.NewFaker(), vm.Config{}) - defer blockchain.Stop() - - blocks, _ := GenerateChain(gspec.Config, genesis, db, 3, func(i int, block *BlockGen) { - var ( - tx *types.Transaction - err error - signer = types.NewEIP155Signer(gspec.Config.ChainId) - ) - switch i { - case 0: - tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), big.NewInt(21000), new(big.Int), nil), signer, key) - case 1: - tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), big.NewInt(21000), new(big.Int), nil), signer, key) - case 2: - tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), big.NewInt(21000), new(big.Int), nil), signer, key) - } - if err != nil { - t.Fatal(err) - } - block.AddTx(tx) - }) - // account must exist pre eip 161 - if _, err := blockchain.InsertChain(types.Blocks{blocks[0]}); err != nil { - t.Fatal(err) - } - if st, _ := blockchain.State(); !st.Exist(theAddr) { - t.Error("expected account to exist") - } - - // account needs to be deleted post eip 161 - if _, err := blockchain.InsertChain(types.Blocks{blocks[1]}); err != nil { - t.Fatal(err) - } - if st, _ := blockchain.State(); st.Exist(theAddr) { - t.Error("account should not exist") - } - - // account musn't be created post eip 161 - if _, err := blockchain.InsertChain(types.Blocks{blocks[2]}); err != nil { - t.Fatal(err) - } - if st, _ := blockchain.State(); st.Exist(theAddr) { - t.Error("account should not exist") - } -} - -*/ diff --git a/client/core/chain_makers.go b/client/core/chain_makers.go index c56d8747a..8ad411f38 100644 --- a/client/core/chain_makers.go +++ b/client/core/chain_makers.go @@ -23,7 +23,7 @@ type BlockGen struct { header *types.Header statedb *state.StateDB - gasPool *GasPool + crpool *ComputationalResourcePool txs []*types.Transaction receipts []*types.Receipt lastCommit *types.Commit @@ -35,14 +35,14 @@ type BlockGen struct { // SetCoinbase sets the coinbase of the generated block. // It can be called at most once. func (b *BlockGen) SetCoinbase(addr common.Address) { - if b.gasPool != nil { + if b.crpool != nil { if len(b.txs) > 0 { panic("coinbase must be set before adding transactions") } panic("coinbase can only be set once") } b.header.Coinbase = addr - b.gasPool = new(GasPool).AddGas(b.header.GasLimit) + b.crpool = new(ComputationalResourcePool).AddResource(params.ComputeCapacity) } // SetExtra sets the extra data field of the generated block. @@ -54,7 +54,7 @@ func (b *BlockGen) SetExtra(data []byte) { // been set, the block's coinbase is set to the zero address. // // AddTx panics if the transaction cannot be executed. In addition to -// the protocol-imposed limitations (gas limit, etc.), there are some +// the protocol-imposed limitations (compute limit, etc.), there are some // further limitations on the content of transactions that can be // added. Notably, contract code relying on the BLOCKHASH instruction // will panic during execution. @@ -66,16 +66,16 @@ func (b *BlockGen) AddTx(tx *types.Transaction) { // been set, the block's coinbase is set to the zero address. // // AddTxWithChain panics if the transaction cannot be executed. In addition to -// the protocol-imposed limitations (gas limit, etc.), there are some +// the protocol-imposed limitations (compute limit, etc.), there are some // further limitations on the content of transactions that can be // added. If contract code relies on the BLOCKHASH instruction, // the block in chain will be returned. func (b *BlockGen) AddTxWithChain(bc *BlockChain, tx *types.Transaction) { - if b.gasPool == nil { + if b.crpool == nil { b.SetCoinbase(common.Address{}) } b.statedb.Prepare(tx.Hash(), common.Hash{}, len(b.txs)) - receipt, _, err := ApplyTransaction(b.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vm.Config{}) + receipt, _, err := ApplyTransaction(b.config, bc, &b.header.Coinbase, b.crpool, b.statedb, b.header, tx, &b.header.ResourceUsage, vm.Config{}) if err != nil { panic(err) } @@ -201,7 +201,6 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.S Root: state.IntermediateRoot(true), ParentHash: parent.Hash(), Coinbase: parent.Coinbase(), - GasLimit: CalcGasLimit(parent), Number: new(big.Int).Add(parent.Number(), common.Big1), Time: time, } diff --git a/client/core/error.go b/client/core/error.go index 410eca1e1..a96053d42 100644 --- a/client/core/error.go +++ b/client/core/error.go @@ -22,13 +22,13 @@ var ( // ErrKnownBlock is returned when a block to import is already known locally. ErrKnownBlock = errors.New("block already known") - // ErrGasLimitReached is returned by the gas pool if the amount of gas required - // by a transaction is higher than what's left in the block. - ErrGasLimitReached = errors.New("gas limit reached") - // ErrBlacklistedHash is returned if a block to import is on the blacklist. ErrBlacklistedHash = errors.New("blacklisted hash") + // ErrNonceTooLow is returned if the nonce of a transaction is lower than the + // one present in the local chain. + ErrNonceTooLow = errors.New("nonce too low") + // ErrNonceTooHigh is returned if the nonce of a transaction is higher than the // next one expected based on the local chain. ErrNonceTooHigh = errors.New("nonce too high") diff --git a/client/core/fees.go b/client/core/fees.go deleted file mode 100644 index 83275ea36..000000000 --- a/client/core/fees.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package core - -import ( - "math/big" -) - -var BlockReward = big.NewInt(5e+18) diff --git a/client/core/gaspool.go b/client/core/gaspool.go deleted file mode 100644 index e3795c1ee..000000000 --- a/client/core/gaspool.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package core - -import ( - "fmt" - "math" -) - -// GasPool tracks the amount of gas available during execution of the transactions -// in a block. The zero value is a pool with zero gas available. -type GasPool uint64 - -// AddGas makes gas available for execution. -func (gp *GasPool) AddGas(amount uint64) *GasPool { - if uint64(*gp) > math.MaxUint64-amount { - panic("gas pool pushed above uint64") - } - *(*uint64)(gp) += amount - return gp -} - -// SubGas deducts the given amount from the pool if enough gas is -// available and returns an error otherwise. -func (gp *GasPool) SubGas(amount uint64) error { - if uint64(*gp) < amount { - return ErrGasLimitReached - } - *(*uint64)(gp) -= amount - return nil -} - -// Gas returns the amount of gas remaining in the pool. -func (gp *GasPool) Gas() uint64 { - return uint64(*gp) -} - -func (gp *GasPool) String() string { - return fmt.Sprintf("%d", *gp) -} diff --git a/client/core/gen_genesis.go b/client/core/gen_genesis.go index c5f874bd8..2cbd39d8d 100644 --- a/client/core/gen_genesis.go +++ b/client/core/gen_genesis.go @@ -20,18 +20,15 @@ func (g Genesis) MarshalJSON() ([]byte, error) { Config *params.ChainConfig `json:"config"` Timestamp math.HexOrDecimal64 `json:"timestamp"` ExtraData hexutil.Bytes `json:"extraData"` - GasLimit math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"` Coinbase common.Address `json:"coinbase"` Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"` Number math.HexOrDecimal64 `json:"number"` - GasUsed math.HexOrDecimal64 `json:"gasUsed"` ParentHash common.Hash `json:"parentHash"` } var enc Genesis enc.Config = g.Config enc.Timestamp = math.HexOrDecimal64(g.Timestamp) enc.ExtraData = g.ExtraData - enc.GasLimit = math.HexOrDecimal64(g.GasLimit) enc.Coinbase = g.Coinbase if g.Alloc != nil { enc.Alloc = make(map[common.UnprefixedAddress]GenesisAccount, len(g.Alloc)) @@ -40,7 +37,6 @@ func (g Genesis) MarshalJSON() ([]byte, error) { } } enc.Number = math.HexOrDecimal64(g.Number) - enc.GasUsed = math.HexOrDecimal64(g.GasUsed) enc.ParentHash = g.ParentHash return json.Marshal(&enc) } @@ -51,11 +47,9 @@ func (g *Genesis) UnmarshalJSON(input []byte) error { Config *params.ChainConfig `json:"config"` Timestamp *math.HexOrDecimal64 `json:"timestamp"` ExtraData *hexutil.Bytes `json:"extraData"` - GasLimit *math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"` Coinbase *common.Address `json:"coinbase"` Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"` Number *math.HexOrDecimal64 `json:"number"` - GasUsed *math.HexOrDecimal64 `json:"gasUsed"` ParentHash *common.Hash `json:"parentHash"` } var dec Genesis @@ -71,10 +65,6 @@ func (g *Genesis) UnmarshalJSON(input []byte) error { if dec.ExtraData != nil { g.ExtraData = *dec.ExtraData } - if dec.GasLimit == nil { - return errors.New("missing required field 'gasLimit' for Genesis") - } - g.GasLimit = uint64(*dec.GasLimit) if dec.Coinbase != nil { g.Coinbase = *dec.Coinbase } @@ -88,9 +78,6 @@ func (g *Genesis) UnmarshalJSON(input []byte) error { if dec.Number != nil { g.Number = uint64(*dec.Number) } - if dec.GasUsed != nil { - g.GasUsed = uint64(*dec.GasUsed) - } if dec.ParentHash != nil { g.ParentHash = *dec.ParentHash } diff --git a/client/core/genesis.go b/client/core/genesis.go index 575fd5bee..6fc5cfdf8 100644 --- a/client/core/genesis.go +++ b/client/core/genesis.go @@ -32,14 +32,12 @@ type Genesis struct { Config *params.ChainConfig `json:"config"` Timestamp uint64 `json:"timestamp"` ExtraData []byte `json:"extraData"` - GasLimit uint64 `json:"gasLimit" gencodec:"required"` Coinbase common.Address `json:"coinbase"` Alloc GenesisAlloc `json:"alloc" gencodec:"required"` // These fields are used for consensus tests. Please don't use them // in actual genesis blocks. Number uint64 `json:"number"` - GasUsed uint64 `json:"gasUsed"` ParentHash common.Hash `json:"parentHash"` } @@ -71,8 +69,6 @@ type GenesisAccount struct { type genesisSpecMarshaling struct { Timestamp math.HexOrDecimal64 ExtraData hexutil.Bytes - GasLimit math.HexOrDecimal64 - GasUsed math.HexOrDecimal64 Number math.HexOrDecimal64 Alloc map[common.UnprefixedAddress]GenesisAccount } @@ -227,14 +223,10 @@ func (g *Genesis) ToBlock(db kcoindb.Database) *types.Block { Time: new(big.Int).SetUint64(g.Timestamp), ParentHash: g.ParentHash, Extra: g.ExtraData, - GasLimit: g.GasLimit, - GasUsed: g.GasUsed, Coinbase: g.Coinbase, Root: root, } - if g.GasLimit == 0 { - head.GasLimit = params.GenesisGasLimit - } + statedb.Commit(false) statedb.Database().TrieDB().Commit(root, true) @@ -283,7 +275,6 @@ func DefaultGenesisBlock() *Genesis { return &Genesis{ Config: params.MainnetChainConfig, ExtraData: hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"), - GasLimit: 5000, Alloc: decodePrealloc(mainnetAllocData), } } @@ -293,7 +284,6 @@ func DefaultTestnetGenesisBlock() *Genesis { return &Genesis{ Config: params.TestnetChainConfig, ExtraData: hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353535"), - GasLimit: 16777216, Alloc: decodePrealloc(testnetAllocData), } } @@ -301,9 +291,8 @@ func DefaultTestnetGenesisBlock() *Genesis { // DevGenesisBlock returns the 'kcoin --dev' genesis block. func DevGenesisBlock() *Genesis { return &Genesis{ - Config: params.AllKonsensusProtocolChanges, - GasLimit: 4712388, - Alloc: decodePrealloc(devAllocData), + Config: params.AllKonsensusProtocolChanges, + Alloc: decodePrealloc(devAllocData), } } diff --git a/client/core/helper_test.go b/client/core/helper_test.go deleted file mode 100644 index 2b4408cb0..000000000 --- a/client/core/helper_test.go +++ /dev/null @@ -1,70 +0,0 @@ -package core - -import ( - "container/list" - - "github.com/kowala-tech/kcoin/client/core/types" - "github.com/kowala-tech/kcoin/client/event" - "github.com/kowala-tech/kcoin/client/kcoindb" -) - -// Implement our EthTest Manager -type TestManager struct { - // stateManager *StateManager - eventMux *event.TypeMux - - db kcoindb.Database - txPool *TxPool - blockChain *BlockChain - Blocks []*types.Block -} - -func (tm *TestManager) IsListening() bool { - return false -} - -func (tm *TestManager) IsMining() bool { - return false -} - -func (tm *TestManager) PeerCount() int { - return 0 -} - -func (tm *TestManager) Peers() *list.List { - return list.New() -} - -func (tm *TestManager) BlockChain() *BlockChain { - return tm.blockChain -} - -func (tm *TestManager) TxPool() *TxPool { - return tm.txPool -} - -// func (tm *TestManager) StateManager() *StateManager { -// return tm.stateManager -// } - -func (tm *TestManager) EventMux() *event.TypeMux { - return tm.eventMux -} - -// func (tm *TestManager) KeyManager() *crypto.KeyManager { -// return nil -// } - -func (tm *TestManager) Db() kcoindb.Database { - return tm.db -} - -func NewTestManager() *TestManager { - testManager := &TestManager{} - testManager.eventMux = new(event.TypeMux) - testManager.db = kcoindb.NewMemDatabase() - // testManager.txPool = NewTxPool(testManager) - // testManager.blockChain = NewBlockChain(testManager) - // testManager.stateManager = NewStateManager(testManager) - return testManager -} diff --git a/client/core/types.go b/client/core/interfaces.go similarity index 90% rename from client/core/types.go rename to client/core/interfaces.go index 0f11a08df..43fcd71e9 100644 --- a/client/core/types.go +++ b/client/core/interfaces.go @@ -31,15 +31,15 @@ type Validator interface { ValidateBody(block *types.Block) error // ValidateState validates the given statedb and optionally the receipts and - // gas used. - ValidateState(block, parent *types.Block, state *state.StateDB, receipts types.Receipts, usedGas uint64) error + // computational resource usage. + ValidateState(block, parent *types.Block, state *state.StateDB, receipts types.Receipts, resourceUsage uint64) error } // Processor is an interface for processing blocks using a given initial state. // // Process takes the block to be processed and the statedb upon which the // initial state is based. It should return the receipts generated, amount -// of gas used in the process and return an error if any of the internal rules +// of computational resource used in the process and return an error if any of the internal rules // failed. type Processor interface { Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) diff --git a/client/core/resource_pool.go b/client/core/resource_pool.go new file mode 100644 index 000000000..a8ce5ecba --- /dev/null +++ b/client/core/resource_pool.go @@ -0,0 +1,45 @@ +package core + +import ( + "errors" + "fmt" + "math" +) + +var ( + // ErrComputeCapacityReached is returned by the computational resources pool if the computational effort required + // by a transaction is higher than what's left in the block. + ErrComputeCapacityReached = errors.New("compute capacity reached") +) + +// ComputationalResourcePool tracks the computational resource available in compute units during +// the execution of the transactions in a block. +type ComputationalResourcePool uint64 + +// AddResource makes computational resource available for execution. +func (pool *ComputationalResourcePool) AddResource(units uint64) *ComputationalResourcePool { + if uint64(*pool) > math.MaxUint64-units { + panic("computational resource pool pushed above uint64") + } + *(*uint64)(pool) += units + return pool +} + +// SubResource deducts the given computational resource units from the pool if enough units are +// available and returns an error otherwise. +func (pool *ComputationalResourcePool) SubResource(units uint64) error { + if uint64(*pool) < units { + return ErrComputeCapacityReached + } + *(*uint64)(pool) -= units + return nil +} + +// Value returns the amount of computational resource (compute units) remaining in the pool. +func (pool *ComputationalResourcePool) Value() uint64 { + return uint64(*pool) +} + +func (pool *ComputationalResourcePool) String() string { + return fmt.Sprintf("%d", *pool) +} diff --git a/client/core/state/state_object.go b/client/core/state/state_object.go index b111af140..dacf90d24 100644 --- a/client/core/state/state_object.go +++ b/client/core/state/state_object.go @@ -31,30 +31,30 @@ var emptyCodeHash = crypto.Keccak256(nil) type Code []byte -func (self Code) String() string { - return string(self) //strings.Join(Disassemble(self), " ") +func (c Code) String() string { + return string(c) //strings.Join(Disassemble(c), " ") } type Storage map[common.Hash]common.Hash -func (self Storage) String() (str string) { - for key, value := range self { +func (st Storage) String() (str string) { + for key, value := range st { str += fmt.Sprintf("%X : %X\n", key, value) } return } -func (self Storage) Copy() Storage { +func (st Storage) Copy() Storage { cpy := make(Storage) - for key, value := range self { + for key, value := range st { cpy[key] = value } return cpy } -// stateObject represents an Ethereum account which is being modified. +// stateObject represents an Kowala account which is being modified. // // The usage pattern is as follows: // First you need to obtain a state object. @@ -62,7 +62,7 @@ func (self Storage) Copy() Storage { // Finally, call CommitTrie to write the modified storage trie into a database. type stateObject struct { address common.Address - addrHash common.Hash // hash of ethereum address of the account + addrHash common.Hash // hash of Kowala address of the account data Account db *StateDB @@ -93,7 +93,7 @@ func (s *stateObject) empty() bool { return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash) } -// Account is the Ethereum consensus representation of accounts. +// Account is the Kowala consensus representation of accounts. // These objects are stored in the main account trie. type Account struct { Nonce uint64 @@ -121,168 +121,168 @@ func newObject(db *StateDB, address common.Address, data Account) *stateObject { } // EncodeRLP implements rlp.Encoder. -func (c *stateObject) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, c.data) +func (so *stateObject) EncodeRLP(w io.Writer) error { + return rlp.Encode(w, so.data) } // setError remembers the first non-nil error it is called with. -func (self *stateObject) setError(err error) { - if self.dbErr == nil { - self.dbErr = err +func (so *stateObject) setError(err error) { + if so.dbErr == nil { + so.dbErr = err } } -func (self *stateObject) markSuicided() { - self.suicided = true +func (so *stateObject) markSuicided() { + so.suicided = true } -func (c *stateObject) touch() { - c.db.journal.append(touchChange{ - account: &c.address, +func (so *stateObject) touch() { + so.db.journal.append(touchChange{ + account: &so.address, }) - if c.address == ripemd { + if so.address == ripemd { // Explicitly put it in the dirty-cache, which is otherwise generated from // flattened journals. - c.db.journal.dirty(c.address) + so.db.journal.dirty(so.address) } } -func (c *stateObject) getTrie(db Database) Trie { - if c.trie == nil { +func (so *stateObject) getTrie(db Database) Trie { + if so.trie == nil { var err error - c.trie, err = db.OpenStorageTrie(c.addrHash, c.data.Root) + so.trie, err = db.OpenStorageTrie(so.addrHash, so.data.Root) if err != nil { - c.trie, _ = db.OpenStorageTrie(c.addrHash, common.Hash{}) - c.setError(fmt.Errorf("can't create storage trie: %v", err)) + so.trie, _ = db.OpenStorageTrie(so.addrHash, common.Hash{}) + so.setError(fmt.Errorf("can't create storage trie: %v", err)) } } - return c.trie + return so.trie } // GetState returns a value in account storage. -func (self *stateObject) GetState(db Database, key common.Hash) common.Hash { - value, exists := self.cachedStorage[key] +func (so *stateObject) GetState(db Database, key common.Hash) common.Hash { + value, exists := so.cachedStorage[key] if exists { return value } // Load from DB in case it is missing. - enc, err := self.getTrie(db).TryGet(key[:]) + enc, err := so.getTrie(db).TryGet(key[:]) if err != nil { - self.setError(err) + so.setError(err) return common.Hash{} } if len(enc) > 0 { _, content, _, err := rlp.Split(enc) if err != nil { - self.setError(err) + so.setError(err) } value.SetBytes(content) } - self.cachedStorage[key] = value + so.cachedStorage[key] = value return value } // SetState updates a value in account storage. -func (self *stateObject) SetState(db Database, key, value common.Hash) { - self.db.journal.append(storageChange{ - account: &self.address, +func (so *stateObject) SetState(db Database, key, value common.Hash) { + so.db.journal.append(storageChange{ + account: &so.address, key: key, - prevalue: self.GetState(db, key), + prevalue: so.GetState(db, key), }) - self.setState(key, value) + so.setState(key, value) } -func (self *stateObject) setState(key, value common.Hash) { - self.cachedStorage[key] = value - self.dirtyStorage[key] = value +func (so *stateObject) setState(key, value common.Hash) { + so.cachedStorage[key] = value + so.dirtyStorage[key] = value } // updateTrie writes cached storage modifications into the object's storage trie. -func (self *stateObject) updateTrie(db Database) Trie { - tr := self.getTrie(db) - for key, value := range self.dirtyStorage { - delete(self.dirtyStorage, key) +func (so *stateObject) updateTrie(db Database) Trie { + tr := so.getTrie(db) + for key, value := range so.dirtyStorage { + delete(so.dirtyStorage, key) if (value == common.Hash{}) { - self.setError(tr.TryDelete(key[:])) + so.setError(tr.TryDelete(key[:])) continue } // Encoding []byte cannot fail, ok to ignore the error. v, _ := rlp.EncodeToBytes(bytes.TrimLeft(value[:], "\x00")) - self.setError(tr.TryUpdate(key[:], v)) + so.setError(tr.TryUpdate(key[:], v)) } return tr } // UpdateRoot sets the trie root to the current root hash of -func (self *stateObject) updateRoot(db Database) { - self.updateTrie(db) - self.data.Root = self.trie.Hash() +func (so *stateObject) updateRoot(db Database) { + so.updateTrie(db) + so.data.Root = so.trie.Hash() } // CommitTrie the storage trie of the object to db. // This updates the trie root. -func (self *stateObject) CommitTrie(db Database) error { - self.updateTrie(db) - if self.dbErr != nil { - return self.dbErr +func (so *stateObject) CommitTrie(db Database) error { + so.updateTrie(db) + if so.dbErr != nil { + return so.dbErr } - root, err := self.trie.Commit(nil) + root, err := so.trie.Commit(nil) if err == nil { - self.data.Root = root + so.data.Root = root } return err } // AddBalance removes amount from c's balance. // It is used to add funds to the destination account of a transfer. -func (c *stateObject) AddBalance(amount *big.Int) { +func (so *stateObject) AddBalance(amount *big.Int) { // EIP158: We must check emptiness for the objects such that the account // clearing (0,0,0 objects) can take effect. if amount.Sign() == 0 { - if c.empty() { - c.touch() + if so.empty() { + so.touch() } return } - c.SetBalance(new(big.Int).Add(c.Balance(), amount)) + so.SetBalance(new(big.Int).Add(so.Balance(), amount)) } // SubBalance removes amount from c's balance. // It is used to remove funds from the origin account of a transfer. -func (c *stateObject) SubBalance(amount *big.Int) { +func (so *stateObject) SubBalance(amount *big.Int) { if amount.Sign() == 0 { return } - c.SetBalance(new(big.Int).Sub(c.Balance(), amount)) + so.SetBalance(new(big.Int).Sub(so.Balance(), amount)) } -func (self *stateObject) SetBalance(amount *big.Int) { - self.db.journal.append(balanceChange{ - account: &self.address, - prev: new(big.Int).Set(self.data.Balance), +func (so *stateObject) SetBalance(amount *big.Int) { + so.db.journal.append(balanceChange{ + account: &so.address, + prev: new(big.Int).Set(so.data.Balance), }) - self.setBalance(amount) + so.setBalance(amount) } -func (self *stateObject) setBalance(amount *big.Int) { - self.data.Balance = amount +func (so *stateObject) setBalance(amount *big.Int) { + so.data.Balance = amount } -// Return the gas back to the origin. Used by the Virtual machine or Closures -func (c *stateObject) ReturnGas(gas *big.Int) {} +// Return the computational resource back to the origin. Used by the Virtual machine or Closures +func (so *stateObject) ReturnComputationalResource(resource *big.Int) {} -func (self *stateObject) deepCopy(db *StateDB) *stateObject { - stateObject := newObject(db, self.address, self.data) - if self.trie != nil { - stateObject.trie = db.db.CopyTrie(self.trie) +func (so *stateObject) deepCopy(db *StateDB) *stateObject { + stateObject := newObject(db, so.address, so.data) + if so.trie != nil { + stateObject.trie = db.db.CopyTrie(so.trie) } - stateObject.code = self.code - stateObject.dirtyStorage = self.dirtyStorage.Copy() - stateObject.cachedStorage = self.dirtyStorage.Copy() - stateObject.suicided = self.suicided - stateObject.dirtyCode = self.dirtyCode - stateObject.deleted = self.deleted + stateObject.code = so.code + stateObject.dirtyStorage = so.dirtyStorage.Copy() + stateObject.cachedStorage = so.dirtyStorage.Copy() + stateObject.suicided = so.suicided + stateObject.dirtyCode = so.dirtyCode + stateObject.deleted = so.deleted return stateObject } @@ -291,69 +291,69 @@ func (self *stateObject) deepCopy(db *StateDB) *stateObject { // // Returns the address of the contract/account -func (c *stateObject) Address() common.Address { - return c.address +func (so *stateObject) Address() common.Address { + return so.address } // Code returns the contract code associated with this object, if any. -func (self *stateObject) Code(db Database) []byte { - if self.code != nil { - return self.code +func (so *stateObject) Code(db Database) []byte { + if so.code != nil { + return so.code } - if bytes.Equal(self.CodeHash(), emptyCodeHash) { + if bytes.Equal(so.CodeHash(), emptyCodeHash) { return nil } - code, err := db.ContractCode(self.addrHash, common.BytesToHash(self.CodeHash())) + code, err := db.ContractCode(so.addrHash, common.BytesToHash(so.CodeHash())) if err != nil { - self.setError(fmt.Errorf("can't load code hash %x: %v", self.CodeHash(), err)) + so.setError(fmt.Errorf("can't load code hash %x: %v", so.CodeHash(), err)) } - self.code = code + so.code = code return code } -func (self *stateObject) SetCode(codeHash common.Hash, code []byte) { - prevcode := self.Code(self.db.db) - self.db.journal.append(codeChange{ - account: &self.address, - prevhash: self.CodeHash(), +func (so *stateObject) SetCode(codeHash common.Hash, code []byte) { + prevcode := so.Code(so.db.db) + so.db.journal.append(codeChange{ + account: &so.address, + prevhash: so.CodeHash(), prevcode: prevcode, }) - self.setCode(codeHash, code) + so.setCode(codeHash, code) } -func (self *stateObject) setCode(codeHash common.Hash, code []byte) { - self.code = code - self.data.CodeHash = codeHash[:] - self.dirtyCode = true +func (so *stateObject) setCode(codeHash common.Hash, code []byte) { + so.code = code + so.data.CodeHash = codeHash[:] + so.dirtyCode = true } -func (self *stateObject) SetNonce(nonce uint64) { - self.db.journal.append(nonceChange{ - account: &self.address, - prev: self.data.Nonce, +func (so *stateObject) SetNonce(nonce uint64) { + so.db.journal.append(nonceChange{ + account: &so.address, + prev: so.data.Nonce, }) - self.setNonce(nonce) + so.setNonce(nonce) } -func (self *stateObject) setNonce(nonce uint64) { - self.data.Nonce = nonce +func (so *stateObject) setNonce(nonce uint64) { + so.data.Nonce = nonce } -func (self *stateObject) CodeHash() []byte { - return self.data.CodeHash +func (so *stateObject) CodeHash() []byte { + return so.data.CodeHash } -func (self *stateObject) Balance() *big.Int { - return self.data.Balance +func (so *stateObject) Balance() *big.Int { + return so.data.Balance } -func (self *stateObject) Nonce() uint64 { - return self.data.Nonce +func (so *stateObject) Nonce() uint64 { + return so.data.Nonce } // Never called, but must be present to allow stateObject to be used // as a vm.Account interface that also satisfies the vm.ContractRef // interface. Interfaces are awesome. -func (self *stateObject) Value() *big.Int { +func (so *stateObject) Value() *big.Int { panic("Value on stateObject should never be called") } diff --git a/client/core/state/statedb.go b/client/core/state/statedb.go index 9946a4273..c32680b3b 100644 --- a/client/core/state/statedb.go +++ b/client/core/state/statedb.go @@ -169,9 +169,9 @@ func (self *StateDB) Preimages() map[common.Hash][]byte { return self.preimages } -func (self *StateDB) AddRefund(gas uint64) { +func (self *StateDB) AddRefund(computationalResource uint64) { self.journal.append(refundChange{prev: self.refund}) - self.refund += gas + self.refund += computationalResource } // Exist reports whether the given account address exists in the state. @@ -536,7 +536,7 @@ func (s *StateDB) Finalise(deleteEmptyObjects bool) { stateObject, exist := s.stateObjects[addr] if !exist { // ripeMD is 'touched' at block 1714175, in tx 0x1237f737031e40bcde4a8b7e717b2d15e3ecadfe49bb1bbc71ee9deb09c6fcf2 - // That tx goes out of gas, and although the notion of 'touched' does not exist there, the + // That tx goes out of computational resource, and although the notion of 'touched' does not exist there, the // touch-event will still be recorded in the journal. Since ripeMD is a special snowflake, // it will persist in the journal even though the journal is reverted. In this special circumstance, // it may exist in `s.journal.dirties` but not in `s.stateObjects`. diff --git a/client/core/state_processor.go b/client/core/state_processor.go index da504481a..31f763393 100644 --- a/client/core/state_processor.go +++ b/client/core/state_processor.go @@ -36,21 +36,21 @@ func NewStateProcessor(config *params.ChainConfig, bc *BlockChain, engine consen // the processor (coinbase) and any included uncles. // // Process returns the receipts and logs accumulated during the process and -// returns the amount of gas that was used in the process. If any of the -// transactions failed to execute due to insufficient gas it will return an error. +// returns the amount of computational resource that was used in the process. If any of the +// transactions failed to execute due to insufficient computational resource it will return an error. func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) { var ( - receipts types.Receipts - usedGas = new(uint64) - header = block.Header() - allLogs []*types.Log - gp = new(GasPool).AddGas(block.GasLimit()) + receipts types.Receipts + resourceUsage = new(uint64) + header = block.Header() + allLogs []*types.Log + crpool = new(ComputationalResourcePool).AddResource(params.ComputeCapacity) ) // Iterate over and process the individual transactions for i, tx := range block.Transactions() { statedb.Prepare(tx.Hash(), block.Hash(), i) - receipt, _, err := ApplyTransaction(p.config, p.bc, nil, gp, statedb, header, tx, usedGas, cfg) + receipt, _, err := ApplyTransaction(p.config, p.bc, nil, crpool, statedb, header, tx, resourceUsage, cfg) if err != nil { log.Debug("failed StateProcessor.Process", "data", spew.Sdump( header.Number, @@ -59,7 +59,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg header.TxHash, header.ValidatorsHash, header.LastCommitHash, - tx, usedGas, allLogs)) + tx, resourceUsage, allLogs)) return nil, nil, 0, err } @@ -69,25 +69,25 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg // Finalize the block, applying any consensus engine specific extras (e.g. block rewards) p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.LastCommit(), receipts) - return receipts, allLogs, *usedGas, nil + return receipts, allLogs, *resourceUsage, nil } // ApplyTransaction attempts to apply a transaction to the given state database // and uses the input parameters for its environment. It returns the receipt -// for the transaction, gas used and an error if the transaction failed, +// for the transaction, computational resource used and an error if the transaction failed, // indicating the block was invalid. -func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, uint64, error) { +func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, crpool *ComputationalResourcePool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, resourceUsage *uint64, cfg vm.Config) (*types.Receipt, uint64, error) { msg, err := tx.AsMessage(types.MakeSigner(config, header.Number)) if err != nil { return nil, 0, err } - // Create a new context to be used in the EVM environment - context := NewEVMContext(msg, header, bc, author) + // Create a new context to be used in the VM environment + context := NewVMContext(msg, header, bc, author) // Create a new environment which holds all relevant information // about the transaction and calling mechanisms. - vmenv := vm.NewEVM(context, statedb, config, cfg) + env := vm.New(context, statedb, config, cfg) // Apply the transaction to the current state (included in the env) - _, gas, failed, err := ApplyMessage(vmenv, msg, gp) + _, resourceUsed, failed, err := ApplyMessage(env, msg, crpool) if err != nil { return nil, 0, err } @@ -95,20 +95,20 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo var root []byte statedb.Finalise(true) - *usedGas += gas + *resourceUsage += resourceUsed - // 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 computational resource used by the tx // based on the eip phase, we're passing wether the root touch-delete accounts. - receipt := types.NewReceipt(root, failed, *usedGas) + receipt := types.NewReceipt(root, failed, *resourceUsage) receipt.TxHash = tx.Hash() - receipt.GasUsed = gas + receipt.ResourceUsage = resourceUsed // if the transaction created a contract, store the creation address in the receipt. if msg.To() == nil { - receipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce()) + receipt.ContractAddress = crypto.CreateAddress(env.Context.Origin, tx.Nonce()) } // Set the receipt logs and create a bloom for filtering receipt.Logs = statedb.GetLogs(tx.Hash()) receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) - return receipt, gas, err + return receipt, resourceUsed, err } diff --git a/client/core/state_transition.go b/client/core/state_transition.go index 818878cbc..bac1b22fe 100644 --- a/client/core/state_transition.go +++ b/client/core/state_transition.go @@ -8,11 +8,11 @@ import ( "github.com/kowala-tech/kcoin/client/common" "github.com/kowala-tech/kcoin/client/core/vm" "github.com/kowala-tech/kcoin/client/log" - "github.com/kowala-tech/kcoin/client/params" + effrt "github.com/kowala-tech/kcoin/client/params/effort" ) var ( - errInsufficientBalanceForGas = errors.New("insufficient balance to pay for gas") + errInsufficientBalanceForComputationalResource = errors.New("insufficient balance to pay for computational resource") ) /* @@ -22,7 +22,7 @@ A state transition is a change made when a transaction is applied to the current The state transitioning model does all all the necessary work to work out a valid new state root. 1) Nonce handling -2) Pre pay gas +2) Pre pay computational resource 3) Create a new state object if the recipient is \0*32 4) Value transfer == If contract creation == @@ -33,25 +33,22 @@ The state transitioning model does all all the necessary work to work out a vali 6) Derive new state root */ type StateTransition struct { - gp *GasPool - msg Message - gas uint64 - gasPrice *big.Int - initialGas uint64 - value *big.Int - data []byte - state vm.StateDB - evm *vm.EVM + crpool *ComputationalResourcePool + msg Message + resource uint64 + initialResource uint64 + value *big.Int + data []byte + state vm.StateDB + vm *vm.VM } // Message represents a message sent to a contract. type Message interface { From() common.Address - //FromFrontier() (common.Address, error) To() *common.Address - GasPrice() *big.Int - Gas() uint64 + ComputeLimit() uint64 Value() *big.Int Nonce() uint64 @@ -59,16 +56,16 @@ type Message interface { Data() []byte } -// IntrinsicGas computes the 'intrinsic gas' for a message with the given data. -func IntrinsicGas(data []byte, contractCreation, homestead bool) (uint64, error) { - // Set the starting gas for the raw transaction - var gas uint64 - if contractCreation && homestead { - gas = params.TxGasContractCreation +// IntrinsicEffort computes the 'intrinsic computational effort' for a message with the given data. +func IntrinsicEffort(data []byte, contractCreation bool) (uint64, error) { + // Set the starting effort for the raw transaction + var effort uint64 + if contractCreation { + effort = effrt.TxContractCreation } else { - gas = params.TxGas + effort = effrt.Tx } - // Bump the required gas by the amount of transactional data + // Bump the required effort by the amount of transactional data if len(data) > 0 { // Zero and non-zero bytes are priced differently var nz uint64 @@ -78,42 +75,41 @@ func IntrinsicGas(data []byte, contractCreation, homestead bool) (uint64, error) } } // Make sure we don't exceed uint64 for all data combinations - if (math.MaxUint64-gas)/params.TxDataNonZeroGas < nz { - return 0, vm.ErrOutOfGas + if (math.MaxUint64-effort)/effrt.TxDataNonZero < nz { + return 0, vm.ErrOutOfComputationalResource } - gas += nz * params.TxDataNonZeroGas + effort += nz * effrt.TxDataNonZero z := uint64(len(data)) - nz - if (math.MaxUint64-gas)/params.TxDataZeroGas < z { - return 0, vm.ErrOutOfGas + if (math.MaxUint64-effort)/effrt.TxDataZero < z { + return 0, vm.ErrOutOfComputationalResource } - gas += z * params.TxDataZeroGas + effort += z * effrt.TxDataZero } - return gas, nil + return effort, nil } // NewStateTransition initialises and returns a new state transition object. -func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition { +func NewStateTransition(vm *vm.VM, msg Message, crpool *ComputationalResourcePool) *StateTransition { return &StateTransition{ - gp: gp, - evm: evm, - msg: msg, - gasPrice: msg.GasPrice(), - value: msg.Value(), - data: msg.Data(), - state: evm.StateDB, + crpool: crpool, + vm: vm, + msg: msg, + value: msg.Value(), + data: msg.Data(), + state: vm.StateDB, } } // ApplyMessage computes the new state by applying the given message // against the old state within the environment. // -// ApplyMessage returns the bytes returned by any EVM execution (if it took place), -// the gas used (which includes gas refunds) and an error if it failed. An error always +// ApplyMessage returns the bytes returned by any VM execution (if it took place), +// the computational resource usage (which includes refunds) and an error if it failed. An error always // indicates a core error meaning that the message would always fail for that particular // state and would never be accepted within a block. -func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) ([]byte, uint64, bool, error) { - return NewStateTransition(evm, msg, gp).TransitionDb() +func ApplyMessage(vm *vm.VM, msg Message, crpool *ComputationalResourcePool) ([]byte, uint64, bool, error) { + return NewStateTransition(vm, msg, crpool).TransitionDb() } // to returns the recipient of the message. @@ -124,26 +120,26 @@ func (st *StateTransition) to() common.Address { return *st.msg.To() } -func (st *StateTransition) useGas(amount uint64) error { - if st.gas < amount { - return vm.ErrOutOfGas +func (st *StateTransition) useResource(amount uint64) error { + if st.resource < amount { + return vm.ErrOutOfComputationalResource } - st.gas -= amount + st.resource -= amount return nil } -func (st *StateTransition) buyGas() error { - mgval := new(big.Int).Mul(new(big.Int).SetUint64(st.msg.Gas()), st.gasPrice) +func (st *StateTransition) buyResource() error { + mgval := new(big.Int).Mul(new(big.Int).SetUint64(st.msg.ComputeLimit()), st.vm.ComputeUnitPrice) if st.state.GetBalance(st.msg.From()).Cmp(mgval) < 0 { - return errInsufficientBalanceForGas + return errInsufficientBalanceForComputationalResource } - if err := st.gp.SubGas(st.msg.Gas()); err != nil { + if err := st.crpool.SubResource(st.msg.ComputeLimit()); err != nil { return err } - st.gas += st.msg.Gas() + st.resource += st.msg.ComputeLimit() - st.initialGas = st.msg.Gas() + st.initialResource = st.msg.ComputeLimit() st.state.SubBalance(st.msg.From(), mgval) return nil } @@ -158,13 +154,13 @@ func (st *StateTransition) preCheck() error { return ErrNonceTooLow } } - return st.buyGas() + return st.buyResource() } // TransitionDb will transition the state by applying the current message and -// returning the result including the the used gas. It returns an error if it +// returning the result including the the used computational resource. It returns an error if it // failed. An error indicates a consensus issue. -func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bool, err error) { +func (st *StateTransition) TransitionDb() (ret []byte, resourceUsage uint64, failed bool, err error) { if err = st.preCheck(); err != nil { return } @@ -172,28 +168,28 @@ func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bo sender := vm.AccountRef(msg.From()) contractCreation := msg.To() == nil - // Pay intrinsic gas - gas, err := IntrinsicGas(st.data, contractCreation, true) + // Pay intrinsic computational effort + effort, err := IntrinsicEffort(st.data, contractCreation) if err != nil { return nil, 0, false, err } - if err = st.useGas(gas); err != nil { + if err = st.useResource(effort); err != nil { return nil, 0, false, err } var ( - evm = st.evm + env = st.vm // vm errors do not effect consensus and are therefor // not assigned to err, except for insufficient balance // error. vmerr error ) if contractCreation { - ret, _, st.gas, vmerr = evm.Create(sender, st.data, st.gas, st.value) + ret, _, st.resource, vmerr = env.Create(sender, st.data, st.resource, st.value) } else { // Increment the nonce for the next transaction st.state.SetNonce(msg.From(), st.state.GetNonce(sender.Address())+1) - ret, st.gas, vmerr = evm.Call(sender, st.to(), st.data, st.gas, st.value) + ret, st.resource, vmerr = env.Call(sender, st.to(), st.data, st.resource, st.value) } if vmerr != nil { log.Debug("VM returned with error", "err", vmerr) @@ -204,30 +200,30 @@ func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bo return nil, 0, false, vmerr } } - st.refundGas() - st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice)) + st.refundResource() + st.state.AddBalance(st.vm.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.resourceUsed()), st.vm.ComputeUnitPrice)) - return ret, st.gasUsed(), vmerr != nil, err + return ret, st.resourceUsed(), vmerr != nil, err } -func (st *StateTransition) refundGas() { - // Apply refund counter, capped to half of the used gas. - refund := st.gasUsed() / 2 +func (st *StateTransition) refundResource() { + // Apply refund counter, capped to half of the used computational resource. + refund := st.resourceUsed() / 2 if refund > st.state.GetRefund() { refund = st.state.GetRefund() } - st.gas += refund + st.resource += refund - // Return kUSD for remaining gas, exchanged at the original rate. - remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gas), st.gasPrice) + // Return kUSD for remaining computational resource. + remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.resource), st.vm.ComputeUnitPrice) st.state.AddBalance(st.msg.From(), remaining) - // Also return remaining gas to the block gas counter so it is + // Also return remaining computational resource to the block resource counter so it is // available for the next transaction. - st.gp.AddGas(st.gas) + st.crpool.AddResource(st.resource) } -// gasUsed returns the amount of gas used up by the state transition. -func (st *StateTransition) gasUsed() uint64 { - return st.initialGas - st.gas +// resourceUsed returns the amount of computational resource used up by the state transition. +func (st *StateTransition) resourceUsed() uint64 { + return st.initialResource - st.resource } diff --git a/client/core/tx_journal.go b/client/core/tx_journal.go index c6fc5c9a9..4a1372c7a 100644 --- a/client/core/tx_journal.go +++ b/client/core/tx_journal.go @@ -1,19 +1,3 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - package core import ( @@ -121,15 +105,13 @@ func (journal *txJournal) insert(tx *types.Transaction) error { if journal.writer == nil { return errNoActiveJournal } - if err := rlp.Encode(journal.writer, tx); err != nil { - return err - } - return nil + + return rlp.Encode(journal.writer, tx) } // rotate regenerates the transaction journal based on the current contents of // the transaction pool. -func (journal *txJournal) rotate(all map[common.Address]types.Transactions) error { +func (journal *txJournal) rotate(all map[common.Address]ValidTransactions) error { // Close the current journal (if any is open) if journal.writer != nil { if err := journal.writer.Close(); err != nil { @@ -145,7 +127,7 @@ func (journal *txJournal) rotate(all map[common.Address]types.Transactions) erro journaled := 0 for _, txs := range all { for _, tx := range txs { - if err = rlp.Encode(replacement, tx); err != nil { + if err = rlp.Encode(replacement, tx.Transaction); err != nil { replacement.Close() return err } diff --git a/client/core/tx_list.go b/client/core/tx_list.go index f08de5d92..e8a171147 100644 --- a/client/core/tx_list.go +++ b/client/core/tx_list.go @@ -1,19 +1,3 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - package core import ( @@ -22,9 +6,7 @@ import ( "math/big" "sort" - "github.com/kowala-tech/kcoin/client/common" "github.com/kowala-tech/kcoin/client/core/types" - "github.com/kowala-tech/kcoin/client/log" ) // nonceHeap is a heap.Interface implementation over 64bit unsigned integers for @@ -47,30 +29,30 @@ func (h *nonceHeap) Pop() interface{} { return x } -// txSortedMap is a nonce->transaction hash map with a heap based index to allow +// txSortedMap is a nonce->tx pool transaction hash map with a heap based index to allow // iterating over the contents in a nonce-incrementing way. type txSortedMap struct { - items map[uint64]*types.Transaction // Hash map storing the transaction data - index *nonceHeap // Heap of nonces of all the stored transactions (non-strict mode) - cache types.Transactions // Cache of the transactions already sorted + items map[uint64]*ValidTransaction // Hash map storing the transaction data + index *nonceHeap // Heap of nonces of all the stored transactions (non-strict mode) + cache ValidTransactions // Cache of the transactions already sorted } // newTxSortedMap creates a new nonce-sorted transaction map. func newTxSortedMap() *txSortedMap { return &txSortedMap{ - items: make(map[uint64]*types.Transaction), + items: make(map[uint64]*ValidTransaction), index: new(nonceHeap), } } // Get retrieves the current transactions associated with the given nonce. -func (m *txSortedMap) Get(nonce uint64) *types.Transaction { +func (m *txSortedMap) Get(nonce uint64) *ValidTransaction { return m.items[nonce] } // Put inserts a new transaction into the map, also updating the map's nonce // index. If a transaction already exists with the same nonce, it's overwritten. -func (m *txSortedMap) Put(tx *types.Transaction) { +func (m *txSortedMap) Put(tx *ValidTransaction) { nonce := tx.Nonce() if m.items[nonce] == nil { heap.Push(m.index, nonce) @@ -81,8 +63,8 @@ func (m *txSortedMap) Put(tx *types.Transaction) { // Forward removes all transactions from the map with a nonce lower than the // provided threshold. Every removed transaction is returned for any post-removal // maintenance. -func (m *txSortedMap) Forward(threshold uint64) types.Transactions { - var removed types.Transactions +func (m *txSortedMap) Forward(threshold uint64) ValidTransactions { + var removed ValidTransactions // Pop off heap items until the threshold is reached for m.index.Len() > 0 && (*m.index)[0] < threshold { @@ -99,8 +81,8 @@ func (m *txSortedMap) Forward(threshold uint64) types.Transactions { // Filter iterates over the list of transactions and removes all of them for which // the specified function evaluates to true. -func (m *txSortedMap) Filter(filter func(*types.Transaction) bool) types.Transactions { - var removed types.Transactions +func (m *txSortedMap) Filter(filter func(*ValidTransaction) bool) ValidTransactions { + var removed ValidTransactions // Collect all the transactions to filter out for nonce, tx := range m.items { @@ -124,13 +106,13 @@ func (m *txSortedMap) Filter(filter func(*types.Transaction) bool) types.Transac // Cap places a hard limit on the number of items, returning all transactions // exceeding that limit. -func (m *txSortedMap) Cap(threshold int) types.Transactions { +func (m *txSortedMap) Cap(threshold int) ValidTransactions { // Short circuit if the number of items is under the limit if len(m.items) <= threshold { return nil } // Otherwise gather and drop the highest nonce'd transactions - var drops types.Transactions + var drops ValidTransactions sort.Sort(*m.index) for size := len(m.items); size > threshold; size-- { @@ -175,13 +157,13 @@ func (m *txSortedMap) Remove(nonce uint64) bool { // Note, all transactions with nonces lower than start will also be returned to // prevent getting into and invalid state. This is not something that should ever // happen but better to be self correcting than failing! -func (m *txSortedMap) Ready(start uint64) types.Transactions { +func (m *txSortedMap) Ready(start uint64) ValidTransactions { // Short circuit if no transactions are available if m.index.Len() == 0 || (*m.index)[0] > start { return nil } // Otherwise start accumulating incremental transactions - var ready types.Transactions + var ready ValidTransactions for next := (*m.index)[0]; m.index.Len() > 0 && (*m.index)[0] == next; next++ { ready = append(ready, m.items[next]) delete(m.items, next) @@ -200,31 +182,29 @@ func (m *txSortedMap) Len() int { // Flatten creates a nonce-sorted slice of transactions based on the loosely // sorted internal representation. The result of the sorting is cached in case // it's requested again before any modifications are made to the contents. -func (m *txSortedMap) Flatten() types.Transactions { +func (m *txSortedMap) Flatten() ValidTransactions { // If the sorting was not cached yet, create and cache it if m.cache == nil { - m.cache = make(types.Transactions, 0, len(m.items)) + m.cache = make(ValidTransactions, 0, len(m.items)) for _, tx := range m.items { m.cache = append(m.cache, tx) } - sort.Sort(types.TxByNonce(m.cache)) + sort.Sort(TxByNonce(m.cache)) } // Copy the cache to prevent accidental modifications - txs := make(types.Transactions, len(m.cache)) + txs := make(ValidTransactions, len(m.cache)) copy(txs, m.cache) return txs } // txList is a "list" of transactions belonging to an account, sorted by account -// nonce. The same type can be used both for storing contiguous transactions for -// the executable/pending queue; and for storing gapped transactions for the non- -// executable/future queue, with minor behavioral changes. +// nonce. type txList struct { strict bool // Whether nonces are strictly continuous or not txs *txSortedMap // Heap indexed sorted hash map of the transactions - costcap *big.Int // Price of the highest costing transaction (reset only if exceeds balance) - gascap uint64 // Gas limit of the highest spending transaction (reset only if exceeds block limit) + costCap *big.Int // Price of the highest costing transaction (reset only if exceeds balance) + computeCap uint64 // Compute limit of the highest spending transaction (reset only if exceeds block limit) } // newTxList create a new transaction list for maintaining nonce-indexable fast, @@ -233,7 +213,7 @@ func newTxList(strict bool) *txList { return &txList{ strict: strict, txs: newTxSortedMap(), - costcap: new(big.Int), + costCap: new(big.Int), } } @@ -243,63 +223,49 @@ func (l *txList) Overlaps(tx *types.Transaction) bool { return l.txs.Get(tx.Nonce()) != nil } -// Add tries to insert a new transaction into the list, returning whether the -// transaction was accepted, and if yes, any previous transaction it replaced. -// -// If the new transaction is accepted into the list, the lists' cost and gas +// Add tries inserts a new transaction into the list. The lists' cost and compute // thresholds are also potentially updated. -func (l *txList) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Transaction) { - // If there's an older better transaction, abort - old := l.txs.Get(tx.Nonce()) - if old != nil { - threshold := new(big.Int).Div(new(big.Int).Mul(old.GasPrice(), big.NewInt(100+int64(priceBump))), big.NewInt(100)) - // Have to ensure that the new gas price is higher than the old gas - // price as well as checking the percentage threshold to ensure that - // this is accurate for low (Wei-level) gas price replacements - if old.GasPrice().Cmp(tx.GasPrice()) >= 0 || threshold.Cmp(tx.GasPrice()) > 0 { - return false, nil - } - } - // Otherwise overwrite the old transaction with the current one +func (l *txList) Add(tx *ValidTransaction) { l.txs.Put(tx) - if cost := tx.Cost(); l.costcap.Cmp(cost) < 0 { - l.costcap = cost + if cost := tx.Cost(); l.costCap.Cmp(cost) < 0 { + l.costCap = cost } - if gas := tx.Gas(); l.gascap < gas { - l.gascap = gas + if computeLimit := tx.ComputeLimit(); l.computeCap < computeLimit { + l.computeCap = computeLimit } - return true, old } // Forward removes all transactions from the list with a nonce lower than the // provided threshold. Every removed transaction is returned for any post-removal // maintenance. -func (l *txList) Forward(threshold uint64) types.Transactions { +func (l *txList) Forward(threshold uint64) ValidTransactions { return l.txs.Forward(threshold) } -// Filter removes all transactions from the list with a cost or gas limit higher +// Filter removes all transactions from the list with a cost or compute limit higher // than the provided thresholds. Every removed transaction is returned for any // post-removal maintenance. Strict-mode invalidated transactions are also // returned. // -// This method uses the cached costcap and gascap to quickly decide if there's even +// This method uses the cached costCap and computeCap to quickly decide if there's even // 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 cost cap, the caps will be reset to a new high after removing // the newly invalidated transactions. -func (l *txList) Filter(costLimit *big.Int, gasLimit uint64) (types.Transactions, types.Transactions) { +func (l *txList) Filter(costLimit *big.Int, computeLimit uint64) (ValidTransactions, ValidTransactions) { // If all transactions are below the threshold, short circuit - if l.costcap.Cmp(costLimit) <= 0 && l.gascap <= gasLimit { + if l.costCap.Cmp(costLimit) <= 0 && l.computeCap <= computeLimit { return nil, nil } - l.costcap = new(big.Int).Set(costLimit) // Lower the caps to the thresholds - l.gascap = gasLimit + l.costCap = new(big.Int).Set(costLimit) // Lower the caps to the thresholds + l.computeCap = computeLimit // 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() > gasLimit }) + removed := l.txs.Filter(func(tx *ValidTransaction) bool { + return tx.Cost().Cmp(costLimit) > 0 || tx.ComputeLimit() > computeLimit + }) // If the list was strict, filter anything above the lowest nonce - var invalids types.Transactions + var invalids ValidTransactions if l.strict && len(removed) > 0 { lowest := uint64(math.MaxUint64) @@ -308,21 +274,21 @@ func (l *txList) Filter(costLimit *big.Int, gasLimit uint64) (types.Transactions lowest = nonce } } - invalids = l.txs.Filter(func(tx *types.Transaction) bool { return tx.Nonce() > lowest }) + invalids = l.txs.Filter(func(tx *ValidTransaction) bool { return tx.Nonce() > lowest }) } return removed, invalids } // Cap places a hard limit on the number of items, returning all transactions // exceeding that limit. -func (l *txList) Cap(threshold int) types.Transactions { +func (l *txList) Cap(threshold int) ValidTransactions { return l.txs.Cap(threshold) } // Remove deletes a transaction from the maintained list, returning whether the // transaction was found, and also returning any transaction invalidated due to // the deletion (strict mode only). -func (l *txList) Remove(tx *types.Transaction) (bool, types.Transactions) { +func (l *txList) Remove(tx *ValidTransaction) (bool, ValidTransactions) { // Remove the transaction from the set nonce := tx.Nonce() if removed := l.txs.Remove(nonce); !removed { @@ -330,7 +296,7 @@ func (l *txList) Remove(tx *types.Transaction) (bool, types.Transactions) { } // In strict mode, filter out non-executable transactions if l.strict { - return true, l.txs.Filter(func(tx *types.Transaction) bool { return tx.Nonce() > nonce }) + return true, l.txs.Filter(func(tx *ValidTransaction) bool { return tx.Nonce() > nonce }) } return true, nil } @@ -342,7 +308,7 @@ func (l *txList) Remove(tx *types.Transaction) (bool, types.Transactions) { // Note, all transactions with nonces lower than start will also be returned to // prevent getting into and invalid state. This is not something that should ever // happen but better to be self correcting than failing! -func (l *txList) Ready(start uint64) types.Transactions { +func (l *txList) Ready(start uint64) ValidTransactions { return l.txs.Ready(start) } @@ -359,162 +325,6 @@ func (l *txList) Empty() bool { // Flatten creates a nonce-sorted slice of transactions based on the loosely // sorted internal representation. The result of the sorting is cached in case // it's requested again before any modifications are made to the contents. -func (l *txList) Flatten() types.Transactions { +func (l *txList) Flatten() ValidTransactions { return l.txs.Flatten() } - -// priceHeap is a heap.Interface implementation over transactions for retrieving -// price-sorted transactions to discard when the pool fills up. -type priceHeap []*types.Transaction - -func (h priceHeap) Len() int { return len(h) } -func (h priceHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } - -func (h priceHeap) Less(i, j int) bool { - // Sort primarily by price, returning the cheaper one - switch h[i].GasPrice().Cmp(h[j].GasPrice()) { - case -1: - return true - case 1: - return false - } - // If the prices match, stabilize via nonces (high nonce is worse) - return h[i].Nonce() > h[j].Nonce() -} - -func (h *priceHeap) Push(x interface{}) { - *h = append(*h, x.(*types.Transaction)) -} - -func (h *priceHeap) Pop() interface{} { - old := *h - n := len(old) - x := old[n-1] - *h = old[0 : n-1] - return x -} - -// txPricedList is a price-sorted heap to allow operating on transactions pool -// contents in a price-incrementing way. -type txPricedList struct { - all *txLookup // Pointer to the map of all transactions - items *priceHeap // Heap of prices of all the stored transactions - stales int // Number of stale price points to (re-heap trigger) -} - -// newTxPricedList creates a new price-sorted transaction heap. -func newTxPricedList(all *txLookup) *txPricedList { - return &txPricedList{ - all: all, - items: new(priceHeap), - } -} - -// Put inserts a new transaction into the heap. -func (l *txPricedList) Put(tx *types.Transaction) { - heap.Push(l.items, tx) -} - -// Removed notifies the prices transaction list that an old transaction dropped -// from the pool. The list will just keep a counter of stale objects and update -// the heap if a large enough ratio of transactions go stale. -func (l *txPricedList) Removed() { - // Bump the stale counter, but exit if still too low (< 25%) - l.stales++ - if l.stales <= len(*l.items)/4 { - return - } - // Seems we've reached a critical number of stale transactions, reheap - reheap := make(priceHeap, 0, l.all.Count()) - - l.stales, l.items = 0, &reheap - l.all.Range(func(hash common.Hash, tx *types.Transaction) bool { - *l.items = append(*l.items, tx) - return true - }) - heap.Init(l.items) -} - -// Cap finds all the transactions below the given price threshold, drops them -// from the priced list and returs them for further removal from the entire pool. -func (l *txPricedList) Cap(threshold *big.Int, local *accountSet) types.Transactions { - drop := make(types.Transactions, 0, 128) // Remote underpriced transactions to drop - save := make(types.Transactions, 0, 64) // Local underpriced transactions to keep - - for len(*l.items) > 0 { - // Discard stale transactions if found during cleanup - tx := heap.Pop(l.items).(*types.Transaction) - if l.all.Get(tx.Hash()) == nil { - l.stales-- - continue - } - // Stop the discards if we've reached the threshold - if tx.GasPrice().Cmp(threshold) >= 0 { - save = append(save, tx) - break - } - // Non stale transaction found, discard unless local - if local.containsTx(tx) { - save = append(save, tx) - } else { - drop = append(drop, tx) - } - } - for _, tx := range save { - heap.Push(l.items, tx) - } - return drop -} - -// Underpriced checks whether a transaction is cheaper than (or as cheap as) the -// lowest priced transaction currently being tracked. -func (l *txPricedList) Underpriced(tx *types.Transaction, local *accountSet) bool { - // Local transactions cannot be underpriced - if local.containsTx(tx) { - return false - } - // Discard stale price points if found at the heap start - for len(*l.items) > 0 { - head := []*types.Transaction(*l.items)[0] - if l.all.Get(head.Hash()) == nil { - l.stales-- - heap.Pop(l.items) - continue - } - break - } - // Check if the transaction is underpriced or not - if len(*l.items) == 0 { - log.Error("Pricing query for empty pool") // This cannot happen, print to catch programming errors - return false - } - cheapest := []*types.Transaction(*l.items)[0] - return cheapest.GasPrice().Cmp(tx.GasPrice()) >= 0 -} - -// Discard finds a number of most underpriced transactions, removes them from the -// priced list and returns them for further removal from the entire pool. -func (l *txPricedList) Discard(count int, local *accountSet) types.Transactions { - drop := make(types.Transactions, 0, count) // Remote underpriced transactions to drop - save := make(types.Transactions, 0, 64) // Local underpriced transactions to keep - - for len(*l.items) > 0 && count > 0 { - // Discard stale transactions if found during cleanup - tx := heap.Pop(l.items).(*types.Transaction) - if l.all.Get(tx.Hash()) == nil { - l.stales-- - continue - } - // Non stale transaction found, discard unless local - if local.containsTx(tx) { - save = append(save, tx) - } else { - drop = append(drop, tx) - count-- - } - } - for _, tx := range save { - heap.Push(l.items, tx) - } - return drop -} diff --git a/client/core/tx_pool.go b/client/core/tx_pool.go index d7a0b1338..9ec0f827c 100644 --- a/client/core/tx_pool.go +++ b/client/core/tx_pool.go @@ -1,26 +1,10 @@ -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - package core import ( + "container/heap" "errors" "fmt" "math" - "math/big" "sort" "sync" "time" @@ -36,42 +20,25 @@ import ( ) const ( - // chainHeadChanSize is the size of channel listening to ChainHeadEvent. - chainHeadChanSize = 10 + // chainHeadChSize is the size of the channel listening to the ChainHeadEvent. + chainHeadChSize = 10 ) var ( - // ErrInvalidSender is returned if the transaction contains an invalid signature. + // ErrInvalidSender is returned if the transaction contains an invalid signature ErrInvalidSender = errors.New("invalid sender") - - // ErrNonceTooLow is returned if the nonce of a transaction is lower than the - // one present in the local chain. - ErrNonceTooLow = errors.New("nonce too low") - - // ErrUnderpriced is returned if a transaction's gas price is below the minimum - // configured for the transaction pool. - ErrUnderpriced = errors.New("transaction underpriced") - - // ErrReplaceUnderpriced is returned if a transaction is attempted to be replaced - // with a different one without the required price bump. - ErrReplaceUnderpriced = errors.New("replacement transaction underpriced") - // ErrInsufficientFunds is returned if the total cost of executing a transaction // is higher than the balance of the user's account. - ErrInsufficientFunds = errors.New("insufficient funds for gas * price + value") - - // ErrIntrinsicGas is returned if the transaction is specified to use less gas - // than required to start the invocation. - ErrIntrinsicGas = errors.New("intrinsic gas too low") - - // ErrGasLimit is returned if a transaction's requested gas limit exceeds the - // maximum allowance of the current block. - ErrGasLimit = errors.New("exceeds block gas limit") - - // ErrNegativeValue is a sanity error to ensure noone is able to specify a + ErrInsufficientFunds = errors.New("insufficient funds for compute units * price + value") + // ErrIntrinsicResources is returned if the transaction is specified + // to use less compute resources than required to start the invocation. + ErrIntrinsicResources = errors.New("intrinsic compute resources low") + // ErrComputeCapacity is returned if a transaction's requested compute + // resources exceeds the compute capacity of the current block. + ErrComputeCapacity = errors.New("exceeds block compute capacity") + // ErrNegativeValue is a sanity error to ensure none is able to specify a // transaction with a negative value. ErrNegativeValue = errors.New("negative value") - // ErrOversizedData is returned if the input data of a transaction is greater // than some meaningful limit a user might use. This is not a consensus error // making the transaction invalid, rather a DOS protection. @@ -84,21 +51,17 @@ var ( ) var ( - // Metrics for the pending pool - pendingDiscardCounter = metrics.NewRegisteredCounter("txpool/pending/discard", nil) - pendingReplaceCounter = metrics.NewRegisteredCounter("txpool/pending/replace", nil) - pendingRateLimitCounter = metrics.NewRegisteredCounter("txpool/pending/ratelimit", nil) // Dropped due to rate limiting + // Metrics for the pending queue pendingNofundsCounter = metrics.NewRegisteredCounter("txpool/pending/nofunds", nil) // Dropped due to out-of-funds + pendingRateLimitCounter = metrics.NewRegisteredCounter("txpool/pending/ratelimit", nil) // Dropped due to rate limiting - // Metrics for the queued pool - queuedDiscardCounter = metrics.NewRegisteredCounter("txpool/queued/discard", nil) - queuedReplaceCounter = metrics.NewRegisteredCounter("txpool/queued/replace", nil) - queuedRateLimitCounter = metrics.NewRegisteredCounter("txpool/queued/ratelimit", nil) // Dropped due to rate limiting + // Metrics for the future queue queuedNofundsCounter = metrics.NewRegisteredCounter("txpool/queued/nofunds", nil) // Dropped due to out-of-funds + queuedRateLimitCounter = metrics.NewRegisteredCounter("txpool/queued/ratelimit", nil) // Dropped due to rate limiting // General tx metrics - invalidTxCounter = metrics.NewRegisteredCounter("txpool/invalid", nil) - underpricedTxCounter = metrics.NewRegisteredCounter("txpool/underpriced", nil) + invalidTxCounter = metrics.NewRegisteredCounter("txpool/invalid", nil) + overlapTxCounter = metrics.NewRegisteredCounter("txpool/overlap", nil) ) // TxStatus is the current status of a transaction as seen by the pool. @@ -111,7 +74,7 @@ const ( TxStatusIncluded ) -// blockChain provides the state of blockchain and current gas limit to do +// blockChain provides the state of blockchain to do // some pre checks in tx pool and event subscribers. type blockChain interface { CurrentBlock() *types.Block @@ -121,14 +84,23 @@ type blockChain interface { SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription } -// TxPoolConfig are the configuration parameters of the transaction pool. -type TxPoolConfig struct { - NoLocals bool // Whether local transaction handling should be disabled - Journal string // Journal of local transactions to survive node restarts - Rejournal time.Duration // Time interval to regenerate the local transaction journal +type ValidTransaction struct { + AddedAt time.Time + *types.Transaction +} + +// ValidTransactions represents a set of txs verified by the tx pool +type ValidTransactions []*ValidTransaction + +// Len returns the length of s. +func (s ValidTransactions) Len() int { return len(s) } - PriceLimit uint64 // Minimum gas price to enforce for acceptance into the pool - PriceBump uint64 // Minimum price bump percentage to replace an already existing transaction (nonce) +// TxPoolConfig are the configurable parameters of the transaction pool. +type TxPoolConfig struct { + Locals []common.Address // Addresses that should be treated by default as local + NoLocals bool // Whether local transaction handling should be disabled + Journal string // Journal of local transactions to survive node restarts + Rejournal time.Duration // Time interval to regenerate the local transaction journal AccountSlots uint64 // Minimum number of executable transaction slots guaranteed per account GlobalSlots uint64 // Maximum number of executable transaction slots for all accounts @@ -141,12 +113,9 @@ type TxPoolConfig struct { // DefaultTxPoolConfig contains the default configurations for the transaction // pool. var DefaultTxPoolConfig = TxPoolConfig{ - Journal: "transactions.rlp", + Journal: "tx.journal", Rejournal: time.Hour, - PriceLimit: 1, - PriceBump: 10, - AccountSlots: 16, GlobalSlots: 4096, AccountQueue: 64, @@ -163,48 +132,32 @@ func (config *TxPoolConfig) sanitize() TxPoolConfig { log.Warn("Sanitizing invalid txpool journal time", "provided", conf.Rejournal, "updated", time.Second) conf.Rejournal = time.Second } - if conf.PriceLimit < 1 { - log.Warn("Sanitizing invalid txpool price limit", "provided", conf.PriceLimit, "updated", DefaultTxPoolConfig.PriceLimit) - conf.PriceLimit = DefaultTxPoolConfig.PriceLimit - } - if conf.PriceBump < 1 { - log.Warn("Sanitizing invalid txpool price bump", "provided", conf.PriceBump, "updated", DefaultTxPoolConfig.PriceBump) - conf.PriceBump = DefaultTxPoolConfig.PriceBump - } return conf } -// TxPool contains all currently known transactions. Transactions -// enter the pool when they are received from the network or submitted -// locally. They exit the pool when they are included in the blockchain. -// -// The pool separates processable transactions (which can be applied to the -// current state) and future transactions. Transactions move between those -// two states over time as they are received and processed. +// TxPool contains all currently known transactions. type TxPool struct { + mu sync.RWMutex + config TxPoolConfig chainconfig *params.ChainConfig chain blockChain - gasPrice *big.Int txFeed event.Feed scope event.SubscriptionScope chainHeadCh chan ChainHeadEvent chainHeadSub event.Subscription signer types.Signer - mu sync.RWMutex - currentState *state.StateDB // Current state in the blockchain head - pendingState *state.ManagedState // Pending state tracking virtual nonces - currentMaxGas uint64 // Current gas limit for transaction caps + currentState *state.StateDB // Current state in the blockchain head + pendingState *state.ManagedState // Pending state tracking virtual nonces - locals *accountSet // Set of local transaction to exempt from eviction rules - journal *txJournal // Journal of local transaction to back up to disk + locals *accountSet // Set of local transactions + journal *txJournal // Journal of local transactions to back up to disk - pending map[common.Address]*txList // All currently processable transactions - queue map[common.Address]*txList // Queued but non-processable transactions + pending map[common.Address]*txList // Processable transactions + queue map[common.Address]*txList // Non-Processable transactions beats map[common.Address]time.Time // Last heartbeat from each known account - all *txLookup // All transactions to allow lookups - priced *txPricedList // All transactions sorted by price + all *txLookup wg sync.WaitGroup // for shutdown sync } @@ -212,10 +165,8 @@ type TxPool struct { // NewTxPool creates a new transaction pool to gather, sort and filter inbound // transactions from the network. func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain blockChain) *TxPool { - // Sanitize the input to ensure no vulnerable gas prices are set config = (&config).sanitize() - // Create the transaction pool with its initial settings pool := &TxPool{ config: config, chainconfig: chainconfig, @@ -225,11 +176,15 @@ func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain block queue: make(map[common.Address]*txList), beats: make(map[common.Address]time.Time), all: newTxLookup(), - chainHeadCh: make(chan ChainHeadEvent, chainHeadChanSize), - gasPrice: new(big.Int).SetUint64(config.PriceLimit), + chainHeadCh: make(chan ChainHeadEvent, chainHeadChSize), } + pool.locals = newAccountSet(pool.signer) - pool.priced = newTxPricedList(pool.all) + for _, addr := range config.Locals { + log.Info("Setting new local account", "address", addr) + pool.locals.add(addr) + } + pool.reset(nil, chain.CurrentBlock().Header()) // If local transactions and journaling is enabled, load from disk @@ -243,25 +198,22 @@ func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain block log.Warn("Failed to rotate transaction journal", "err", err) } } - // Subscribe events from blockchain + pool.chainHeadSub = pool.chain.SubscribeChainHeadEvent(pool.chainHeadCh) - // Start the event loop and return pool.wg.Add(1) go pool.loop() return pool } -// loop is the transaction pool's main event loop, waiting for and reacting to -// outside blockchain events as well as for various reporting and transaction -// eviction events. +// loop is the transaction pool's main event loop. func (pool *TxPool) loop() { defer pool.wg.Done() - // Start the stats reporting and transaction eviction tickers - var prevPending, prevQueued, prevStales int + var prevPending, prevQueued int + // start the stats reporting/transaction eviction/journal tickers report := time.NewTicker(statsReportInterval) defer report.Stop() @@ -271,10 +223,10 @@ func (pool *TxPool) loop() { journal := time.NewTicker(pool.config.Rejournal) defer journal.Stop() - // Track the previous head headers for transaction reorgs + // track the previous head headers for transaction reorgs head := pool.chain.CurrentBlock() - // Keep waiting for and reacting to the various events + // keep waiting for and reacting to the various events for { select { // Handle ChainHeadEvent @@ -286,20 +238,19 @@ func (pool *TxPool) loop() { pool.mu.Unlock() } - // Be unsubscribed due to system stopped + // be unsubscribed due to system stopped case <-pool.chainHeadSub.Err(): return - // Handle stats reporting ticks + // handle stats reporting ticks case <-report.C: pool.mu.RLock() pending, queued := pool.stats() - stales := pool.priced.stales pool.mu.RUnlock() - if pending != prevPending || queued != prevQueued || stales != prevStales { - log.Debug("Transaction pool status report", "executable", pending, "queued", queued, "stales", stales) - prevPending, prevQueued, prevStales = pending, queued, stales + if pending != prevPending || queued != prevQueued { + log.Debug("Transaction pool status report", "executable", pending, "queued", queued) + prevPending, prevQueued = pending, queued } // Handle inactive account transaction eviction @@ -313,13 +264,13 @@ func (pool *TxPool) loop() { // Any non-locals old enough should be removed if time.Since(pool.beats[addr]) > pool.config.Lifetime { for _, tx := range pool.queue[addr].Flatten() { - pool.removeTx(tx.Hash(), true) + pool.removeTx(tx.Hash()) } } } pool.mu.Unlock() - // Handle local transaction journal rotation + // handle local transaction journal rotation case <-journal.C: if pool.journal != nil { pool.mu.Lock() @@ -402,17 +353,15 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) { } pool.currentState = statedb pool.pendingState = state.ManageState(statedb) - pool.currentMaxGas = newHead.GasLimit // Inject any transactions discarded due to reorgs log.Debug("Reinjecting stale transactions", "count", len(reinject)) senderCacher.recover(pool.signer, reinject) pool.addTxsLocked(reinject, false) - // validate the pool of pending transactions, this will remove + // validate the pool of executable transactions, this will remove // any transactions that have been included in the block or - // have been invalidated because of another transaction (e.g. - // higher gas price) + // have been invalidated because of another transaction pool.demoteUnexecutables() // Update all accounts to the latest known pending nonce @@ -446,27 +395,6 @@ func (pool *TxPool) SubscribeNewTxsEvent(ch chan<- NewTxsEvent) event.Subscripti return pool.scope.Track(pool.txFeed.Subscribe(ch)) } -// GasPrice returns the current gas price enforced by the transaction pool. -func (pool *TxPool) GasPrice() *big.Int { - pool.mu.RLock() - defer pool.mu.RUnlock() - - return new(big.Int).Set(pool.gasPrice) -} - -// SetGasPrice updates the minimum price required by the transaction pool for a -// new transaction, and drops all transactions below this threshold. -func (pool *TxPool) SetGasPrice(price *big.Int) { - pool.mu.Lock() - defer pool.mu.Unlock() - - pool.gasPrice = price - for _, tx := range pool.priced.Cap(price, pool.locals) { - pool.removeTx(tx.Hash(), false) - } - log.Info("Transaction pool price threshold updated", "price", price) -} - // State returns the virtual managed state of the transaction pool. func (pool *TxPool) State() *state.ManagedState { pool.mu.RLock() @@ -476,7 +404,7 @@ func (pool *TxPool) State() *state.ManagedState { } // Stats retrieves the current pool stats, namely the number of pending and the -// number of queued (non-executable) transactions. +// number of executable transactions. func (pool *TxPool) Stats() (int, int) { pool.mu.RLock() defer pool.mu.RUnlock() @@ -506,11 +434,19 @@ func (pool *TxPool) Content() (map[common.Address]types.Transactions, map[common pending := make(map[common.Address]types.Transactions) for addr, list := range pool.pending { - pending[addr] = list.Flatten() + txs := make(types.Transactions, 0, list.Len()) + for _, validTx := range list.Flatten() { + txs = append(txs, validTx.Transaction) + } + pending[addr] = txs } queued := make(map[common.Address]types.Transactions) for addr, list := range pool.queue { - queued[addr] = list.Flatten() + txs := make(types.Transactions, 0, list.Len()) + for _, validTx := range list.Flatten() { + txs = append(txs, validTx.Transaction) + } + queued[addr] = txs } return pending, queued } @@ -518,22 +454,49 @@ func (pool *TxPool) Content() (map[common.Address]types.Transactions, map[common // Pending retrieves all currently processable transactions, groupped by origin // account and sorted by nonce. The returned transaction set is a copy and can be // freely modified by calling code. -func (pool *TxPool) Pending() (map[common.Address]types.Transactions, error) { +func (pool *TxPool) Pending() map[common.Address]types.Transactions { pool.mu.Lock() defer pool.mu.Unlock() pending := make(map[common.Address]types.Transactions) + for addr, list := range pool.pending { + txs := make(types.Transactions, 0, list.Len()) + for _, validTx := range list.Flatten() { + txs = append(txs, validTx.Transaction) + } + pending[addr] = txs + } + + return pending +} + +// Transactions retrieves a transaction set that can retrieve timestamp sorted +// processable transactions in a nonce-honouring way. +func (pool *TxPool) Transactions() *TransactionsByTimestampAndNonce { + pool.mu.Lock() + defer pool.mu.Unlock() + + pending := make(map[common.Address]ValidTransactions) for addr, list := range pool.pending { pending[addr] = list.Flatten() } - return pending, nil + + return NewTransactionsByTimestampAndNonce(pool.signer, pending) +} + +// Locals retrieves the accounts currently considered local by the pool. +func (pool *TxPool) Locals() []common.Address { + pool.mu.Lock() + defer pool.mu.Unlock() + + return pool.locals.flatten() } // local retrieves all currently known local transactions, groupped by origin // account and sorted by nonce. The returned transaction set is a copy and can be // freely modified by calling code. -func (pool *TxPool) local() map[common.Address]types.Transactions { - txs := make(map[common.Address]types.Transactions) +func (pool *TxPool) local() map[common.Address]ValidTransactions { + txs := make(map[common.Address]ValidTransactions) for addr := range pool.locals.accounts { if pending := pool.pending[addr]; pending != nil { txs[addr] = append(txs[addr], pending.Flatten()...) @@ -546,9 +509,9 @@ func (pool *TxPool) local() map[common.Address]types.Transactions { } // validateTx checks whether a transaction is valid according to the consensus -// rules and adheres to some heuristic limits of the local node (price and size). +// rules and adheres to some heuristic limits (ex: size). func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { - // Heuristic limit, reject transactions over 32KB to prevent DOS attacks + // Heuristic limit, reject transactions over the maximum size to prevent DOS attacks if tx.Size() > 32*1024 { return ErrOversizedData } @@ -557,143 +520,94 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { if tx.Value().Sign() < 0 { return ErrNegativeValue } - // Ensure the transaction doesn't exceed the current block limit gas. - if pool.currentMaxGas < tx.Gas() { - return ErrGasLimit + // Ensure the transaction doesn't exceed the block compute capacity. + if params.ComputeCapacity < tx.ComputeLimit() { + return ErrComputeCapacity } // Make sure the transaction is signed properly from, err := types.TxSender(pool.signer, tx) if err != nil { return ErrInvalidSender } - // Drop non-local transactions under our own minimal accepted gas price - local = local || pool.locals.contains(from) // account may be local even if the transaction arrived from the network - if !local && pool.gasPrice.Cmp(tx.GasPrice()) > 0 { - return ErrUnderpriced - } - // Ensure the transaction adheres to nonce ordering + + // Ensure the transaction has a valid nonce if pool.currentState.GetNonce(from) > tx.Nonce() { return ErrNonceTooLow } - // Transactor should have enough funds to cover the costs - // cost == V + GP * GL + + // Sender should have enough funds to cover the (maximum) costs + // cost == value + computational effort (compute units) * compute unit price if pool.currentState.GetBalance(from).Cmp(tx.Cost()) < 0 { return ErrInsufficientFunds } - intrGas, err := IntrinsicGas(tx.Data(), tx.To() == nil, true) + + // compute limit must cover the transaction's intrinsic computational effort. + intrinsicEffort, err := IntrinsicEffort(tx.Data(), tx.To() == nil) if err != nil { return err } - if tx.Gas() < intrGas { - return ErrIntrinsicGas + if tx.ComputeLimit() < intrinsicEffort { + return ErrIntrinsicResources } return nil } -// add validates a transaction and inserts it into the non-executable queue for -// later pending promotion and execution. If the transaction is a replacement for -// an already pending or queued one, it overwrites the previous and returns this -// so outer code doesn't uselessly call promote. -// -// If a newly added transaction is marked as local, its sending account will be -// whitelisted, preventing any associated transaction from being dropped out of -// the pool due to pricing constraints. -func (pool *TxPool) add(tx *types.Transaction, local bool) (bool, error) { - // If the transaction is already known, discard it +// add validates a transaction and inserts it into the pending queue. +func (pool *TxPool) add(tx *types.Transaction, local bool) error { hash := tx.Hash() if pool.all.Get(hash) != nil { log.Trace("Discarding already known transaction", "hash", hash) - return false, fmt.Errorf("known transaction: %x", hash) + return fmt.Errorf("known transaction: %x", hash) } - // If the transaction fails basic validation, discard it + if err := pool.validateTx(tx, local); err != nil { log.Trace("Discarding invalid transaction", "hash", hash, "err", err) invalidTxCounter.Inc(1) - return false, err + return err } - // If the transaction pool is full, discard underpriced transactions - if uint64(pool.all.Count()) >= pool.config.GlobalSlots+pool.config.GlobalQueue { - // If the new transaction is underpriced, don't accept it - if !local && pool.priced.Underpriced(tx, pool.locals) { - log.Trace("Discarding underpriced transaction", "hash", hash, "price", tx.GasPrice()) - underpricedTxCounter.Inc(1) - return false, ErrUnderpriced - } - // New transaction is better than our worse ones, make room for it - drop := pool.priced.Discard(pool.all.Count()-int(pool.config.GlobalSlots+pool.config.GlobalQueue-1), pool.locals) - for _, tx := range drop { - log.Trace("Discarding freshly underpriced transaction", "hash", tx.Hash(), "price", tx.GasPrice()) - underpricedTxCounter.Inc(1) - pool.removeTx(tx.Hash(), false) - } + + // If the new transaction overlaps a known transaction, discard it. + from, _ := types.TxSender(pool.signer, tx) + if list := pool.queue[from]; list != nil && list.Overlaps(tx) { + log.Trace("Discarding transaction that overlaps a known future transaction", "nonce", tx.Nonce()) + overlapTxCounter.Inc(1) + return fmt.Errorf("known nonce: %d", tx.Nonce()) } - // If the transaction is replacing an already pending one, do directly - from, _ := types.TxSender(pool.signer, tx) // already validated if list := pool.pending[from]; list != nil && list.Overlaps(tx) { - // Nonce already pending, check if required price bump is met - inserted, old := list.Add(tx, pool.config.PriceBump) - if !inserted { - pendingDiscardCounter.Inc(1) - return false, ErrReplaceUnderpriced - } - // New transaction is better, replace old one - if old != nil { - pool.all.Remove(old.Hash()) - pool.priced.Removed() - pendingReplaceCounter.Inc(1) - } - pool.all.Add(tx) - pool.priced.Put(tx) - pool.journalTx(from, tx) + log.Trace("Discarding transaction that overlaps a known pending transaction", "nonce", tx.Nonce()) + overlapTxCounter.Inc(1) + return fmt.Errorf("known nonce: %d", tx.Nonce()) + } - log.Trace("Pooled new executable transaction", "hash", hash, "from", from, "to", tx.To()) + validTx := &ValidTransaction{ + AddedAt: time.Now(), + Transaction: tx, + } - // We've directly injected a replacement transaction, notify subsystems - go pool.txFeed.Send(NewTxsEvent{types.Transactions{tx}}) + pool.enqueueTx(hash, validTx) - return old != nil, nil - } - // New transaction isn't replacing a pending one, push into queue - replace, err := pool.enqueueTx(hash, tx) - if err != nil { - return false, err - } - // Mark local addresses and journal local transactions if local { pool.locals.add(from) } - pool.journalTx(from, tx) + + pool.journalTx(from, validTx.Transaction) log.Trace("Pooled new future transaction", "hash", hash, "from", from, "to", tx.To()) - return replace, nil + return nil } // enqueueTx inserts a new transaction into the non-executable transaction queue. // // Note, this method assumes the pool lock is held! -func (pool *TxPool) enqueueTx(hash common.Hash, tx *types.Transaction) (bool, error) { - // Try to insert the transaction into the future queue - from, _ := types.TxSender(pool.signer, tx) // already validated +func (pool *TxPool) enqueueTx(hash common.Hash, validTx *ValidTransaction) { + from, _ := types.TxSender(pool.signer, validTx.Transaction) if pool.queue[from] == nil { pool.queue[from] = newTxList(false) } - inserted, old := pool.queue[from].Add(tx, pool.config.PriceBump) - if !inserted { - // An older transaction was better, discard this - queuedDiscardCounter.Inc(1) - return false, ErrReplaceUnderpriced - } - // Discard any previous transaction and mark this - if old != nil { - pool.all.Remove(old.Hash()) - pool.priced.Removed() - queuedReplaceCounter.Inc(1) - } + pool.queue[from].Add(validTx) if pool.all.Get(hash) == nil { - pool.all.Add(tx) - pool.priced.Put(tx) + pool.all.Add(validTx) } - return old != nil, nil } // journalTx adds the specified transaction to the local disk journal if it is @@ -708,69 +622,48 @@ func (pool *TxPool) journalTx(from common.Address, tx *types.Transaction) { } } -// promoteTx adds a transaction to the pending (processable) list of transactions -// and returns whether it was inserted or an older was better. +// promoteTx adds a transaction to the pending (processable) list of transactions. // // Note, this method assumes the pool lock is held! -func (pool *TxPool) promoteTx(addr common.Address, hash common.Hash, tx *types.Transaction) bool { +func (pool *TxPool) promoteTx(addr common.Address, hash common.Hash, validTx *ValidTransaction) bool { // Try to insert the transaction into the pending queue if pool.pending[addr] == nil { pool.pending[addr] = newTxList(true) } list := pool.pending[addr] - inserted, old := list.Add(tx, pool.config.PriceBump) - if !inserted { - // An older transaction was better, discard this - pool.all.Remove(hash) - pool.priced.Removed() + list.Add(validTx) - pendingDiscardCounter.Inc(1) - return false - } - // Otherwise discard any previous transaction and mark this - if old != nil { - pool.all.Remove(old.Hash()) - pool.priced.Removed() - - pendingReplaceCounter.Inc(1) - } // Failsafe to work around direct pending inserts (tests) if pool.all.Get(hash) == nil { - pool.all.Add(tx) - pool.priced.Put(tx) + pool.all.Add(validTx) } // Set the potentially new pending nonce and notify any subsystems of the new tx pool.beats[addr] = time.Now() - pool.pendingState.SetNonce(addr, tx.Nonce()+1) + pool.pendingState.SetNonce(addr, validTx.Nonce()+1) return true } -// AddLocal enqueues a single transaction into the pool if it is valid, marking -// the sender as a local one in the mean time, ensuring it goes around the local -// pricing constraints. +// AddLocal enqueues a single transaction into the pool if it is valid, marking the sender +// as local if the distinction between local/remote transactions is enabled. func (pool *TxPool) AddLocal(tx *types.Transaction) error { return pool.addTx(tx, !pool.config.NoLocals) } -// AddRemote enqueues a single transaction into the pool if it is valid. If the -// sender is not among the locally tracked ones, full pricing constraints will -// apply. +// AddRemote enqueues a single remote transaction into the pool if it is valid. func (pool *TxPool) AddRemote(tx *types.Transaction) error { return pool.addTx(tx, false) } // AddLocals enqueues a batch of transactions into the pool if they are valid, -// marking the senders as a local ones in the mean time, ensuring they go around -// the local pricing constraints. +// marking the senders as a local ones if the distinction between local/remote +// transactions is enabled. func (pool *TxPool) AddLocals(txs []*types.Transaction) []error { return pool.addTxs(txs, !pool.config.NoLocals) } -// AddRemotes enqueues a batch of transactions into the pool if they are valid. -// If the senders are not among the locally tracked ones, full pricing constraints -// will apply. +// AddRemotes enqueues a batch of remote transactions into the pool if they are valid. func (pool *TxPool) AddRemotes(txs []*types.Transaction) []error { return pool.addTxs(txs, false) } @@ -781,15 +674,13 @@ func (pool *TxPool) addTx(tx *types.Transaction, local bool) error { defer pool.mu.Unlock() // Try to inject the transaction and update any state - replace, err := pool.add(tx, local) - if err != nil { + if err := pool.add(tx, local); err != nil { return err } - // If we added a new transaction, run promotion checks and return - if !replace { - from, _ := types.TxSender(pool.signer, tx) // already validated - pool.promoteExecutables([]common.Address{from}) - } + + from, _ := types.TxSender(pool.signer, tx) // already validated + pool.promoteExecutables([]common.Address{from}) + return nil } @@ -809,8 +700,7 @@ func (pool *TxPool) addTxsLocked(txs []*types.Transaction, local bool) []error { errs := make([]error, len(txs)) for i, tx := range txs { - var replace bool - if replace, errs[i] = pool.add(tx, local); errs[i] == nil && !replace { + if errs[i] = pool.add(tx, local); errs[i] == nil { from, _ := types.TxSender(pool.signer, tx) // already validated dirty[from] = struct{}{} } @@ -835,7 +725,7 @@ func (pool *TxPool) Status(hashes []common.Hash) []TxStatus { status := make([]TxStatus, len(hashes)) for i, hash := range hashes { if tx := pool.all.Get(hash); tx != nil { - from, _ := types.TxSender(pool.signer, tx) // already validated + from, _ := types.TxSender(pool.signer, tx.Transaction) // already validated if pool.pending[from] != nil && pool.pending[from].txs.items[tx.Nonce()] != nil { status[i] = TxStatusPending } else { @@ -849,25 +739,22 @@ func (pool *TxPool) Status(hashes []common.Hash) []TxStatus { // Get returns a transaction if it is contained in the pool // and nil otherwise. func (pool *TxPool) Get(hash common.Hash) *types.Transaction { - return pool.all.Get(hash) + return pool.all.Get(hash).Transaction } // removeTx removes a single transaction from the queue, moving all subsequent // transactions back to the future queue. -func (pool *TxPool) removeTx(hash common.Hash, outofbound bool) { +func (pool *TxPool) removeTx(hash common.Hash) { // Fetch the transaction we wish to delete tx := pool.all.Get(hash) if tx == nil { return } - addr, _ := types.TxSender(pool.signer, tx) // already validated during insertion + addr, _ := types.TxSender(pool.signer, tx.Transaction) // already validated during insertion - // Remove it from the list of known transactions pool.all.Remove(hash) - if outofbound { - pool.priced.Removed() - } - // Remove the transaction from the pending lists and reset the account nonce + + // Remove the transaction from the lists and reset the account nonce if pending := pool.pending[addr]; pending != nil { if removed, invalids := pending.Remove(tx); removed { // If no more pending transactions are left, remove the list @@ -899,13 +786,12 @@ func (pool *TxPool) removeTx(hash common.Hash, outofbound bool) { // future queue to the set of pending transactions. During this process, all // invalidated transactions (low nonce, low balance) are deleted. func (pool *TxPool) promoteExecutables(accounts []common.Address) { - // Track the promoted transactions to broadcast them at once var promoted []*types.Transaction // Gather all the accounts potentially needing updates if accounts == nil { - accounts = make([]common.Address, 0, len(pool.queue)) - for addr := range pool.queue { + accounts = make([]common.Address, 0, len(pool.pending)) + for addr := range pool.pending { accounts = append(accounts, addr) } } @@ -920,15 +806,13 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) { hash := tx.Hash() log.Trace("Removed old queued transaction", "hash", hash) pool.all.Remove(hash) - pool.priced.Removed() } - // Drop all transactions that are too costly (low balance or out of gas) - drops, _ := list.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas) + // Drop all transactions that are too costly (low balance or out of compute resources) + drops, _ := list.Filter(pool.currentState.GetBalance(addr), params.ComputeCapacity) for _, tx := range drops { hash := tx.Hash() log.Trace("Removed unpayable queued transaction", "hash", hash) pool.all.Remove(hash) - pool.priced.Removed() queuedNofundsCounter.Inc(1) } // Gather all executable transactions and promote them @@ -936,7 +820,7 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) { hash := tx.Hash() if pool.promoteTx(addr, hash, tx) { log.Trace("Promoting queued transaction", "hash", hash) - promoted = append(promoted, tx) + promoted = append(promoted, tx.Transaction) } } // Drop all transactions over the allowed limit @@ -944,7 +828,6 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) { for _, tx := range list.Cap(int(pool.config.AccountQueue)) { hash := tx.Hash() pool.all.Remove(hash) - pool.priced.Removed() queuedRateLimitCounter.Inc(1) log.Trace("Removed cap-exceeding queued transaction", "hash", hash) } @@ -993,13 +876,12 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) { // Drop the transaction from the global pools too hash := tx.Hash() pool.all.Remove(hash) - pool.priced.Removed() // Update the account nonce to the dropped transaction if nonce := tx.Nonce(); pool.pendingState.GetNonce(offenders[i]) > nonce { pool.pendingState.SetNonce(offenders[i], nonce) } - log.Trace("Removed fairness-exceeding pending transaction", "hash", hash) + log.Trace("Removed fairness-exceeding transaction", "hash", hash) } pending-- } @@ -1015,13 +897,12 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) { // Drop the transaction from the global pools too hash := tx.Hash() pool.all.Remove(hash) - pool.priced.Removed() // Update the account nonce to the dropped transaction if nonce := tx.Nonce(); pool.pendingState.GetNonce(addr) > nonce { pool.pendingState.SetNonce(addr, nonce) } - log.Trace("Removed fairness-exceeding pending transaction", "hash", hash) + log.Trace("Removed fairness-exceeding transaction", "hash", hash) } pending-- } @@ -1029,6 +910,7 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) { } pendingRateLimitCounter.Inc(int64(pendingBeforeCap - pending)) } + // If we've queued more transactions than the hard limit, drop oldest ones queued := uint64(0) for _, list := range pool.queue { @@ -1036,7 +918,7 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) { } if queued > pool.config.GlobalQueue { // Sort all accounts with queued transactions by heartbeat - addresses := make(addresssByHeartbeat, 0, len(pool.queue)) + addresses := make(addressesByHeartbeat, 0, len(pool.queue)) for addr := range pool.queue { if !pool.locals.contains(addr) { // don't drop locals addresses = append(addresses, addressByHeartbeat{addr, pool.beats[addr]}) @@ -1054,7 +936,7 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) { // Drop all transactions if they are less than the overflow if size := uint64(list.Len()); size <= drop { for _, tx := range list.Flatten() { - pool.removeTx(tx.Hash(), true) + pool.removeTx(tx.Hash()) } drop -= size queuedRateLimitCounter.Inc(int64(size)) @@ -1063,7 +945,7 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) { // Otherwise drop only last few transactions txs := list.Flatten() for i := len(txs) - 1; i >= 0 && drop > 0; i-- { - pool.removeTx(txs[i].Hash(), true) + pool.removeTx(txs[i].Hash()) drop-- queuedRateLimitCounter.Inc(1) } @@ -1071,33 +953,32 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) { } } -// demoteUnexecutables removes invalid and processed transactions from the pools -// executable/pending queue and any subsequent transactions that become unexecutable +// demoteUnexecutables removes invalid and mined transactions from the pools +// future/pending queue and any subsequent transactions that become unexecutable // are moved back into the future queue. func (pool *TxPool) demoteUnexecutables() { - // Iterate over all accounts and demote any non-executable transactions + // Iterate over all accounts and remove any non-executable transactions for addr, list := range pool.pending { nonce := pool.currentState.GetNonce(addr) // Drop all transactions that are deemed too old (low nonce) for _, tx := range list.Forward(nonce) { hash := tx.Hash() - log.Trace("Removed old pending transaction", "hash", hash) + log.Trace("Removed old transaction", "hash", hash) pool.all.Remove(hash) - pool.priced.Removed() } - // Drop all transactions that are too costly (low balance or out of gas), and queue any invalids back for later - drops, invalids := list.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas) + // Drop all transactions that are too costly (low balance or out of computation resources), + // and queue any invalids back for later + drops, invalids := list.Filter(pool.currentState.GetBalance(addr), params.ComputeCapacity) for _, tx := range drops { hash := tx.Hash() - log.Trace("Removed unpayable pending transaction", "hash", hash) + log.Trace("Removed unpayable transaction", "hash", hash) pool.all.Remove(hash) - pool.priced.Removed() pendingNofundsCounter.Inc(1) } for _, tx := range invalids { hash := tx.Hash() - log.Trace("Demoting pending transaction", "hash", hash) + log.Trace("Demoting transaction", "hash", hash) pool.enqueueTx(hash, tx) } // If there's a gap in front, alert (should never happen) and postpone all transactions @@ -1122,17 +1003,18 @@ type addressByHeartbeat struct { heartbeat time.Time } -type addresssByHeartbeat []addressByHeartbeat +type addressesByHeartbeat []addressByHeartbeat -func (a addresssByHeartbeat) Len() int { return len(a) } -func (a addresssByHeartbeat) Less(i, j int) bool { return a[i].heartbeat.Before(a[j].heartbeat) } -func (a addresssByHeartbeat) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a addressesByHeartbeat) Len() int { return len(a) } +func (a addressesByHeartbeat) Less(i, j int) bool { return a[i].heartbeat.Before(a[j].heartbeat) } +func (a addressesByHeartbeat) Swap(i, j int) { a[i], a[j] = a[j], a[i] } // accountSet is simply a set of addresses to check for existence, and a signer // capable of deriving addresses from transactions. type accountSet struct { accounts map[common.Address]struct{} signer types.Signer + cache *[]common.Address } // newAccountSet creates a new address set with an associated signer for sender @@ -1162,6 +1044,20 @@ func (as *accountSet) containsTx(tx *types.Transaction) bool { // add inserts a new address into the set to track. func (as *accountSet) add(addr common.Address) { as.accounts[addr] = struct{}{} + as.cache = nil +} + +// flatten returns the list of addresses within this set, also caching it for later +// reuse. The returned slice should not be changed! +func (as *accountSet) flatten() []common.Address { + if as.cache == nil { + accounts := make([]common.Address, 0, len(as.accounts)) + for account := range as.accounts { + accounts = append(accounts, account) + } + as.cache = &accounts + } + return *as.cache } // txLookup is used internally by TxPool to track transactions while allowing lookup without @@ -1174,19 +1070,19 @@ func (as *accountSet) add(addr common.Address) { // peeking into the pool in TxPool.Get without having to acquire the widely scoped // TxPool.mu mutex. type txLookup struct { - all map[common.Hash]*types.Transaction + all map[common.Hash]*ValidTransaction lock sync.RWMutex } // newTxLookup returns a new txLookup structure. func newTxLookup() *txLookup { return &txLookup{ - all: make(map[common.Hash]*types.Transaction), + all: make(map[common.Hash]*ValidTransaction), } } // Range calls f on each key and value present in the map. -func (t *txLookup) Range(f func(hash common.Hash, tx *types.Transaction) bool) { +func (t *txLookup) Range(f func(hash common.Hash, tx *ValidTransaction) bool) { t.lock.RLock() defer t.lock.RUnlock() @@ -1198,7 +1094,7 @@ func (t *txLookup) Range(f func(hash common.Hash, tx *types.Transaction) bool) { } // Get returns a transaction if it exists in the lookup, or nil if not found. -func (t *txLookup) Get(hash common.Hash) *types.Transaction { +func (t *txLookup) Get(hash common.Hash) *ValidTransaction { t.lock.RLock() defer t.lock.RUnlock() @@ -1214,7 +1110,7 @@ func (t *txLookup) Count() int { } // Add adds a transaction to the lookup. -func (t *txLookup) Add(tx *types.Transaction) { +func (t *txLookup) Add(tx *ValidTransaction) { t.lock.Lock() defer t.lock.Unlock() @@ -1228,3 +1124,90 @@ func (t *txLookup) Remove(hash common.Hash) { delete(t.all, hash) } + +// TxByNonce implements the sort interface to allow sorting a list of transactions +// by their nonces. This is usually only useful for sorting transactions from a +// single account, otherwise a nonce comparison doesn't make much sense. +type TxByNonce ValidTransactions + +func (s TxByNonce) Len() int { return len(s) } +func (s TxByNonce) Less(i, j int) bool { + return s[i].Nonce() < s[j].Nonce() +} +func (s TxByNonce) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// TxByTimestamp implements the heap interface, making it useful for all +// at once sorting as well as individually adding and removing elements. +type TxByTimestamp ValidTransactions + +func (s TxByTimestamp) Len() int { return len(s) } +func (s TxByTimestamp) Less(i, j int) bool { return s[i].AddedAt.Before(s[j].AddedAt) } +func (s TxByTimestamp) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +func (s *TxByTimestamp) Push(x interface{}) { + *s = append(*s, x.(*ValidTransaction)) +} + +func (s *TxByTimestamp) Pop() interface{} { + old := *s + n := len(old) + x := old[n-1] + *s = old[0 : n-1] + return x +} + +// TransactionsByTimestampAndNonce represents a set of transactions that can return +// transactions in a timestamp and nonce-honouring order. +type TransactionsByTimestampAndNonce struct { + txs map[common.Address]ValidTransactions // per account nonce-sorted list of transactions + heads TxByTimestamp // Next transaction for each unique account (timestamp heap) + signer types.Signer // signer for the set of transactions +} + +// NewTransactionsByTimestampAndNonce creates a transaction set that can retrieve +// timestamp sorted transactions in a nonce-honouring way. +func NewTransactionsByTimestampAndNonce(signer types.Signer, txs map[common.Address]ValidTransactions) *TransactionsByTimestampAndNonce { + heads := make(TxByTimestamp, 0, len(txs)) + for from, accTxs := range txs { + heads = append(heads, accTxs[0]) + // Ensure the sender address is from the signer + acc, _ := types.TxSender(signer, accTxs[0].Transaction) + txs[acc] = accTxs[1:] + if from != acc { + delete(txs, from) + } + } + heap.Init(&heads) + + return &TransactionsByTimestampAndNonce{ + txs: txs, + heads: heads, + signer: signer, + } +} + +// Peek returns the next transaction by price. +func (t *TransactionsByTimestampAndNonce) Peek() *types.Transaction { + if len(t.heads) == 0 { + return nil + } + return t.heads[0].Transaction +} + +// Shift removes the current best head and adds the next one to the queue from the same account. +func (t *TransactionsByTimestampAndNonce) Shift() { + acc, _ := types.TxSender(t.signer, t.heads[0].Transaction) + heap.Pop(&t.heads) + if txs, ok := t.txs[acc]; ok && len(txs) > 0 { + var nextValidTx *ValidTransaction + nextValidTx, t.txs[acc] = txs[0], txs[1:] + t.heads.Push(nextValidTx) + } +} + +// Pop removes the best transaction, *not* replacing it with the next one from +// the same account. This should be used when a transaction cannot be executed +// and hence all subsequent ones should be discarded from the same account. +func (t *TransactionsByTimestampAndNonce) Pop() { + heap.Pop(&t.heads) +} diff --git a/client/core/types/block.go b/client/core/types/block.go index 715319e93..6a8ca843c 100644 --- a/client/core/types/block.go +++ b/client/core/types/block.go @@ -33,20 +33,18 @@ type Header struct { LastCommitHash common.Hash `json:"lastCommit" gencodec:"required"` Bloom Bloom `json:"logsBloom" gencodec:"required"` Number *big.Int `json:"number" gencodec:"required"` - GasLimit uint64 `json:"gasLimit" gencodec:"required"` - GasUsed uint64 `json:"gasUsed" gencodec:"required"` + ResourceUsage uint64 `json:"resourceUsage" gencodec:"required"` Time *big.Int `json:"timestamp" gencodec:"required"` Extra []byte `json:"extraData" gencodec:"required"` } // field type overrides for gencodec type headerMarshaling struct { - Number *hexutil.Big - GasLimit hexutil.Uint64 - GasUsed hexutil.Uint64 - Time *hexutil.Big - Extra hexutil.Bytes - Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON + Number *hexutil.Big + ResourceUsage hexutil.Uint64 + Time *hexutil.Big + Extra hexutil.Bytes + Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON } // Hash returns the block hash of the header, which is simply the keccak256 hash of its @@ -67,8 +65,7 @@ func (h *Header) HashNoNonce() common.Hash { h.LastCommitHash, h.Bloom, h.Number, - h.GasLimit, - h.GasUsed, + h.ResourceUsage, h.Time, h.Extra, }) @@ -260,10 +257,9 @@ func (b *Block) Transaction(hash common.Hash) *Transaction { func (b *Block) LastCommit() *Commit { return b.lastCommit } -func (b *Block) Number() *big.Int { return new(big.Int).Set(b.header.Number) } -func (b *Block) GasLimit() uint64 { return b.header.GasLimit } -func (b *Block) GasUsed() uint64 { return b.header.GasUsed } -func (b *Block) Time() *big.Int { return new(big.Int).Set(b.header.Time) } +func (b *Block) Number() *big.Int { return new(big.Int).Set(b.header.Number) } +func (b *Block) ResourceUsage() uint64 { return b.header.ResourceUsage } +func (b *Block) Time() *big.Int { return new(big.Int).Set(b.header.Time) } func (b *Block) NumberU64() uint64 { return b.header.Number.Uint64() } func (b *Block) Bloom() Bloom { return b.header.Bloom } diff --git a/client/core/types/gen_header_json.go b/client/core/types/gen_header_json.go index 595639b99..0466d721f 100644 --- a/client/core/types/gen_header_json.go +++ b/client/core/types/gen_header_json.go @@ -25,8 +25,7 @@ func (h Header) MarshalJSON() ([]byte, error) { LastCommitHash common.Hash `json:"lastCommit" gencodec:"required"` Bloom Bloom `json:"logsBloom" gencodec:"required"` Number *hexutil.Big `json:"number" gencodec:"required"` - GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` - GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + ResourceUsage hexutil.Uint64 `json:"resourceUsage" gencodec:"required"` Time *hexutil.Big `json:"timestamp" gencodec:"required"` Extra hexutil.Bytes `json:"extraData" gencodec:"required"` Hash common.Hash `json:"hash"` @@ -41,8 +40,7 @@ func (h Header) MarshalJSON() ([]byte, error) { enc.LastCommitHash = h.LastCommitHash enc.Bloom = h.Bloom enc.Number = (*hexutil.Big)(h.Number) - enc.GasLimit = hexutil.Uint64(h.GasLimit) - enc.GasUsed = hexutil.Uint64(h.GasUsed) + enc.ResourceUsage = hexutil.Uint64(h.ResourceUsage) enc.Time = (*hexutil.Big)(h.Time) enc.Extra = h.Extra enc.Hash = h.Hash() @@ -61,8 +59,7 @@ func (h *Header) UnmarshalJSON(input []byte) error { LastCommitHash *common.Hash `json:"lastCommit" gencodec:"required"` Bloom *Bloom `json:"logsBloom" gencodec:"required"` Number *hexutil.Big `json:"number" gencodec:"required"` - GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` - GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + ResourceUsage *hexutil.Uint64 `json:"resourceUsage" gencodec:"required"` Time *hexutil.Big `json:"timestamp" gencodec:"required"` Extra *hexutil.Bytes `json:"extraData" gencodec:"required"` } @@ -106,14 +103,10 @@ func (h *Header) UnmarshalJSON(input []byte) error { return errors.New("missing required field 'number' for Header") } h.Number = (*big.Int)(dec.Number) - if dec.GasLimit == nil { - return errors.New("missing required field 'gasLimit' for Header") + if dec.ResourceUsage == nil { + return errors.New("missing required field 'resourceUsage' for Header") } - h.GasLimit = uint64(*dec.GasLimit) - if dec.GasUsed == nil { - return errors.New("missing required field 'gasUsed' for Header") - } - h.GasUsed = uint64(*dec.GasUsed) + h.ResourceUsage = uint64(*dec.ResourceUsage) if dec.Time == nil { return errors.New("missing required field 'timestamp' for Header") } diff --git a/client/core/types/gen_receipt_json.go b/client/core/types/gen_receipt_json.go index 61e14aa78..3935d4ee8 100644 --- a/client/core/types/gen_receipt_json.go +++ b/client/core/types/gen_receipt_json.go @@ -15,38 +15,38 @@ var _ = (*receiptMarshaling)(nil) // MarshalJSON marshals as JSON. func (r Receipt) MarshalJSON() ([]byte, error) { type Receipt struct { - PostState hexutil.Bytes `json:"root"` - Status hexutil.Uint64 `json:"status"` - CumulativeGasUsed hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` - Bloom Bloom `json:"logsBloom" gencodec:"required"` - Logs []*Log `json:"logs" gencodec:"required"` - TxHash common.Hash `json:"transactionHash" gencodec:"required"` - ContractAddress common.Address `json:"contractAddress"` - GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + PostState hexutil.Bytes `json:"root"` + Status hexutil.Uint64 `json:"status"` + CumulativeResourceUsage hexutil.Uint64 `json:"cumulativeResourceUsage" gencodec:"required"` + Bloom Bloom `json:"logsBloom" gencodec:"required"` + Logs []*Log `json:"logs" gencodec:"required"` + TxHash common.Hash `json:"transactionHash" gencodec:"required"` + ContractAddress common.Address `json:"contractAddress"` + ResourceUsage hexutil.Uint64 `json:"resourceUsage" gencodec:"required"` } var enc Receipt enc.PostState = r.PostState enc.Status = hexutil.Uint64(r.Status) - enc.CumulativeGasUsed = hexutil.Uint64(r.CumulativeGasUsed) + enc.CumulativeResourceUsage = hexutil.Uint64(r.CumulativeResourceUsage) enc.Bloom = r.Bloom enc.Logs = r.Logs enc.TxHash = r.TxHash enc.ContractAddress = r.ContractAddress - enc.GasUsed = hexutil.Uint64(r.GasUsed) + enc.ResourceUsage = hexutil.Uint64(r.ResourceUsage) return json.Marshal(&enc) } // UnmarshalJSON unmarshals from JSON. func (r *Receipt) UnmarshalJSON(input []byte) error { type Receipt struct { - PostState *hexutil.Bytes `json:"root"` - Status *hexutil.Uint64 `json:"status"` - CumulativeGasUsed *hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` - Bloom *Bloom `json:"logsBloom" gencodec:"required"` - Logs []*Log `json:"logs" gencodec:"required"` - TxHash *common.Hash `json:"transactionHash" gencodec:"required"` - ContractAddress *common.Address `json:"contractAddress"` - GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + PostState *hexutil.Bytes `json:"root"` + Status *hexutil.Uint64 `json:"status"` + CumulativeResourceUsage *hexutil.Uint64 `json:"cumulativeResourceUsage" gencodec:"required"` + Bloom *Bloom `json:"logsBloom" gencodec:"required"` + Logs []*Log `json:"logs" gencodec:"required"` + TxHash *common.Hash `json:"transactionHash" gencodec:"required"` + ContractAddress *common.Address `json:"contractAddress"` + ResourceUsage *hexutil.Uint64 `json:"resourceUsage" gencodec:"required"` } var dec Receipt if err := json.Unmarshal(input, &dec); err != nil { @@ -58,10 +58,10 @@ func (r *Receipt) UnmarshalJSON(input []byte) error { if dec.Status != nil { r.Status = uint64(*dec.Status) } - if dec.CumulativeGasUsed == nil { - return errors.New("missing required field 'cumulativeGasUsed' for Receipt") + if dec.CumulativeResourceUsage == nil { + return errors.New("missing required field 'cumulativeResourceUsage' for Receipt") } - r.CumulativeGasUsed = uint64(*dec.CumulativeGasUsed) + r.CumulativeResourceUsage = uint64(*dec.CumulativeResourceUsage) if dec.Bloom == nil { return errors.New("missing required field 'logsBloom' for Receipt") } @@ -77,9 +77,9 @@ func (r *Receipt) UnmarshalJSON(input []byte) error { if dec.ContractAddress != nil { r.ContractAddress = *dec.ContractAddress } - if dec.GasUsed == nil { - return errors.New("missing required field 'gasUsed' for Receipt") + if dec.ResourceUsage == nil { + return errors.New("missing required field 'resourceUsage' for Receipt") } - r.GasUsed = uint64(*dec.GasUsed) + r.ResourceUsage = uint64(*dec.ResourceUsage) return nil } diff --git a/client/core/types/gen_tx_json.go b/client/core/types/gen_tx_json.go index 4628462cc..6fe1a1b7e 100644 --- a/client/core/types/gen_tx_json.go +++ b/client/core/types/gen_tx_json.go @@ -16,12 +16,11 @@ var _ = (*txdataMarshaling)(nil) // MarshalJSON marshals as JSON. func (t txdata) MarshalJSON() ([]byte, error) { type txdata struct { - AccountNonce hexutil.Uint64 `json:"nonce" gencodec:"required"` - Price *hexutil.Big `json:"gasPrice" gencodec:"required"` - GasLimit hexutil.Uint64 `json:"gas" gencodec:"required"` - Recipient *common.Address `json:"to" rlp:"nil"` - Amount *hexutil.Big `json:"value" gencodec:"required"` - Payload hexutil.Bytes `json:"input" gencodec:"required"` + AccountNonce hexutil.Uint64 `json:"nonce" gencodec:"required"` + ComputeLimit hexutil.Uint64 `json:"computeLimit" gencodec:"required"` + Recipient *common.Address `json:"to" rlp:"nil"` + Amount *hexutil.Big `json:"value" gencodec:"required"` + Payload hexutil.Bytes `json:"input" gencodec:"required"` V *hexutil.Big `json:"v" gencodec:"required"` R *hexutil.Big `json:"r" gencodec:"required"` S *hexutil.Big `json:"s" gencodec:"required"` @@ -29,8 +28,7 @@ func (t txdata) MarshalJSON() ([]byte, error) { } var enc txdata enc.AccountNonce = hexutil.Uint64(t.AccountNonce) - enc.Price = (*hexutil.Big)(t.Price) - enc.GasLimit = hexutil.Uint64(t.GasLimit) + enc.ComputeLimit = hexutil.Uint64(t.ComputeLimit) enc.Recipient = t.Recipient enc.Amount = (*hexutil.Big)(t.Amount) enc.Payload = t.Payload @@ -44,12 +42,11 @@ func (t txdata) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals from JSON. func (t *txdata) UnmarshalJSON(input []byte) error { type txdata struct { - AccountNonce *hexutil.Uint64 `json:"nonce" gencodec:"required"` - Price *hexutil.Big `json:"gasPrice" gencodec:"required"` - GasLimit *hexutil.Uint64 `json:"gas" gencodec:"required"` - Recipient *common.Address `json:"to" rlp:"nil"` - Amount *hexutil.Big `json:"value" gencodec:"required"` - Payload *hexutil.Bytes `json:"input" gencodec:"required"` + AccountNonce *hexutil.Uint64 `json:"nonce" gencodec:"required"` + ComputeLimit *hexutil.Uint64 `json:"computeLimit" gencodec:"required"` + Recipient *common.Address `json:"to" rlp:"nil"` + Amount *hexutil.Big `json:"value" gencodec:"required"` + Payload *hexutil.Bytes `json:"input" gencodec:"required"` V *hexutil.Big `json:"v" gencodec:"required"` R *hexutil.Big `json:"r" gencodec:"required"` S *hexutil.Big `json:"s" gencodec:"required"` @@ -63,14 +60,10 @@ func (t *txdata) UnmarshalJSON(input []byte) error { return errors.New("missing required field 'nonce' for txdata") } t.AccountNonce = uint64(*dec.AccountNonce) - if dec.Price == nil { - return errors.New("missing required field 'gasPrice' for txdata") + if dec.ComputeLimit == nil { + return errors.New("missing required field 'computeLimit' for txdata") } - t.Price = (*big.Int)(dec.Price) - if dec.GasLimit == nil { - return errors.New("missing required field 'gas' for txdata") - } - t.GasLimit = uint64(*dec.GasLimit) + t.ComputeLimit = uint64(*dec.ComputeLimit) if dec.Recipient != nil { t.Recipient = dec.Recipient } diff --git a/client/core/types/receipt.go b/client/core/types/receipt.go index b6c5c3132..3a6e0a587 100644 --- a/client/core/types/receipt.go +++ b/client/core/types/receipt.go @@ -45,46 +45,46 @@ const ( // Receipt represents the results of a transaction. type Receipt struct { // Consensus fields - PostState []byte `json:"root"` - Status uint64 `json:"status"` - CumulativeGasUsed uint64 `json:"cumulativeGasUsed" gencodec:"required"` - Bloom Bloom `json:"logsBloom" gencodec:"required"` - Logs []*Log `json:"logs" gencodec:"required"` + PostState []byte `json:"root"` + Status uint64 `json:"status"` + CumulativeResourceUsage uint64 `json:"cumulativeResourceUsage" gencodec:"required"` + Bloom Bloom `json:"logsBloom" gencodec:"required"` + Logs []*Log `json:"logs" gencodec:"required"` // Implementation fields (don't reorder!) - TxHash common.Hash `json:"transactionHash" gencodec:"required"` + TxHash common.Hash `json:"transactionHash" gencodec:"required"` ContractAddress common.Address `json:"contractAddress"` - GasUsed uint64 `json:"gasUsed" gencodec:"required"` + ResourceUsage uint64 `json:"resourceUsage" gencodec:"required"` } type receiptMarshaling struct { - PostState hexutil.Bytes - Status hexutil.Uint64 - CumulativeGasUsed hexutil.Uint64 - GasUsed hexutil.Uint64 + PostState hexutil.Bytes + Status hexutil.Uint64 + CumulativeResourceUsage hexutil.Uint64 + ResourceUsage hexutil.Uint64 } // receiptRLP is the consensus encoding of a receipt. type receiptRLP struct { - PostStateOrStatus []byte - CumulativeGasUsed uint64 - Bloom Bloom - Logs []*Log + PostStateOrStatus []byte + CumulativeResourceUsage uint64 + Bloom Bloom + Logs []*Log } type receiptStorageRLP struct { - PostStateOrStatus []byte - CumulativeGasUsed uint64 - Bloom Bloom - TxHash common.Hash - ContractAddress common.Address - Logs []*LogForStorage - GasUsed uint64 + PostStateOrStatus []byte + CumulativeResourceUsage uint64 + Bloom Bloom + TxHash common.Hash + ContractAddress common.Address + Logs []*LogForStorage + ResourceUsage uint64 } // NewReceipt creates a barebone transaction receipt, copying the init fields. -func NewReceipt(root []byte, failed bool, cumulativeGasUsed uint64) *Receipt { - r := &Receipt{PostState: common.CopyBytes(root), CumulativeGasUsed: cumulativeGasUsed} +func NewReceipt(root []byte, failed bool, cumulativeResourceUsage uint64) *Receipt { + r := &Receipt{PostState: common.CopyBytes(root), CumulativeResourceUsage: cumulativeResourceUsage} if failed { r.Status = ReceiptStatusFailed } else { @@ -96,7 +96,7 @@ func NewReceipt(root []byte, failed bool, cumulativeGasUsed uint64) *Receipt { // EncodeRLP implements rlp.Encoder, and flattens the consensus fields of a receipt // into an RLP stream. If no post state is present, byzantium fork is assumed. func (r *Receipt) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, &receiptRLP{r.statusEncoding(), r.CumulativeGasUsed, r.Bloom, r.Logs}) + return rlp.Encode(w, &receiptRLP{r.statusEncoding(), r.CumulativeResourceUsage, r.Bloom, r.Logs}) } // DecodeRLP implements rlp.Decoder, and loads the consensus fields of a receipt @@ -109,7 +109,7 @@ func (r *Receipt) DecodeRLP(s *rlp.Stream) error { if err := r.setStatus(dec.PostStateOrStatus); err != nil { return err } - r.CumulativeGasUsed, r.Bloom, r.Logs = dec.CumulativeGasUsed, dec.Bloom, dec.Logs + r.CumulativeResourceUsage, r.Bloom, r.Logs = dec.CumulativeResourceUsage, dec.Bloom, dec.Logs return nil } @@ -151,14 +151,14 @@ func (r *Receipt) Size() common.StorageSize { func (r *Receipt) String() string { return fmt.Sprintf(` -TxHash: %s -ContractAddress: %s -GasUsed: %d -CumulativeGasUsed: %d -Status: %d -Size: %s -Logs: %v -`, r.TxHash.String(), r.ContractAddress.String(), r.CumulativeGasUsed, r.GasUsed, r.Status, r.Size().String(), r.Logs) +TxHash: %s +ContractAddress: %s +ResourceUsage: %d +CumulativeResourceUsage: %d +Status: %d +Size: %s +Logs: %v +`, r.TxHash.String(), r.ContractAddress.String(), r.CumulativeResourceUsage, r.ResourceUsage, r.Status, r.Size().String(), r.Logs) } // ReceiptForStorage is a wrapper around a Receipt that flattens and parses the @@ -169,13 +169,13 @@ type ReceiptForStorage Receipt // into an RLP stream. func (r *ReceiptForStorage) EncodeRLP(w io.Writer) error { enc := &receiptStorageRLP{ - PostStateOrStatus: (*Receipt)(r).statusEncoding(), - CumulativeGasUsed: r.CumulativeGasUsed, - Bloom: r.Bloom, - TxHash: r.TxHash, - ContractAddress: r.ContractAddress, - Logs: make([]*LogForStorage, len(r.Logs)), - GasUsed: r.GasUsed, + PostStateOrStatus: (*Receipt)(r).statusEncoding(), + CumulativeResourceUsage: r.CumulativeResourceUsage, + Bloom: r.Bloom, + TxHash: r.TxHash, + ContractAddress: r.ContractAddress, + Logs: make([]*LogForStorage, len(r.Logs)), + ResourceUsage: r.ResourceUsage, } for i, log := range r.Logs { enc.Logs[i] = (*LogForStorage)(log) @@ -194,13 +194,13 @@ func (r *ReceiptForStorage) DecodeRLP(s *rlp.Stream) error { return err } // Assign the consensus fields - r.CumulativeGasUsed, r.Bloom = dec.CumulativeGasUsed, dec.Bloom + r.CumulativeResourceUsage, r.Bloom = dec.CumulativeResourceUsage, dec.Bloom r.Logs = make([]*Log, len(dec.Logs)) for i, log := range dec.Logs { r.Logs[i] = (*Log)(log) } // Assign the implementation fields - r.TxHash, r.ContractAddress, r.GasUsed = dec.TxHash, dec.ContractAddress, dec.GasUsed + r.TxHash, r.ContractAddress, r.ResourceUsage = dec.TxHash, dec.ContractAddress, dec.ResourceUsage return nil } diff --git a/client/core/types/transaction.go b/client/core/types/transaction.go index 8d7dbb815..d3402af41 100644 --- a/client/core/types/transaction.go +++ b/client/core/types/transaction.go @@ -1,7 +1,6 @@ package types import ( - "container/heap" "errors" "fmt" "io" @@ -11,6 +10,7 @@ import ( "github.com/kowala-tech/kcoin/client/common" "github.com/kowala-tech/kcoin/client/common/hexutil" "github.com/kowala-tech/kcoin/client/crypto" + "github.com/kowala-tech/kcoin/client/params" "github.com/kowala-tech/kcoin/client/rlp" ) @@ -30,12 +30,11 @@ type Transaction struct { } type txdata struct { - AccountNonce uint64 `json:"nonce" gencodec:"required"` - Price *big.Int `json:"gasPrice" gencodec:"required"` - GasLimit uint64 `json:"gas" gencodec:"required"` - Recipient *common.Address `json:"to" rlp:"nil"` // nil means contract creation - Amount *big.Int `json:"value" gencodec:"required"` - Payload []byte `json:"input" gencodec:"required"` + AccountNonce uint64 `json:"nonce" gencodec:"required"` + ComputeLimit uint64 `json:"computeLimit" gencodec:"required"` + Recipient *common.Address `json:"to" rlp:"nil"` // nil means contract creation + Amount *big.Int `json:"value" gencodec:"required"` + Payload []byte `json:"input" gencodec:"required"` // Signature values V *big.Int `json:"v" gencodec:"required"` @@ -48,8 +47,7 @@ type txdata struct { type txdataMarshaling struct { AccountNonce hexutil.Uint64 - Price *hexutil.Big - GasLimit hexutil.Uint64 + ComputeLimit hexutil.Uint64 Amount *hexutil.Big Payload hexutil.Bytes V *hexutil.Big @@ -57,15 +55,15 @@ type txdataMarshaling struct { S *hexutil.Big } -func NewTransaction(nonce uint64, to common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction { - return newTransaction(nonce, &to, amount, gasLimit, gasPrice, data) +func NewTransaction(nonce uint64, to common.Address, amount *big.Int, computeLimit uint64, data []byte) *Transaction { + return newTransaction(nonce, &to, amount, computeLimit, data) } -func NewContractCreation(nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction { - return newTransaction(nonce, nil, amount, gasLimit, gasPrice, data) +func NewContractCreation(nonce uint64, amount *big.Int, computeLimit uint64, data []byte) *Transaction { + return newTransaction(nonce, nil, amount, computeLimit, data) } -func newTransaction(nonce uint64, to *common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction { +func newTransaction(nonce uint64, to *common.Address, amount *big.Int, computeLimit uint64, data []byte) *Transaction { if len(data) > 0 { data = common.CopyBytes(data) } @@ -74,8 +72,7 @@ func newTransaction(nonce uint64, to *common.Address, amount *big.Int, gasLimit Recipient: to, Payload: data, Amount: new(big.Int), - GasLimit: gasLimit, - Price: new(big.Int), + ComputeLimit: computeLimit, V: new(big.Int), R: new(big.Int), S: new(big.Int), @@ -83,9 +80,6 @@ func newTransaction(nonce uint64, to *common.Address, amount *big.Int, gasLimit if amount != nil { d.Amount.Set(amount) } - if gasPrice != nil { - d.Price.Set(gasPrice) - } return &Transaction{data: d} } @@ -143,12 +137,11 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error { return nil } -func (tx *Transaction) Data() []byte { return common.CopyBytes(tx.data.Payload) } -func (tx *Transaction) Gas() uint64 { return tx.data.GasLimit } -func (tx *Transaction) GasPrice() *big.Int { return new(big.Int).Set(tx.data.Price) } -func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.data.Amount) } -func (tx *Transaction) Nonce() uint64 { return tx.data.AccountNonce } -func (tx *Transaction) CheckNonce() bool { return true } +func (tx *Transaction) Data() []byte { return common.CopyBytes(tx.data.Payload) } +func (tx *Transaction) ComputeLimit() uint64 { return tx.data.ComputeLimit } +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) CheckNonce() bool { return true } func (tx *Transaction) From() (*common.Address, error) { if tx.data.V == nil { @@ -198,8 +191,7 @@ func (tx *Transaction) UnprotectedHash() common.Hash { func (tx *Transaction) HashWithData(data ...interface{}) common.Hash { txData := []interface{}{ tx.data.AccountNonce, - tx.data.Price, - tx.data.GasLimit, + tx.data.ComputeLimit, tx.data.Recipient, tx.data.Amount, tx.data.Payload, @@ -240,13 +232,12 @@ func (tx *Transaction) Size() common.StorageSize { // XXX Rename message to something less arbitrary? func (tx *Transaction) AsMessage(s Signer) (Message, error) { msg := Message{ - nonce: tx.data.AccountNonce, - gasLimit: tx.data.GasLimit, - gasPrice: new(big.Int).Set(tx.data.Price), - to: tx.data.Recipient, - amount: tx.data.Amount, - data: tx.data.Payload, - checkNonce: true, + nonce: tx.data.AccountNonce, + computeLimit: tx.data.ComputeLimit, + to: tx.data.Recipient, + amount: tx.data.Amount, + data: tx.data.Payload, + checkNonce: true, } var err error @@ -266,9 +257,9 @@ func (tx *Transaction) WithSignature(signer Signer, sig []byte) (*Transaction, e return cpy, nil } -// Cost returns amount + gasprice * gaslimit. +// Cost returns amount + computational effort * compute unit price. func (tx *Transaction) Cost() *big.Int { - total := new(big.Int).Mul(tx.data.Price, new(big.Int).SetUint64(tx.data.GasLimit)) + total := new(big.Int).Mul(params.ComputeUnitPrice, new(big.Int).SetUint64(tx.data.ComputeLimit)) total.Add(total, tx.data.Amount) return total } @@ -300,26 +291,24 @@ func (tx *Transaction) String() string { enc, _ := rlp.EncodeToBytes(&tx.data) return fmt.Sprintf(` TX(%x) - Contract: %v - From: %s - To: %s - Nonce: %v - GasPrice: %#x - GasLimit %v - Value: %#x - Data: 0x%x - V: %#x - R: %#x - S: %#x - Hex: %x + Contract: %v + From: %s + To: %s + Nonce: %v + ComputeLimit: %v + Value: %#x + Data: 0x%x + V: %#x + R: %#x + S: %#x + Hex: %x `, tx.Hash(), tx.data.Recipient == nil, from, to, tx.data.AccountNonce, - tx.data.Price, - tx.data.GasLimit, + tx.data.ComputeLimit, tx.data.Amount, tx.data.Payload, tx.data.V, @@ -362,129 +351,35 @@ func TxDifference(a, b Transactions) (keep Transactions) { return keep } -// TxByNonce implements the sort interface to allow sorting a list of transactions -// by their nonces. This is usually only useful for sorting transactions from a -// single account, otherwise a nonce comparison doesn't make much sense. -type TxByNonce Transactions - -func (s TxByNonce) Len() int { return len(s) } -func (s TxByNonce) Less(i, j int) bool { return s[i].data.AccountNonce < s[j].data.AccountNonce } -func (s TxByNonce) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -// TxByPrice implements both the sort and the heap interface, making it useful -// for all at once sorting as well as individually adding and removing elements. -type TxByPrice Transactions - -func (s TxByPrice) Len() int { return len(s) } -func (s TxByPrice) Less(i, j int) bool { return s[i].data.Price.Cmp(s[j].data.Price) > 0 } -func (s TxByPrice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -func (s *TxByPrice) Push(x interface{}) { - *s = append(*s, x.(*Transaction)) -} - -func (s *TxByPrice) Pop() interface{} { - old := *s - n := len(old) - x := old[n-1] - *s = old[0 : n-1] - return x -} - -// TransactionsByPriceAndNonce represents a set of transactions that can return -// transactions in a profit-maximizing sorted order, while supporting removing -// entire batches of transactions for non-executable accounts. -type TransactionsByPriceAndNonce struct { - txs map[common.Address]Transactions // Per account nonce-sorted list of transactions - heads TxByPrice // Next transaction for each unique account (price heap) - signer Signer // Signer for the set of transactions -} - -// NewTransactionsByPriceAndNonce creates a transaction set that can retrieve -// price sorted transactions in a nonce-honouring way. -// -// Note, the input map is reowned so the caller should not interact any more with -// if after providing it to the constructor. -func NewTransactionsByPriceAndNonce(signer Signer, txs map[common.Address]Transactions) *TransactionsByPriceAndNonce { - // Initialize a price based heap with the head transactions - heads := make(TxByPrice, 0, len(txs)) - for from, accTxs := range txs { - heads = append(heads, accTxs[0]) - // Ensure the sender address is from the signer - acc, _ := TxSender(signer, accTxs[0]) - txs[acc] = accTxs[1:] - if from != acc { - delete(txs, from) - } - } - heap.Init(&heads) - - // Assemble and return the transaction set - return &TransactionsByPriceAndNonce{ - txs: txs, - heads: heads, - signer: signer, - } -} - -// Peek returns the next transaction by price. -func (t *TransactionsByPriceAndNonce) Peek() *Transaction { - if len(t.heads) == 0 { - return nil - } - return t.heads[0] -} - -// Shift replaces the current best head with the next one from the same account. -func (t *TransactionsByPriceAndNonce) Shift() { - acc, _ := TxSender(t.signer, t.heads[0]) - if txs, ok := t.txs[acc]; ok && len(txs) > 0 { - t.heads[0], t.txs[acc] = txs[0], txs[1:] - heap.Fix(&t.heads, 0) - } else { - heap.Pop(&t.heads) - } -} - -// Pop removes the best transaction, *not* replacing it with the next one from -// the same account. This should be used when a transaction cannot be executed -// and hence all subsequent ones should be discarded from the same account. -func (t *TransactionsByPriceAndNonce) Pop() { - heap.Pop(&t.heads) -} - // Message is a fully derived transaction and implements core.Message // // NOTE: In a future PR this will be removed. type Message struct { - to *common.Address - from common.Address - nonce uint64 - amount *big.Int - gasLimit uint64 - gasPrice *big.Int - data []byte - checkNonce bool + to *common.Address + from common.Address + nonce uint64 + amount *big.Int + computeLimit uint64 + data []byte + checkNonce bool } -func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, checkNonce bool) Message { +func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, computeLimit uint64, data []byte, checkNonce bool) Message { return Message{ - from: from, - to: to, - nonce: nonce, - amount: amount, - gasLimit: gasLimit, - gasPrice: gasPrice, - data: data, - checkNonce: checkNonce, + from: from, + to: to, + nonce: nonce, + amount: amount, + computeLimit: computeLimit, + data: data, + checkNonce: checkNonce, } } func (m Message) From() common.Address { return m.from } func (m Message) To() *common.Address { return m.to } -func (m Message) GasPrice() *big.Int { return m.gasPrice } func (m Message) Value() *big.Int { return m.amount } -func (m Message) Gas() uint64 { return m.gasLimit } +func (m Message) ComputeLimit() uint64 { return m.computeLimit } func (m Message) Nonce() uint64 { return m.nonce } func (m Message) Data() []byte { return m.data } func (m Message) CheckNonce() bool { return m.checkNonce } diff --git a/client/core/types/transaction_test.go b/client/core/types/transaction_test.go index 3db3eb45b..49bee68b2 100644 --- a/client/core/types/transaction_test.go +++ b/client/core/types/transaction_test.go @@ -27,7 +27,6 @@ func TestFrom(t *testing.T) { common.HexToAddress("0xecf8f87f810ecf450940c9f60066b4a7a501d6a7"), big.NewInt(10), 10, - big.NewInt(1), nil, ) diff --git a/client/core/evm.go b/client/core/virtual_machine.go similarity index 75% rename from client/core/evm.go rename to client/core/virtual_machine.go index 2f546758e..e8fdea807 100644 --- a/client/core/evm.go +++ b/client/core/virtual_machine.go @@ -7,6 +7,7 @@ import ( "github.com/kowala-tech/kcoin/client/consensus" "github.com/kowala-tech/kcoin/client/core/types" "github.com/kowala-tech/kcoin/client/core/vm" + "github.com/kowala-tech/kcoin/client/params" ) // ChainContext supports retrieving headers and consensus parameters from the @@ -19,8 +20,8 @@ type ChainContext interface { GetHeader(common.Hash, uint64) *types.Header } -// NewEVMContext creates a new context for use in the EVM. -func NewEVMContext(msg Message, header *types.Header, chain ChainContext, author *common.Address) vm.Context { +// NewVMContext creates a new context for use in the VM. +func NewVMContext(msg Message, header *types.Header, chain ChainContext, author *common.Address) vm.Context { // If we don't have an explicit author (i.e. not mining), extract from the header var beneficiary common.Address if author == nil { @@ -29,15 +30,15 @@ func NewEVMContext(msg Message, header *types.Header, chain ChainContext, author beneficiary = *author } return vm.Context{ - CanTransfer: CanTransfer, - Transfer: Transfer, - GetHash: GetHashFn(header, chain), - Origin: msg.From(), - Coinbase: beneficiary, - BlockNumber: new(big.Int).Set(header.Number), - Time: new(big.Int).Set(header.Time), - GasLimit: header.GasLimit, - GasPrice: new(big.Int).Set(msg.GasPrice()), + CanTransfer: CanTransfer, + Transfer: Transfer, + GetHash: GetHashFn(header, chain), + Origin: msg.From(), + Coinbase: beneficiary, + BlockNumber: new(big.Int).Set(header.Number), + Time: new(big.Int).Set(header.Time), + ComputeCapacity: params.ComputeCapacity, + ComputeUnitPrice: new(big.Int).Set(params.ComputeUnitPrice), } } @@ -68,7 +69,7 @@ func GetHashFn(ref *types.Header, chain ChainContext) func(n uint64) common.Hash } // CanTransfer checks wether there are enough funds in the address' account to make a transfer. -// This does not take the necessary gas in to account to make the transfer valid. +// This does not take the necessary computational resource in to account to make the transfer valid. func CanTransfer(db vm.StateDB, addr common.Address, amount *big.Int) bool { return db.GetBalance(addr).Cmp(amount) >= 0 } diff --git a/client/core/vm/gas.go b/client/core/vm/comp_effort.go similarity index 51% rename from client/core/vm/gas.go rename to client/core/vm/comp_effort.go index fe6ede054..856d57829 100644 --- a/client/core/vm/gas.go +++ b/client/core/vm/comp_effort.go @@ -19,40 +19,37 @@ package vm import ( "math/big" - "github.com/kowala-tech/kcoin/client/params" + "github.com/kowala-tech/kcoin/client/params/effort" ) -// Gas costs +// Computational Effort const ( - GasQuickStep uint64 = 2 - GasFastestStep uint64 = 3 - GasFastStep uint64 = 5 - GasMidStep uint64 = 8 - GasSlowStep uint64 = 10 - GasExtStep uint64 = 20 + EffortQuickStep uint64 = 2 + EffortFastestStep uint64 = 3 + EffortFastStep uint64 = 5 + EffortMidStep uint64 = 8 + EffortSlowStep uint64 = 10 + EffortExtStep uint64 = 20 - GasReturn uint64 = 0 - GasStop uint64 = 0 - GasContractByte uint64 = 200 + EffortReturn uint64 = 0 + EffortStop uint64 = 0 + EffortContractByte uint64 = 200 ) -// calcGas returns the actual gas cost of the call. -// -// The cost of gas was changed during the homestead price change HF. To allow for EIP150 -// to be implemented. The returned gas is gas - base * 63 / 64. -func callGas(gasTable params.GasTable, availableGas, base uint64, callCost *big.Int) (uint64, error) { - if gasTable.CreateBySuicide > 0 { - availableGas = availableGas - base - gas := availableGas - availableGas/64 - // If the bit length exceeds 64 bit we know that the newly calculated "gas" for EIP150 - // is smaller than the requested amount. Therefor we return the new gas instead +// calcEffort returns the actual computational effort of the call. +func callEffort(table effort.Table, availableResource, base uint64, callCost *big.Int) (uint64, error) { + if table.CreateBySuicide > 0 { + availableResource = availableResource - base + resource := availableResource - availableResource/64 + // If the bit length exceeds 64 bit we know that the newly calculated "computational effort" for EIP150 + // is smaller than the requested amount. Therefore we return the new computational effort instead // of returning an error. - if callCost.BitLen() > 64 || gas < callCost.Uint64() { - return gas, nil + if callCost.BitLen() > 64 || resource < callCost.Uint64() { + return resource, nil } } if callCost.BitLen() > 64 { - return 0, errGasUintOverflow + return 0, errEffortUintOverflow } return callCost.Uint64(), nil diff --git a/client/core/vm/contract.go b/client/core/vm/contract.go index 90794b67d..af9b7abe5 100644 --- a/client/core/vm/contract.go +++ b/client/core/vm/contract.go @@ -56,16 +56,16 @@ type Contract struct { CodeAddr *common.Address Input []byte - Gas uint64 - value *big.Int + ComputationalResource uint64 + value *big.Int Args []byte DelegateCall bool } -// NewContract returns a new contract environment for the execution of EVM. -func NewContract(caller ContractRef, object ContractRef, value *big.Int, gas uint64) *Contract { +// NewContract returns a new contract environment for the execution of VM. +func NewContract(caller ContractRef, object ContractRef, value *big.Int, resource uint64) *Contract { c := &Contract{CallerAddress: caller.Address(), caller: caller, self: object, Args: nil} if parent, ok := caller.(*Contract); ok { @@ -75,9 +75,9 @@ func NewContract(caller ContractRef, object ContractRef, value *big.Int, gas uin c.jumpdests = make(destinations) } - // Gas should be a pointer so it can safely be reduced through the run + // ComputationalResource should be a pointer so it can safely be reduced through the run // This pointer will be off the state transition - c.Gas = gas + c.ComputationalResource = resource // ensures a value is set c.value = value @@ -119,12 +119,12 @@ func (c *Contract) Caller() common.Address { return c.CallerAddress } -// UseGas attempts the use gas and subtracts it and returns true on success -func (c *Contract) UseGas(gas uint64) (ok bool) { - if c.Gas < gas { +// UseResource attempts the use computational resource and subtracts it and returns true on success +func (c *Contract) UseResource(amount uint64) (ok bool) { + if c.ComputationalResource < amount { return false } - c.Gas -= gas + c.ComputationalResource -= amount return true } diff --git a/client/core/vm/contracts.go b/client/core/vm/contracts.go index 37dfc6507..2b09bd874 100644 --- a/client/core/vm/contracts.go +++ b/client/core/vm/contracts.go @@ -25,17 +25,18 @@ import ( "github.com/kowala-tech/kcoin/client/common/math" "github.com/kowala-tech/kcoin/client/crypto" "github.com/kowala-tech/kcoin/client/crypto/bn256" - "github.com/kowala-tech/kcoin/client/params" + effrt "github.com/kowala-tech/kcoin/client/params/effort" "golang.org/x/crypto/ripemd160" ) // PrecompiledContract is the basic interface for native Go contracts. The implementation -// requires a deterministic gas count based on the input size of the Run method of the +// requires a deterministic computational resource count based on the input size of the Run method of the // contract. type PrecompiledContract interface { - RequiredGas(input []byte) uint64 // RequiredPrice calculates the contract gas use + RequiredComputationalEffort(input []byte) uint64 Run(input []byte) ([]byte, error) // Run runs the precompiled contract } + // PrecompiledContractsAndromeda contains the default set of pre-compiled Kowala // contracts used in the Andromeda release. var PrecompiledContractsAndromeda = map[common.Address]PrecompiledContract{ @@ -51,18 +52,18 @@ var PrecompiledContractsAndromeda = map[common.Address]PrecompiledContract{ // RunPrecompiledContract runs and evaluates the output of a precompiled contract. func RunPrecompiledContract(p PrecompiledContract, input []byte, contract *Contract) (ret []byte, err error) { - gas := p.RequiredGas(input) - if contract.UseGas(gas) { + effort := p.RequiredComputationalEffort(input) + if contract.UseResource(effort) { return p.Run(input) } - return nil, ErrOutOfGas + return nil, ErrOutOfComputationalResource } // ECRECOVER implemented as a native contract. type ecrecover struct{} -func (c *ecrecover) RequiredGas(input []byte) uint64 { - return params.EcrecoverGas +func (c *ecrecover) RequiredComputationalEffort(input []byte) uint64 { + return effrt.Ecrecover } func (c *ecrecover) Run(input []byte) ([]byte, error) { @@ -94,12 +95,12 @@ func (c *ecrecover) Run(input []byte) ([]byte, error) { // SHA256 implemented as a native contract. type sha256hash struct{} -// RequiredGas returns the gas required to execute the pre-compiled contract. +// RequiredComputationalEffort returns the computational effort required to execute the pre-compiled contract. // -// This method does not require any overflow checking as the input size gas costs +// This method does not require any overflow checking as the input size resource costs // required for anything significant is so high it's impossible to pay for. -func (c *sha256hash) RequiredGas(input []byte) uint64 { - return uint64(len(input)+31)/32*params.Sha256PerWordGas + params.Sha256BaseGas +func (c *sha256hash) RequiredComputationalEffort(input []byte) uint64 { + return uint64(len(input)+31)/32*effrt.Sha256PerWord + effrt.Sha256Base } func (c *sha256hash) Run(input []byte) ([]byte, error) { h := sha256.Sum256(input) @@ -109,12 +110,12 @@ func (c *sha256hash) Run(input []byte) ([]byte, error) { // RIPMED160 implemented as a native contract. type ripemd160hash struct{} -// RequiredGas returns the gas required to execute the pre-compiled contract. +// RequiredComputationalEffort returns the computational effort required to execute the pre-compiled contract. // -// This method does not require any overflow checking as the input size gas costs +// This method does not require any overflow checking as the input size resource costs // required for anything significant is so high it's impossible to pay for. -func (c *ripemd160hash) RequiredGas(input []byte) uint64 { - return uint64(len(input)+31)/32*params.Ripemd160PerWordGas + params.Ripemd160BaseGas +func (c *ripemd160hash) RequiredComputationalEffort(input []byte) uint64 { + return uint64(len(input)+31)/32*effrt.Ripemd160PerWord + effrt.Ripemd160Base } func (c *ripemd160hash) Run(input []byte) ([]byte, error) { ripemd := ripemd160.New() @@ -125,12 +126,12 @@ func (c *ripemd160hash) Run(input []byte) ([]byte, error) { // data copy implemented as a native contract. type dataCopy struct{} -// RequiredGas returns the gas required to execute the pre-compiled contract. +// RequiredComputationalEffort returns the computational effort required to execute the pre-compiled contract. // -// This method does not require any overflow checking as the input size gas costs +// This method does not require any overflow checking as the input size resource costs // required for anything significant is so high it's impossible to pay for. -func (c *dataCopy) RequiredGas(input []byte) uint64 { - return uint64(len(input)+31)/32*params.IdentityPerWordGas + params.IdentityBaseGas +func (c *dataCopy) RequiredComputationalEffort(input []byte) uint64 { + return uint64(len(input)+31)/32*effrt.IdentityPerWord + effrt.IdentityBase } func (c *dataCopy) Run(in []byte) ([]byte, error) { return in, nil @@ -153,8 +154,8 @@ var ( big199680 = big.NewInt(199680) ) -// RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bigModExp) RequiredGas(input []byte) uint64 { +// RequiredComputationalEffort returns the computational effort required to execute the pre-compiled contract. +func (c *bigModExp) RequiredComputationalEffort(input []byte) uint64 { var ( baseLen = new(big.Int).SetBytes(getData(input, 0, 32)) expLen = new(big.Int).SetBytes(getData(input, 32, 32)) @@ -188,29 +189,29 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 { } adjExpLen.Add(adjExpLen, big.NewInt(int64(msb))) - // Calculate the gas cost of the operation - gas := new(big.Int).Set(math.BigMax(modLen, baseLen)) + // Calculate the computational effort of the operation + effort := new(big.Int).Set(math.BigMax(modLen, baseLen)) switch { - case gas.Cmp(big64) <= 0: - gas.Mul(gas, gas) - case gas.Cmp(big1024) <= 0: - gas = new(big.Int).Add( - new(big.Int).Div(new(big.Int).Mul(gas, gas), big4), - new(big.Int).Sub(new(big.Int).Mul(big96, gas), big3072), + case effort.Cmp(big64) <= 0: + effort.Mul(effort, effort) + case effort.Cmp(big1024) <= 0: + effort = new(big.Int).Add( + new(big.Int).Div(new(big.Int).Mul(effort, effort), big4), + new(big.Int).Sub(new(big.Int).Mul(big96, effort), big3072), ) default: - gas = new(big.Int).Add( - new(big.Int).Div(new(big.Int).Mul(gas, gas), big16), - new(big.Int).Sub(new(big.Int).Mul(big480, gas), big199680), + effort = new(big.Int).Add( + new(big.Int).Div(new(big.Int).Mul(effort, effort), big16), + new(big.Int).Sub(new(big.Int).Mul(big480, effort), big199680), ) } - gas.Mul(gas, math.BigMax(adjExpLen, big1)) - gas.Div(gas, new(big.Int).SetUint64(params.ModExpQuadCoeffDiv)) + effort.Mul(effort, math.BigMax(adjExpLen, big1)) + effort.Div(effort, new(big.Int).SetUint64(effrt.ModExpQuadCoeffDiv)) - if gas.BitLen() > 64 { + if effort.BitLen() > 64 { return math.MaxUint64 } - return gas.Uint64() + return effort.Uint64() } func (c *bigModExp) Run(input []byte) ([]byte, error) { @@ -264,9 +265,9 @@ func newTwistPoint(blob []byte) (*bn256.G2, error) { // bn256Add implements a native elliptic curve point addition. type bn256Add struct{} -// RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bn256Add) RequiredGas(input []byte) uint64 { - return params.Bn256AddGas +// RequiredComputationalEffort returns the computational effort required to execute the pre-compiled contract. +func (c *bn256Add) RequiredComputationalEffort(input []byte) uint64 { + return effrt.Bn256Add } func (c *bn256Add) Run(input []byte) ([]byte, error) { @@ -286,9 +287,9 @@ func (c *bn256Add) Run(input []byte) ([]byte, error) { // bn256ScalarMul implements a native elliptic curve scalar multiplication. type bn256ScalarMul struct{} -// RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bn256ScalarMul) RequiredGas(input []byte) uint64 { - return params.Bn256ScalarMulGas +// RequiredComputationalEffort returns the computational effort required to execute the pre-compiled contract. +func (c *bn256ScalarMul) RequiredComputationalEffort(input []byte) uint64 { + return effrt.Bn256ScalarMul } func (c *bn256ScalarMul) Run(input []byte) ([]byte, error) { @@ -315,9 +316,9 @@ var ( // bn256Pairing implements a pairing pre-compile for the bn256 curve type bn256Pairing struct{} -// RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bn256Pairing) RequiredGas(input []byte) uint64 { - return params.Bn256PairingBaseGas + uint64(len(input)/192)*params.Bn256PairingPerPointGas +// RequiredComputationalEffort returns the computational effort required to execute the pre-compiled contract. +func (c *bn256Pairing) RequiredComputationalEffort(input []byte) uint64 { + return effrt.Bn256PairingBase + uint64(len(input)/192)*effrt.Bn256PairingPerPoint } func (c *bn256Pairing) Run(input []byte) ([]byte, error) { diff --git a/client/core/vm/contracts_test.go b/client/core/vm/contracts_test.go index be7217bb8..4868255ee 100644 --- a/client/core/vm/contracts_test.go +++ b/client/core/vm/contracts_test.go @@ -11,7 +11,7 @@ import ( // precompiledTest defines the input/output pairs for precompiled contract tests. type precompiledTest struct { input, expected string - gas uint64 + resource uint64 name string noBenchmark bool // Benchmark primarily the worst-cases } @@ -285,11 +285,11 @@ var bn256PairingTests = []precompiledTest{ input: "1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f593034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf704bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a416782bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550111e129f1cf1097710d41c4ac70fcdfa5ba2023c6ff1cbeac322de49d1b6df7c103188585e2364128fe25c70558f1560f4f9350baf3959e603cc91486e110936198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", expected: "0000000000000000000000000000000000000000000000000000000000000000", name: "jeff6", - }, { // ecpairing_empty_data_insufficient_gas + }, { // ecpairing_empty_data_insufficient_computational_resource input: "", expected: "0000000000000000000000000000000000000000000000000000000000000001", name: "empty_data", - }, { // ecpairing_one_point_insufficient_gas + }, { // ecpairing_one_point_insufficient_computational_resource input: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", expected: "0000000000000000000000000000000000000000000000000000000000000000", name: "one_point", @@ -324,8 +324,8 @@ func testPrecompiled(addr string, test precompiledTest, t *testing.T) { p := PrecompiledContractsByzantium[common.HexToAddress(addr)] in := common.Hex2Bytes(test.input) contract := NewContract(AccountRef(common.HexToAddress("1337")), - nil, new(big.Int), p.RequiredGas(in)) - t.Run(fmt.Sprintf("%s-Gas=%d", test.name, contract.Gas), func(t *testing.T) { + nil, new(big.Int), p.RequiredComputationalEffort(in)) + t.Run(fmt.Sprintf("%s-Computational Resource=%d", test.name, contract.ComputationalResource), func(t *testing.T) { if res, err := RunPrecompiledContract(p, in, contract); err != nil { t.Error(err) } else if common.Bytes2Hex(res) != test.expected { @@ -340,9 +340,9 @@ func benchmarkPrecompiled(addr string, test precompiledTest, bench *testing.B) { } p := PrecompiledContractsByzantium[common.HexToAddress(addr)] in := common.Hex2Bytes(test.input) - reqGas := p.RequiredGas(in) + reqEffort := p.RequiredComputationalEffort(in) contract := NewContract(AccountRef(common.HexToAddress("1337")), - nil, new(big.Int), reqGas) + nil, new(big.Int), reqEffort) var ( res []byte @@ -350,10 +350,10 @@ func benchmarkPrecompiled(addr string, test precompiledTest, bench *testing.B) { data = make([]byte, len(in)) ) - bench.Run(fmt.Sprintf("%s-Gas=%d", test.name, contract.Gas), func(bench *testing.B) { + bench.Run(fmt.Sprintf("%s-Computational Resource=%d", test.name, contract.ComputationalResource), func(bench *testing.B) { bench.ResetTimer() for i := 0; i < bench.N; i++ { - contract.Gas = reqGas + contract.ComputationalResource = reqEffort copy(data, in) res, err = RunPrecompiledContract(p, data, contract) } diff --git a/client/core/vm/doc.go b/client/core/vm/doc.go index 5864d0cfa..4cee5d5b1 100644 --- a/client/core/vm/doc.go +++ b/client/core/vm/doc.go @@ -15,10 +15,9 @@ // along with the go-ethereum library. If not, see . /* -Package vm implements the Ethereum Virtual Machine. +Package vm implements the Virtual Machine. -The vm package implements one EVM, a byte code VM. The BC (Byte Code) VM loops -over a set of bytes and executes them according to the set of rules defined -in the Ethereum yellow paper. +The vm package implements a byte code VM. The BC (Byte Code) VM loops +over a set of bytes and executes them according to the set of rules. */ package vm diff --git a/client/core/vm/effort_table.go b/client/core/vm/effort_table.go new file mode 100644 index 000000000..738d13ef3 --- /dev/null +++ b/client/core/vm/effort_table.go @@ -0,0 +1,451 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package vm + +import ( + "github.com/kowala-tech/kcoin/client/common" + "github.com/kowala-tech/kcoin/client/common/math" + effrt "github.com/kowala-tech/kcoin/client/params/effort" +) + +// memoryEffort calculates the quadratic computational effort for memory expansion. It does so +// only for the memory region that is expanded, not the total memory. +func memoryEffort(mem *Memory, newMemSize uint64) (uint64, error) { + + if newMemSize == 0 { + return 0, nil + } + // The maximum that will fit in a uint64 is max_word_count - 1 + // anything above that will result in an overflow. + // Additionally, a newMemSize which results in a + // newMemSizeWords larger than 0x7ffffffff will cause the square operation + // to overflow. + // The constant 0xffffffffe0 is the highest number that can be used without + // overflowing the effort calculation + if newMemSize > 0xffffffffe0 { + return 0, errEffortUintOverflow + } + + newMemSizeWords := toWordSize(newMemSize) + newMemSize = newMemSizeWords * 32 + + if newMemSize > uint64(mem.Len()) { + square := newMemSizeWords * newMemSizeWords + linCoef := newMemSizeWords * effrt.Memory + quadCoef := square / effrt.QuadCoeffDiv + newTotalFee := linCoef + quadCoef + + fee := newTotalFee - mem.lastResourceUsage + mem.lastResourceUsage = newTotalFee + + return fee, nil + } + return 0, nil +} + +func constEffortFunc(effort uint64) effortFunc { + return func(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + return effort, nil + } +} + +func effortCallDataCopy(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + effort, err := memoryEffort(mem, memorySize) + if err != nil { + return 0, err + } + + var overflow bool + if effort, overflow = math.SafeAdd(effort, EffortFastestStep); overflow { + return 0, errEffortUintOverflow + } + + words, overflow := bigUint64(stack.Back(2)) + if overflow { + return 0, errEffortUintOverflow + } + + if words, overflow = math.SafeMul(toWordSize(words), effrt.Copy); overflow { + return 0, errEffortUintOverflow + } + + if effort, overflow = math.SafeAdd(effort, words); overflow { + return 0, errEffortUintOverflow + } + return effort, nil +} + +func effortReturnDataCopy(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + effort, err := memoryEffort(mem, memorySize) + if err != nil { + return 0, err + } + + var overflow bool + if effort, overflow = math.SafeAdd(effort, EffortFastestStep); overflow { + return 0, errEffortUintOverflow + } + + words, overflow := bigUint64(stack.Back(2)) + if overflow { + return 0, errEffortUintOverflow + } + + if words, overflow = math.SafeMul(toWordSize(words), effrt.Copy); overflow { + return 0, errEffortUintOverflow + } + + if effort, overflow = math.SafeAdd(effort, words); overflow { + return 0, errEffortUintOverflow + } + return effort, nil +} + +func effortSStore(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + var ( + y, x = stack.Back(1), stack.Back(0) + val = vm.StateDB.GetState(contract.Address(), common.BigToHash(x)) + ) + // This checks for 3 scenario's and calculates effort accordingly + // 1. From a zero-value address to a non-zero value (NEW VALUE) + // 2. From a non-zero value address to a zero-value address (DELETE) + // 3. From a non-zero to a non-zero (CHANGE) + if val == (common.Hash{}) && y.Sign() != 0 { + // 0 => non 0 + return effrt.SstoreSet, nil + } else if val != (common.Hash{}) && y.Sign() == 0 { + // non 0 => 0 + vm.StateDB.AddRefund(effrt.SstoreRefund) + return effrt.SstoreClear, nil + } else { + // non 0 => non 0 (or 0 => 0) + return effrt.SstoreReset, nil + } +} + +func makeEffortLog(n uint64) effortFunc { + return func(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + requestedSize, overflow := bigUint64(stack.Back(1)) + if overflow { + return 0, errEffortUintOverflow + } + + effort, err := memoryEffort(mem, memorySize) + if err != nil { + return 0, err + } + + if effort, overflow = math.SafeAdd(effort, effrt.Log); overflow { + return 0, errEffortUintOverflow + } + if effort, overflow = math.SafeAdd(effort, n*effrt.LogTopic); overflow { + return 0, errEffortUintOverflow + } + + var memorySizeEffort uint64 + if memorySizeEffort, overflow = math.SafeMul(requestedSize, effrt.LogData); overflow { + return 0, errEffortUintOverflow + } + if effort, overflow = math.SafeAdd(effort, memorySizeEffort); overflow { + return 0, errEffortUintOverflow + } + return effort, nil + } +} + +func effortSha3(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + var overflow bool + effort, err := memoryEffort(mem, memorySize) + if err != nil { + return 0, err + } + + if effort, overflow = math.SafeAdd(effort, effrt.Sha3); overflow { + return 0, errEffortUintOverflow + } + + wordEffort, overflow := bigUint64(stack.Back(1)) + if overflow { + return 0, errEffortUintOverflow + } + if wordEffort, overflow = math.SafeMul(toWordSize(wordEffort), effrt.Sha3Word); overflow { + return 0, errEffortUintOverflow + } + if effort, overflow = math.SafeAdd(effort, wordEffort); overflow { + return 0, errEffortUintOverflow + } + return effort, nil +} + +func effortCodeCopy(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + effort, err := memoryEffort(mem, memorySize) + if err != nil { + return 0, err + } + + var overflow bool + if effort, overflow = math.SafeAdd(effort, EffortFastestStep); overflow { + return 0, errEffortUintOverflow + } + + wordEffort, overflow := bigUint64(stack.Back(2)) + if overflow { + return 0, errEffortUintOverflow + } + if wordEffort, overflow = math.SafeMul(toWordSize(wordEffort), effrt.Copy); overflow { + return 0, errEffortUintOverflow + } + if effort, overflow = math.SafeAdd(effort, wordEffort); overflow { + return 0, errEffortUintOverflow + } + return effort, nil +} + +func effortExtCodeCopy(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + effort, err := memoryEffort(mem, memorySize) + if err != nil { + return 0, err + } + + var overflow bool + if effort, overflow = math.SafeAdd(effort, gt.ExtcodeCopy); overflow { + return 0, errEffortUintOverflow + } + + wordEffort, overflow := bigUint64(stack.Back(3)) + if overflow { + return 0, errEffortUintOverflow + } + + if wordEffort, overflow = math.SafeMul(toWordSize(wordEffort), effrt.Copy); overflow { + return 0, errEffortUintOverflow + } + + if effort, overflow = math.SafeAdd(effort, wordEffort); overflow { + return 0, errEffortUintOverflow + } + return effort, nil +} + +func effortMLoad(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + var overflow bool + effort, err := memoryEffort(mem, memorySize) + if err != nil { + return 0, errEffortUintOverflow + } + if effort, overflow = math.SafeAdd(effort, EffortFastestStep); overflow { + return 0, errEffortUintOverflow + } + return effort, nil +} + +func effortMStore8(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + var overflow bool + effort, err := memoryEffort(mem, memorySize) + if err != nil { + return 0, errEffortUintOverflow + } + if effort, overflow = math.SafeAdd(effort, EffortFastestStep); overflow { + return 0, errEffortUintOverflow + } + return effort, nil +} + +func effortMStore(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + var overflow bool + effort, err := memoryEffort(mem, memorySize) + if err != nil { + return 0, errEffortUintOverflow + } + if effort, overflow = math.SafeAdd(effort, EffortFastestStep); overflow { + return 0, errEffortUintOverflow + } + return effort, nil +} + +func effortCreate(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + var overflow bool + effort, err := memoryEffort(mem, memorySize) + if err != nil { + return 0, err + } + if effort, overflow = math.SafeAdd(effort, effrt.Create); overflow { + return 0, errEffortUintOverflow + } + return effort, nil +} + +func effortBalance(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + return gt.Balance, nil +} + +func effortExtCodeSize(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + return gt.ExtcodeSize, nil +} + +func effortSLoad(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + return gt.SLoad, nil +} + +func effortExp(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + expByteLen := uint64((stack.data[stack.len()-2].BitLen() + 7) / 8) + + var ( + effort = expByteLen * gt.ExpByte // no overflow check required. Max is 256 * ExpByte effort + overflow bool + ) + if effort, overflow = math.SafeAdd(effort, EffortSlowStep); overflow { + return 0, errEffortUintOverflow + } + return effort, nil +} + +func effortCall(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + var ( + effort = gt.Calls + transfersValue = stack.Back(2).Sign() != 0 + address = common.BigToAddress(stack.Back(1)) + ) + + if transfersValue && vm.StateDB.Empty(address) { + effort += effrt.CallNewAccount + } + + if transfersValue { + effort += effrt.CallValueTransfer + } + memoryEffort, err := memoryEffort(mem, memorySize) + if err != nil { + return 0, err + } + var overflow bool + if effort, overflow = math.SafeAdd(effort, memoryEffort); overflow { + return 0, errEffortUintOverflow + } + + vm.callResourceTemp, err = callEffort(gt, contract.ComputationalResource, effort, stack.Back(0)) + if err != nil { + return 0, err + } + if effort, overflow = math.SafeAdd(effort, vm.callResourceTemp); overflow { + return 0, errEffortUintOverflow + } + return effort, nil +} + +func effortCallCode(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + effort := gt.Calls + if stack.Back(2).Sign() != 0 { + effort += effrt.CallValueTransfer + } + memoryEffort, err := memoryEffort(mem, memorySize) + if err != nil { + return 0, err + } + var overflow bool + if effort, overflow = math.SafeAdd(effort, memoryEffort); overflow { + return 0, errEffortUintOverflow + } + + vm.callResourceTemp, err = callEffort(gt, contract.ComputationalResource, effort, stack.Back(0)) + if err != nil { + return 0, err + } + if effort, overflow = math.SafeAdd(effort, vm.callResourceTemp); overflow { + return 0, errEffortUintOverflow + } + return effort, nil +} + +func effortReturn(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + return memoryEffort(mem, memorySize) +} + +func effortRevert(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + return memoryEffort(mem, memorySize) +} + +func effortSuicide(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + var effort uint64 + + effort = gt.Suicide + var ( + address = common.BigToAddress(stack.Back(0)) + ) + + // if empty and transfers value + if vm.StateDB.Empty(address) && vm.StateDB.GetBalance(contract.Address()).Sign() != 0 { + effort += gt.CreateBySuicide + } + + if !vm.StateDB.HasSuicided(contract.Address()) { + vm.StateDB.AddRefund(effrt.SuicideRefund) + } + return effort, nil +} + +func effortDelegateCall(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + effort, err := memoryEffort(mem, memorySize) + if err != nil { + return 0, err + } + var overflow bool + if effort, overflow = math.SafeAdd(effort, gt.Calls); overflow { + return 0, errEffortUintOverflow + } + + vm.callResourceTemp, err = callEffort(gt, contract.ComputationalResource, effort, stack.Back(0)) + if err != nil { + return 0, err + } + if effort, overflow = math.SafeAdd(effort, vm.callResourceTemp); overflow { + return 0, errEffortUintOverflow + } + return effort, nil +} + +func effortStaticCall(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + effort, err := memoryEffort(mem, memorySize) + if err != nil { + return 0, err + } + var overflow bool + if effort, overflow = math.SafeAdd(effort, gt.Calls); overflow { + return 0, errEffortUintOverflow + } + + vm.callResourceTemp, err = callEffort(gt, contract.ComputationalResource, effort, stack.Back(0)) + if err != nil { + return 0, err + } + if effort, overflow = math.SafeAdd(effort, vm.callResourceTemp); overflow { + return 0, errEffortUintOverflow + } + return effort, nil +} + +func effortPush(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + return EffortFastestStep, nil +} + +func effortSwap(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + return EffortFastestStep, nil +} + +func effortDup(gt effrt.Table, vm *VM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + return EffortFastestStep, nil +} diff --git a/client/core/vm/gas_table_test.go b/client/core/vm/effort_table_test.go similarity index 89% rename from client/core/vm/gas_table_test.go rename to client/core/vm/effort_table_test.go index 1b91aee56..dbf3d24fb 100644 --- a/client/core/vm/gas_table_test.go +++ b/client/core/vm/effort_table_test.go @@ -18,10 +18,10 @@ package vm import "testing" -func TestMemoryGasCost(t *testing.T) { +func TestMemoryEffort(t *testing.T) { //size := uint64(math.MaxUint64 - 64) size := uint64(0xffffffffe0) - v, err := memoryGasCost(&Memory{}, size) + v, err := memoryEffort(&Memory{}, size) if err != nil { t.Error("didn't expect error:", err) } @@ -29,7 +29,7 @@ func TestMemoryGasCost(t *testing.T) { t.Errorf("Expected: 36028899963961341, got %d", v) } - _, err = memoryGasCost(&Memory{}, size+1) + _, err = memoryEffort(&Memory{}, size+1) if err == nil { t.Error("expected error") } diff --git a/client/core/vm/errors.go b/client/core/vm/errors.go index ea33f13f3..9203255d0 100644 --- a/client/core/vm/errors.go +++ b/client/core/vm/errors.go @@ -20,10 +20,10 @@ import "errors" // List execution errors var ( - ErrOutOfGas = errors.New("out of gas") - ErrCodeStoreOutOfGas = errors.New("contract creation code storage out of gas") - ErrDepth = errors.New("max call depth exceeded") - ErrTraceLimitReached = errors.New("the number of logs reached the specified limit") - ErrInsufficientBalance = errors.New("insufficient balance for transfer") - ErrContractAddressCollision = errors.New("contract address collision") + ErrOutOfComputationalResource = errors.New("out of computational resource") + ErrCodeStoreOutOfComputationalResource = errors.New("contract creation code storage out of computational resource") + ErrDepth = errors.New("max call depth exceeded") + ErrTraceLimitReached = errors.New("the number of logs reached the specified limit") + ErrInsufficientBalance = errors.New("insufficient balance for transfer") + ErrContractAddressCollision = errors.New("contract address collision") ) diff --git a/client/core/vm/evm.go b/client/core/vm/evm.go deleted file mode 100644 index 6da9f5a9d..000000000 --- a/client/core/vm/evm.go +++ /dev/null @@ -1,381 +0,0 @@ -package vm - -import ( - "math/big" - "sync/atomic" - "time" - - "github.com/kowala-tech/kcoin/client/common" - "github.com/kowala-tech/kcoin/client/crypto" - "github.com/kowala-tech/kcoin/client/params" -) - -// emptyCodeHash is used by create to ensure deployment is disallowed to already -// deployed contract addresses (relevant after the account abstraction). -var emptyCodeHash = crypto.Keccak256Hash(nil) - -type ( - // CanTransferFunc is the signature of a transfer guard function - CanTransferFunc func(StateDB, common.Address, *big.Int) bool - // TransferFunc is the signature of a transfer function - TransferFunc func(StateDB, common.Address, common.Address, *big.Int) - // GetHashFunc returns the nth block hash in the blockchain - // and is used by the BLOCKHASH EVM op code. - GetHashFunc func(uint64) common.Hash -) - -// run runs the given contract and takes care of running precompiles with a fallback to the byte code interpreter. -func run(evm *EVM, contract *Contract, input []byte) ([]byte, error) { - if contract.CodeAddr != nil { - precompiles := PrecompiledContractsAndromeda - if p := precompiles[*contract.CodeAddr]; p != nil { - return RunPrecompiledContract(p, input, contract) - } - } - return evm.interpreter.Run(contract, input) -} - -// Context provides the EVM with auxiliary information. Once provided -// it shouldn't be modified. -type Context struct { - // CanTransfer returns whether the account contains - // sufficient ether to transfer the value - CanTransfer CanTransferFunc - // Transfer transfers ether from one account to the other - Transfer TransferFunc - // GetHash returns the hash corresponding to n - GetHash GetHashFunc - - // Message information - Origin common.Address // Provides information for ORIGIN - GasPrice *big.Int // Provides information for GASPRICE - - // Block information - Coinbase common.Address // Provides information for COINBASE - GasLimit uint64 // Provides information for GASLIMIT - BlockNumber *big.Int // Provides information for NUMBER - Time *big.Int // Provides information for TIME - Difficulty *big.Int // Provides information for DIFFICULTY -} - -// EVM is the Ethereum Virtual Machine base object and provides -// the necessary tools to run a contract on the given state with -// the provided context. It should be noted that any error -// generated through any of the calls should be considered a -// revert-state-and-consume-all-gas operation, no checks on -// specific errors should ever be performed. The interpreter makes -// sure that any errors generated are to be considered faulty code. -// -// The EVM should never be reused and is not thread safe. -type EVM struct { - // Context provides auxiliary blockchain related information - Context - // StateDB gives access to the underlying state - StateDB StateDB - // Depth is the current call stack - depth int - - // chainConfig contains information about the current chain - chainConfig *params.ChainConfig - // chain rules contains the chain rules for the current epoch - chainRules params.Rules - // virtual machine configuration options used to initialise the - // evm. - vmConfig Config - // global (to this context) ethereum virtual machine - // used throughout the execution of the tx. - interpreter *Interpreter - // abort is used to abort the EVM calling operations - // NOTE: must be set atomically - abort int32 - // callGasTemp holds the gas available for the current call. This is needed because the - // available gas is calculated in gasCall* according to the 63/64 rule and later - // applied in opCall*. - callGasTemp uint64 -} - -// NewEVM returns a new EVM. The returned EVM is not thread safe and should -// only ever be used *once*. -func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) *EVM { - evm := &EVM{ - Context: ctx, - StateDB: statedb, - vmConfig: vmConfig, - chainConfig: chainConfig, - chainRules: chainConfig.Rules(ctx.BlockNumber), - } - - evm.interpreter = NewInterpreter(evm, vmConfig) - return evm -} - -// Cancel cancels any running EVM operation. This may be called concurrently and -// it's safe to be called multiple times. -func (evm *EVM) Cancel() { - atomic.StoreInt32(&evm.abort, 1) -} - -// Call executes the contract associated with the addr with the given input as -// parameters. It also handles any necessary value transfer required and takes -// the necessary steps to create accounts and reverses the state in case of an -// execution error or failed value transfer. -func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) { - if evm.vmConfig.NoRecursion && evm.depth > 0 { - return nil, gas, nil - } - - // Fail if we're trying to execute above the call depth limit - if evm.depth > int(params.CallCreateDepth) { - return nil, gas, ErrDepth - } - // Fail if we're trying to transfer more than the available balance - if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { - return nil, gas, ErrInsufficientBalance - } - - var ( - to = AccountRef(addr) - snapshot = evm.StateDB.Snapshot() - ) - if !evm.StateDB.Exist(addr) { - precompiles := PrecompiledContractsAndromeda - if precompiles[addr] == nil && value.Sign() == 0 { - // Calling a non existing account, don't do antything, but ping the tracer - if evm.vmConfig.Debug && evm.depth == 0 { - evm.vmConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value) - evm.vmConfig.Tracer.CaptureEnd(ret, 0, 0, nil) - } - return nil, gas, nil - } - evm.StateDB.CreateAccount(addr) - } - evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value) - - // Initialise a new contract and set the code that is to be used by the EVM. - // The contract is a scoped environment for this execution context only. - contract := NewContract(caller, to, value, gas) - contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) - - start := time.Now() - - // Capture the tracer start/end events in debug mode - if evm.vmConfig.Debug && evm.depth == 0 { - evm.vmConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value) - - defer func() { // Lazy evaluation of the parameters - evm.vmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err) - }() - } - ret, err = run(evm, contract, input) - - // When an error was returned by the EVM or when setting the creation code - // above we revert to the snapshot and consume any gas remaining. Additionally - // when we're in homestead this also counts for code storage gas errors. - if err != nil { - evm.StateDB.RevertToSnapshot(snapshot) - if err != errExecutionReverted { - contract.UseGas(contract.Gas) - } - } - return ret, contract.Gas, err -} - -// CallCode executes the contract associated with the addr with the given input -// as parameters. It also handles any necessary value transfer required and takes -// the necessary steps to create accounts and reverses the state in case of an -// execution error or failed value transfer. -// -// CallCode differs from Call in the sense that it executes the given address' -// code with the caller as context. -func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) { - if evm.vmConfig.NoRecursion && evm.depth > 0 { - return nil, gas, nil - } - - // Fail if we're trying to execute above the call depth limit - if evm.depth > int(params.CallCreateDepth) { - return nil, gas, ErrDepth - } - // Fail if we're trying to transfer more than the available balance - if !evm.CanTransfer(evm.StateDB, caller.Address(), value) { - return nil, gas, ErrInsufficientBalance - } - - var ( - snapshot = evm.StateDB.Snapshot() - to = AccountRef(caller.Address()) - ) - // initialise a new contract and set the code that is to be used by the - // EVM. The contract is a scoped environment for this execution context - // only. - contract := NewContract(caller, to, value, gas) - contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) - - ret, err = run(evm, contract, input) - if err != nil { - evm.StateDB.RevertToSnapshot(snapshot) - if err != errExecutionReverted { - contract.UseGas(contract.Gas) - } - } - return ret, contract.Gas, err -} - -// DelegateCall executes the contract associated with the addr with the given input -// as parameters. It reverses the state in case of an execution error. -// -// DelegateCall differs from CallCode in the sense that it executes the given address' -// code with the caller as context and the caller is set to the caller of the caller. -func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { - if evm.vmConfig.NoRecursion && evm.depth > 0 { - return nil, gas, nil - } - // Fail if we're trying to execute above the call depth limit - if evm.depth > int(params.CallCreateDepth) { - return nil, gas, ErrDepth - } - - var ( - snapshot = evm.StateDB.Snapshot() - to = AccountRef(caller.Address()) - ) - - // Initialise a new contract and make initialise the delegate values - contract := NewContract(caller, to, nil, gas).AsDelegate() - contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) - - ret, err = run(evm, contract, input) - if err != nil { - evm.StateDB.RevertToSnapshot(snapshot) - if err != errExecutionReverted { - contract.UseGas(contract.Gas) - } - } - return ret, contract.Gas, err -} - -// StaticCall executes the contract associated with the addr with the given input -// as parameters while disallowing any modifications to the state during the call. -// Opcodes that attempt to perform such modifications will result in exceptions -// instead of performing the modifications. -func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { - if evm.vmConfig.NoRecursion && evm.depth > 0 { - return nil, gas, nil - } - // Fail if we're trying to execute above the call depth limit - if evm.depth > int(params.CallCreateDepth) { - return nil, gas, ErrDepth - } - // Make sure the readonly is only set if we aren't in readonly yet - // this makes also sure that the readonly flag isn't removed for - // child calls. - if !evm.interpreter.readOnly { - evm.interpreter.readOnly = true - defer func() { evm.interpreter.readOnly = false }() - } - - var ( - to = AccountRef(addr) - snapshot = evm.StateDB.Snapshot() - ) - // Initialise a new contract and set the code that is to be used by the - // EVM. The contract is a scoped environment for this execution context - // only. - contract := NewContract(caller, to, new(big.Int), gas) - contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) - - // When an error was returned by the EVM or when setting the creation code - // above we revert to the snapshot and consume any gas remaining. Additionally - // when we're in Homestead this also counts for code storage gas errors. - ret, err = run(evm, contract, input) - if err != nil { - evm.StateDB.RevertToSnapshot(snapshot) - if err != errExecutionReverted { - contract.UseGas(contract.Gas) - } - } - return ret, contract.Gas, err -} - -// Create creates a new contract using code as deployment code. -func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { - // Depth check execution. Fail if we're trying to execute above the - // limit. - if evm.depth > int(params.CallCreateDepth) { - return nil, common.Address{}, gas, ErrDepth - } - if !evm.CanTransfer(evm.StateDB, caller.Address(), value) { - return nil, common.Address{}, gas, ErrInsufficientBalance - } - // Ensure there's no existing contract already at the designated address - nonce := evm.StateDB.GetNonce(caller.Address()) - evm.StateDB.SetNonce(caller.Address(), nonce+1) - - contractAddr = crypto.CreateAddress(caller.Address(), nonce) - contractHash := evm.StateDB.GetCodeHash(contractAddr) - if evm.StateDB.GetNonce(contractAddr) != 0 || (contractHash != (common.Hash{}) && contractHash != emptyCodeHash) { - return nil, common.Address{}, 0, ErrContractAddressCollision - } - // Create a new account on the state - snapshot := evm.StateDB.Snapshot() - evm.StateDB.CreateAccount(contractAddr) - evm.StateDB.SetNonce(contractAddr, 1) - - evm.Transfer(evm.StateDB, caller.Address(), contractAddr, value) - - // initialise a new contract and set the code that is to be used by the - // EVM. The contract is a scoped environment for this execution context - // only. - contract := NewContract(caller, AccountRef(contractAddr), value, gas) - contract.SetCallCode(&contractAddr, crypto.Keccak256Hash(code), code) - - if evm.vmConfig.NoRecursion && evm.depth > 0 { - return nil, contractAddr, gas, nil - } - - if evm.vmConfig.Debug && evm.depth == 0 { - evm.vmConfig.Tracer.CaptureStart(caller.Address(), contractAddr, true, code, gas, value) - } - start := time.Now() - - ret, err = run(evm, contract, nil) - - // check whether the max code size has been exceeded - maxCodeSizeExceeded := len(ret) > params.MaxCodeSize - // if the contract creation ran successfully and no errors were returned - // calculate the gas required to store the code. If the code could not - // be stored due to not enough gas set an error and let it be handled - // by the error checking condition below. - if err == nil && !maxCodeSizeExceeded { - createDataGas := uint64(len(ret)) * params.CreateDataGas - if contract.UseGas(createDataGas) { - evm.StateDB.SetCode(contractAddr, ret) - } else { - err = ErrCodeStoreOutOfGas - } - } - - // When an error was returned by the EVM or when setting the creation code - // above we revert to the snapshot and consume any gas remaining. Additionally - // when we're in homestead this also counts for code storage gas errors. - if maxCodeSizeExceeded || (err != nil && err != ErrCodeStoreOutOfGas) { - evm.StateDB.RevertToSnapshot(snapshot) - if err != errExecutionReverted { - contract.UseGas(contract.Gas) - } - } - // Assign err if contract code size exceeds the max while the err is still empty. - if maxCodeSizeExceeded && err == nil { - err = errMaxCodeSizeExceeded - } - if evm.vmConfig.Debug && evm.depth == 0 { - evm.vmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err) - } - return ret, contractAddr, contract.Gas, err -} - -// ChainConfig returns the environment's chain configuration -func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig } - -// Interpreter returns the EVM interpreter -func (evm *EVM) Interpreter() *Interpreter { return evm.interpreter } diff --git a/client/core/vm/gas_table.go b/client/core/vm/gas_table.go deleted file mode 100644 index f789fcfce..000000000 --- a/client/core/vm/gas_table.go +++ /dev/null @@ -1,451 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "github.com/kowala-tech/kcoin/client/common" - "github.com/kowala-tech/kcoin/client/common/math" - "github.com/kowala-tech/kcoin/client/params" -) - -// memoryGasCosts calculates the quadratic gas for memory expansion. It does so -// only for the memory region that is expanded, not the total memory. -func memoryGasCost(mem *Memory, newMemSize uint64) (uint64, error) { - - if newMemSize == 0 { - return 0, nil - } - // The maximum that will fit in a uint64 is max_word_count - 1 - // anything above that will result in an overflow. - // Additionally, a newMemSize which results in a - // newMemSizeWords larger than 0x7ffffffff will cause the square operation - // to overflow. - // The constant 0xffffffffe0 is the highest number that can be used without - // overflowing the gas calculation - if newMemSize > 0xffffffffe0 { - return 0, errGasUintOverflow - } - - newMemSizeWords := toWordSize(newMemSize) - newMemSize = newMemSizeWords * 32 - - if newMemSize > uint64(mem.Len()) { - square := newMemSizeWords * newMemSizeWords - linCoef := newMemSizeWords * params.MemoryGas - quadCoef := square / params.QuadCoeffDiv - newTotalFee := linCoef + quadCoef - - fee := newTotalFee - mem.lastGasCost - mem.lastGasCost = newTotalFee - - return fee, nil - } - return 0, nil -} - -func constGasFunc(gas uint64) gasFunc { - return func(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - return gas, nil - } -} - -func gasCallDataCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - gas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, err - } - - var overflow bool - if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow { - return 0, errGasUintOverflow - } - - words, overflow := bigUint64(stack.Back(2)) - if overflow { - return 0, errGasUintOverflow - } - - if words, overflow = math.SafeMul(toWordSize(words), params.CopyGas); overflow { - return 0, errGasUintOverflow - } - - if gas, overflow = math.SafeAdd(gas, words); overflow { - return 0, errGasUintOverflow - } - return gas, nil -} - -func gasReturnDataCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - gas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, err - } - - var overflow bool - if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow { - return 0, errGasUintOverflow - } - - words, overflow := bigUint64(stack.Back(2)) - if overflow { - return 0, errGasUintOverflow - } - - if words, overflow = math.SafeMul(toWordSize(words), params.CopyGas); overflow { - return 0, errGasUintOverflow - } - - if gas, overflow = math.SafeAdd(gas, words); overflow { - return 0, errGasUintOverflow - } - return gas, nil -} - -func gasSStore(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - var ( - y, x = stack.Back(1), stack.Back(0) - val = evm.StateDB.GetState(contract.Address(), common.BigToHash(x)) - ) - // This checks for 3 scenario's and calculates gas accordingly - // 1. From a zero-value address to a non-zero value (NEW VALUE) - // 2. From a non-zero value address to a zero-value address (DELETE) - // 3. From a non-zero to a non-zero (CHANGE) - if val == (common.Hash{}) && y.Sign() != 0 { - // 0 => non 0 - return params.SstoreSetGas, nil - } else if val != (common.Hash{}) && y.Sign() == 0 { - // non 0 => 0 - evm.StateDB.AddRefund(params.SstoreRefundGas) - return params.SstoreClearGas, nil - } else { - // non 0 => non 0 (or 0 => 0) - return params.SstoreResetGas, nil - } -} - -func makeGasLog(n uint64) gasFunc { - return func(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - requestedSize, overflow := bigUint64(stack.Back(1)) - if overflow { - return 0, errGasUintOverflow - } - - gas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, err - } - - if gas, overflow = math.SafeAdd(gas, params.LogGas); overflow { - return 0, errGasUintOverflow - } - if gas, overflow = math.SafeAdd(gas, n*params.LogTopicGas); overflow { - return 0, errGasUintOverflow - } - - var memorySizeGas uint64 - if memorySizeGas, overflow = math.SafeMul(requestedSize, params.LogDataGas); overflow { - return 0, errGasUintOverflow - } - if gas, overflow = math.SafeAdd(gas, memorySizeGas); overflow { - return 0, errGasUintOverflow - } - return gas, nil - } -} - -func gasSha3(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - var overflow bool - gas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, err - } - - if gas, overflow = math.SafeAdd(gas, params.Sha3Gas); overflow { - return 0, errGasUintOverflow - } - - wordGas, overflow := bigUint64(stack.Back(1)) - if overflow { - return 0, errGasUintOverflow - } - if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.Sha3WordGas); overflow { - return 0, errGasUintOverflow - } - if gas, overflow = math.SafeAdd(gas, wordGas); overflow { - return 0, errGasUintOverflow - } - return gas, nil -} - -func gasCodeCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - gas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, err - } - - var overflow bool - if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow { - return 0, errGasUintOverflow - } - - wordGas, overflow := bigUint64(stack.Back(2)) - if overflow { - return 0, errGasUintOverflow - } - if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.CopyGas); overflow { - return 0, errGasUintOverflow - } - if gas, overflow = math.SafeAdd(gas, wordGas); overflow { - return 0, errGasUintOverflow - } - return gas, nil -} - -func gasExtCodeCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - gas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, err - } - - var overflow bool - if gas, overflow = math.SafeAdd(gas, gt.ExtcodeCopy); overflow { - return 0, errGasUintOverflow - } - - wordGas, overflow := bigUint64(stack.Back(3)) - if overflow { - return 0, errGasUintOverflow - } - - if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.CopyGas); overflow { - return 0, errGasUintOverflow - } - - if gas, overflow = math.SafeAdd(gas, wordGas); overflow { - return 0, errGasUintOverflow - } - return gas, nil -} - -func gasMLoad(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - var overflow bool - gas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, errGasUintOverflow - } - if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow { - return 0, errGasUintOverflow - } - return gas, nil -} - -func gasMStore8(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - var overflow bool - gas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, errGasUintOverflow - } - if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow { - return 0, errGasUintOverflow - } - return gas, nil -} - -func gasMStore(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - var overflow bool - gas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, errGasUintOverflow - } - if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow { - return 0, errGasUintOverflow - } - return gas, nil -} - -func gasCreate(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - var overflow bool - gas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, err - } - if gas, overflow = math.SafeAdd(gas, params.CreateGas); overflow { - return 0, errGasUintOverflow - } - return gas, nil -} - -func gasBalance(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - return gt.Balance, nil -} - -func gasExtCodeSize(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - return gt.ExtcodeSize, nil -} - -func gasSLoad(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - return gt.SLoad, nil -} - -func gasExp(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - expByteLen := uint64((stack.data[stack.len()-2].BitLen() + 7) / 8) - - var ( - gas = expByteLen * gt.ExpByte // no overflow check required. Max is 256 * ExpByte gas - overflow bool - ) - if gas, overflow = math.SafeAdd(gas, GasSlowStep); overflow { - return 0, errGasUintOverflow - } - return gas, nil -} - -func gasCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - var ( - gas = gt.Calls - transfersValue = stack.Back(2).Sign() != 0 - address = common.BigToAddress(stack.Back(1)) - ) - - if transfersValue && evm.StateDB.Empty(address) { - gas += params.CallNewAccountGas - } - - if transfersValue { - gas += params.CallValueTransferGas - } - memoryGas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, err - } - var overflow bool - if gas, overflow = math.SafeAdd(gas, memoryGas); overflow { - return 0, errGasUintOverflow - } - - evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0)) - if err != nil { - return 0, err - } - if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow { - return 0, errGasUintOverflow - } - return gas, nil -} - -func gasCallCode(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - gas := gt.Calls - if stack.Back(2).Sign() != 0 { - gas += params.CallValueTransferGas - } - memoryGas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, err - } - var overflow bool - if gas, overflow = math.SafeAdd(gas, memoryGas); overflow { - return 0, errGasUintOverflow - } - - evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0)) - if err != nil { - return 0, err - } - if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow { - return 0, errGasUintOverflow - } - return gas, nil -} - -func gasReturn(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - return memoryGasCost(mem, memorySize) -} - -func gasRevert(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - return memoryGasCost(mem, memorySize) -} - -func gasSuicide(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - var gas uint64 - - gas = gt.Suicide - var ( - address = common.BigToAddress(stack.Back(0)) - ) - - // if empty and transfers value - if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).Sign() != 0 { - gas += gt.CreateBySuicide - } - - if !evm.StateDB.HasSuicided(contract.Address()) { - evm.StateDB.AddRefund(params.SuicideRefundGas) - } - return gas, nil -} - -func gasDelegateCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - gas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, err - } - var overflow bool - if gas, overflow = math.SafeAdd(gas, gt.Calls); overflow { - return 0, errGasUintOverflow - } - - evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0)) - if err != nil { - return 0, err - } - if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow { - return 0, errGasUintOverflow - } - return gas, nil -} - -func gasStaticCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - gas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, err - } - var overflow bool - if gas, overflow = math.SafeAdd(gas, gt.Calls); overflow { - return 0, errGasUintOverflow - } - - evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0)) - if err != nil { - return 0, err - } - if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow { - return 0, errGasUintOverflow - } - return gas, nil -} - -func gasPush(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - return GasFastestStep, nil -} - -func gasSwap(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - return GasFastestStep, nil -} - -func gasDup(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - return GasFastestStep, nil -} diff --git a/client/core/vm/gen_structlog.go b/client/core/vm/gen_structlog.go index dfb674a3f..dc2df7b3e 100644 --- a/client/core/vm/gen_structlog.go +++ b/client/core/vm/gen_structlog.go @@ -16,24 +16,24 @@ var _ = (*structLogMarshaling)(nil) // MarshalJSON marshals as JSON. func (s StructLog) MarshalJSON() ([]byte, error) { type StructLog struct { - Pc uint64 `json:"pc"` - Op OpCode `json:"op"` - Gas math.HexOrDecimal64 `json:"gas"` - GasCost math.HexOrDecimal64 `json:"gasCost"` - Memory hexutil.Bytes `json:"memory"` - MemorySize int `json:"memSize"` - Stack []*math.HexOrDecimal256 `json:"stack"` - Storage map[common.Hash]common.Hash `json:"-"` - Depth int `json:"depth"` - Err error `json:"-"` - OpName string `json:"opName"` - ErrorString string `json:"error"` + Pc uint64 `json:"pc"` + Op OpCode `json:"op"` + Resource math.HexOrDecimal64 `json:"resource"` + ComputeUnitPrice math.HexOrDecimal64 `json:"compUnitPrice"` + Memory hexutil.Bytes `json:"memory"` + MemorySize int `json:"memSize"` + Stack []*math.HexOrDecimal256 `json:"stack"` + Storage map[common.Hash]common.Hash `json:"-"` + Depth int `json:"depth"` + Err error `json:"-"` + OpName string `json:"opName"` + ErrorString string `json:"error"` } var enc StructLog enc.Pc = s.Pc enc.Op = s.Op - enc.Gas = math.HexOrDecimal64(s.Gas) - enc.GasCost = math.HexOrDecimal64(s.GasCost) + enc.Resource = math.HexOrDecimal64(s.Resource) + enc.ComputeUnitPrice = math.HexOrDecimal64(s.ComputeUnitPrice) enc.Memory = s.Memory enc.MemorySize = s.MemorySize if s.Stack != nil { @@ -53,16 +53,16 @@ func (s StructLog) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals from JSON. func (s *StructLog) UnmarshalJSON(input []byte) error { type StructLog struct { - Pc *uint64 `json:"pc"` - Op *OpCode `json:"op"` - Gas *math.HexOrDecimal64 `json:"gas"` - GasCost *math.HexOrDecimal64 `json:"gasCost"` - Memory *hexutil.Bytes `json:"memory"` - MemorySize *int `json:"memSize"` - Stack []*math.HexOrDecimal256 `json:"stack"` - Storage map[common.Hash]common.Hash `json:"-"` - Depth *int `json:"depth"` - Err error `json:"-"` + Pc *uint64 `json:"pc"` + Op *OpCode `json:"op"` + Resource *math.HexOrDecimal64 `json:"resource"` + ComputeUnitPrice *math.HexOrDecimal64 `json:"compUnitPrice"` + Memory *hexutil.Bytes `json:"memory"` + MemorySize *int `json:"memSize"` + Stack []*math.HexOrDecimal256 `json:"stack"` + Storage map[common.Hash]common.Hash `json:"-"` + Depth *int `json:"depth"` + Err error `json:"-"` } var dec StructLog if err := json.Unmarshal(input, &dec); err != nil { @@ -74,11 +74,11 @@ func (s *StructLog) UnmarshalJSON(input []byte) error { if dec.Op != nil { s.Op = *dec.Op } - if dec.Gas != nil { - s.Gas = uint64(*dec.Gas) + if dec.Resource != nil { + s.Resource = uint64(*dec.Resource) } - if dec.GasCost != nil { - s.GasCost = uint64(*dec.GasCost) + if dec.ComputeUnitPrice != nil { + s.ComputeUnitPrice = uint64(*dec.ComputeUnitPrice) } if dec.Memory != nil { s.Memory = *dec.Memory diff --git a/client/core/vm/instructions.go b/client/core/vm/instructions.go index 485625983..c32e0b148 100644 --- a/client/core/vm/instructions.go +++ b/client/core/vm/instructions.go @@ -25,57 +25,57 @@ import ( "github.com/kowala-tech/kcoin/client/common/math" "github.com/kowala-tech/kcoin/client/core/types" "github.com/kowala-tech/kcoin/client/crypto" - "github.com/kowala-tech/kcoin/client/params" + "github.com/kowala-tech/kcoin/client/params/effort" ) var ( bigZero = new(big.Int) tt255 = math.BigPow(2, 255) - errWriteProtection = errors.New("evm: write protection") - errReturnDataOutOfBounds = errors.New("evm: return data out of bounds") - errExecutionReverted = errors.New("evm: execution reverted") - errMaxCodeSizeExceeded = errors.New("evm: max code size exceeded") + errWriteProtection = errors.New("vm: write protection") + errReturnDataOutOfBounds = errors.New("vm: return data out of bounds") + errExecutionReverted = errors.New("vm: execution reverted") + errMaxCodeSizeExceeded = errors.New("vm: max code size exceeded") ) -func opAdd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opAdd(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.peek() math.U256(y.Add(x, y)) - evm.interpreter.intPool.put(x) + vm.interpreter.intPool.put(x) return nil, nil } -func opSub(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSub(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.peek() math.U256(y.Sub(x, y)) - evm.interpreter.intPool.put(x) + vm.interpreter.intPool.put(x) return nil, nil } -func opMul(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opMul(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.pop() stack.push(math.U256(x.Mul(x, y))) - evm.interpreter.intPool.put(y) + vm.interpreter.intPool.put(y) return nil, nil } -func opDiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opDiv(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.peek() if y.Sign() != 0 { math.U256(y.Div(x, y)) } else { y.SetUint64(0) } - evm.interpreter.intPool.put(x) + vm.interpreter.intPool.put(x) return nil, nil } -func opSdiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSdiv(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := math.S256(stack.pop()), math.S256(stack.pop()) - res := evm.interpreter.intPool.getZero() + res := vm.interpreter.intPool.getZero() if y.Sign() == 0 || x.Sign() == 0 { stack.push(res) @@ -88,24 +88,24 @@ func opSdiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta } stack.push(math.U256(res)) } - evm.interpreter.intPool.put(x, y) + vm.interpreter.intPool.put(x, y) return nil, nil } -func opMod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opMod(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.pop() if y.Sign() == 0 { stack.push(x.SetUint64(0)) } else { stack.push(math.U256(x.Mod(x, y))) } - evm.interpreter.intPool.put(y) + vm.interpreter.intPool.put(y) return nil, nil } -func opSmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSmod(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := math.S256(stack.pop()), math.S256(stack.pop()) - res := evm.interpreter.intPool.getZero() + res := vm.interpreter.intPool.getZero() if y.Sign() == 0 { stack.push(res) @@ -118,20 +118,20 @@ func opSmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta } stack.push(math.U256(res)) } - evm.interpreter.intPool.put(x, y) + vm.interpreter.intPool.put(x, y) return nil, nil } -func opExp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opExp(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { base, exponent := stack.pop(), stack.pop() stack.push(math.Exp(base, exponent)) - evm.interpreter.intPool.put(base, exponent) + vm.interpreter.intPool.put(base, exponent) return nil, nil } -func opSignExtend(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSignExtend(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { back := stack.pop() if back.Cmp(big.NewInt(31)) < 0 { bit := uint(back.Uint64()*8 + 7) @@ -147,39 +147,39 @@ func opSignExtend(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stac stack.push(math.U256(num)) } - evm.interpreter.intPool.put(back) + vm.interpreter.intPool.put(back) return nil, nil } -func opNot(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opNot(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x := stack.peek() math.U256(x.Not(x)) return nil, nil } -func opLt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opLt(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.peek() if x.Cmp(y) < 0 { y.SetUint64(1) } else { y.SetUint64(0) } - evm.interpreter.intPool.put(x) + vm.interpreter.intPool.put(x) return nil, nil } -func opGt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opGt(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.peek() if x.Cmp(y) > 0 { y.SetUint64(1) } else { y.SetUint64(0) } - evm.interpreter.intPool.put(x) + vm.interpreter.intPool.put(x) return nil, nil } -func opSlt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSlt(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.peek() xSign := x.Cmp(tt255) @@ -199,11 +199,11 @@ func opSlt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac y.SetUint64(0) } } - evm.interpreter.intPool.put(x) + vm.interpreter.intPool.put(x) return nil, nil } -func opSgt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSgt(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.peek() xSign := x.Cmp(tt255) @@ -223,22 +223,22 @@ func opSgt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac y.SetUint64(0) } } - evm.interpreter.intPool.put(x) + vm.interpreter.intPool.put(x) return nil, nil } -func opEq(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opEq(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.peek() if x.Cmp(y) == 0 { y.SetUint64(1) } else { y.SetUint64(0) } - evm.interpreter.intPool.put(x) + vm.interpreter.intPool.put(x) return nil, nil } -func opIszero(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opIszero(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x := stack.peek() if x.Sign() > 0 { x.SetUint64(0) @@ -248,31 +248,31 @@ func opIszero(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *S return nil, nil } -func opAnd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opAnd(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.pop() stack.push(x.And(x, y)) - evm.interpreter.intPool.put(y) + vm.interpreter.intPool.put(y) return nil, nil } -func opOr(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opOr(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.peek() y.Or(x, y) - evm.interpreter.intPool.put(x) + vm.interpreter.intPool.put(x) return nil, nil } -func opXor(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opXor(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.peek() y.Xor(x, y) - evm.interpreter.intPool.put(x) + vm.interpreter.intPool.put(x) return nil, nil } -func opByte(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opByte(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { th, val := stack.pop(), stack.peek() if th.Cmp(common.Big32) < 0 { b := math.Byte(val, 32, int(th.Int64())) @@ -280,11 +280,11 @@ func opByte(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta } else { val.SetUint64(0) } - evm.interpreter.intPool.put(th) + vm.interpreter.intPool.put(th) return nil, nil } -func opAddmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opAddmod(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y, z := stack.pop(), stack.pop(), stack.pop() if z.Cmp(bigZero) > 0 { x.Add(x, y) @@ -293,11 +293,11 @@ func opAddmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *S } else { stack.push(x.SetUint64(0)) } - evm.interpreter.intPool.put(y, z) + vm.interpreter.intPool.put(y, z) return nil, nil } -func opMulmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opMulmod(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y, z := stack.pop(), stack.pop(), stack.pop() if z.Cmp(bigZero) > 0 { x.Mul(x, y) @@ -306,17 +306,17 @@ func opMulmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *S } else { stack.push(x.SetUint64(0)) } - evm.interpreter.intPool.put(y, z) + vm.interpreter.intPool.put(y, z) return nil, nil } // opSHL implements Shift Left // The SHL instruction (shift left) pops 2 values from the stack, first arg1 and then arg2, // and pushes on the stack arg2 shifted to the left by arg1 number of bits. -func opSHL(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSHL(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { // Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards shift, value := math.U256(stack.pop()), math.U256(stack.peek()) - defer evm.interpreter.intPool.put(shift) // First operand back into the pool + defer vm.interpreter.intPool.put(shift) // First operand back into the pool if shift.Cmp(common.Big256) >= 0 { value.SetUint64(0) @@ -331,10 +331,10 @@ func opSHL(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac // opSHR implements Logical Shift Right // The SHR instruction (logical shift right) pops 2 values from the stack, first arg1 and then arg2, // and pushes on the stack arg2 shifted to the right by arg1 number of bits with zero fill. -func opSHR(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSHR(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { // Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards shift, value := math.U256(stack.pop()), math.U256(stack.peek()) - defer evm.interpreter.intPool.put(shift) // First operand back into the pool + defer vm.interpreter.intPool.put(shift) // First operand back into the pool if shift.Cmp(common.Big256) >= 0 { value.SetUint64(0) @@ -349,10 +349,10 @@ func opSHR(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac // opSAR implements Arithmetic Shift Right // The SAR instruction (arithmetic shift right) pops 2 values from the stack, first arg1 and then arg2, // and pushes on the stack arg2 shifted to the right by arg1 number of bits with sign extension. -func opSAR(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSAR(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { // Note, S256 returns (potentially) a new bigint, so we're popping, not peeking this one shift, value := math.U256(stack.pop()), math.S256(stack.pop()) - defer evm.interpreter.intPool.put(shift) // First operand back into the pool + defer vm.interpreter.intPool.put(shift) // First operand back into the pool if shift.Cmp(common.Big256) >= 0 { if value.Sign() > 0 { @@ -370,57 +370,57 @@ func opSAR(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac return nil, nil } -func opSha3(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSha3(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { offset, size := stack.pop(), stack.pop() data := memory.Get(offset.Int64(), size.Int64()) hash := crypto.Keccak256(data) - if evm.vmConfig.EnablePreimageRecording { - evm.StateDB.AddPreimage(common.BytesToHash(hash), data) + if vm.vmConfig.EnablePreimageRecording { + vm.StateDB.AddPreimage(common.BytesToHash(hash), data) } - stack.push(evm.interpreter.intPool.get().SetBytes(hash)) + stack.push(vm.interpreter.intPool.get().SetBytes(hash)) - evm.interpreter.intPool.put(offset, size) + vm.interpreter.intPool.put(offset, size) return nil, nil } -func opAddress(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opAddress(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { stack.push(contract.Address().Big()) return nil, nil } -func opBalance(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opBalance(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { slot := stack.peek() - slot.Set(evm.StateDB.GetBalance(common.BigToAddress(slot))) + slot.Set(vm.StateDB.GetBalance(common.BigToAddress(slot))) return nil, nil } -func opOrigin(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(evm.Origin.Big()) +func opOrigin(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(vm.Origin.Big()) return nil, nil } -func opCaller(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opCaller(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { stack.push(contract.Caller().Big()) return nil, nil } -func opCallValue(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(evm.interpreter.intPool.get().Set(contract.value)) +func opCallValue(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(vm.interpreter.intPool.get().Set(contract.value)) return nil, nil } -func opCallDataLoad(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(evm.interpreter.intPool.get().SetBytes(getDataBig(contract.Input, stack.pop(), big32))) +func opCallDataLoad(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(vm.interpreter.intPool.get().SetBytes(getDataBig(contract.Input, stack.pop(), big32))) return nil, nil } -func opCallDataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(evm.interpreter.intPool.get().SetInt64(int64(len(contract.Input)))) +func opCallDataSize(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(vm.interpreter.intPool.get().SetInt64(int64(len(contract.Input)))) return nil, nil } -func opCallDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opCallDataCopy(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { var ( memOffset = stack.pop() dataOffset = stack.pop() @@ -428,48 +428,48 @@ func opCallDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, st ) memory.Set(memOffset.Uint64(), length.Uint64(), getDataBig(contract.Input, dataOffset, length)) - evm.interpreter.intPool.put(memOffset, dataOffset, length) + vm.interpreter.intPool.put(memOffset, dataOffset, length) return nil, nil } -func opReturnDataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(evm.interpreter.intPool.get().SetUint64(uint64(len(evm.interpreter.returnData)))) +func opReturnDataSize(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(vm.interpreter.intPool.get().SetUint64(uint64(len(vm.interpreter.returnData)))) return nil, nil } -func opReturnDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opReturnDataCopy(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { var ( memOffset = stack.pop() dataOffset = stack.pop() length = stack.pop() - end = evm.interpreter.intPool.get().Add(dataOffset, length) + end = vm.interpreter.intPool.get().Add(dataOffset, length) ) - defer evm.interpreter.intPool.put(memOffset, dataOffset, length, end) + defer vm.interpreter.intPool.put(memOffset, dataOffset, length, end) - if end.BitLen() > 64 || uint64(len(evm.interpreter.returnData)) < end.Uint64() { + if end.BitLen() > 64 || uint64(len(vm.interpreter.returnData)) < end.Uint64() { return nil, errReturnDataOutOfBounds } - memory.Set(memOffset.Uint64(), length.Uint64(), evm.interpreter.returnData[dataOffset.Uint64():end.Uint64()]) + memory.Set(memOffset.Uint64(), length.Uint64(), vm.interpreter.returnData[dataOffset.Uint64():end.Uint64()]) return nil, nil } -func opExtCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opExtCodeSize(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { slot := stack.peek() - slot.SetUint64(uint64(evm.StateDB.GetCodeSize(common.BigToAddress(slot)))) + slot.SetUint64(uint64(vm.StateDB.GetCodeSize(common.BigToAddress(slot)))) return nil, nil } -func opCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - l := evm.interpreter.intPool.get().SetInt64(int64(len(contract.Code))) +func opCodeSize(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + l := vm.interpreter.intPool.get().SetInt64(int64(len(contract.Code))) stack.push(l) return nil, nil } -func opCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opCodeCopy(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { var ( memOffset = stack.pop() codeOffset = stack.pop() @@ -478,114 +478,109 @@ func opCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack codeCopy := getDataBig(contract.Code, codeOffset, length) memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) - evm.interpreter.intPool.put(memOffset, codeOffset, length) + vm.interpreter.intPool.put(memOffset, codeOffset, length) return nil, nil } -func opExtCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opExtCodeCopy(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { var ( addr = common.BigToAddress(stack.pop()) memOffset = stack.pop() codeOffset = stack.pop() length = stack.pop() ) - codeCopy := getDataBig(evm.StateDB.GetCode(addr), codeOffset, length) + codeCopy := getDataBig(vm.StateDB.GetCode(addr), codeOffset, length) memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) - evm.interpreter.intPool.put(memOffset, codeOffset, length) + vm.interpreter.intPool.put(memOffset, codeOffset, length) return nil, nil } -func opGasprice(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(evm.interpreter.intPool.get().Set(evm.GasPrice)) +func opComputeUnitPrice(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(vm.interpreter.intPool.get().Set(vm.ComputeUnitPrice)) return nil, nil } -func opBlockhash(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opBlockhash(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { num := stack.pop() - n := evm.interpreter.intPool.get().Sub(evm.BlockNumber, common.Big257) - if num.Cmp(n) > 0 && num.Cmp(evm.BlockNumber) < 0 { - stack.push(evm.GetHash(num.Uint64()).Big()) + n := vm.interpreter.intPool.get().Sub(vm.BlockNumber, common.Big257) + if num.Cmp(n) > 0 && num.Cmp(vm.BlockNumber) < 0 { + stack.push(vm.GetHash(num.Uint64()).Big()) } else { - stack.push(evm.interpreter.intPool.getZero()) + stack.push(vm.interpreter.intPool.getZero()) } - evm.interpreter.intPool.put(num, n) + vm.interpreter.intPool.put(num, n) return nil, nil } -func opCoinbase(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(evm.Coinbase.Big()) +func opCoinbase(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(vm.Coinbase.Big()) return nil, nil } -func opTimestamp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(math.U256(evm.interpreter.intPool.get().Set(evm.Time))) +func opTimestamp(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(math.U256(vm.interpreter.intPool.get().Set(vm.Time))) return nil, nil } -func opNumber(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(math.U256(evm.interpreter.intPool.get().Set(evm.BlockNumber))) +func opNumber(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(math.U256(vm.interpreter.intPool.get().Set(vm.BlockNumber))) return nil, nil } -func opDifficulty(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(math.U256(evm.interpreter.intPool.get().Set(evm.Difficulty))) +func opComputeCapacity(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(math.U256(vm.interpreter.intPool.get().SetUint64(vm.ComputeCapacity))) return nil, nil } -func opGasLimit(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(math.U256(evm.interpreter.intPool.get().SetUint64(evm.GasLimit))) +func opPop(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + vm.interpreter.intPool.put(stack.pop()) return nil, nil } -func opPop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - evm.interpreter.intPool.put(stack.pop()) - return nil, nil -} - -func opMload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opMload(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { offset := stack.pop() - val := evm.interpreter.intPool.get().SetBytes(memory.Get(offset.Int64(), 32)) + val := vm.interpreter.intPool.get().SetBytes(memory.Get(offset.Int64(), 32)) stack.push(val) - evm.interpreter.intPool.put(offset) + vm.interpreter.intPool.put(offset) return nil, nil } -func opMstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opMstore(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { // pop value of the stack mStart, val := stack.pop(), stack.pop() memory.Set32(mStart.Uint64(), val) - evm.interpreter.intPool.put(mStart, val) + vm.interpreter.intPool.put(mStart, val) return nil, nil } -func opMstore8(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opMstore8(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { off, val := stack.pop().Int64(), stack.pop().Int64() memory.store[off] = byte(val & 0xff) return nil, nil } -func opSload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSload(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { loc := stack.peek() - val := evm.StateDB.GetState(contract.Address(), common.BigToHash(loc)) + val := vm.StateDB.GetState(contract.Address(), common.BigToHash(loc)) loc.SetBytes(val.Bytes()) return nil, nil } -func opSstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSstore(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { loc := common.BigToHash(stack.pop()) val := stack.pop() - evm.StateDB.SetState(contract.Address(), loc, common.BigToHash(val)) + vm.StateDB.SetState(contract.Address(), loc, common.BigToHash(val)) - evm.interpreter.intPool.put(val) + vm.interpreter.intPool.put(val) return nil, nil } -func opJump(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opJump(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { pos := stack.pop() if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) { nop := contract.GetOp(pos.Uint64()) @@ -593,11 +588,11 @@ func opJump(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta } *pc = pos.Uint64() - evm.interpreter.intPool.put(pos) + vm.interpreter.intPool.put(pos) return nil, nil } -func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opJumpi(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { pos, cond := stack.pop(), stack.pop() if cond.Sign() != 0 { if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) { @@ -609,54 +604,54 @@ func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *St *pc++ } - evm.interpreter.intPool.put(pos, cond) + vm.interpreter.intPool.put(pos, cond) return nil, nil } -func opJumpdest(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opJumpdest(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { return nil, nil } -func opPc(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(evm.interpreter.intPool.get().SetUint64(*pc)) +func opPc(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(vm.interpreter.intPool.get().SetUint64(*pc)) return nil, nil } -func opMsize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(evm.interpreter.intPool.get().SetInt64(int64(memory.Len()))) +func opMsize(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(vm.interpreter.intPool.get().SetInt64(int64(memory.Len()))) return nil, nil } -func opGas(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(evm.interpreter.intPool.get().SetUint64(contract.Gas)) +func opResourceLeft(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(vm.interpreter.intPool.get().SetUint64(contract.ComputationalResource)) return nil, nil } -func opCreate(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opCreate(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { var ( value = stack.pop() offset, size = stack.pop(), stack.pop() input = memory.Get(offset.Int64(), size.Int64()) - gas = contract.Gas + resource = contract.ComputationalResource ) - gas -= gas / 64 + resource -= resource / 64 - contract.UseGas(gas) - res, addr, returnGas, suberr := evm.Create(contract, input, gas, value) + contract.UseResource(resource) + res, addr, returnResource, suberr := vm.Create(contract, input, resource, value) // Push item on the stack based on the returned error. If the ruleset is - // homestead we must check for CodeStoreOutOfGasError (homestead only + // homestead we must check for CodeStoreOutOfComputationalResourceError (homestead only // rule) and treat as an error, if the ruleset is frontier we must // ignore this error and pretend the operation was successful. - if suberr == ErrCodeStoreOutOfGas { - stack.push(evm.interpreter.intPool.getZero()) - } else if suberr != nil && suberr != ErrCodeStoreOutOfGas { - stack.push(evm.interpreter.intPool.getZero()) + if suberr == ErrCodeStoreOutOfComputationalResource { + stack.push(vm.interpreter.intPool.getZero()) + } else if suberr != nil && suberr != ErrCodeStoreOutOfComputationalResource { + stack.push(vm.interpreter.intPool.getZero()) } else { stack.push(addr.Big()) } - contract.Gas += returnGas - evm.interpreter.intPool.put(value, offset, size) + contract.ComputationalResource += returnResource + vm.interpreter.intPool.put(value, offset, size) if suberr == errExecutionReverted { return res, nil @@ -664,10 +659,10 @@ func opCreate(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *S return nil, nil } -func opCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - // Pop gas. The actual gas in in evm.callGasTemp. - evm.interpreter.intPool.put(stack.pop()) - gas := evm.callGasTemp +func opCall(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + // Pop computational resource. The actual resource in in vm.callResourceTemp. + vm.interpreter.intPool.put(stack.pop()) + resource := vm.callResourceTemp // Pop other call parameters. addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() toAddr := common.BigToAddress(addr) @@ -676,27 +671,27 @@ func opCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta args := memory.Get(inOffset.Int64(), inSize.Int64()) if value.Sign() != 0 { - gas += params.CallStipend + resource += effort.CallStipend } - ret, returnGas, err := evm.Call(contract, toAddr, args, gas, value) + ret, returnResource, err := vm.Call(contract, toAddr, args, resource, value) if err != nil { - stack.push(evm.interpreter.intPool.getZero()) + stack.push(vm.interpreter.intPool.getZero()) } else { - stack.push(evm.interpreter.intPool.get().SetUint64(1)) + stack.push(vm.interpreter.intPool.get().SetUint64(1)) } if err == nil || err == errExecutionReverted { memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) } - contract.Gas += returnGas + contract.ComputationalResource += returnResource - evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) + vm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) return ret, nil } -func opCallCode(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - // Pop gas. The actual gas is in evm.callGasTemp. - evm.interpreter.intPool.put(stack.pop()) - gas := evm.callGasTemp +func opCallCode(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + // Pop computational resource. The actual resource is in vm.callResourceTemp. + vm.interpreter.intPool.put(stack.pop()) + resource := vm.callResourceTemp // Pop other call parameters. addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() toAddr := common.BigToAddress(addr) @@ -705,98 +700,98 @@ func opCallCode(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack args := memory.Get(inOffset.Int64(), inSize.Int64()) if value.Sign() != 0 { - gas += params.CallStipend + resource += effort.CallStipend } - ret, returnGas, err := evm.CallCode(contract, toAddr, args, gas, value) + ret, returnResource, err := vm.CallCode(contract, toAddr, args, resource, value) if err != nil { - stack.push(evm.interpreter.intPool.getZero()) + stack.push(vm.interpreter.intPool.getZero()) } else { - stack.push(evm.interpreter.intPool.get().SetUint64(1)) + stack.push(vm.interpreter.intPool.get().SetUint64(1)) } if err == nil || err == errExecutionReverted { memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) } - contract.Gas += returnGas + contract.ComputationalResource += returnResource - evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) + vm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) return ret, nil } -func opDelegateCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - // Pop gas. The actual gas is in evm.callGasTemp. - evm.interpreter.intPool.put(stack.pop()) - gas := evm.callGasTemp +func opDelegateCall(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + // Pop computational resource. The actual resource is in vm.callResourceTemp. + vm.interpreter.intPool.put(stack.pop()) + resource := vm.callResourceTemp // Pop other call parameters. addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() toAddr := common.BigToAddress(addr) // Get arguments from the memory. args := memory.Get(inOffset.Int64(), inSize.Int64()) - ret, returnGas, err := evm.DelegateCall(contract, toAddr, args, gas) + ret, returnResource, err := vm.DelegateCall(contract, toAddr, args, resource) if err != nil { - stack.push(evm.interpreter.intPool.getZero()) + stack.push(vm.interpreter.intPool.getZero()) } else { - stack.push(evm.interpreter.intPool.get().SetUint64(1)) + stack.push(vm.interpreter.intPool.get().SetUint64(1)) } if err == nil || err == errExecutionReverted { memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) } - contract.Gas += returnGas + contract.ComputationalResource += returnResource - evm.interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize) + vm.interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize) return ret, nil } -func opStaticCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - // Pop gas. The actual gas is in evm.callGasTemp. - evm.interpreter.intPool.put(stack.pop()) - gas := evm.callGasTemp +func opStaticCall(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + // Pop computational resource. The actual resource is in vm.callResourceTemp. + vm.interpreter.intPool.put(stack.pop()) + resource := vm.callResourceTemp // Pop other call parameters. addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() toAddr := common.BigToAddress(addr) // Get arguments from the memory. args := memory.Get(inOffset.Int64(), inSize.Int64()) - ret, returnGas, err := evm.StaticCall(contract, toAddr, args, gas) + ret, returnResource, err := vm.StaticCall(contract, toAddr, args, resource) if err != nil { - stack.push(evm.interpreter.intPool.getZero()) + stack.push(vm.interpreter.intPool.getZero()) } else { - stack.push(evm.interpreter.intPool.get().SetUint64(1)) + stack.push(vm.interpreter.intPool.get().SetUint64(1)) } if err == nil || err == errExecutionReverted { memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) } - contract.Gas += returnGas + contract.ComputationalResource += returnResource - evm.interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize) + vm.interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize) return ret, nil } -func opReturn(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opReturn(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { offset, size := stack.pop(), stack.pop() ret := memory.GetPtr(offset.Int64(), size.Int64()) - evm.interpreter.intPool.put(offset, size) + vm.interpreter.intPool.put(offset, size) return ret, nil } -func opRevert(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opRevert(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { offset, size := stack.pop(), stack.pop() ret := memory.GetPtr(offset.Int64(), size.Int64()) - evm.interpreter.intPool.put(offset, size) + vm.interpreter.intPool.put(offset, size) return ret, nil } -func opStop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opStop(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { return nil, nil } -func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - balance := evm.StateDB.GetBalance(contract.Address()) - evm.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance) +func opSuicide(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + balance := vm.StateDB.GetBalance(contract.Address()) + vm.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance) - evm.StateDB.Suicide(contract.Address()) + vm.StateDB.Suicide(contract.Address()) return nil, nil } @@ -804,7 +799,7 @@ func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack * // make log instruction function func makeLog(size int) executionFunc { - return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + return func(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { topics := make([]common.Hash, size) mStart, mSize := stack.pop(), stack.pop() for i := 0; i < size; i++ { @@ -812,23 +807,23 @@ func makeLog(size int) executionFunc { } d := memory.Get(mStart.Int64(), mSize.Int64()) - evm.StateDB.AddLog(&types.Log{ + vm.StateDB.AddLog(&types.Log{ Address: contract.Address(), Topics: topics, Data: d, // This is a non-consensus field, but assigned here because // core/state doesn't know the current block number. - BlockNumber: evm.BlockNumber.Uint64(), + BlockNumber: vm.BlockNumber.Uint64(), }) - evm.interpreter.intPool.put(mStart, mSize) + vm.interpreter.intPool.put(mStart, mSize) return nil, nil } } // make push instruction function func makePush(size uint64, pushByteSize int) executionFunc { - return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + return func(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { codeLen := len(contract.Code) startMin := codeLen @@ -841,7 +836,7 @@ func makePush(size uint64, pushByteSize int) executionFunc { endMin = startMin + pushByteSize } - integer := evm.interpreter.intPool.get() + integer := vm.interpreter.intPool.get() stack.push(integer.SetBytes(common.RightPadBytes(contract.Code[startMin:endMin], pushByteSize))) *pc += size @@ -851,8 +846,8 @@ func makePush(size uint64, pushByteSize int) executionFunc { // make dup instruction function func makeDup(size int64) executionFunc { - return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.dup(evm.interpreter.intPool, int(size)) + return func(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.dup(vm.interpreter.intPool, int(size)) return nil, nil } } @@ -861,7 +856,7 @@ func makeDup(size int64) executionFunc { func makeSwap(size int64) executionFunc { // switch n + 1 otherwise n would be swapped with n size++ - return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + return func(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { stack.swap(int(size)) return nil, nil } diff --git a/client/core/vm/instructions_test.go b/client/core/vm/instructions_test.go index d4c932166..c5cf520af 100644 --- a/client/core/vm/instructions_test.go +++ b/client/core/vm/instructions_test.go @@ -14,7 +14,7 @@ type twoOperandTest struct { expected string } -func testTwoOperandOp(t *testing.T, tests []twoOperandTest, opFn func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)) { +func testTwoOperandOp(t *testing.T, tests []twoOperandTest, opFn func(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)) { var ( env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}) stack = newstack() @@ -184,7 +184,7 @@ func TestSLT(t *testing.T) { testTwoOperandOp(t, tests, opSlt) } -func opBenchmark(bench *testing.B, op func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error), args ...string) { +func opBenchmark(bench *testing.B, op func(pc *uint64, vm *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error), args ...string) { var ( env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}) stack = newstack() diff --git a/client/core/vm/interface.go b/client/core/vm/interface.go index f6e7577d7..ed7592a27 100644 --- a/client/core/vm/interface.go +++ b/client/core/vm/interface.go @@ -23,7 +23,7 @@ import ( "github.com/kowala-tech/kcoin/client/core/types" ) -// StateDB is an EVM database for full state querying. +// StateDB is a VM database for full state querying. type StateDB interface { CreateAccount(common.Address) @@ -64,15 +64,15 @@ type StateDB interface { ForEachStorage(common.Address, func(common.Hash, common.Hash) bool) } -// CallContext provides a basic interface for the EVM calling conventions. The EVM EVM -// depends on this context being implemented for doing subcalls and initialising new EVM contracts. +// CallContext provides a basic interface for the VM calling conventions. The VM depends +// on this context being implemented for doing subcalls and initialising new VM contracts. type CallContext interface { // Call another contract - Call(env *EVM, me ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error) + Call(env *VM, me ContractRef, addr common.Address, data []byte, computeLimit, value *big.Int) ([]byte, error) // Take another's contract code and execute within our own context - CallCode(env *EVM, me ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error) + CallCode(env *VM, me ContractRef, addr common.Address, data []byte, computeLimit, value *big.Int) ([]byte, error) // Same as CallCode except sender and value is propagated from parent to child scope - DelegateCall(env *EVM, me ContractRef, addr common.Address, data []byte, gas *big.Int) ([]byte, error) + DelegateCall(env *VM, me ContractRef, addr common.Address, data []byte, computeLimit *big.Int) ([]byte, error) // Create a new contract - Create(env *EVM, me ContractRef, data []byte, gas, value *big.Int) ([]byte, common.Address, error) + Create(env *VM, me ContractRef, data []byte, computeLimit, value *big.Int) ([]byte, common.Address, error) } diff --git a/client/core/vm/interpreter.go b/client/core/vm/interpreter.go index 0b3fa8409..8d25e9630 100644 --- a/client/core/vm/interpreter.go +++ b/client/core/vm/interpreter.go @@ -19,9 +19,9 @@ package vm import ( "fmt" "sync/atomic" - + "github.com/kowala-tech/kcoin/client/common/math" - "github.com/kowala-tech/kcoin/client/params" + "github.com/kowala-tech/kcoin/client/params/effort" ) // Config are the configuration options for the Interpreter @@ -35,28 +35,28 @@ type Config struct { NoRecursion bool // Enable recording of SHA3/keccak preimages EnablePreimageRecording bool - // JumpTable contains the EVM instruction table. This + // JumpTable contains the VM instruction table. This // may be left uninitialised and will be set to the default // table. JumpTable [256]operation } -// Interpreter is used to run Ethereum based contracts and will utilise the +// Interpreter is used to run contracts and will utilise the // passed environment to query external sources for state information. // The Interpreter will run the byte code VM based on the passed // configuration. type Interpreter struct { - evm *EVM - cfg Config - gasTable params.GasTable - intPool *intPool + vm *VM + cfg Config + requirements effort.Table + intPool *intPool readOnly bool // Whether to throw on stateful modifications returnData []byte // Last CALL's return data for subsequent reuse } // NewInterpreter returns a new instance of the Interpreter. -func NewInterpreter(evm *EVM, cfg Config) *Interpreter { +func NewInterpreter(vm *VM, cfg Config) *Interpreter { // We use the STOP instruction whether to see // the jump table was initialised. If it was not // we'll set the default jump table. @@ -68,9 +68,9 @@ func NewInterpreter(evm *EVM, cfg Config) *Interpreter { } return &Interpreter{ - evm: evm, - cfg: cfg, - gasTable: evm.ChainConfig().GasTable(evm.BlockNumber), + vm: vm, + cfg: cfg, + requirements: vm.ChainConfig().ComputationalRequirements(vm.BlockNumber), } } @@ -92,8 +92,8 @@ func (in *Interpreter) enforceRestrictions(op OpCode, operation operation, stack // the return byte-slice and an error if one occurred. // // It's important to note that any errors returned by the interpreter should be -// considered a revert-and-consume-all-gas operation except for -// errExecutionReverted which means revert-and-keep-gas-left. +// considered a revert-and-consume-all-computational-resource operation except for +// errExecutionReverted which means revert-and-keep-computational-resource-left. func (in *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err error) { if in.intPool == nil { in.intPool = poolOfIntPools.get() @@ -104,8 +104,8 @@ func (in *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err er } // Increment the call depth which is restricted to 1024 - in.evm.depth++ - defer func() { in.evm.depth-- }() + in.vm.depth++ + defer func() { in.vm.depth-- }() // Reset the previous call's return data. It's unimportant to preserve the old buffer // as every returning call will return new data anyway. @@ -126,9 +126,9 @@ func (in *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err er pc = uint64(0) // program counter cost uint64 // copies used by tracer - pcCopy uint64 // needed for the deferred Tracer - gasCopy uint64 // for Tracer to log gas remaining before execution - logged bool // deferred Tracer should ignore already logged steps + pcCopy uint64 // needed for the deferred Tracer + resourceCopy uint64 // for Tracer to log resource remaining before execution + logged bool // deferred Tracer should ignore already logged steps ) contract.Input = input @@ -139,9 +139,9 @@ func (in *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err er defer func() { if err != nil { if !logged { - in.cfg.Tracer.CaptureState(in.evm, pcCopy, op, gasCopy, cost, mem, stack, contract, in.evm.depth, err) + in.cfg.Tracer.CaptureState(in.vm, pcCopy, op, resourceCopy, cost, mem, stack, contract, in.vm.depth, err) } else { - in.cfg.Tracer.CaptureFault(in.evm, pcCopy, op, gasCopy, cost, mem, stack, contract, in.evm.depth, err) + in.cfg.Tracer.CaptureFault(in.vm, pcCopy, op, resourceCopy, cost, mem, stack, contract, in.vm.depth, err) } } }() @@ -150,10 +150,10 @@ func (in *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err er // explicit STOP, RETURN or SELFDESTRUCT is executed, an error occurred during // the execution of one of the operations or until the done flag is set by the // parent context. - for atomic.LoadInt32(&in.evm.abort) == 0 { + for atomic.LoadInt32(&in.vm.abort) == 0 { if in.cfg.Debug { // Capture pre-execution values for tracing. - logged, pcCopy, gasCopy = false, pc, contract.Gas + logged, pcCopy, resourceCopy = false, pc, contract.ComputationalResource } // Get the operation from the jump table and validate the stack to ensure there are @@ -177,31 +177,31 @@ func (in *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err er if operation.memorySize != nil { memSize, overflow := bigUint64(operation.memorySize(stack)) if overflow { - return nil, errGasUintOverflow + return nil, errEffortUintOverflow } - // memory is expanded in words of 32 bytes. Gas + // memory is expanded in words of 32 bytes. Computational effort // is also calculated in words. if memorySize, overflow = math.SafeMul(toWordSize(memSize), 32); overflow { - return nil, errGasUintOverflow + return nil, errEffortUintOverflow } } - // consume the gas and return an error if not enough gas is available. + // consume the computational resource and return an error if not enough resource is available. // cost is explicitly set so that the capture state defer method can get the proper cost - cost, err = operation.gasCost(in.gasTable, in.evm, contract, stack, mem, memorySize) - if err != nil || !contract.UseGas(cost) { - return nil, ErrOutOfGas + cost, err = operation.computationalEffort(in.requirements, in.vm, contract, stack, mem, memorySize) + if err != nil || !contract.UseResource(cost) { + return nil, ErrOutOfComputationalResource } if memorySize > 0 { mem.Resize(memorySize) } if in.cfg.Debug { - in.cfg.Tracer.CaptureState(in.evm, pc, op, gasCopy, cost, mem, stack, contract, in.evm.depth, err) + in.cfg.Tracer.CaptureState(in.vm, pc, op, resourceCopy, cost, mem, stack, contract, in.vm.depth, err) logged = true } // execute the operation - res, err := operation.execute(&pc, in.evm, contract, mem, stack) + res, err := operation.execute(&pc, in.vm, contract, mem, stack) // verifyPool is a build flag. Pool verification makes sure the integrity // of the integer pool by comparing values to a default value. if verifyPool { diff --git a/client/core/vm/jump_table.go b/client/core/vm/jump_table.go index d46faa3ce..07a0d929b 100644 --- a/client/core/vm/jump_table.go +++ b/client/core/vm/jump_table.go @@ -4,23 +4,23 @@ import ( "errors" "math/big" - "github.com/kowala-tech/kcoin/client/params" + "github.com/kowala-tech/kcoin/client/params/effort" ) type ( - executionFunc func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) - gasFunc func(params.GasTable, *EVM, *Contract, *Stack, *Memory, uint64) (uint64, error) // last parameter is the requested memory size as a uint64 + executionFunc func(pc *uint64, env *VM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) + effortFunc func(effort.Table, *VM, *Contract, *Stack, *Memory, uint64) (uint64, error) // last parameter is the requested memory size as a uint64 stackValidationFunc func(*Stack) error memorySizeFunc func(*Stack) *big.Int ) -var errGasUintOverflow = errors.New("gas uint64 overflow") +var errEffortUintOverflow = errors.New("effort uint64 overflow") type operation struct { // execute is the operation function execute executionFunc - // gasCost is the gas function and returns the gas required for execution - gasCost gasFunc + // computationalEffort is the effort function and returns the required computational effort for execution + computationalEffort effortFunc // validateStack validates the stack (size) for the operation validateStack stackValidationFunc // memorySize returns the memory size required for the operation @@ -43,867 +43,861 @@ var ( func NewAndromedaInstructionSet() [256]operation { return [256]operation{ STOP: { - execute: opStop, - gasCost: constGasFunc(0), - validateStack: makeStackFunc(0, 0), - halts: true, - valid: true, + execute: opStop, + computationalEffort: constEffortFunc(0), + validateStack: makeStackFunc(0, 0), + halts: true, + valid: true, }, ADD: { - execute: opAdd, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, + execute: opAdd, + computationalEffort: constEffortFunc(EffortFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, }, MUL: { - execute: opMul, - gasCost: constGasFunc(GasFastStep), - validateStack: makeStackFunc(2, 1), - valid: true, + execute: opMul, + computationalEffort: constEffortFunc(EffortFastStep), + validateStack: makeStackFunc(2, 1), + valid: true, }, SUB: { - execute: opSub, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, + execute: opSub, + computationalEffort: constEffortFunc(EffortFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, }, DIV: { - execute: opDiv, - gasCost: constGasFunc(GasFastStep), - validateStack: makeStackFunc(2, 1), - valid: true, + execute: opDiv, + computationalEffort: constEffortFunc(EffortFastStep), + validateStack: makeStackFunc(2, 1), + valid: true, }, SDIV: { - execute: opSdiv, - gasCost: constGasFunc(GasFastStep), - validateStack: makeStackFunc(2, 1), - valid: true, + execute: opSdiv, + computationalEffort: constEffortFunc(EffortFastStep), + validateStack: makeStackFunc(2, 1), + valid: true, }, MOD: { - execute: opMod, - gasCost: constGasFunc(GasFastStep), - validateStack: makeStackFunc(2, 1), - valid: true, + execute: opMod, + computationalEffort: constEffortFunc(EffortFastStep), + validateStack: makeStackFunc(2, 1), + valid: true, }, SMOD: { - execute: opSmod, - gasCost: constGasFunc(GasFastStep), - validateStack: makeStackFunc(2, 1), - valid: true, + execute: opSmod, + computationalEffort: constEffortFunc(EffortFastStep), + validateStack: makeStackFunc(2, 1), + valid: true, }, ADDMOD: { - execute: opAddmod, - gasCost: constGasFunc(GasMidStep), - validateStack: makeStackFunc(3, 1), - valid: true, + execute: opAddmod, + computationalEffort: constEffortFunc(EffortMidStep), + validateStack: makeStackFunc(3, 1), + valid: true, }, MULMOD: { - execute: opMulmod, - gasCost: constGasFunc(GasMidStep), - validateStack: makeStackFunc(3, 1), - valid: true, + execute: opMulmod, + computationalEffort: constEffortFunc(EffortMidStep), + validateStack: makeStackFunc(3, 1), + valid: true, }, EXP: { - execute: opExp, - gasCost: gasExp, - validateStack: makeStackFunc(2, 1), - valid: true, + execute: opExp, + computationalEffort: effortExp, + validateStack: makeStackFunc(2, 1), + valid: true, }, SIGNEXTEND: { - execute: opSignExtend, - gasCost: constGasFunc(GasFastStep), - validateStack: makeStackFunc(2, 1), - valid: true, + execute: opSignExtend, + computationalEffort: constEffortFunc(EffortFastStep), + validateStack: makeStackFunc(2, 1), + valid: true, }, LT: { - execute: opLt, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, + execute: opLt, + computationalEffort: constEffortFunc(EffortFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, }, GT: { - execute: opGt, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, + execute: opGt, + computationalEffort: constEffortFunc(EffortFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, }, SLT: { - execute: opSlt, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, + execute: opSlt, + computationalEffort: constEffortFunc(EffortFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, }, SGT: { - execute: opSgt, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, + execute: opSgt, + computationalEffort: constEffortFunc(EffortFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, }, EQ: { - execute: opEq, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, + execute: opEq, + computationalEffort: constEffortFunc(EffortFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, }, ISZERO: { - execute: opIszero, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(1, 1), - valid: true, + execute: opIszero, + computationalEffort: constEffortFunc(EffortFastestStep), + validateStack: makeStackFunc(1, 1), + valid: true, }, AND: { - execute: opAnd, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, + execute: opAnd, + computationalEffort: constEffortFunc(EffortFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, }, XOR: { - execute: opXor, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, + execute: opXor, + computationalEffort: constEffortFunc(EffortFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, }, OR: { - execute: opOr, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, + execute: opOr, + computationalEffort: constEffortFunc(EffortFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, }, NOT: { - execute: opNot, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(1, 1), - valid: true, + execute: opNot, + computationalEffort: constEffortFunc(EffortFastestStep), + validateStack: makeStackFunc(1, 1), + valid: true, }, BYTE: { - execute: opByte, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, + execute: opByte, + computationalEffort: constEffortFunc(EffortFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, }, SHA3: { - execute: opSha3, - gasCost: gasSha3, - validateStack: makeStackFunc(2, 1), - memorySize: memorySha3, - valid: true, + execute: opSha3, + computationalEffort: effortSha3, + validateStack: makeStackFunc(2, 1), + memorySize: memorySha3, + valid: true, }, ADDRESS: { - execute: opAddress, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, + execute: opAddress, + computationalEffort: constEffortFunc(EffortQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, }, BALANCE: { - execute: opBalance, - gasCost: gasBalance, - validateStack: makeStackFunc(1, 1), - valid: true, + execute: opBalance, + computationalEffort: effortBalance, + validateStack: makeStackFunc(1, 1), + valid: true, }, ORIGIN: { - execute: opOrigin, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, + execute: opOrigin, + computationalEffort: constEffortFunc(EffortQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, }, CALLER: { - execute: opCaller, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, + execute: opCaller, + computationalEffort: constEffortFunc(EffortQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, }, CALLVALUE: { - execute: opCallValue, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, + execute: opCallValue, + computationalEffort: constEffortFunc(EffortQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, }, CALLDATALOAD: { - execute: opCallDataLoad, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(1, 1), - valid: true, + execute: opCallDataLoad, + computationalEffort: constEffortFunc(EffortFastestStep), + validateStack: makeStackFunc(1, 1), + valid: true, }, CALLDATASIZE: { - execute: opCallDataSize, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, + execute: opCallDataSize, + computationalEffort: constEffortFunc(EffortQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, }, CALLDATACOPY: { - execute: opCallDataCopy, - gasCost: gasCallDataCopy, - validateStack: makeStackFunc(3, 0), - memorySize: memoryCallDataCopy, - valid: true, + execute: opCallDataCopy, + computationalEffort: effortCallDataCopy, + validateStack: makeStackFunc(3, 0), + memorySize: memoryCallDataCopy, + valid: true, }, CODESIZE: { - execute: opCodeSize, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, + execute: opCodeSize, + computationalEffort: constEffortFunc(EffortQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, }, CODECOPY: { - execute: opCodeCopy, - gasCost: gasCodeCopy, - validateStack: makeStackFunc(3, 0), - memorySize: memoryCodeCopy, - valid: true, - }, - GASPRICE: { - execute: opGasprice, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, + execute: opCodeCopy, + computationalEffort: effortCodeCopy, + validateStack: makeStackFunc(3, 0), + memorySize: memoryCodeCopy, + valid: true, + }, + COMPUTEUNITPRICE: { + execute: opComputeUnitPrice, + computationalEffort: constEffortFunc(EffortQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, }, EXTCODESIZE: { - execute: opExtCodeSize, - gasCost: gasExtCodeSize, - validateStack: makeStackFunc(1, 1), - valid: true, + execute: opExtCodeSize, + computationalEffort: effortExtCodeSize, + validateStack: makeStackFunc(1, 1), + valid: true, }, EXTCODECOPY: { - execute: opExtCodeCopy, - gasCost: gasExtCodeCopy, - validateStack: makeStackFunc(4, 0), - memorySize: memoryExtCodeCopy, - valid: true, + execute: opExtCodeCopy, + computationalEffort: effortExtCodeCopy, + validateStack: makeStackFunc(4, 0), + memorySize: memoryExtCodeCopy, + valid: true, }, BLOCKHASH: { - execute: opBlockhash, - gasCost: constGasFunc(GasExtStep), - validateStack: makeStackFunc(1, 1), - valid: true, + execute: opBlockhash, + computationalEffort: constEffortFunc(EffortExtStep), + validateStack: makeStackFunc(1, 1), + valid: true, }, COINBASE: { - execute: opCoinbase, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, + execute: opCoinbase, + computationalEffort: constEffortFunc(EffortQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, }, TIMESTAMP: { - execute: opTimestamp, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, + execute: opTimestamp, + computationalEffort: constEffortFunc(EffortQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, }, NUMBER: { - execute: opNumber, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, - }, - DIFFICULTY: { - execute: opDifficulty, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, - }, - GASLIMIT: { - execute: opGasLimit, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, + execute: opNumber, + computationalEffort: constEffortFunc(EffortQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, + }, + COMPUTECAPACITY: { + execute: opComputeCapacity, + computationalEffort: constEffortFunc(EffortQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, }, POP: { - execute: opPop, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(1, 0), - valid: true, + execute: opPop, + computationalEffort: constEffortFunc(EffortQuickStep), + validateStack: makeStackFunc(1, 0), + valid: true, }, MLOAD: { - execute: opMload, - gasCost: gasMLoad, - validateStack: makeStackFunc(1, 1), - memorySize: memoryMLoad, - valid: true, + execute: opMload, + computationalEffort: effortMLoad, + validateStack: makeStackFunc(1, 1), + memorySize: memoryMLoad, + valid: true, }, MSTORE: { - execute: opMstore, - gasCost: gasMStore, - validateStack: makeStackFunc(2, 0), - memorySize: memoryMStore, - valid: true, + execute: opMstore, + computationalEffort: effortMStore, + validateStack: makeStackFunc(2, 0), + memorySize: memoryMStore, + valid: true, }, MSTORE8: { - execute: opMstore8, - gasCost: gasMStore8, - memorySize: memoryMStore8, - validateStack: makeStackFunc(2, 0), + execute: opMstore8, + computationalEffort: effortMStore8, + memorySize: memoryMStore8, + validateStack: makeStackFunc(2, 0), valid: true, }, SLOAD: { - execute: opSload, - gasCost: gasSLoad, - validateStack: makeStackFunc(1, 1), - valid: true, + execute: opSload, + computationalEffort: effortSLoad, + validateStack: makeStackFunc(1, 1), + valid: true, }, SSTORE: { - execute: opSstore, - gasCost: gasSStore, - validateStack: makeStackFunc(2, 0), - valid: true, - writes: true, + execute: opSstore, + computationalEffort: effortSStore, + validateStack: makeStackFunc(2, 0), + valid: true, + writes: true, }, JUMP: { - execute: opJump, - gasCost: constGasFunc(GasMidStep), - validateStack: makeStackFunc(1, 0), - jumps: true, - valid: true, + execute: opJump, + computationalEffort: constEffortFunc(EffortMidStep), + validateStack: makeStackFunc(1, 0), + jumps: true, + valid: true, }, JUMPI: { - execute: opJumpi, - gasCost: constGasFunc(GasSlowStep), - validateStack: makeStackFunc(2, 0), - jumps: true, - valid: true, + execute: opJumpi, + computationalEffort: constEffortFunc(EffortSlowStep), + validateStack: makeStackFunc(2, 0), + jumps: true, + valid: true, }, PC: { - execute: opPc, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, + execute: opPc, + computationalEffort: constEffortFunc(EffortQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, }, MSIZE: { - execute: opMsize, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, + execute: opMsize, + computationalEffort: constEffortFunc(EffortQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, }, - GAS: { - execute: opGas, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, + RESOURCELEFT: { + execute: opResourceLeft, + computationalEffort: constEffortFunc(EffortQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, }, JUMPDEST: { - execute: opJumpdest, - gasCost: constGasFunc(params.JumpdestGas), - validateStack: makeStackFunc(0, 0), - valid: true, + execute: opJumpdest, + computationalEffort: constEffortFunc(effort.Jumpdest), + validateStack: makeStackFunc(0, 0), + valid: true, }, PUSH1: { - execute: makePush(1, 1), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(1, 1), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH2: { - execute: makePush(2, 2), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(2, 2), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH3: { - execute: makePush(3, 3), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(3, 3), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH4: { - execute: makePush(4, 4), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(4, 4), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH5: { - execute: makePush(5, 5), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(5, 5), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH6: { - execute: makePush(6, 6), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(6, 6), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH7: { - execute: makePush(7, 7), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(7, 7), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH8: { - execute: makePush(8, 8), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(8, 8), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH9: { - execute: makePush(9, 9), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(9, 9), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH10: { - execute: makePush(10, 10), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(10, 10), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH11: { - execute: makePush(11, 11), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(11, 11), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH12: { - execute: makePush(12, 12), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(12, 12), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH13: { - execute: makePush(13, 13), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(13, 13), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH14: { - execute: makePush(14, 14), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(14, 14), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH15: { - execute: makePush(15, 15), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(15, 15), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH16: { - execute: makePush(16, 16), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(16, 16), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH17: { - execute: makePush(17, 17), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(17, 17), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH18: { - execute: makePush(18, 18), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(18, 18), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH19: { - execute: makePush(19, 19), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(19, 19), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH20: { - execute: makePush(20, 20), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(20, 20), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH21: { - execute: makePush(21, 21), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(21, 21), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH22: { - execute: makePush(22, 22), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(22, 22), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH23: { - execute: makePush(23, 23), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(23, 23), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH24: { - execute: makePush(24, 24), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(24, 24), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH25: { - execute: makePush(25, 25), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(25, 25), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH26: { - execute: makePush(26, 26), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(26, 26), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH27: { - execute: makePush(27, 27), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(27, 27), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH28: { - execute: makePush(28, 28), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(28, 28), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH29: { - execute: makePush(29, 29), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(29, 29), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH30: { - execute: makePush(30, 30), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(30, 30), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH31: { - execute: makePush(31, 31), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(31, 31), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, PUSH32: { - execute: makePush(32, 32), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, + execute: makePush(32, 32), + computationalEffort: effortPush, + validateStack: makeStackFunc(0, 1), + valid: true, }, DUP1: { - execute: makeDup(1), - gasCost: gasDup, - validateStack: makeDupStackFunc(1), - valid: true, + execute: makeDup(1), + computationalEffort: effortDup, + validateStack: makeDupStackFunc(1), + valid: true, }, DUP2: { - execute: makeDup(2), - gasCost: gasDup, - validateStack: makeDupStackFunc(2), - valid: true, + execute: makeDup(2), + computationalEffort: effortDup, + validateStack: makeDupStackFunc(2), + valid: true, }, DUP3: { - execute: makeDup(3), - gasCost: gasDup, - validateStack: makeDupStackFunc(3), - valid: true, + execute: makeDup(3), + computationalEffort: effortDup, + validateStack: makeDupStackFunc(3), + valid: true, }, DUP4: { - execute: makeDup(4), - gasCost: gasDup, - validateStack: makeDupStackFunc(4), - valid: true, + execute: makeDup(4), + computationalEffort: effortDup, + validateStack: makeDupStackFunc(4), + valid: true, }, DUP5: { - execute: makeDup(5), - gasCost: gasDup, - validateStack: makeDupStackFunc(5), - valid: true, + execute: makeDup(5), + computationalEffort: effortDup, + validateStack: makeDupStackFunc(5), + valid: true, }, DUP6: { - execute: makeDup(6), - gasCost: gasDup, - validateStack: makeDupStackFunc(6), - valid: true, + execute: makeDup(6), + computationalEffort: effortDup, + validateStack: makeDupStackFunc(6), + valid: true, }, DUP7: { - execute: makeDup(7), - gasCost: gasDup, - validateStack: makeDupStackFunc(7), - valid: true, + execute: makeDup(7), + computationalEffort: effortDup, + validateStack: makeDupStackFunc(7), + valid: true, }, DUP8: { - execute: makeDup(8), - gasCost: gasDup, - validateStack: makeDupStackFunc(8), - valid: true, + execute: makeDup(8), + computationalEffort: effortDup, + validateStack: makeDupStackFunc(8), + valid: true, }, DUP9: { - execute: makeDup(9), - gasCost: gasDup, - validateStack: makeDupStackFunc(9), - valid: true, + execute: makeDup(9), + computationalEffort: effortDup, + validateStack: makeDupStackFunc(9), + valid: true, }, DUP10: { - execute: makeDup(10), - gasCost: gasDup, - validateStack: makeDupStackFunc(10), - valid: true, + execute: makeDup(10), + computationalEffort: effortDup, + validateStack: makeDupStackFunc(10), + valid: true, }, DUP11: { - execute: makeDup(11), - gasCost: gasDup, - validateStack: makeDupStackFunc(11), - valid: true, + execute: makeDup(11), + computationalEffort: effortDup, + validateStack: makeDupStackFunc(11), + valid: true, }, DUP12: { - execute: makeDup(12), - gasCost: gasDup, - validateStack: makeDupStackFunc(12), - valid: true, + execute: makeDup(12), + computationalEffort: effortDup, + validateStack: makeDupStackFunc(12), + valid: true, }, DUP13: { - execute: makeDup(13), - gasCost: gasDup, - validateStack: makeDupStackFunc(13), - valid: true, + execute: makeDup(13), + computationalEffort: effortDup, + validateStack: makeDupStackFunc(13), + valid: true, }, DUP14: { - execute: makeDup(14), - gasCost: gasDup, - validateStack: makeDupStackFunc(14), - valid: true, + execute: makeDup(14), + computationalEffort: effortDup, + validateStack: makeDupStackFunc(14), + valid: true, }, DUP15: { - execute: makeDup(15), - gasCost: gasDup, - validateStack: makeDupStackFunc(15), - valid: true, + execute: makeDup(15), + computationalEffort: effortDup, + validateStack: makeDupStackFunc(15), + valid: true, }, DUP16: { - execute: makeDup(16), - gasCost: gasDup, - validateStack: makeDupStackFunc(16), - valid: true, + execute: makeDup(16), + computationalEffort: effortDup, + validateStack: makeDupStackFunc(16), + valid: true, }, SWAP1: { - execute: makeSwap(1), - gasCost: gasSwap, - validateStack: makeSwapStackFunc(2), - valid: true, + execute: makeSwap(1), + computationalEffort: effortSwap, + validateStack: makeSwapStackFunc(2), + valid: true, }, SWAP2: { - execute: makeSwap(2), - gasCost: gasSwap, - validateStack: makeSwapStackFunc(3), - valid: true, + execute: makeSwap(2), + computationalEffort: effortSwap, + validateStack: makeSwapStackFunc(3), + valid: true, }, SWAP3: { - execute: makeSwap(3), - gasCost: gasSwap, - validateStack: makeSwapStackFunc(4), - valid: true, + execute: makeSwap(3), + computationalEffort: effortSwap, + validateStack: makeSwapStackFunc(4), + valid: true, }, SWAP4: { - execute: makeSwap(4), - gasCost: gasSwap, - validateStack: makeSwapStackFunc(5), - valid: true, + execute: makeSwap(4), + computationalEffort: effortSwap, + validateStack: makeSwapStackFunc(5), + valid: true, }, SWAP5: { - execute: makeSwap(5), - gasCost: gasSwap, - validateStack: makeSwapStackFunc(6), - valid: true, + execute: makeSwap(5), + computationalEffort: effortSwap, + validateStack: makeSwapStackFunc(6), + valid: true, }, SWAP6: { - execute: makeSwap(6), - gasCost: gasSwap, - validateStack: makeSwapStackFunc(7), - valid: true, + execute: makeSwap(6), + computationalEffort: effortSwap, + validateStack: makeSwapStackFunc(7), + valid: true, }, SWAP7: { - execute: makeSwap(7), - gasCost: gasSwap, - validateStack: makeSwapStackFunc(8), - valid: true, + execute: makeSwap(7), + computationalEffort: effortSwap, + validateStack: makeSwapStackFunc(8), + valid: true, }, SWAP8: { - execute: makeSwap(8), - gasCost: gasSwap, - validateStack: makeSwapStackFunc(9), - valid: true, + execute: makeSwap(8), + computationalEffort: effortSwap, + validateStack: makeSwapStackFunc(9), + valid: true, }, SWAP9: { - execute: makeSwap(9), - gasCost: gasSwap, - validateStack: makeSwapStackFunc(10), - valid: true, + execute: makeSwap(9), + computationalEffort: effortSwap, + validateStack: makeSwapStackFunc(10), + valid: true, }, SWAP10: { - execute: makeSwap(10), - gasCost: gasSwap, - validateStack: makeSwapStackFunc(11), - valid: true, + execute: makeSwap(10), + computationalEffort: effortSwap, + validateStack: makeSwapStackFunc(11), + valid: true, }, SWAP11: { - execute: makeSwap(11), - gasCost: gasSwap, - validateStack: makeSwapStackFunc(12), - valid: true, + execute: makeSwap(11), + computationalEffort: effortSwap, + validateStack: makeSwapStackFunc(12), + valid: true, }, SWAP12: { - execute: makeSwap(12), - gasCost: gasSwap, - validateStack: makeSwapStackFunc(13), - valid: true, + execute: makeSwap(12), + computationalEffort: effortSwap, + validateStack: makeSwapStackFunc(13), + valid: true, }, SWAP13: { - execute: makeSwap(13), - gasCost: gasSwap, - validateStack: makeSwapStackFunc(14), - valid: true, + execute: makeSwap(13), + computationalEffort: effortSwap, + validateStack: makeSwapStackFunc(14), + valid: true, }, SWAP14: { - execute: makeSwap(14), - gasCost: gasSwap, - validateStack: makeSwapStackFunc(15), - valid: true, + execute: makeSwap(14), + computationalEffort: effortSwap, + validateStack: makeSwapStackFunc(15), + valid: true, }, SWAP15: { - execute: makeSwap(15), - gasCost: gasSwap, - validateStack: makeSwapStackFunc(16), - valid: true, + execute: makeSwap(15), + computationalEffort: effortSwap, + validateStack: makeSwapStackFunc(16), + valid: true, }, SWAP16: { - execute: makeSwap(16), - gasCost: gasSwap, - validateStack: makeSwapStackFunc(17), - valid: true, + execute: makeSwap(16), + computationalEffort: effortSwap, + validateStack: makeSwapStackFunc(17), + valid: true, }, LOG0: { - execute: makeLog(0), - gasCost: makeGasLog(0), - validateStack: makeStackFunc(2, 0), - memorySize: memoryLog, - valid: true, - writes: true, + execute: makeLog(0), + computationalEffort: makeEffortLog(0), + validateStack: makeStackFunc(2, 0), + memorySize: memoryLog, + valid: true, + writes: true, }, LOG1: { - execute: makeLog(1), - gasCost: makeGasLog(1), - validateStack: makeStackFunc(3, 0), - memorySize: memoryLog, - valid: true, - writes: true, + execute: makeLog(1), + computationalEffort: makeEffortLog(1), + validateStack: makeStackFunc(3, 0), + memorySize: memoryLog, + valid: true, + writes: true, }, LOG2: { - execute: makeLog(2), - gasCost: makeGasLog(2), - validateStack: makeStackFunc(4, 0), - memorySize: memoryLog, - valid: true, - writes: true, + execute: makeLog(2), + computationalEffort: makeEffortLog(2), + validateStack: makeStackFunc(4, 0), + memorySize: memoryLog, + valid: true, + writes: true, }, LOG3: { - execute: makeLog(3), - gasCost: makeGasLog(3), - validateStack: makeStackFunc(5, 0), - memorySize: memoryLog, - valid: true, - writes: true, + execute: makeLog(3), + computationalEffort: makeEffortLog(3), + validateStack: makeStackFunc(5, 0), + memorySize: memoryLog, + valid: true, + writes: true, }, LOG4: { - execute: makeLog(4), - gasCost: makeGasLog(4), - validateStack: makeStackFunc(6, 0), - memorySize: memoryLog, - valid: true, - writes: true, + execute: makeLog(4), + computationalEffort: makeEffortLog(4), + validateStack: makeStackFunc(6, 0), + memorySize: memoryLog, + valid: true, + writes: true, }, CREATE: { - execute: opCreate, - gasCost: gasCreate, - validateStack: makeStackFunc(3, 1), - memorySize: memoryCreate, - valid: true, - writes: true, - returns: true, + execute: opCreate, + computationalEffort: effortCreate, + validateStack: makeStackFunc(3, 1), + memorySize: memoryCreate, + valid: true, + writes: true, + returns: true, }, CALL: { - execute: opCall, - gasCost: gasCall, - validateStack: makeStackFunc(7, 1), - memorySize: memoryCall, - valid: true, - returns: true, + execute: opCall, + computationalEffort: effortCall, + validateStack: makeStackFunc(7, 1), + memorySize: memoryCall, + valid: true, + returns: true, }, CALLCODE: { - execute: opCallCode, - gasCost: gasCallCode, - validateStack: makeStackFunc(7, 1), - memorySize: memoryCall, - valid: true, - returns: true, + execute: opCallCode, + computationalEffort: effortCallCode, + validateStack: makeStackFunc(7, 1), + memorySize: memoryCall, + valid: true, + returns: true, }, RETURN: { - execute: opReturn, - gasCost: gasReturn, - validateStack: makeStackFunc(2, 0), - memorySize: memoryReturn, - halts: true, - valid: true, + execute: opReturn, + computationalEffort: effortReturn, + validateStack: makeStackFunc(2, 0), + memorySize: memoryReturn, + halts: true, + valid: true, }, SELFDESTRUCT: { - execute: opSuicide, - gasCost: gasSuicide, - validateStack: makeStackFunc(1, 0), - halts: true, - valid: true, - writes: true, + execute: opSuicide, + computationalEffort: effortSuicide, + validateStack: makeStackFunc(1, 0), + halts: true, + valid: true, + writes: true, }, DELEGATECALL: { - execute: opDelegateCall, - gasCost: gasDelegateCall, - validateStack: makeStackFunc(6, 1), - memorySize: memoryDelegateCall, - valid: true, - returns: true, + execute: opDelegateCall, + computationalEffort: effortDelegateCall, + validateStack: makeStackFunc(6, 1), + memorySize: memoryDelegateCall, + valid: true, + returns: true, }, STATICCALL: { - execute: opStaticCall, - gasCost: gasStaticCall, - validateStack: makeStackFunc(6, 1), - memorySize: memoryStaticCall, - valid: true, - returns: true, + execute: opStaticCall, + computationalEffort: effortStaticCall, + validateStack: makeStackFunc(6, 1), + memorySize: memoryStaticCall, + valid: true, + returns: true, }, RETURNDATASIZE: { - execute: opReturnDataSize, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, + execute: opReturnDataSize, + computationalEffort: constEffortFunc(EffortQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, }, RETURNDATACOPY: { - execute: opReturnDataCopy, - gasCost: gasReturnDataCopy, - validateStack: makeStackFunc(3, 0), - memorySize: memoryReturnDataCopy, - valid: true, + execute: opReturnDataCopy, + computationalEffort: effortReturnDataCopy, + validateStack: makeStackFunc(3, 0), + memorySize: memoryReturnDataCopy, + valid: true, }, REVERT: { - execute: opRevert, - gasCost: gasRevert, - validateStack: makeStackFunc(2, 0), - memorySize: memoryRevert, - valid: true, - reverts: true, - returns: true, + execute: opRevert, + computationalEffort: effortRevert, + validateStack: makeStackFunc(2, 0), + memorySize: memoryRevert, + valid: true, + reverts: true, + returns: true, }, SHL: { - execute: opSHL, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, + execute: opSHL, + computationalEffort: constEffortFunc(EffortFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, }, SHR: { - execute: opSHR, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, + execute: opSHR, + computationalEffort: constEffortFunc(EffortFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, }, SAR: { - execute: opSAR, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, + execute: opSAR, + computationalEffort: constEffortFunc(EffortFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, }, } } diff --git a/client/core/vm/logger.go b/client/core/vm/logger.go index dce85a5e2..4bda0d370 100644 --- a/client/core/vm/logger.go +++ b/client/core/vm/logger.go @@ -42,7 +42,7 @@ func (s Storage) Copy() Storage { return cpy } -// LogConfig are the configuration options for structured logger the EVM +// LogConfig are the configuration options for structured logger the VM type LogConfig struct { DisableMemory bool // disable memory capture DisableStack bool // disable stack capture @@ -53,29 +53,29 @@ type LogConfig struct { //go:generate gencodec -type StructLog -field-override structLogMarshaling -out gen_structlog.go -// StructLog is emitted to the EVM each cycle and lists information about the current internal state +// StructLog is emitted to the VM each cycle and lists information about the current internal state // prior to the execution of the statement. type StructLog struct { - Pc uint64 `json:"pc"` - Op OpCode `json:"op"` - Gas uint64 `json:"gas"` - GasCost uint64 `json:"gasCost"` - Memory []byte `json:"memory"` - MemorySize int `json:"memSize"` - Stack []*big.Int `json:"stack"` - Storage map[common.Hash]common.Hash `json:"-"` - Depth int `json:"depth"` - Err error `json:"-"` + Pc uint64 `json:"pc"` + Op OpCode `json:"op"` + Resource uint64 `json:"resource"` + ComputeUnitPrice uint64 `json:"compUnitPrice"` + Memory []byte `json:"memory"` + MemorySize int `json:"memSize"` + Stack []*big.Int `json:"stack"` + Storage map[common.Hash]common.Hash `json:"-"` + Depth int `json:"depth"` + Err error `json:"-"` } // overrides for gencodec type structLogMarshaling struct { - Stack []*math.HexOrDecimal256 - Gas math.HexOrDecimal64 - GasCost math.HexOrDecimal64 - Memory hexutil.Bytes - OpName string `json:"opName"` // adds call to OpName() in MarshalJSON - ErrorString string `json:"error"` // adds call to ErrorString() in MarshalJSON + Stack []*math.HexOrDecimal256 + Resource math.HexOrDecimal64 + ComputeUnitPrice math.HexOrDecimal64 + Memory hexutil.Bytes + OpName string `json:"opName"` // adds call to OpName() in MarshalJSON + ErrorString string `json:"error"` // adds call to ErrorString() in MarshalJSON } // OpName formats the operand name in a human-readable format. @@ -91,19 +91,19 @@ func (s *StructLog) ErrorString() string { return "" } -// Tracer is used to collect execution traces from an EVM transaction +// Tracer is used to collect execution traces from an VM transaction // execution. CaptureState is called for each step of the VM with the // current VM state. // Note that reference types are actual VM data structures; make copies // if you need to retain them beyond the current call. type Tracer interface { - CaptureStart(from common.Address, to common.Address, call bool, input []byte, gas uint64, value *big.Int) error - CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error - CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error - CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error + CaptureStart(from common.Address, to common.Address, call bool, input []byte, resource uint64, value *big.Int) error + CaptureState(env *VM, pc uint64, op OpCode, resource, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error + CaptureFault(env *VM, pc uint64, op OpCode, resource, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error + CaptureEnd(output []byte, resourceUsage uint64, t time.Duration, err error) error } -// StructLogger is an EVM state logger and implements Tracer. +// StructLogger is an VM state logger and implements Tracer. // // StructLogger can capture state based on the given Log configuration and also keeps // a track record of modified storage which is used in reporting snapshots of the @@ -129,14 +129,14 @@ func NewStructLogger(cfg *LogConfig) *StructLogger { } // CaptureStart implements the Tracer interface to initialize the tracing operation. -func (l *StructLogger) CaptureStart(from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) error { +func (l *StructLogger) CaptureStart(from common.Address, to common.Address, create bool, input []byte, resource uint64, value *big.Int) error { return nil } // CaptureState logs a new structured log message and pushes it out to the environment // // CaptureState also tracks SSTORE ops to track dirty values. -func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error { +func (l *StructLogger) CaptureState(env *VM, pc uint64, op OpCode, resource, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error { // check if already accumulated the specified number of logs if l.cfg.Limit != 0 && l.cfg.Limit <= len(l.logs) { return ErrTraceLimitReached @@ -176,8 +176,8 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui if !l.cfg.DisableStorage { storage = l.changedValues[contract.Address()].Copy() } - // create a new snaptshot of the EVM. - log := StructLog{pc, op, gas, cost, mem, memory.Len(), stck, storage, depth, err} + // create a new snaptshot of the VM. + log := StructLog{pc, op, resource, cost, mem, memory.Len(), stck, storage, depth, err} l.logs = append(l.logs, log) return nil @@ -185,12 +185,12 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui // CaptureFault implements the Tracer interface to trace an execution fault // while running an opcode. -func (l *StructLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error { +func (l *StructLogger) CaptureFault(env *VM, pc uint64, op OpCode, resource, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error { return nil } // CaptureEnd is called after the call finishes to finalize the tracing. -func (l *StructLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error { +func (l *StructLogger) CaptureEnd(output []byte, resourceUsage uint64, t time.Duration, err error) error { l.output = output l.err = err if l.cfg.Debug { @@ -214,7 +214,7 @@ func (l *StructLogger) Output() []byte { return l.output } // WriteTrace writes a formatted trace to the given writer func WriteTrace(writer io.Writer, logs []StructLog) { for _, log := range logs { - fmt.Fprintf(writer, "%-16spc=%08d gas=%v cost=%v", log.Op, log.Pc, log.Gas, log.GasCost) + fmt.Fprintf(writer, "%-16spc=%08d computational resource=%v cost=%v", log.Op, log.Pc, log.Resource, log.ComputeUnitPrice) if log.Err != nil { fmt.Fprintf(writer, " ERROR: %v", log.Err) } diff --git a/client/core/vm/logger_test.go b/client/core/vm/logger_test.go index fd5e7116b..a15df4eeb 100644 --- a/client/core/vm/logger_test.go +++ b/client/core/vm/logger_test.go @@ -28,7 +28,7 @@ type dummyContractRef struct { calledForEach bool } -func (dummyContractRef) ReturnGas(*big.Int) {} +func (dummyContractRef) ReturnResource(*big.Int) {} func (dummyContractRef) Address() common.Address { return common.Address{} } func (dummyContractRef) Value() *big.Int { return new(big.Int) } func (dummyContractRef) SetCode(common.Hash, []byte) {} @@ -48,7 +48,7 @@ type dummyStateDB struct { func TestStoreCapture(t *testing.T) { var ( - env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}) + env = NewVM(Context{}, nil, params.TestChainConfig, Config{}) logger = NewStructLogger(nil) mem = NewMemory() stack = newstack() diff --git a/client/core/vm/memory.go b/client/core/vm/memory.go index 19cfe4ae4..a37738b25 100644 --- a/client/core/vm/memory.go +++ b/client/core/vm/memory.go @@ -25,8 +25,8 @@ import ( // Memory implements a simple memory model for the ethereum virtual machine. type Memory struct { - store []byte - lastGasCost uint64 + store []byte + lastResourceUsage uint64 } // NewMemory returns a new memory memory model. diff --git a/client/core/vm/noop.go b/client/core/vm/noop.go index 141d057bf..71b5d8887 100644 --- a/client/core/vm/noop.go +++ b/client/core/vm/noop.go @@ -28,18 +28,18 @@ func NoopCanTransfer(db StateDB, from common.Address, balance *big.Int) bool { } func NoopTransfer(db StateDB, from, to common.Address, amount *big.Int) {} -type NoopEVMCallContext struct{} +type NoopVMCallContext struct{} -func (NoopEVMCallContext) Call(caller ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error) { +func (NoopVMCallContext) Call(caller ContractRef, addr common.Address, data []byte, computeLimit, value *big.Int) ([]byte, error) { return nil, nil } -func (NoopEVMCallContext) CallCode(caller ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error) { +func (NoopVMCallContext) CallCode(caller ContractRef, addr common.Address, data []byte, computeLimit, value *big.Int) ([]byte, error) { return nil, nil } -func (NoopEVMCallContext) Create(caller ContractRef, data []byte, gas, value *big.Int) ([]byte, common.Address, error) { +func (NoopVMCallContext) Create(caller ContractRef, data []byte, computeLimit, value *big.Int) ([]byte, common.Address, error) { return nil, common.Address{}, nil } -func (NoopEVMCallContext) DelegateCall(me ContractRef, addr common.Address, data []byte, gas *big.Int) ([]byte, error) { +func (NoopVMCallContext) DelegateCall(me ContractRef, addr common.Address, data []byte, computeLimit *big.Int) ([]byte, error) { return nil, nil } diff --git a/client/core/vm/opcodes.go b/client/core/vm/opcodes.go index 6c12c50e5..f12ec1c41 100644 --- a/client/core/vm/opcodes.go +++ b/client/core/vm/opcodes.go @@ -85,7 +85,7 @@ const ( CALLDATACOPY CODESIZE CODECOPY - GASPRICE + COMPUTEUNITPRICE EXTCODESIZE EXTCODECOPY RETURNDATASIZE @@ -98,8 +98,7 @@ const ( COINBASE TIMESTAMP NUMBER - DIFFICULTY - GASLIMIT + COMPUTECAPACITY ) // 0x50 range - 'storage' and execution. @@ -114,7 +113,7 @@ const ( JUMPI PC MSIZE - GAS + RESOURCELEFT JUMPDEST ) @@ -251,45 +250,44 @@ var opCodeToString = map[OpCode]string{ SHA3: "SHA3", // 0x30 range - closure state. - ADDRESS: "ADDRESS", - BALANCE: "BALANCE", - ORIGIN: "ORIGIN", - CALLER: "CALLER", - CALLVALUE: "CALLVALUE", - CALLDATALOAD: "CALLDATALOAD", - CALLDATASIZE: "CALLDATASIZE", - CALLDATACOPY: "CALLDATACOPY", - CODESIZE: "CODESIZE", - CODECOPY: "CODECOPY", - GASPRICE: "GASPRICE", - EXTCODESIZE: "EXTCODESIZE", - EXTCODECOPY: "EXTCODECOPY", - RETURNDATASIZE: "RETURNDATASIZE", - RETURNDATACOPY: "RETURNDATACOPY", + ADDRESS: "ADDRESS", + BALANCE: "BALANCE", + ORIGIN: "ORIGIN", + CALLER: "CALLER", + CALLVALUE: "CALLVALUE", + CALLDATALOAD: "CALLDATALOAD", + CALLDATASIZE: "CALLDATASIZE", + CALLDATACOPY: "CALLDATACOPY", + CODESIZE: "CODESIZE", + CODECOPY: "CODECOPY", + COMPUTEUNITPRICE: "COMPUTEUNITPRICE", + EXTCODESIZE: "EXTCODESIZE", + EXTCODECOPY: "EXTCODECOPY", + RETURNDATASIZE: "RETURNDATASIZE", + RETURNDATACOPY: "RETURNDATACOPY", // 0x40 range - block operations. - BLOCKHASH: "BLOCKHASH", - COINBASE: "COINBASE", - TIMESTAMP: "TIMESTAMP", - NUMBER: "NUMBER", - DIFFICULTY: "DIFFICULTY", - GASLIMIT: "GASLIMIT", + BLOCKHASH: "BLOCKHASH", + COINBASE: "COINBASE", + TIMESTAMP: "TIMESTAMP", + NUMBER: "NUMBER", + COMPUTECAPACITY: "COMPUTECAPACITY", // 0x50 range - 'storage' and execution. POP: "POP", //DUP: "DUP", //SWAP: "SWAP", - MLOAD: "MLOAD", - MSTORE: "MSTORE", - MSTORE8: "MSTORE8", - SLOAD: "SLOAD", - SSTORE: "SSTORE", - JUMP: "JUMP", - JUMPI: "JUMPI", - PC: "PC", - MSIZE: "MSIZE", - GAS: "GAS", - JUMPDEST: "JUMPDEST", + MLOAD: "MLOAD", + MSTORE: "MSTORE", + MSTORE8: "MSTORE8", + SLOAD: "SLOAD", + SSTORE: "SSTORE", + JUMP: "JUMP", + JUMPI: "JUMPI", + PC: "PC", + MSIZE: "MSIZE", + RESOURCELEFT: "RESOURCELEFT", + JUMPDEST: "JUMPDEST", // 0x60 range - push. PUSH1: "PUSH1", @@ -389,143 +387,142 @@ func (op OpCode) String() string { } var stringToOp = map[string]OpCode{ - "STOP": STOP, - "ADD": ADD, - "MUL": MUL, - "SUB": SUB, - "DIV": DIV, - "SDIV": SDIV, - "MOD": MOD, - "SMOD": SMOD, - "EXP": EXP, - "NOT": NOT, - "LT": LT, - "GT": GT, - "SLT": SLT, - "SGT": SGT, - "EQ": EQ, - "ISZERO": ISZERO, - "SIGNEXTEND": SIGNEXTEND, - "AND": AND, - "OR": OR, - "XOR": XOR, - "BYTE": BYTE, - "SHL": SHL, - "SHR": SHR, - "SAR": SAR, - "ADDMOD": ADDMOD, - "MULMOD": MULMOD, - "SHA3": SHA3, - "ADDRESS": ADDRESS, - "BALANCE": BALANCE, - "ORIGIN": ORIGIN, - "CALLER": CALLER, - "CALLVALUE": CALLVALUE, - "CALLDATALOAD": CALLDATALOAD, - "CALLDATASIZE": CALLDATASIZE, - "CALLDATACOPY": CALLDATACOPY, - "DELEGATECALL": DELEGATECALL, - "STATICCALL": STATICCALL, - "CODESIZE": CODESIZE, - "CODECOPY": CODECOPY, - "GASPRICE": GASPRICE, - "EXTCODESIZE": EXTCODESIZE, - "EXTCODECOPY": EXTCODECOPY, - "RETURNDATASIZE": RETURNDATASIZE, - "RETURNDATACOPY": RETURNDATACOPY, - "BLOCKHASH": BLOCKHASH, - "COINBASE": COINBASE, - "TIMESTAMP": TIMESTAMP, - "NUMBER": NUMBER, - "DIFFICULTY": DIFFICULTY, - "GASLIMIT": GASLIMIT, - "POP": POP, - "MLOAD": MLOAD, - "MSTORE": MSTORE, - "MSTORE8": MSTORE8, - "SLOAD": SLOAD, - "SSTORE": SSTORE, - "JUMP": JUMP, - "JUMPI": JUMPI, - "PC": PC, - "MSIZE": MSIZE, - "GAS": GAS, - "JUMPDEST": JUMPDEST, - "PUSH1": PUSH1, - "PUSH2": PUSH2, - "PUSH3": PUSH3, - "PUSH4": PUSH4, - "PUSH5": PUSH5, - "PUSH6": PUSH6, - "PUSH7": PUSH7, - "PUSH8": PUSH8, - "PUSH9": PUSH9, - "PUSH10": PUSH10, - "PUSH11": PUSH11, - "PUSH12": PUSH12, - "PUSH13": PUSH13, - "PUSH14": PUSH14, - "PUSH15": PUSH15, - "PUSH16": PUSH16, - "PUSH17": PUSH17, - "PUSH18": PUSH18, - "PUSH19": PUSH19, - "PUSH20": PUSH20, - "PUSH21": PUSH21, - "PUSH22": PUSH22, - "PUSH23": PUSH23, - "PUSH24": PUSH24, - "PUSH25": PUSH25, - "PUSH26": PUSH26, - "PUSH27": PUSH27, - "PUSH28": PUSH28, - "PUSH29": PUSH29, - "PUSH30": PUSH30, - "PUSH31": PUSH31, - "PUSH32": PUSH32, - "DUP1": DUP1, - "DUP2": DUP2, - "DUP3": DUP3, - "DUP4": DUP4, - "DUP5": DUP5, - "DUP6": DUP6, - "DUP7": DUP7, - "DUP8": DUP8, - "DUP9": DUP9, - "DUP10": DUP10, - "DUP11": DUP11, - "DUP12": DUP12, - "DUP13": DUP13, - "DUP14": DUP14, - "DUP15": DUP15, - "DUP16": DUP16, - "SWAP1": SWAP1, - "SWAP2": SWAP2, - "SWAP3": SWAP3, - "SWAP4": SWAP4, - "SWAP5": SWAP5, - "SWAP6": SWAP6, - "SWAP7": SWAP7, - "SWAP8": SWAP8, - "SWAP9": SWAP9, - "SWAP10": SWAP10, - "SWAP11": SWAP11, - "SWAP12": SWAP12, - "SWAP13": SWAP13, - "SWAP14": SWAP14, - "SWAP15": SWAP15, - "SWAP16": SWAP16, - "LOG0": LOG0, - "LOG1": LOG1, - "LOG2": LOG2, - "LOG3": LOG3, - "LOG4": LOG4, - "CREATE": CREATE, - "CALL": CALL, - "RETURN": RETURN, - "CALLCODE": CALLCODE, - "REVERT": REVERT, - "SELFDESTRUCT": SELFDESTRUCT, + "STOP": STOP, + "ADD": ADD, + "MUL": MUL, + "SUB": SUB, + "DIV": DIV, + "SDIV": SDIV, + "MOD": MOD, + "SMOD": SMOD, + "EXP": EXP, + "NOT": NOT, + "LT": LT, + "GT": GT, + "SLT": SLT, + "SGT": SGT, + "EQ": EQ, + "ISZERO": ISZERO, + "SIGNEXTEND": SIGNEXTEND, + "AND": AND, + "OR": OR, + "XOR": XOR, + "BYTE": BYTE, + "SHL": SHL, + "SHR": SHR, + "SAR": SAR, + "ADDMOD": ADDMOD, + "MULMOD": MULMOD, + "SHA3": SHA3, + "ADDRESS": ADDRESS, + "BALANCE": BALANCE, + "ORIGIN": ORIGIN, + "CALLER": CALLER, + "CALLVALUE": CALLVALUE, + "CALLDATALOAD": CALLDATALOAD, + "CALLDATASIZE": CALLDATASIZE, + "CALLDATACOPY": CALLDATACOPY, + "DELEGATECALL": DELEGATECALL, + "STATICCALL": STATICCALL, + "CODESIZE": CODESIZE, + "CODECOPY": CODECOPY, + "COMPUTEUNITPRICE": COMPUTEUNITPRICE, + "EXTCODESIZE": EXTCODESIZE, + "EXTCODECOPY": EXTCODECOPY, + "RETURNDATASIZE": RETURNDATASIZE, + "RETURNDATACOPY": RETURNDATACOPY, + "BLOCKHASH": BLOCKHASH, + "COINBASE": COINBASE, + "TIMESTAMP": TIMESTAMP, + "NUMBER": NUMBER, + "COMPUTECAPACITY": COMPUTECAPACITY, + "POP": POP, + "MLOAD": MLOAD, + "MSTORE": MSTORE, + "MSTORE8": MSTORE8, + "SLOAD": SLOAD, + "SSTORE": SSTORE, + "JUMP": JUMP, + "JUMPI": JUMPI, + "PC": PC, + "MSIZE": MSIZE, + "RESOURCELEFT": RESOURCELEFT, + "JUMPDEST": JUMPDEST, + "PUSH1": PUSH1, + "PUSH2": PUSH2, + "PUSH3": PUSH3, + "PUSH4": PUSH4, + "PUSH5": PUSH5, + "PUSH6": PUSH6, + "PUSH7": PUSH7, + "PUSH8": PUSH8, + "PUSH9": PUSH9, + "PUSH10": PUSH10, + "PUSH11": PUSH11, + "PUSH12": PUSH12, + "PUSH13": PUSH13, + "PUSH14": PUSH14, + "PUSH15": PUSH15, + "PUSH16": PUSH16, + "PUSH17": PUSH17, + "PUSH18": PUSH18, + "PUSH19": PUSH19, + "PUSH20": PUSH20, + "PUSH21": PUSH21, + "PUSH22": PUSH22, + "PUSH23": PUSH23, + "PUSH24": PUSH24, + "PUSH25": PUSH25, + "PUSH26": PUSH26, + "PUSH27": PUSH27, + "PUSH28": PUSH28, + "PUSH29": PUSH29, + "PUSH30": PUSH30, + "PUSH31": PUSH31, + "PUSH32": PUSH32, + "DUP1": DUP1, + "DUP2": DUP2, + "DUP3": DUP3, + "DUP4": DUP4, + "DUP5": DUP5, + "DUP6": DUP6, + "DUP7": DUP7, + "DUP8": DUP8, + "DUP9": DUP9, + "DUP10": DUP10, + "DUP11": DUP11, + "DUP12": DUP12, + "DUP13": DUP13, + "DUP14": DUP14, + "DUP15": DUP15, + "DUP16": DUP16, + "SWAP1": SWAP1, + "SWAP2": SWAP2, + "SWAP3": SWAP3, + "SWAP4": SWAP4, + "SWAP5": SWAP5, + "SWAP6": SWAP6, + "SWAP7": SWAP7, + "SWAP8": SWAP8, + "SWAP9": SWAP9, + "SWAP10": SWAP10, + "SWAP11": SWAP11, + "SWAP12": SWAP12, + "SWAP13": SWAP13, + "SWAP14": SWAP14, + "SWAP15": SWAP15, + "SWAP16": SWAP16, + "LOG0": LOG0, + "LOG1": LOG1, + "LOG2": LOG2, + "LOG3": LOG3, + "LOG4": LOG4, + "CREATE": CREATE, + "CALL": CALL, + "RETURN": RETURN, + "CALLCODE": CALLCODE, + "REVERT": REVERT, + "SELFDESTRUCT": SELFDESTRUCT, } // StringToOp finds the opcode whose name is stored in `str`. diff --git a/client/core/vm/runtime/env.go b/client/core/vm/runtime/env.go index 2fb53d694..f08821037 100644 --- a/client/core/vm/runtime/env.go +++ b/client/core/vm/runtime/env.go @@ -6,19 +6,19 @@ import ( "github.com/kowala-tech/kcoin/client/core/vm" ) -func NewEnv(cfg *Config) *vm.EVM { +func NewEnv(cfg *Config) *vm.VM { context := vm.Context{ CanTransfer: core.CanTransfer, Transfer: core.Transfer, GetHash: func(uint64) common.Hash { return common.Hash{} }, - Origin: cfg.Origin, - Coinbase: cfg.Coinbase, - BlockNumber: cfg.BlockNumber, - Time: cfg.Time, - GasLimit: cfg.GasLimit, - GasPrice: cfg.GasPrice, + Origin: cfg.Origin, + Coinbase: cfg.Coinbase, + BlockNumber: cfg.BlockNumber, + Time: cfg.Time, + ComputeCapacity: cfg.ComputeLimit, + ComputeUnitPrice: cfg.ComputeUnitPrice, } - return vm.NewEVM(context, cfg.State, cfg.ChainConfig, cfg.EVMConfig) + return vm.New(context, cfg.State, cfg.ChainConfig, cfg.VMConfig) } diff --git a/client/core/vm/runtime/runtime.go b/client/core/vm/runtime/runtime.go index ab148d865..0e8dbe6a8 100644 --- a/client/core/vm/runtime/runtime.go +++ b/client/core/vm/runtime/runtime.go @@ -14,18 +14,18 @@ import ( ) // Config is a basic type specifying certain configuration flags for running -// the EVM. +// the VM. type Config struct { - ChainConfig *params.ChainConfig - Origin common.Address - Coinbase common.Address - BlockNumber *big.Int - Time *big.Int - GasLimit uint64 - GasPrice *big.Int - Value *big.Int - Debug bool - EVMConfig vm.Config + ChainConfig *params.ChainConfig + Origin common.Address + Coinbase common.Address + BlockNumber *big.Int + Time *big.Int + ComputeLimit uint64 + ComputeUnitPrice *big.Int + Value *big.Int + Debug bool + VMConfig vm.Config State *state.StateDB GetHashFn func(n uint64) common.Hash @@ -42,11 +42,11 @@ func setDefaults(cfg *Config) { if cfg.Time == nil { cfg.Time = big.NewInt(time.Now().Unix()) } - if cfg.GasLimit == 0 { - cfg.GasLimit = math.MaxUint64 + if cfg.ComputeLimit == 0 { + cfg.ComputeLimit = math.MaxUint64 } - if cfg.GasPrice == nil { - cfg.GasPrice = new(big.Int) + if cfg.ComputeUnitPrice == nil { + cfg.ComputeUnitPrice = new(big.Int) } if cfg.Value == nil { cfg.Value = new(big.Int) @@ -88,7 +88,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) { sender, common.BytesToAddress([]byte("contract")), input, - cfg.GasLimit, + cfg.ComputeLimit, cfg.Value, ) @@ -111,13 +111,13 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) { ) // Call the code with the given configuration. - code, address, leftOverGas, err := vmenv.Create( + code, address, leftOverResource, err := vmenv.Create( sender, input, - cfg.GasLimit, + cfg.ComputeLimit, cfg.Value, ) - return code, address, leftOverGas, err + return code, address, leftOverResource, err } // Call executes the code given by the contract's address. It will return the @@ -132,13 +132,13 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, er sender := cfg.State.GetOrNewStateObject(cfg.Origin) // Call the code with the given configuration. - ret, leftOverGas, err := vmenv.Call( + ret, leftOverResource, err := vmenv.Call( sender, address, input, - cfg.GasLimit, + cfg.ComputeLimit, cfg.Value, ) - return ret, leftOverGas, err + return ret, leftOverResource, err } diff --git a/client/core/vm/runtime/runtime_test.go b/client/core/vm/runtime/runtime_test.go index 4c8840db5..0a22244cf 100644 --- a/client/core/vm/runtime/runtime_test.go +++ b/client/core/vm/runtime/runtime_test.go @@ -16,18 +16,14 @@ func TestDefaults(t *testing.T) { cfg := new(Config) setDefaults(cfg) - if cfg.Difficulty == nil { - t.Error("expected difficulty to be non nil") - } - if cfg.Time == nil { t.Error("expected time to be non nil") } - if cfg.GasLimit == 0 { - t.Error("didn't expect gaslimit to be zero") + if cfg.ComputeLimit == 0 { + t.Error("didn't expect computeLimit to be zero") } - if cfg.GasPrice == nil { - t.Error("expected time to be non nil") + if cfg.ComputeUnitPrice == nil { + t.Error("expected compute unit price to be non nil") } if cfg.Value == nil { t.Error("expected time to be non nil") @@ -40,7 +36,7 @@ func TestDefaults(t *testing.T) { } } -func TestEVM(t *testing.T) { +func TestVM(t *testing.T) { defer func() { if r := recover(); r != nil { t.Fatalf("crashed with: %v", r) @@ -48,9 +44,8 @@ func TestEVM(t *testing.T) { }() Execute([]byte{ - byte(vm.DIFFICULTY), byte(vm.TIMESTAMP), - byte(vm.GASLIMIT), + byte(vm.COMPUTELIMIT), byte(vm.PUSH1), byte(vm.ORIGIN), byte(vm.BLOCKHASH), diff --git a/client/core/vm/vm.go b/client/core/vm/vm.go new file mode 100644 index 000000000..ba791ee44 --- /dev/null +++ b/client/core/vm/vm.go @@ -0,0 +1,383 @@ +package vm + +import ( + "math/big" + "sync/atomic" + "time" + + "github.com/kowala-tech/kcoin/client/common" + "github.com/kowala-tech/kcoin/client/crypto" + "github.com/kowala-tech/kcoin/client/params" + "github.com/kowala-tech/kcoin/client/params/effort" +) + +// emptyCodeHash is used by create to ensure deployment is disallowed to already +// deployed contract addresses (relevant after the account abstraction). +var emptyCodeHash = crypto.Keccak256Hash(nil) + +type ( + // CanTransferFunc is the signature of a transfer guard function + CanTransferFunc func(StateDB, common.Address, *big.Int) bool + // TransferFunc is the signature of a transfer function + TransferFunc func(StateDB, common.Address, common.Address, *big.Int) + // GetHashFunc returns the nth block hash in the blockchain + // and is used by the BLOCKHASH VM op code. + GetHashFunc func(uint64) common.Hash +) + +// run runs the given contract and takes care of running precompiles with a fallback to the byte code interpreter. +func run(vm *VM, contract *Contract, input []byte) ([]byte, error) { + if contract.CodeAddr != nil { + precompiles := PrecompiledContractsAndromeda + if p := precompiles[*contract.CodeAddr]; p != nil { + return RunPrecompiledContract(p, input, contract) + } + } + return vm.interpreter.Run(contract, input) +} + +// Context provides the VM with auxiliary information. Once provided +// it shouldn't be modified. +type Context struct { + // CanTransfer returns whether the account contains + // sufficient ether to transfer the value + CanTransfer CanTransferFunc + // Transfer transfers ether from one account to the other + Transfer TransferFunc + // GetHash returns the hash corresponding to n + GetHash GetHashFunc + + // Message information + Origin common.Address // Provides information for ORIGIN + + // Block information + Coinbase common.Address // Provides information for COINBASE + BlockNumber *big.Int // Provides information for NUMBER + Time *big.Int // Provides information for TIME + + // Network + ComputeUnitPrice *big.Int // Provides information for COMPUTEUNITPRICE + ComputeCapacity uint64 // Provides information for COMPUTECAPACITY +} + +// VM is the Ethereum Virtual Machine base object and provides +// the necessary tools to run a contract on the given state with +// the provided context. It should be noted that any error +// generated through any of the calls should be considered a +// revert-state-and-consume-all-computational-resource operation, no checks on +// specific errors should ever be performed. The interpreter makes +// sure that any errors generated are to be considered faulty code. +// +// The VM should never be reused and is not thread safe. +type VM struct { + // Context provides auxiliary blockchain related information + Context + // StateDB gives access to the underlying state + StateDB StateDB + // Depth is the current call stack + depth int + + // chainConfig contains information about the current chain + chainConfig *params.ChainConfig + // chain rules contains the chain rules for the current epoch + chainRules params.Rules + // virtual machine configuration options used to initialise the + // vm. + vmConfig Config + // global (to this context) ethereum virtual machine + // used throughout the execution of the tx. + interpreter *Interpreter + // abort is used to abort the VM calling operations + // NOTE: must be set atomically + abort int32 + // callResourceTemp holds the computational resource available for the current call. This is needed because the + // available resource is calculated in resourceCall* according to the 63/64 rule and later + // applied in opCall*. + callResourceTemp uint64 +} + +// New returns a new VM. The returned VM is not thread safe and should +// only ever be used *once*. +func New(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) *VM { + vm := &VM{ + Context: ctx, + StateDB: statedb, + vmConfig: vmConfig, + chainConfig: chainConfig, + chainRules: chainConfig.Rules(ctx.BlockNumber), + } + + vm.interpreter = NewInterpreter(vm, vmConfig) + return vm +} + +// Cancel cancels any running VM operation. This may be called concurrently and +// it's safe to be called multiple times. +func (vm *VM) Cancel() { + atomic.StoreInt32(&vm.abort, 1) +} + +// Call executes the contract associated with the addr with the given input as +// parameters. It also handles any necessary value transfer required and takes +// the necessary steps to create accounts and reverses the state in case of an +// execution error or failed value transfer. +func (vm *VM) Call(caller ContractRef, addr common.Address, input []byte, computeLimit uint64, value *big.Int) (ret []byte, leftOverResource uint64, err error) { + if vm.vmConfig.NoRecursion && vm.depth > 0 { + return nil, computeLimit, nil + } + + // Fail if we're trying to execute above the call depth limit + if vm.depth > int(params.CallCreateDepth) { + return nil, computeLimit, ErrDepth + } + // Fail if we're trying to transfer more than the available balance + if !vm.Context.CanTransfer(vm.StateDB, caller.Address(), value) { + return nil, computeLimit, ErrInsufficientBalance + } + + var ( + to = AccountRef(addr) + snapshot = vm.StateDB.Snapshot() + ) + if !vm.StateDB.Exist(addr) { + precompiles := PrecompiledContractsAndromeda + if precompiles[addr] == nil && value.Sign() == 0 { + // Calling a non existing account, don't do antything, but ping the tracer + if vm.vmConfig.Debug && vm.depth == 0 { + vm.vmConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, computeLimit, value) + vm.vmConfig.Tracer.CaptureEnd(ret, 0, 0, nil) + } + return nil, computeLimit, nil + } + vm.StateDB.CreateAccount(addr) + } + vm.Transfer(vm.StateDB, caller.Address(), to.Address(), value) + + // Initialise a new contract and set the code that is to be used by the VM. + // The contract is a scoped environment for this execution context only. + contract := NewContract(caller, to, value, computeLimit) + contract.SetCallCode(&addr, vm.StateDB.GetCodeHash(addr), vm.StateDB.GetCode(addr)) + + start := time.Now() + + // Capture the tracer start/end events in debug mode + if vm.vmConfig.Debug && vm.depth == 0 { + vm.vmConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, computeLimit, value) + + defer func() { // Lazy evaluation of the parameters + vm.vmConfig.Tracer.CaptureEnd(ret, computeLimit-contract.ComputationalResource, time.Since(start), err) + }() + } + ret, err = run(vm, contract, input) + + // When an error was returned by the VM or when setting the creation code + // above we revert to the snapshot and consume any resource remaining. Additionally + // when we're in homestead this also counts for code storage resource errors. + if err != nil { + vm.StateDB.RevertToSnapshot(snapshot) + if err != errExecutionReverted { + contract.UseResource(contract.ComputationalResource) + } + } + return ret, contract.ComputationalResource, err +} + +// CallCode executes the contract associated with the addr with the given input +// as parameters. It also handles any necessary value transfer required and takes +// the necessary steps to create accounts and reverses the state in case of an +// execution error or failed value transfer. +// +// CallCode differs from Call in the sense that it executes the given address' +// code with the caller as context. +func (vm *VM) CallCode(caller ContractRef, addr common.Address, input []byte, computeLimit uint64, value *big.Int) (ret []byte, leftOverResource uint64, err error) { + if vm.vmConfig.NoRecursion && vm.depth > 0 { + return nil, computeLimit, nil + } + + // Fail if we're trying to execute above the call depth limit + if vm.depth > int(params.CallCreateDepth) { + return nil, computeLimit, ErrDepth + } + // Fail if we're trying to transfer more than the available balance + if !vm.CanTransfer(vm.StateDB, caller.Address(), value) { + return nil, computeLimit, ErrInsufficientBalance + } + + var ( + snapshot = vm.StateDB.Snapshot() + to = AccountRef(caller.Address()) + ) + // initialise a new contract and set the code that is to be used by the + // VM. The contract is a scoped environment for this execution context + // only. + contract := NewContract(caller, to, value, computeLimit) + contract.SetCallCode(&addr, vm.StateDB.GetCodeHash(addr), vm.StateDB.GetCode(addr)) + + ret, err = run(vm, contract, input) + if err != nil { + vm.StateDB.RevertToSnapshot(snapshot) + if err != errExecutionReverted { + contract.UseResource(contract.ComputationalResource) + } + } + return ret, contract.ComputationalResource, err +} + +// DelegateCall executes the contract associated with the addr with the given input +// as parameters. It reverses the state in case of an execution error. +// +// DelegateCall differs from CallCode in the sense that it executes the given address' +// code with the caller as context and the caller is set to the caller of the caller. +func (vm *VM) DelegateCall(caller ContractRef, addr common.Address, input []byte, computeLimit uint64) (ret []byte, leftOverResource uint64, err error) { + if vm.vmConfig.NoRecursion && vm.depth > 0 { + return nil, computeLimit, nil + } + // Fail if we're trying to execute above the call depth limit + if vm.depth > int(params.CallCreateDepth) { + return nil, computeLimit, ErrDepth + } + + var ( + snapshot = vm.StateDB.Snapshot() + to = AccountRef(caller.Address()) + ) + + // Initialise a new contract and make initialise the delegate values + contract := NewContract(caller, to, nil, computeLimit).AsDelegate() + contract.SetCallCode(&addr, vm.StateDB.GetCodeHash(addr), vm.StateDB.GetCode(addr)) + + ret, err = run(vm, contract, input) + if err != nil { + vm.StateDB.RevertToSnapshot(snapshot) + if err != errExecutionReverted { + contract.UseResource(contract.ComputationalResource) + } + } + return ret, contract.ComputationalResource, err +} + +// StaticCall executes the contract associated with the addr with the given input +// as parameters while disallowing any modifications to the state during the call. +// Opcodes that attempt to perform such modifications will result in exceptions +// instead of performing the modifications. +func (vm *VM) StaticCall(caller ContractRef, addr common.Address, input []byte, computeLimit uint64) (ret []byte, leftOverResource uint64, err error) { + if vm.vmConfig.NoRecursion && vm.depth > 0 { + return nil, computeLimit, nil + } + // Fail if we're trying to execute above the call depth limit + if vm.depth > int(params.CallCreateDepth) { + return nil, computeLimit, ErrDepth + } + // Make sure the readonly is only set if we aren't in readonly yet + // this makes also sure that the readonly flag isn't removed for + // child calls. + if !vm.interpreter.readOnly { + vm.interpreter.readOnly = true + defer func() { vm.interpreter.readOnly = false }() + } + + var ( + to = AccountRef(addr) + snapshot = vm.StateDB.Snapshot() + ) + // Initialise a new contract and set the code that is to be used by the + // VM. The contract is a scoped environment for this execution context + // only. + contract := NewContract(caller, to, new(big.Int), computeLimit) + contract.SetCallCode(&addr, vm.StateDB.GetCodeHash(addr), vm.StateDB.GetCode(addr)) + + // When an error was returned by the VM or when setting the creation code + // above we revert to the snapshot and consume any resource remaining. Additionally + // when we're in Homestead this also counts for code storage resource errors. + ret, err = run(vm, contract, input) + if err != nil { + vm.StateDB.RevertToSnapshot(snapshot) + if err != errExecutionReverted { + contract.UseResource(contract.ComputationalResource) + } + } + return ret, contract.ComputationalResource, err +} + +// Create creates a new contract using code as deployment code. +func (vm *VM) Create(caller ContractRef, code []byte, computeLimit uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverResource uint64, err error) { + // Depth check execution. Fail if we're trying to execute above the + // limit. + if vm.depth > int(params.CallCreateDepth) { + return nil, common.Address{}, computeLimit, ErrDepth + } + if !vm.CanTransfer(vm.StateDB, caller.Address(), value) { + return nil, common.Address{}, computeLimit, ErrInsufficientBalance + } + // Ensure there's no existing contract already at the designated address + nonce := vm.StateDB.GetNonce(caller.Address()) + vm.StateDB.SetNonce(caller.Address(), nonce+1) + + contractAddr = crypto.CreateAddress(caller.Address(), nonce) + contractHash := vm.StateDB.GetCodeHash(contractAddr) + if vm.StateDB.GetNonce(contractAddr) != 0 || (contractHash != (common.Hash{}) && contractHash != emptyCodeHash) { + return nil, common.Address{}, 0, ErrContractAddressCollision + } + // Create a new account on the state + snapshot := vm.StateDB.Snapshot() + vm.StateDB.CreateAccount(contractAddr) + vm.StateDB.SetNonce(contractAddr, 1) + + vm.Transfer(vm.StateDB, caller.Address(), contractAddr, value) + + // initialise a new contract and set the code that is to be used by the + // VM. The contract is a scoped environment for this execution context + // only. + contract := NewContract(caller, AccountRef(contractAddr), value, computeLimit) + contract.SetCallCode(&contractAddr, crypto.Keccak256Hash(code), code) + + if vm.vmConfig.NoRecursion && vm.depth > 0 { + return nil, contractAddr, computeLimit, nil + } + + if vm.vmConfig.Debug && vm.depth == 0 { + vm.vmConfig.Tracer.CaptureStart(caller.Address(), contractAddr, true, code, computeLimit, value) + } + start := time.Now() + + ret, err = run(vm, contract, nil) + + // check whether the max code size has been exceeded + maxCodeSizeExceeded := len(ret) > params.MaxCodeSize + // if the contract creation ran successfully and no errors were returned + // calculate the computational effort required to store the code. If the code could not + // be stored due to not enough resource set an error and let it be handled + // by the error checking condition below. + if err == nil && !maxCodeSizeExceeded { + createDataEffort := uint64(len(ret)) * effort.CreateData + if contract.UseResource(createDataEffort) { + vm.StateDB.SetCode(contractAddr, ret) + } else { + err = ErrCodeStoreOutOfComputationalResource + } + } + + // When an error was returned by the VM or when setting the creation code + // above we revert to the snapshot and consume any resource remaining. Additionally + // when we're in homestead this also counts for code storage resource errors. + if maxCodeSizeExceeded || (err != nil && err != ErrCodeStoreOutOfComputationalResource) { + vm.StateDB.RevertToSnapshot(snapshot) + if err != errExecutionReverted { + contract.UseResource(contract.ComputationalResource) + } + } + // Assign err if contract code size exceeds the max while the err is still empty. + if maxCodeSizeExceeded && err == nil { + err = errMaxCodeSizeExceeded + } + if vm.vmConfig.Debug && vm.depth == 0 { + vm.vmConfig.Tracer.CaptureEnd(ret, computeLimit-contract.ComputationalResource, time.Since(start), err) + } + return ret, contractAddr, contract.ComputationalResource, err +} + +// ChainConfig returns the environment's chain configuration +func (vm *VM) ChainConfig() *params.ChainConfig { return vm.chainConfig } + +// Interpreter returns the VM interpreter +func (vm *VM) Interpreter() *Interpreter { return vm.interpreter } diff --git a/client/interfaces.go b/client/interfaces.go index 89d860513..5e8dcd0b5 100644 --- a/client/interfaces.go +++ b/client/interfaces.go @@ -97,12 +97,11 @@ type ChainSyncReader interface { // CallMsg contains parameters for contract calls. type CallMsg struct { - From common.Address // the sender of the 'transaction' - To *common.Address // the destination contract (nil for contract creation) - Gas uint64 // if 0, the call executes with near-infinite gas - GasPrice *big.Int // wei <-> gas exchange ratio - Value *big.Int // amount of wei sent along with the call - Data []byte // input data, usually an ABI-encoded contract method invocation + From common.Address // the sender of the 'transaction' + To *common.Address // the destination contract (nil for contract creation) + ComputeLimit uint64 // if 0, the call executes with near-infinite gas + Value *big.Int // amount of wei sent along with the call + Data []byte // input data, usually an ABI-encoded contract method invocation } // A ContractCaller provides contract calls, essentially transactions that are executed by @@ -155,12 +154,6 @@ type TransactionSender interface { SendTransaction(ctx context.Context, tx *types.Transaction) error } -// GasPricer wraps the gas price oracle, which monitors the blockchain to determine the -// optimal gas price given current fee market conditions. -type GasPricer interface { - SuggestGasPrice(ctx context.Context) (*big.Int, error) -} - // A PendingStateReader provides access to the pending state, which is the result of all // known executable transactions which have not yet been included in the blockchain. It is // commonly used to display the result of ’unconfirmed’ actions (e.g. wallet value @@ -179,12 +172,12 @@ type PendingContractCaller interface { PendingCallContract(ctx context.Context, call CallMsg) ([]byte, error) } -// GasEstimator wraps EstimateGas, which tries to estimate the gas needed to execute a -// specific transaction based on the pending state. There is no guarantee that this is the -// true gas limit requirement as other transactions may be added or removed by validators, but -// it should provide a basis for setting a reasonable default. -type GasEstimator interface { - EstimateGas(ctx context.Context, call CallMsg) (uint64, error) +// ComputationalEffortEstimator wraps EstimateComputationalEffort, which tries to estimate the required +// computational effort to execute a specific transaction based on the pending state. There is no +// guarantee that this is the true gas limit requirement as other transactions may be added or +// removed by validators, but it should provide a basis for setting a reasonable default. +type ComputationalEffortEstimator interface { + EstimateComputationalEffort(ctx context.Context, call CallMsg) (uint64, error) } // A PendingStateEventer provides access to real time notifications about changes to the diff --git a/client/internal/assets/genesis.json b/client/internal/assets/genesis.json deleted file mode 100644 index c95b307c8..000000000 --- a/client/internal/assets/genesis.json +++ /dev/null @@ -1,813 +0,0 @@ -{ - "config": { - "chainID": 1000, - "tendermint": { - "rewarded": true - } - }, - "timestamp": "0x5ab925ec", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x47b760", - "coinbase": "0x0000000000000000000000000000000000000000", - "alloc": { - "0000000000000000000000000000000000000000": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000001": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000002": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000003": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000004": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000005": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000006": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000007": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000008": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000009": { - "balance": "0x1" - }, - "000000000000000000000000000000000000000a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000000b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000000c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000000d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000000e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000000f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000010": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000011": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000012": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000013": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000014": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000015": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000016": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000017": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000018": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000019": { - "balance": "0x1" - }, - "000000000000000000000000000000000000001a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000001b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000001c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000001d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000001e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000001f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000020": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000021": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000022": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000023": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000024": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000025": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000026": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000027": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000028": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000029": { - "balance": "0x1" - }, - "000000000000000000000000000000000000002a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000002b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000002c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000002d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000002e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000002f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000030": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000031": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000032": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000033": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000034": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000035": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000036": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000037": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000038": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000039": { - "balance": "0x1" - }, - "000000000000000000000000000000000000003a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000003b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000003c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000003d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000003e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000003f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000040": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000041": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000042": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000043": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000044": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000045": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000046": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000047": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000048": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000049": { - "balance": "0x1" - }, - "000000000000000000000000000000000000004a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000004b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000004c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000004d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000004e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000004f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000050": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000051": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000052": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000053": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000054": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000055": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000056": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000057": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000058": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000059": { - "balance": "0x1" - }, - "000000000000000000000000000000000000005a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000005b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000005c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000005d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000005e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000005f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000060": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000061": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000062": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000063": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000064": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000065": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000066": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000067": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000068": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000069": { - "balance": "0x1" - }, - "000000000000000000000000000000000000006a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000006b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000006c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000006d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000006e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000006f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000070": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000071": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000072": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000073": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000074": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000075": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000076": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000077": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000078": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000079": { - "balance": "0x1" - }, - "000000000000000000000000000000000000007a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000007b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000007c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000007d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000007e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000007f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000080": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000081": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000082": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000083": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000084": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000085": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000086": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000087": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000088": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000089": { - "balance": "0x1" - }, - "000000000000000000000000000000000000008a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000008b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000008c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000008d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000008e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000008f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000090": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000091": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000092": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000093": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000094": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000095": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000096": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000097": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000098": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000099": { - "balance": "0x1" - }, - "000000000000000000000000000000000000009a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000009b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000009c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000009d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000009e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000009f": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a0": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a1": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a2": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a3": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a4": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a5": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a6": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a7": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a8": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a9": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000aa": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ab": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ac": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ad": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ae": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000af": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b0": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b1": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b2": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b3": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b4": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b5": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b6": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b7": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b8": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b9": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ba": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000bb": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000bc": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000bd": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000be": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000bf": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c0": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c1": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c2": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c3": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c4": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c5": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c6": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c7": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c8": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c9": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ca": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000cb": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000cc": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000cd": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ce": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000cf": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d0": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d1": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d2": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d3": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d4": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d5": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d6": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d7": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d8": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d9": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000da": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000db": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000dc": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000dd": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000de": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000df": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e0": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e1": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e2": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e3": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e4": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e5": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e6": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e7": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e8": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e9": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ea": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000eb": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ec": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ed": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ee": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ef": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f0": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f1": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f2": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f3": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f4": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f5": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f6": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f7": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f8": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f9": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000fa": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000fb": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000fc": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000fd": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000fe": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ff": { - "balance": "0x1" - }, - "259be75d96876f2ada3d202722523e9cd4dd917d": { - "balance": "0xde0b6b3a7640000" - }, - "497dc8a0096cf116e696ba9072516c92383770ed": { - "balance": "0x200000000000000000000000000000000000000000000000000000000000000" - }, - "d6e579085c82329c89fca7a9f012be59028ed53f": { - "balance": "0x200000000000000000000000000000000000000000000000000000000000000" - }, - "fe9bed356e7bc4f7a8fc48cc19c958f4e640ac62": { - "code": "0x606060405260043610610112576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063035cf1421461011457806308ac52561461013d5780633ed0a373146101665780634b2c89d5146101a457806369474625146101b95780636cf6d675146101e25780637071688a1461020b578063893d20e8146102345780639363a1411461028957806397584b3e146102b25780639bb2ea5a146102df578063b688a36314610302578063b774cb1e1461030c578063c22a933c1461033d578063cefddda914610360578063d66d9e19146103b1578063e7a60a9c146103c6578063f2fde38b14610430578063f963aeea14610481578063facd743b146104d6575b005b341561011f57600080fd5b610127610527565b6040518082815260200191505060405180910390f35b341561014857600080fd5b6101506105fb565b6040518082815260200191505060405180910390f35b341561017157600080fd5b6101876004808035906020019091905050610601565b604051808381526020018281526020019250505060405180910390f35b34156101af57600080fd5b6101b761068c565b005b34156101c457600080fd5b6101cc6107cb565b6040518082815260200191505060405180910390f35b34156101ed57600080fd5b6101f56107d1565b6040518082815260200191505060405180910390f35b341561021657600080fd5b61021e6107d7565b6040518082815260200191505060405180910390f35b341561023f57600080fd5b6102476107e4565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561029457600080fd5b61029c61080d565b6040518082815260200191505060405180910390f35b34156102bd57600080fd5b6102c561085a565b604051808215151515815260200191505060405180910390f35b34156102ea57600080fd5b610300600480803590602001909190505061086d565b005b61030a610911565b005b341561031757600080fd5b61031f61095f565b60405180826000191660001916815260200191505060405180910390f35b341561034857600080fd5b61035e6004808035906020019091905050610965565b005b341561036b57600080fd5b610397600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506109ca565b604051808215151515815260200191505060405180910390f35b34156103bc57600080fd5b6103c4610a24565b005b34156103d157600080fd5b6103e76004808035906020019091905050610a43565b604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390f35b341561043b57600080fd5b610467600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610afb565b604051808215151515815260200191505060405180910390f35b341561048c57600080fd5b610494610bd8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104e157600080fd5b61050d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610bfe565b604051808215151515815260200191505060405180910390f35b60008061053261085a565b156105415760015491506105f7565b60066000600760016007805490500381548110151561055c57fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060018160020160018360020180549050038154811015156105e157fe5b9060005260206000209060020201600001540191505b5090565b60025481565b6000806000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002018481548110151561065557fe5b90600052602060002090600202019050670de0b6b3a7640000816000015481151561067c57fe5b0481600101549250925050915091565b600080600080925060009150600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020190505b8080549050821080156107105750600081838154811015156106fb57fe5b90600052602060002090600202016001015414155b1561077257808281548110151561072357fe5b90600052602060002090600202016001015442101561074157610772565b808281548110151561074f57fe5b9060005260206000209060020201600001548301925081806001019250506106dd565b61077c3383610c57565b60008311156107c6573373ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f1935050505015156107c557600080fd5b5b505050565b60015481565b60035481565b6000600780549050905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020180549050905090565b6000806007805490506002540311905090565b6000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156108cb57600080fd5b6007805490508310156109055782600780549050039150600090505b81811015610904576108f7610d44565b80806001019150506108e7565b5b82600281905550505050565b61091a33610bfe565b15151561092657600080fd5b61092e610527565b341015151561093c57600080fd5b61094461085a565b151561095357610952610d44565b5b61095d3334610d91565b565b60055481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156109c057600080fd5b8060018190555050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050919050565b610a2d33610bfe565b1515610a3857600080fd5b610a41336110ab565b565b6000806000600784815481101515610a5757fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169250600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050806002016001826002018054905003815481101515610ae157fe5b906000526020600020906002020160000154915050915091565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610b5857600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141515610bcf57816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60019050919050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff169050919050565b600080600080841415610c6957610d3d565b600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209250600091508390505b8260020180549050811015610d2b578260020181815481101515610cd257fe5b90600052602060002090600202018360020183815481101515610cf157fe5b9060005260206000209060020201600082015481600001556001820154816001015590505081806001019250508080600101915050610cb2565b818360020181610d3b91906112a2565b505b5050505050565b610d8f6007600160078054905003815481101515610d5e57fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166110ab565b565b600080600080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209350600160078054806001018281610dee91906112d4565b9160005260206000209001600089909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555003846000018190555060018460010160006101000a81548160ff021916908315150217905550836002018054806001018281610e789190611300565b916000526020600020906002020160006040805190810160405280898152602001600081525090919091506000820151816000015560208201518160010155505050836000015492505b600083111561109b5760066000600760018603815481101515610ee157fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209150816002016001836002018054905003815481101515610f6457fe5b90600052602060002090600202019050806000015485111515610f865761109b565b600760018403815481101515610f9857fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600784815481101515610fd357fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508560076001850381548110151561102f57fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828260000181905550600183038460000181905550828060019003935050610ec2565b6110a361121f565b505050505050565b600080600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209150816000015490505b6001600780549050038110156111aa5760076001820181548110151561111957fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660078281548110151561115457fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080806001019150506110f7565b60078054809190600190036111bf9190611332565b5060008260010160006101000a81548160ff02191690831515021790555060035442018260020160018460020180549050038154811015156111fd57fe5b90600052602060002090600202016001018190555061121a61121f565b505050565b600760405180828054801561128957602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001906001019080831161123f575b5050915050604051809103902060058160001916905550565b8154818355818115116112cf576002028160020283600052602060002091820191016112ce919061135e565b5b505050565b8154818355818115116112fb578183600052602060002091820191016112fa919061138d565b5b505050565b81548183558181151161132d5760020281600202836000526020600020918201910161132c919061135e565b5b505050565b81548183558181151161135957818360005260206000209182019101611358919061138d565b5b505050565b61138a91905b8082111561138657600080820160009055600182016000905550600201611364565b5090565b90565b6113af91905b808211156113ab576000816000905550600101611393565b5090565b905600a165627a7a7230582004c0f76b4cb3f421efddd477adca85a1887a1439f575c8c52bcf312cbc22abb40029", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000259be75d96876f2ada3d202722523e9cd4dd917d", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000008ac7230489e80000", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000000064", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x000000000000000000000000d6e579085c82329c89fca7a9f012be59028ed53f", - "0x0000000000000000000000000000000000000000000000000000000000000005": "0x12477bc1dfe8a4faf0c2e4bfb2c50cf3981368a304201dc9aba236dbee40db72", - "0x0000000000000000000000000000000000000000000000000000000000000007": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688": "0x000000000000000000000000d6e579085c82329c89fca7a9f012be59028ed53f", - "0xb7258c32ea11fe2c3bbfdd0d61e71124d642d4aa559c217c9083a7b8000f1cc4": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xb7258c32ea11fe2c3bbfdd0d61e71124d642d4aa559c217c9083a7b8000f1cc5": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xb7258c32ea11fe2c3bbfdd0d61e71124d642d4aa559c217c9083a7b8000f1cc6": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xe716af36e7ec4868c5e52ab6a359350606280aa1f37f8dbd8324d6d0fd9fce77": "0x0000000000000000000000000000000000000000000000008ac7230489e80000", - "0xe716af36e7ec4868c5e52ab6a359350606280aa1f37f8dbd8324d6d0fd9fce78": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "balance": "0x8ac7230489e80000" - } - }, - "number": "0x0", - "gasUsed": "0x0", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" -} diff --git a/client/internal/assets/join-election.toml b/client/internal/assets/join-election.toml deleted file mode 100644 index 306553af2..000000000 --- a/client/internal/assets/join-election.toml +++ /dev/null @@ -1,39 +0,0 @@ -[Kowala] -NetworkId = 1 -SyncMode = "fast" -LightPeers = 20 -DatabaseCache = 128 -GasPrice = 20 -EnablePreimageRecording = false - -[Kowala.TxPool] -NoLocals = false -Journal = "transactions.rlp" -Rejournal = 3600000000000 -PriceLimit = 1 -PriceBump = 10 -AccountSlots = 16 -GlobalSlots = 4096 -AccountQueue = 64 -GlobalQueue = 1024 -Lifetime = 10800000000000 - -[Kowala.GPO] -Blocks = 10 -Percentile = 50 - -[Node] -DataDir = ".kowala10" - -[Node.P2P] -MaxPeers = 25 -NoDiscovery = false -DiscoveryV5Addr = ":30310" -BootstrapNodes = ["enode://111929beaa10c4eef786996c79267ad041b919830d0c66587f213418d759e83416047df57c9dca9cb86af9b4f53b4491112a905ec7bc2540ec73f1fa066bfb8f@54.162.29.69:33445"] -# BootstrapNodesV5 = ["enode://bae38251dece370a6c99482364d433244f183ce74169ed148a57960e46b2ab36995c0ee15d54cdff2edfa92a423ab62faecdb8185a5c536c9090507284c87427@192.168.12.171:33445"] -StaticNodes = [] -TrustedNodes = [] -ListenAddr = ":30310" - -[Stats] -URL = "Ricardo's node (3):DVagynuHLdn9sK6c@testnet.kowala.io:80" diff --git a/client/internal/assets/log.txt b/client/internal/assets/log.txt deleted file mode 100644 index 934fa4d5a..000000000 --- a/client/internal/assets/log.txt +++ /dev/null @@ -1,61 +0,0 @@ -Local bootnode - -// @NOTE(rgeraldes) - high verbosity to verify errors like running out of gas -// @NOTE(rgeraldes) - if you remove the datadir folder, you will lose the node p2p key and the enode will change on a new startup -// as it will generate a new random key. - -bootnode --nodekey /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/node.key --verbosity 6 - -Node 1 - Genesis Validator -./kcoin --config /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/sample-kowala.toml init /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/test.json -cp /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/UTC--2018-01-16T16-31-38.006625000Z--d6e579085c82329c89fca7a9f012be59028ed53f /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/build/bin/.kowala/keystore -./kcoin --config /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/sample-kowala.toml --validate --coinbase 0xd6e579085c82329c89fca7a9f012be59028ed53f --unlock 0xd6e579085c82329c89fca7a9f012be59028ed53f console - -Node 2 - Non Genesis Validator -./kcoin --config /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/sample-kowala2.toml init /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/test.json -cp /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/UTC--2018-01-16T16-33-27.301502000Z--497dc8a0096cf116e696ba9072516c92383770ed /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/build/bin/.kowala2/keystore -./kcoin --config /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/sample-kowala2.toml --validate --coinbase 0x497dc8a0096cf116e696ba9072516c92383770ed --unlock 0x497dc8a0096cf116e696ba9072516c92383770ed --deposit 0 --bootnodes "enode://7873ad60b29d1072ca6be745df23f39eb07131b5ab9e1c565a8d28d59d980686fcb1b65f28066474c3e807a26862868a74a68d86fee1dd11a12e17a0942e050d@127.0.0.1:30303" console 2>> kowala2.log - - - - -eth.sendTransaction({from:eth.coinbase, to:"0xcfff0fdae894be2ed95e02f514b3fbfc1bf41656", value: web3.toWei(0.05, "ether")}) - -tail -f kowala1.log - -./kcoin --config /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/sample-kowala.toml --validate --coinbase 0xd6e579085c82329c89fca7a9f012be59028ed53f --unlock 0xd6e579085c82329c89fca7a9f012be59028ed53f --verbosity 6 - - - -Node 3 - Archive Node (Full sync) - -./kcoin --config /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/sample-kowala3.toml init /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/genesis.json -./kcoin --config /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/sample-kowala3.toml --bootnodes "enode://12750fb281941b23ef8a19b714103769e71cee929ef9adf840079ae01e2b5c9a46bf6f3d78d71f29539c08c153af66ffbf7911091226360b2607c40d00e23f30@127.0.0.1:30303" --verbosity 4 - -Node 4 - Archive Node (Fast sync) - -./kcoin --config /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/sample-kowala4.toml init /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/genesis.json -./kcoin --config /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/sample-kowala4.toml --bootnodes "enode://12750fb281941b23ef8a19b714103769e71cee929ef9adf840079ae01e2b5c9a46bf6f3d78d71f29539c08c153af66ffbf7911091226360b2607c40d00e23f30@127.0.0.1:30303" --cache=512 --verbosity 4 - -Node 5 - Genesis Validator not included as a voter from the start - -// @NOTE(rgeraldes) - deposit needs to be bigger than 100 000 at the moment -./kcoin --config /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/join-election.toml init /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/genesis.json -cp /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/UTC--2018-01-16T16-35-12.309844000Z--259be75d96876f2ada3d202722523e9cd4dd917d /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/build/bin/.kowala10/keystore -./kcoin --config /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/join-election.toml --validate --coinbase 0x259be75d96876f2ada3d202722523e9cd4dd917d --unlock 0x259be75d96876f2ada3d202722523e9cd4dd917d --deposit 0 --bootnodes "enode://e7d246a287b40d3a509b747d8e2d287f30e5f65b31cc565dd61e9bf5515e0ce1de557ca092cfe6ef54428e1324412512e1d3aa56b614daeb052b5be5bb97c5e8@127.0.0.1:30303" - -Node 6 - Non Genesis Validator - -Faucet - -// @NOTE (rgeraldes) - attention to the networkid - -faucet --genesis /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/genesis.json --bootnodes "enode://39a9bc8a8ec8cc52eecbf9d150a45539e81b12de3489a7aeb67bc15b40df4760b7f109ee5bb7ee52a7f229f7284951a679b74c8b2ad5fcb6374fa4c0f2544b40@127.0.0.1:30303" --account.json /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/UTC--2018-01-16T16-35-12.309844000Z--259be75d96876f2ada3d202722523e9cd4dd917d --account.pass /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/password.txt --kcoinport 30004 --network 1 --noauth - -Console - -./kcoin --config /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/sample-kowala.toml init /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/genesis.json -cp /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/internal/assets/UTC--2018-01-16T16-31-38.006625000Z--d6e579085c82329c89fca7a9f012be59028ed53f /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/build/bin/.kowala/keystore -./kcoin --config /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/sample-kowala.toml --validate --coinbase 0xd6e579085c82329c89fca7a9f012be59028ed53f --unlock 0xd6e579085c82329c89fca7a9f012be59028ed53f console 2>> kowala1.log - -./kcoin --config /Users/ricardogeraldes/Code/src/github.com/kowala-tech/kcoin/client/sample-kowala.toml --validate --coinbase 0xd6e579085c82329c89fca7a9f012be59028ed53f --unlock 0xd6e579085c82329c89fca7a9f012be59028ed53f --verbosity 4 console 2>> kowala1.log diff --git a/client/internal/assets/node.key b/client/internal/assets/node.key deleted file mode 100644 index 0e9f7a407..000000000 --- a/client/internal/assets/node.key +++ /dev/null @@ -1 +0,0 @@ -dcc33ed448885a1f576ce8fb8e6a59cb622feba3bd562c4346ba76aea26d1d7e \ No newline at end of file diff --git a/client/internal/assets/password.txt b/client/internal/assets/password.txt deleted file mode 100644 index 30d74d258..000000000 --- a/client/internal/assets/password.txt +++ /dev/null @@ -1 +0,0 @@ -test \ No newline at end of file diff --git a/client/internal/assets/sample-kowala.toml b/client/internal/assets/sample-kowala.toml deleted file mode 100644 index 4b95f9ec6..000000000 --- a/client/internal/assets/sample-kowala.toml +++ /dev/null @@ -1,39 +0,0 @@ -[Kowala] -NetworkId = 3680923 -SyncMode = "full" -LightPeers = 20 -DatabaseCache = 128 -GasPrice = 1 -EnablePreimageRecording = false - -[Kowala.TxPool] -NoLocals = false -Journal = "transactions.rlp" -Rejournal = 3600000000000 -PriceLimit = 1 -PriceBump = 10 -AccountSlots = 16 -GlobalSlots = 4096 -AccountQueue = 64 -GlobalQueue = 1024 -Lifetime = 10800000000000 - -[Kowala.GPO] -Blocks = 10 -Percentile = 50 - -[Node] -DataDir = ".kowala" - -[Node.P2P] -MaxPeers = 25 -NoDiscovery = false -DiscoveryV5Addr = ":30304" -BootstrapNodes = ["enode://111929beaa10c4eef786996c79267ad041b919830d0c66587f213418d759e83416047df57c9dca9cb86af9b4f53b4491112a905ec7bc2540ec73f1fa066bfb8f@54.162.29.69:33445"] -# BootstrapNodesV5 = ["enode://bae38251dece370a6c99482364d433244f183ce74169ed148a57960e46b2ab36995c0ee15d54cdff2edfa92a423ab62faecdb8185a5c536c9090507284c87427@192.168.12.171:33445"] -StaticNodes = [] -TrustedNodes = [] -ListenAddr = ":30303" - -[Stats] -URL = "Ricardo's node (1):DVagynuHLdn9sK6c@testnet.kowala.io:80" diff --git a/client/internal/assets/sample-kowala2.toml b/client/internal/assets/sample-kowala2.toml deleted file mode 100644 index 505269e71..000000000 --- a/client/internal/assets/sample-kowala2.toml +++ /dev/null @@ -1,39 +0,0 @@ -[Kowala] -NetworkId = 3680923 -SyncMode = "full" -LightPeers = 20 -DatabaseCache = 128 -GasPrice = 1 -EnablePreimageRecording = false - -[Kowala.TxPool] -NoLocals = false -Journal = "transactions.rlp" -Rejournal = 3600000000000 -PriceLimit = 1 -PriceBump = 10 -AccountSlots = 16 -GlobalSlots = 4096 -AccountQueue = 64 -GlobalQueue = 1024 -Lifetime = 10800000000000 - -[Kowala.GPO] -Blocks = 10 -Percentile = 50 - -[Node] -DataDir = ".kowala2" - -[Node.P2P] -MaxPeers = 25 -NoDiscovery = false -DiscoveryV5Addr = ":30304" -BootstrapNodes = ["enode://111929beaa10c4eef786996c79267ad041b919830d0c66587f213418d759e83416047df57c9dca9cb86af9b4f53b4491112a905ec7bc2540ec73f1fa066bfb8f@54.162.29.69:33445"] -# BootstrapNodesV5 = ["enode://bae38251dece370a6c99482364d433244f183ce74169ed148a57960e46b2ab36995c0ee15d54cdff2edfa92a423ab62faecdb8185a5c536c9090507284c87427@192.168.12.171:33445"] -StaticNodes = [] -TrustedNodes = [] -ListenAddr = ":30304" - -[Stats] -URL = "Ricardo's node (2):DVagynuHLdn9sK6c@testnet.kowala.io:80" diff --git a/client/internal/assets/sample-kowala3.toml b/client/internal/assets/sample-kowala3.toml deleted file mode 100644 index 5084a74f4..000000000 --- a/client/internal/assets/sample-kowala3.toml +++ /dev/null @@ -1,38 +0,0 @@ -[Kowala] -NetworkId = 1 -SyncMode = "full" -DatabaseCache = 128 -GasPrice = 20 -EnablePreimageRecording = false - -[Kowala.TxPool] -NoLocals = false -Journal = "transactions.rlp" -Rejournal = 3600000000000 -PriceLimit = 1 -PriceBump = 10 -AccountSlots = 16 -GlobalSlots = 4096 -AccountQueue = 64 -GlobalQueue = 1024 -Lifetime = 10800000000000 - -[Kowala.GPO] -Blocks = 10 -Percentile = 50 - -[Node] -DataDir = ".kowala3" - -[Node.P2P] -MaxPeers = 25 -NoDiscovery = false -DiscoveryV5Addr = ":30305" -BootstrapNodes = ["enode://111929beaa10c4eef786996c79267ad041b919830d0c66587f213418d759e83416047df57c9dca9cb86af9b4f53b4491112a905ec7bc2540ec73f1fa066bfb8f@54.162.29.69:33445"] -# BootstrapNodesV5 = ["enode://bae38251dece370a6c99482364d433244f183ce74169ed148a57960e46b2ab36995c0ee15d54cdff2edfa92a423ab62faecdb8185a5c536c9090507284c87427@192.168.12.171:33445"] -StaticNodes = [] -TrustedNodes = [] -ListenAddr = ":30305" - -[Stats] -URL = "Ricardo's archival node (3):DVagynuHLdn9sK6c@testnet.kowala.io:80" diff --git a/client/internal/assets/sample-kowala4.toml b/client/internal/assets/sample-kowala4.toml deleted file mode 100644 index 7615d00a0..000000000 --- a/client/internal/assets/sample-kowala4.toml +++ /dev/null @@ -1,38 +0,0 @@ -[Kowala] -NetworkId = 1 -SyncMode = "fast" -DatabaseCache = 128 -GasPrice = 20 -EnablePreimageRecording = false - -[Kowala.TxPool] -NoLocals = false -Journal = "transactions.rlp" -Rejournal = 3600000000000 -PriceLimit = 1 -PriceBump = 10 -AccountSlots = 16 -GlobalSlots = 4096 -AccountQueue = 64 -GlobalQueue = 1024 -Lifetime = 10800000000000 - -[Kowala.GPO] -Blocks = 10 -Percentile = 50 - -[Node] -DataDir = ".kowala4" - -[Node.P2P] -MaxPeers = 25 -NoDiscovery = false -DiscoveryV5Addr = ":30306" -BootstrapNodes = ["enode://111929beaa10c4eef786996c79267ad041b919830d0c66587f213418d759e83416047df57c9dca9cb86af9b4f53b4491112a905ec7bc2540ec73f1fa066bfb8f@54.162.29.69:33445"] -# BootstrapNodesV5 = ["enode://bae38251dece370a6c99482364d433244f183ce74169ed148a57960e46b2ab36995c0ee15d54cdff2edfa92a423ab62faecdb8185a5c536c9090507284c87427@192.168.12.171:33445"] -StaticNodes = [] -TrustedNodes = [] -ListenAddr = ":30306" - -[Stats] -URL = "Ricardo's archival node (fast sync) (4):DVagynuHLdn9sK6c@testnet.kowala.io:80" diff --git a/client/internal/assets/test.json b/client/internal/assets/test.json deleted file mode 100644 index 742ddfa5c..000000000 --- a/client/internal/assets/test.json +++ /dev/null @@ -1,831 +0,0 @@ -{ - "config": { - "chainID": 3680923, - "konsensus": { - "rewarded": true - } - }, - "timestamp": "0x5ab534e6", - "extraData": - "0x0000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x47b760", - "coinbase": "0x0000000000000000000000000000000000000000", - "alloc": { - "0000000000000000000000000000000000000000": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000001": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000002": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000003": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000004": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000005": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000006": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000007": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000008": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000009": { - "balance": "0x1" - }, - "000000000000000000000000000000000000000a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000000b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000000c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000000d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000000e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000000f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000010": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000011": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000012": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000013": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000014": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000015": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000016": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000017": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000018": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000019": { - "balance": "0x1" - }, - "000000000000000000000000000000000000001a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000001b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000001c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000001d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000001e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000001f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000020": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000021": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000022": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000023": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000024": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000025": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000026": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000027": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000028": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000029": { - "balance": "0x1" - }, - "000000000000000000000000000000000000002a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000002b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000002c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000002d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000002e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000002f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000030": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000031": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000032": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000033": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000034": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000035": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000036": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000037": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000038": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000039": { - "balance": "0x1" - }, - "000000000000000000000000000000000000003a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000003b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000003c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000003d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000003e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000003f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000040": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000041": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000042": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000043": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000044": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000045": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000046": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000047": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000048": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000049": { - "balance": "0x1" - }, - "000000000000000000000000000000000000004a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000004b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000004c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000004d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000004e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000004f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000050": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000051": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000052": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000053": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000054": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000055": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000056": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000057": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000058": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000059": { - "balance": "0x1" - }, - "000000000000000000000000000000000000005a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000005b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000005c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000005d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000005e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000005f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000060": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000061": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000062": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000063": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000064": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000065": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000066": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000067": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000068": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000069": { - "balance": "0x1" - }, - "000000000000000000000000000000000000006a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000006b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000006c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000006d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000006e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000006f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000070": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000071": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000072": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000073": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000074": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000075": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000076": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000077": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000078": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000079": { - "balance": "0x1" - }, - "000000000000000000000000000000000000007a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000007b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000007c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000007d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000007e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000007f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000080": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000081": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000082": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000083": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000084": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000085": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000086": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000087": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000088": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000089": { - "balance": "0x1" - }, - "000000000000000000000000000000000000008a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000008b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000008c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000008d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000008e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000008f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000090": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000091": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000092": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000093": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000094": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000095": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000096": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000097": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000098": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000099": { - "balance": "0x1" - }, - "000000000000000000000000000000000000009a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000009b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000009c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000009d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000009e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000009f": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a0": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a1": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a2": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a3": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a4": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a5": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a6": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a7": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a8": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a9": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000aa": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ab": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ac": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ad": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ae": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000af": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b0": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b1": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b2": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b3": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b4": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b5": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b6": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b7": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b8": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b9": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ba": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000bb": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000bc": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000bd": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000be": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000bf": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c0": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c1": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c2": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c3": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c4": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c5": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c6": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c7": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c8": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c9": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ca": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000cb": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000cc": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000cd": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ce": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000cf": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d0": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d1": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d2": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d3": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d4": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d5": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d6": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d7": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d8": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d9": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000da": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000db": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000dc": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000dd": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000de": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000df": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e0": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e1": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e2": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e3": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e4": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e5": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e6": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e7": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e8": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e9": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ea": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000eb": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ec": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ed": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ee": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ef": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f0": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f1": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f2": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f3": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f4": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f5": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f6": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f7": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f8": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f9": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000fa": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000fb": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000fc": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000fd": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000fe": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ff": { - "balance": "0x1" - }, - "259be75d96876f2ada3d202722523e9cd4dd917d": { - "balance": "0xde0b6b3a7640000" - }, - "497dc8a0096cf116e696ba9072516c92383770ed": { - "balance": - "0x200000000000000000000000000000000000000000000000000000000000000" - }, - "d6e579085c82329c89fca7a9f012be59028ed53f": { - "balance": - "0x200000000000000000000000000000000000000000000000000000000000000" - }, - "fe9bed356e7bc4f7a8fc48cc19c958f4e640ac62": { - "code": - "0x606060405260043610610112576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063035cf1421461011457806308ac52561461013d5780633ed0a373146101665780634b2c89d5146101a457806369474625146101b95780636cf6d675146101e25780637071688a1461020b578063893d20e8146102345780639363a1411461028957806397584b3e146102b25780639bb2ea5a146102df578063b688a36314610302578063b774cb1e1461030c578063c22a933c1461033d578063cefddda914610360578063d66d9e19146103b1578063e7a60a9c146103c6578063f2fde38b14610430578063f963aeea14610481578063facd743b146104d6575b005b341561011f57600080fd5b610127610527565b6040518082815260200191505060405180910390f35b341561014857600080fd5b6101506105fb565b6040518082815260200191505060405180910390f35b341561017157600080fd5b6101876004808035906020019091905050610601565b604051808381526020018281526020019250505060405180910390f35b34156101af57600080fd5b6101b7610679565b005b34156101c457600080fd5b6101cc6107b8565b6040518082815260200191505060405180910390f35b34156101ed57600080fd5b6101f56107be565b6040518082815260200191505060405180910390f35b341561021657600080fd5b61021e6107c4565b6040518082815260200191505060405180910390f35b341561023f57600080fd5b6102476107d1565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561029457600080fd5b61029c6107fa565b6040518082815260200191505060405180910390f35b34156102bd57600080fd5b6102c5610847565b604051808215151515815260200191505060405180910390f35b34156102ea57600080fd5b610300600480803590602001909190505061085a565b005b61030a6108fe565b005b341561031757600080fd5b61031f61094c565b60405180826000191660001916815260200191505060405180910390f35b341561034857600080fd5b61035e6004808035906020019091905050610952565b005b341561036b57600080fd5b610397600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506109b7565b604051808215151515815260200191505060405180910390f35b34156103bc57600080fd5b6103c4610a11565b005b34156103d157600080fd5b6103e76004808035906020019091905050610a30565b604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390f35b341561043b57600080fd5b610467600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610ae8565b604051808215151515815260200191505060405180910390f35b341561048c57600080fd5b610494610bc5565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104e157600080fd5b61050d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610beb565b604051808215151515815260200191505060405180910390f35b600080610532610847565b156105415760015491506105f7565b60066000600760016007805490500381548110151561055c57fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060018160020160018360020180549050038154811015156105e157fe5b9060005260206000209060020201600001540191505b5090565b60025481565b6000806000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002018481548110151561065557fe5b90600052602060002090600202019050806000015481600101549250925050915091565b600080600080925060009150600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020190505b8080549050821080156106fd5750600081838154811015156106e857fe5b90600052602060002090600202016001015414155b1561075f57808281548110151561071057fe5b90600052602060002090600202016001015442101561072e5761075f565b808281548110151561073c57fe5b9060005260206000209060020201600001548301925081806001019250506106ca565b6107693383610c44565b60008311156107b3573373ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f1935050505015156107b257600080fd5b5b505050565b60015481565b60035481565b6000600780549050905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020180549050905090565b6000806007805490506002540311905090565b6000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156108b857600080fd5b6007805490508310156108f25782600780549050039150600090505b818110156108f1576108e4610d31565b80806001019150506108d4565b5b82600281905550505050565b61090733610beb565b15151561091357600080fd5b61091b610527565b341015151561092957600080fd5b610931610847565b15156109405761093f610d31565b5b61094a3334610d7e565b565b60055481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156109ad57600080fd5b8060018190555050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050919050565b610a1a33610beb565b1515610a2557600080fd5b610a2e33611098565b565b6000806000600784815481101515610a4457fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169250600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050806002016001826002018054905003815481101515610ace57fe5b906000526020600020906002020160000154915050915091565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610b4557600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141515610bbc57816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60019050919050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff169050919050565b600080600080841415610c5657610d2a565b600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209250600091508390505b8260020180549050811015610d18578260020181815481101515610cbf57fe5b90600052602060002090600202018360020183815481101515610cde57fe5b9060005260206000209060020201600082015481600001556001820154816001015590505081806001019250508080600101915050610c9f565b818360020181610d28919061128f565b505b5050505050565b610d7c6007600160078054905003815481101515610d4b57fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16611098565b565b600080600080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209350600160078054806001018281610ddb91906112c1565b9160005260206000209001600089909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555003846000018190555060018460010160006101000a81548160ff021916908315150217905550836002018054806001018281610e6591906112ed565b916000526020600020906002020160006040805190810160405280898152602001600081525090919091506000820151816000015560208201518160010155505050836000015492505b60008311156110885760066000600760018603815481101515610ece57fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209150816002016001836002018054905003815481101515610f5157fe5b90600052602060002090600202019050806000015485111515610f7357611088565b600760018403815481101515610f8557fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600784815481101515610fc057fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508560076001850381548110151561101c57fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828260000181905550600183038460000181905550828060019003935050610eaf565b61109061120c565b505050505050565b600080600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209150816000015490505b6001600780549050038110156111975760076001820181548110151561110657fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660078281548110151561114157fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080806001019150506110e4565b60078054809190600190036111ac919061131f565b5060008260010160006101000a81548160ff02191690831515021790555060035442018260020160018460020180549050038154811015156111ea57fe5b90600052602060002090600202016001018190555061120761120c565b505050565b600760405180828054801561127657602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001906001019080831161122c575b5050915050604051809103902060058160001916905550565b8154818355818115116112bc576002028160020283600052602060002091820191016112bb919061134b565b5b505050565b8154818355818115116112e8578183600052602060002091820191016112e7919061137a565b5b505050565b81548183558181151161131a57600202816002028360005260206000209182019101611319919061134b565b5b505050565b81548183558181151161134657818360005260206000209182019101611345919061137a565b5b505050565b61137791905b8082111561137357600080820160009055600182016000905550600201611351565b5090565b90565b61139c91905b80821115611398576000816000905550600101611380565b5090565b905600a165627a7a72305820881930b6f16ce882a4514160cdfd6c97c8741d251701b86838dd2b3f3cc337ab0029", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": - "0x000000000000000000000000259be75d96876f2ada3d202722523e9cd4dd917d", - "0x0000000000000000000000000000000000000000000000000000000000000001": - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002": - "0x0000000000000000000000000000000000000000000000000000000000000064", - "0x0000000000000000000000000000000000000000000000000000000000000003": - "0x0000000000000000000000000000000000000000000000000000000000015180", - "0x0000000000000000000000000000000000000000000000000000000000000004": - "0x000000000000000000000000d6e579085c82329c89fca7a9f012be59028ed53f", - "0x0000000000000000000000000000000000000000000000000000000000000005": - "0x12477bc1dfe8a4faf0c2e4bfb2c50cf3981368a304201dc9aba236dbee40db72", - "0x0000000000000000000000000000000000000000000000000000000000000007": - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688": - "0x000000000000000000000000d6e579085c82329c89fca7a9f012be59028ed53f", - "0xb7258c32ea11fe2c3bbfdd0d61e71124d642d4aa559c217c9083a7b8000f1cc4": - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xb7258c32ea11fe2c3bbfdd0d61e71124d642d4aa559c217c9083a7b8000f1cc5": - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xb7258c32ea11fe2c3bbfdd0d61e71124d642d4aa559c217c9083a7b8000f1cc6": - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xe716af36e7ec4868c5e52ab6a359350606280aa1f37f8dbd8324d6d0fd9fce77": - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xe716af36e7ec4868c5e52ab6a359350606280aa1f37f8dbd8324d6d0fd9fce78": - "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "balance": "0x0" - } - }, - "number": "0x0", - "gasUsed": "0x0", - "parentHash": - "0x0000000000000000000000000000000000000000000000000000000000000000" -} diff --git a/client/internal/assets/test.md b/client/internal/assets/test.md deleted file mode 100644 index 337d9af73..000000000 --- a/client/internal/assets/test.md +++ /dev/null @@ -1,23 +0,0 @@ -# Accounts - -## Genesis Validators - -1. -Address: 0xd6e579085c82329c89fca7a9f012be59028ed53f -File: UTC--2018-01-16T16-31-38.006625000Z--d6e579085c82329c89fca7a9f012be59028ed53f -Passphrase: test - -2. -Address: 0x497dc8a0096cf116e696ba9072516c92383770ed -File: UTC--2018-01-16T16-33-27.301502000Z--497dc8a0096cf116e696ba9072516c92383770ed -Passphrase: test - -## Contract Owner - -Address: 0x259be75d96876f2ada3d202722523e9cd4dd917d -File: UTC--2018-01-16T16-35-12.309844000Z--259be75d96876f2ada3d202722523e9cd4dd917d -Passphrase: test - -## Genesis file - -File: genesis.json diff --git a/client/internal/kcoinapi/api.go b/client/internal/kcoinapi/api.go index 3e183f156..7f3211a0a 100644 --- a/client/internal/kcoinapi/api.go +++ b/client/internal/kcoinapi/api.go @@ -23,6 +23,7 @@ import ( "github.com/kowala-tech/kcoin/client/log" "github.com/kowala-tech/kcoin/client/p2p" "github.com/kowala-tech/kcoin/client/params" + "github.com/kowala-tech/kcoin/client/params/effort" "github.com/kowala-tech/kcoin/client/rlp" "github.com/kowala-tech/kcoin/client/rpc" "github.com/syndtr/goleveldb/leveldb" @@ -30,9 +31,8 @@ import ( ) const ( - defaultGas = 90000 - defaultGasPrice = 50 * params.Shannon - emptyHex = "0x" + defaultComputeLimit = 90000 + emptyHex = "0x" ) // PublicKowalaAPI provides an API to access Kowala related information. @@ -46,11 +46,6 @@ func NewPublicKowalaAPI(b Backend) *PublicKowalaAPI { return &PublicKowalaAPI{b} } -// GasPrice returns a suggestion for a gas price. -func (s *PublicKowalaAPI) GasPrice(ctx context.Context) (*big.Int, error) { - return s.b.SuggestPrice(ctx) -} - // ProtocolVersion returns the current Kowala protocol version this node supports func (s *PublicKowalaAPI) ProtocolVersion() hexutil.Uint { return hexutil.Uint(s.b.ProtocolVersion()) @@ -138,9 +133,9 @@ func (s *PublicTxPoolAPI) Inspect() map[string]map[string]map[string]string { // Define a formatter to flatten a transaction into a string var format = func(tx *types.Transaction) string { if to := tx.To(); to != nil { - return fmt.Sprintf("%s: %v wei + %v gas × %v wei", tx.To().Hex(), tx.Value(), tx.Gas(), tx.GasPrice()) + return fmt.Sprintf("%s: %v wei + %v compute limit", tx.To().Hex(), tx.Value(), tx.ComputeLimit()) } - return fmt.Sprintf("contract creation: %v wei + %v gas × %v wei", tx.Value(), tx.Gas(), tx.GasPrice()) + return fmt.Sprintf("contract creation: %v wei + %v compute limit", tx.Value(), tx.ComputeLimit()) } // Flatten the pending transactions for account, txs := range pending { @@ -320,7 +315,7 @@ func (s *PrivateAccountAPI) LockAccount(addr common.Address) bool { return fetchKeystore(s.am).Lock(addr) == nil } -// signTransactions sets defaults and signs the given transaction +// signTransaction sets defaults and signs the given transaction // NOTE: the caller needs to ensure that the nonceLock is held, if applicable, // and release it after the transaction has been submitted to the tx pool func (s *PrivateAccountAPI) signTransaction(ctx context.Context, args SendTxArgs, passwd string) (*types.Transaction, error) { @@ -366,11 +361,8 @@ func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs func (s *PrivateAccountAPI) SignTransaction(ctx context.Context, args SendTxArgs, passwd string) (*SignTransactionResult, error) { // No need to obtain the noncelock mutex, since we won't be sending this // tx into the transaction pool, but right back to the user - if args.Gas == nil { - return nil, fmt.Errorf("gas not specified") - } - if args.GasPrice == nil { - return nil, fmt.Errorf("gasPrice not specified") + if args.ComputeLimit == nil { + return nil, fmt.Errorf("compute limit not specified") } if args.Nonce == nil { return nil, fmt.Errorf("nonce not specified") @@ -535,16 +527,15 @@ func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.A // CallArgs represents the arguments for a call. type CallArgs struct { - From common.Address `json:"from"` - To *common.Address `json:"to"` - Gas hexutil.Uint64 `json:"gas"` - GasPrice hexutil.Big `json:"gasPrice"` - Value hexutil.Big `json:"value"` - Data hexutil.Bytes `json:"data"` + From common.Address `json:"from"` + To *common.Address `json:"to"` + ComputeLimit hexutil.Uint64 `json:"computeLimit"` + Value hexutil.Big `json:"value"` + Data hexutil.Bytes `json:"data"` } func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber, vmCfg vm.Config, timeout time.Duration) ([]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 VM call finished", "runtime", time.Since(start)) }(time.Now()) state, header, err := s.b.StateAndHeaderByNumber(ctx, blockNr) if state == nil || err != nil { @@ -562,20 +553,17 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr } } } - // Set default gas & gas price if none were set - gas, gasPrice := uint64(args.Gas), args.GasPrice.ToInt() - if gas == 0 { - gas = math.MaxUint64 / 2 - } - if gasPrice.Sign() == 0 { - gasPrice = new(big.Int).SetUint64(defaultGasPrice) + // Set default compute limit if not set + computeLimit := uint64(args.ComputeLimit) + if computeLimit == 0 { + computeLimit = math.MaxUint64 / 2 } // Create new call message - msg := types.NewMessage(addr, args.To, 0, args.Value.ToInt(), gas, gasPrice, args.Data, false) + msg := types.NewMessage(addr, args.To, 0, args.Value.ToInt(), computeLimit, args.Data, false) // Setup context so it may be cancelled the call has completed - // or, in case of unmetered gas, setup a context with a timeout. + // or, in case of unmetered computational resource, setup a context with a timeout. var cancel context.CancelFunc if timeout > 0 { ctx, cancel = context.WithTimeout(ctx, timeout) @@ -586,30 +574,27 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr // this makes sure resources are cleaned up. defer cancel() - // Get a new instance of the EVM. - evm, vmError, err := s.b.GetEVM(ctx, msg, state, header, vmCfg) + // Get a new instance of the VM. + vmachine, vmError, err := s.b.GetVM(ctx, msg, state, header, vmCfg) if err != nil { - log.Error("an error while the blockchain do a call. can't get a EVM instance", "err", err) + log.Error("an error while the blockchain do a call. can't get a VM instance", "err", err) return nil, 0, false, err } - // Wait for the context to be done and cancel the evm. Even if the - // EVM has finished, cancelling may be done (repeatedly) + // Wait for the context to be done and cancel the vm. Even if the + // VM has finished, cancelling may be done (repeatedly) go func() { <-ctx.Done() - evm.Cancel() + vmachine.Cancel() }() - // Setup the gas pool (also for unmetered requests) + // Setup the computational resource pool (also for unmetered requests) // and apply the message. - gp := new(core.GasPool).AddGas(math.MaxUint64) - res, gas, failed, err := core.ApplyMessage(evm, msg, gp) + crpool := new(core.ComputationalResourcePool).AddResource(math.MaxUint64) + res, resourceUsage, failed, err := core.ApplyMessage(vmachine, msg, crpool) if err := vmError(); err != nil { - if err != nil { - log.Error("an error while setting GasPrice", "err", err) - } return nil, 0, false, err } - return res, gas, failed, err + return res, resourceUsage, failed, err } // Call executes the given transaction on the state for the given block number. @@ -619,42 +604,37 @@ func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNr r return (hexutil.Bytes)(result), err } -// EstimateGas returns an estimate of the amount of gas needed to execute the +// EstimateComputationalEffort returns an estimate of the computational effort required to execute the // given transaction against the current pending block. -func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (hexutil.Uint64, error) { - // Binary search the gas requirement, as it may be higher than the amount used +func (s *PublicBlockChainAPI) EstimateComputationalEffort(ctx context.Context, args CallArgs) (hexutil.Uint64, error) { + // Binary search the resource requirement, as it may be higher than the amount used var ( - lo uint64 = params.TxGas - 1 + lo uint64 = effort.Tx - 1 hi uint64 cap uint64 ) - if uint64(args.Gas) >= params.TxGas { - hi = uint64(args.Gas) + if uint64(args.ComputeLimit) >= effort.Tx { + hi = uint64(args.ComputeLimit) } else { - // Retrieve the current pending block to act as the gas ceiling - block, err := s.b.BlockByNumber(ctx, rpc.PendingBlockNumber) - if err != nil { - return 0, err - } - hi = block.GasLimit() + hi = params.ComputeCapacity } cap = hi - // Create a helper to check if a gas allowance results in an executable transaction - executable := func(gas uint64) bool { - args.Gas = hexutil.Uint64(gas) + // Create a helper to check if a resource allowance results in an executable transaction + executable := func(computeLimit uint64) bool { + args.ComputeLimit = hexutil.Uint64(computeLimit) _, _, failed, err := s.doCall(ctx, args, rpc.PendingBlockNumber, vm.Config{}, 0) if err != nil || failed { if err != nil { - log.Error("can't estimate gas limit", "err", err) + log.Error("can't estimate compute limit", "err", err) } return false } return true } - // Execute the binary search and hone in on an executable gas limit + // Execute the binary search and hone in on an executable compute limit for lo+1 < hi { mid := (hi + lo) / 2 if !executable(mid) { @@ -666,47 +646,47 @@ func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (h // Reject the transaction as invalid if it still fails at the highest allowance if hi == cap { if !executable(hi) { - return 0, fmt.Errorf("gas required exceeds allowance or always failing transaction") + return 0, fmt.Errorf("computational effort required exceeds allowance or always failing transaction") } } return hexutil.Uint64(hi), nil } -// ExecutionResult groups all structured logs emitted by the EVM +// ExecutionResult groups all structured logs emitted by the VM // 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 resource usage and the return value type ExecutionResult struct { - Gas uint64 `json:"gas"` - Failed bool `json:"failed"` - ReturnValue string `json:"returnValue"` - StructLogs []StructLogRes `json:"structLogs"` + ResourceUsage uint64 `json:"resourceUsage"` + Failed bool `json:"failed"` + ReturnValue string `json:"returnValue"` + StructLogs []StructLogRes `json:"structLogs"` } -// StructLogRes stores a structured log emitted by the EVM while replaying a +// StructLogRes stores a structured log emitted by the VM while replaying a // transaction in debug mode type StructLogRes struct { - Pc uint64 `json:"pc"` - Op string `json:"op"` - Gas uint64 `json:"gas"` - GasCost uint64 `json:"gasCost"` - Depth int `json:"depth"` - Error error `json:"error,omitempty"` - Stack *[]string `json:"stack,omitempty"` - Memory *[]string `json:"memory,omitempty"` - Storage *map[string]string `json:"storage,omitempty"` -} - -// formatLogs formats EVM returned structured logs for json output + Pc uint64 `json:"pc"` + Op string `json:"op"` + ComputationalResource uint64 `json:"compResource"` + ComputeUnitPrice uint64 `json:"compUnitPrice"` + Depth int `json:"depth"` + Error error `json:"error,omitempty"` + Stack *[]string `json:"stack,omitempty"` + Memory *[]string `json:"memory,omitempty"` + Storage *map[string]string `json:"storage,omitempty"` +} + +// formatLogs formats VM returned structured logs for json output func FormatLogs(logs []vm.StructLog) []StructLogRes { formatted := make([]StructLogRes, len(logs)) for index, trace := range logs { formatted[index] = StructLogRes{ - Pc: trace.Pc, - Op: trace.Op.String(), - Gas: trace.Gas, - GasCost: trace.GasCost, - Depth: trace.Depth, - Error: trace.Err, + Pc: trace.Pc, + Op: trace.Op.String(), + ComputationalResource: trace.Resource, + ComputeUnitPrice: trace.ComputeUnitPrice, + Depth: trace.Depth, + Error: trace.Err, } if trace.Stack != nil { stack := make([]string, len(trace.Stack)) @@ -747,8 +727,7 @@ func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]inter "miner": head.Coinbase, "extraData": hexutil.Bytes(head.Extra), "size": hexutil.Uint64(b.Size()), - "gasLimit": hexutil.Uint64(head.GasLimit), - "gasUsed": hexutil.Uint64(head.GasUsed), + "resourceUsage": hexutil.Uint64(head.ResourceUsage), "timestamp": (*hexutil.Big)(head.Time), "transactionsRoot": head.TxHash, "receiptsRoot": head.ReceiptHash, @@ -781,14 +760,13 @@ func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]inter return fields, nil } -// rpcOutputBlock uses the generalized output filler, then adds the total difficulty field, which requires -// a `PublicBlockchainAPI`. +// rpcOutputBlock uses the generalized output filler. func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { fields, err := RPCMarshalBlock(b, inclTx, fullTx) if err != nil { return nil, err } - //fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(b.Hash())) + return fields, err } @@ -797,8 +775,7 @@ type RPCTransaction struct { BlockHash common.Hash `json:"blockHash"` BlockNumber *hexutil.Big `json:"blockNumber"` From common.Address `json:"from"` - Gas hexutil.Uint64 `json:"gas"` - GasPrice *hexutil.Big `json:"gasPrice"` + ComputeLimit hexutil.Uint64 `json:"computeLimit"` Hash common.Hash `json:"hash"` Input hexutil.Bytes `json:"input"` Nonce hexutil.Uint64 `json:"nonce"` @@ -819,17 +796,16 @@ func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber v, r, s := tx.RawSignatureValues() result := &RPCTransaction{ - From: from, - Gas: hexutil.Uint64(tx.Gas()), - GasPrice: (*hexutil.Big)(tx.GasPrice()), - Hash: tx.Hash(), - Input: hexutil.Bytes(tx.Data()), - Nonce: hexutil.Uint64(tx.Nonce()), - To: tx.To(), - Value: (*hexutil.Big)(tx.Value()), - V: (*hexutil.Big)(v), - R: (*hexutil.Big)(r), - S: (*hexutil.Big)(s), + From: from, + ComputeLimit: hexutil.Uint64(tx.ComputeLimit()), + Hash: tx.Hash(), + Input: hexutil.Bytes(tx.Data()), + Nonce: hexutil.Uint64(tx.Nonce()), + To: tx.To(), + Value: (*hexutil.Big)(tx.Value()), + V: (*hexutil.Big)(v), + R: (*hexutil.Big)(r), + S: (*hexutil.Big)(s), } if blockHash != (common.Hash{}) { result.BlockHash = blockHash @@ -992,17 +968,17 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, ha from, _ := types.TxSender(signer, tx) fields := map[string]interface{}{ - "blockHash": blockHash, - "blockNumber": hexutil.Uint64(blockNumber), - "transactionHash": hash, - "transactionIndex": hexutil.Uint64(index), - "from": from, - "to": tx.To(), - "gasUsed": hexutil.Uint64(receipt.GasUsed), - "cumulativeGasUsed": hexutil.Uint64(receipt.CumulativeGasUsed), - "contractAddress": nil, - "logs": receipt.Logs, - "logsBloom": receipt.Bloom, + "blockHash": blockHash, + "blockNumber": hexutil.Uint64(blockNumber), + "transactionHash": hash, + "transactionIndex": hexutil.Uint64(index), + "from": from, + "to": tx.To(), + "resourceUsage": hexutil.Uint64(receipt.ResourceUsage), + "cumulativeResourceUsage": hexutil.Uint64(receipt.CumulativeResourceUsage), + "contractAddress": nil, + "logs": receipt.Logs, + "logsBloom": receipt.Bloom, } // Assign receipt status or post state. @@ -1038,12 +1014,11 @@ func (s *PublicTransactionPoolAPI) sign(addr common.Address, tx *types.Transacti // SendTxArgs represents the arguments to sumbit a new transaction into the transaction pool. type SendTxArgs struct { - From common.Address `json:"from"` - To *common.Address `json:"to"` - Gas *hexutil.Uint64 `json:"gas"` - GasPrice *hexutil.Big `json:"gasPrice"` - Value *hexutil.Big `json:"value"` - Nonce *hexutil.Uint64 `json:"nonce"` + From common.Address `json:"from"` + To *common.Address `json:"to"` + ComputeLimit *hexutil.Uint64 `json:"computeLimit"` + Value *hexutil.Big `json:"value"` + Nonce *hexutil.Uint64 `json:"nonce"` // We accept "data" and "input" for backwards-compatibility reasons. "input" is the // newer name and should be preferred by clients. Data *hexutil.Bytes `json:"data"` @@ -1052,16 +1027,9 @@ type SendTxArgs struct { // setDefaults is a helper function that fills in default values for unspecified tx fields. func (args *SendTxArgs) setDefaults(ctx context.Context, b Backend) error { - if args.Gas == nil { - args.Gas = new(hexutil.Uint64) - *(*uint64)(args.Gas) = 90000 - } - if args.GasPrice == nil { - price, err := b.SuggestPrice(ctx) - if err != nil { - return err - } - args.GasPrice = (*hexutil.Big)(price) + if args.ComputeLimit == nil { + args.ComputeLimit = new(hexutil.Uint64) + *(*uint64)(args.ComputeLimit) = 90000 } if args.Value == nil { args.Value = new(hexutil.Big) @@ -1099,9 +1067,9 @@ func (args *SendTxArgs) toTransaction() *types.Transaction { input = *args.Input } if args.To == nil { - return types.NewContractCreation(uint64(*args.Nonce), (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), input) + return types.NewContractCreation(uint64(*args.Nonce), (*big.Int)(args.Value), uint64(*args.ComputeLimit), input) } - return types.NewTransaction(uint64(*args.Nonce), *args.To, (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), input) + return types.NewTransaction(uint64(*args.Nonce), *args.To, (*big.Int)(args.Value), uint64(*args.ComputeLimit), input) } // submitTransaction is a helper function that submits tx to txPool and logs a message. @@ -1203,11 +1171,8 @@ type SignTransactionResult struct { // The node needs to have the private key of the account corresponding with // the given from address and it needs to be unlocked. func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args SendTxArgs) (*SignTransactionResult, error) { - if args.Gas == nil { - return nil, fmt.Errorf("gas not specified") - } - if args.GasPrice == nil { - return nil, fmt.Errorf("gasPrice not specified") + if args.ComputeLimit == nil { + return nil, fmt.Errorf("compute limit not specified") } if args.Nonce == nil { return nil, fmt.Errorf("nonce not specified") @@ -1229,10 +1194,7 @@ func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args Sen // PendingTransactions returns the transactions that are in the transaction pool // and have a from address that is one of the accounts this node manages. func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, error) { - pending, err := s.b.GetPoolTransactions() - if err != nil { - return nil, err - } + pending := s.b.GetPoolTransactions() accounts := make(map[common.Address]struct{}) for _, wallet := range s.b.AccountManager().Wallets() { for _, account := range wallet.Accounts() { @@ -1251,49 +1213,6 @@ func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, err return transactions, nil } -// 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. -func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxArgs, gasPrice *hexutil.Big, gasLimit *hexutil.Uint64) (common.Hash, error) { - if sendArgs.Nonce == nil { - return common.Hash{}, fmt.Errorf("missing transaction nonce in transaction spec") - } - if err := sendArgs.setDefaults(ctx, s.b); err != nil { - return common.Hash{}, err - } - matchTx := sendArgs.toTransaction() - pending, err := s.b.GetPoolTransactions() - if err != nil { - return common.Hash{}, err - } - - for _, p := range pending { - signer := types.NewAndromedaSigner(p.ChainID()) - - wantSigHash := matchTx.ProtectedHash(p.ChainID()) - hash := p.ProtectedHash(p.ChainID()) - - if pFrom, err := types.TxSender(signer, p); err == nil && pFrom == sendArgs.From && hash == wantSigHash { - // Match. Re-sign and send the transaction. - if gasPrice != nil && (*big.Int)(gasPrice).Sign() != 0 { - sendArgs.GasPrice = gasPrice - } - if gasLimit != nil && *gasLimit != 0 { - sendArgs.Gas = gasLimit - } - signedTx, err := s.sign(sendArgs.From, sendArgs.toTransaction()) - if err != nil { - return common.Hash{}, err - } - if err = s.b.SendTx(ctx, signedTx); err != nil { - return common.Hash{}, err - } - return signedTx.Hash(), nil - } - } - - return common.Hash{}, fmt.Errorf("Transaction %#x not found", matchTx.Hash()) -} - // PublicDebugAPI is the collection of Kowala APIs exposed over the public // debugging endpoint. type PublicDebugAPI struct { diff --git a/client/internal/kcoinapi/backend.go b/client/internal/kcoinapi/backend.go index 9a32dcc4c..348703799 100644 --- a/client/internal/kcoinapi/backend.go +++ b/client/internal/kcoinapi/backend.go @@ -3,7 +3,6 @@ package kcoinapi import ( "context" - "math/big" "github.com/kowala-tech/kcoin/client/accounts" "github.com/kowala-tech/kcoin/client/common" @@ -24,7 +23,6 @@ type Backend interface { // General Ethereum API Downloader() *downloader.Downloader ProtocolVersion() int - SuggestPrice(ctx context.Context) (*big.Int, error) ChainDb() kcoindb.Database EventMux() *event.TypeMux AccountManager() *accounts.Manager @@ -36,14 +34,14 @@ type Backend interface { StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error) GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error) GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error) - GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header, vmCfg vm.Config) (*vm.EVM, func() error, error) + GetVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header, vmCfg vm.Config) (*vm.VM, func() error, error) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription // TxPool API SendTx(ctx context.Context, signedTx *types.Transaction) error - GetPoolTransactions() (types.Transactions, error) + GetPoolTransactions() types.Transactions GetPoolTransaction(txHash common.Hash) *types.Transaction GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) Stats() (pending int, queued int) diff --git a/client/internal/web3ext/web3ext.go b/client/internal/web3ext/web3ext.go index b1e256f9b..5e8a2def6 100644 --- a/client/internal/web3ext/web3ext.go +++ b/client/internal/web3ext/web3ext.go @@ -522,12 +522,6 @@ web3._extend({ call: 'validator_setExtra', params: 1 }), - new web3._extend.Method({ - name: 'setGasPrice', - call: 'validator_setGasPrice', - params: 1, - inputFormatter: [web3._extend.utils.fromDecimal] - }), new web3._extend.Method({ name: 'getMinimumDeposit', call: 'validator_getMinimumDeposit', diff --git a/client/kcoinclient/client.go b/client/kcoinclient/client.go index 5a7cdaec9..e6b41c4bf 100644 --- a/client/kcoinclient/client.go +++ b/client/kcoinclient/client.go @@ -454,7 +454,7 @@ func (ec *Client) CallContract(ctx context.Context, msg kowala.CallMsg, blockNum return hex, nil } -// PendingCallContract executes a message call transaction using the EVM. +// PendingCallContract executes a message call transaction using the VM. // The state seen by the contract call is the pending state. func (ec *Client) PendingCallContract(ctx context.Context, msg kowala.CallMsg) ([]byte, error) { var hex hexutil.Bytes @@ -465,23 +465,13 @@ func (ec *Client) PendingCallContract(ctx context.Context, msg kowala.CallMsg) ( return hex, nil } -// SuggestGasPrice retrieves the currently suggested gas price to allow a timely -// execution of a transaction. -func (ec *Client) SuggestGasPrice(ctx context.Context) (*big.Int, error) { - var hex big.Int - if err := ec.c.CallContext(ctx, &hex, "eth_gasPrice"); err != nil { - return nil, err - } - return &hex, nil -} - -// EstimateGas tries to estimate the gas needed to execute a specific transaction based on +// EstimateComputationalEffort tries to estimate the required computational effort to execute a specific transaction based on // 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 compute limit requirement as other transactions may be added or removed by miners, // but it should provide a basis for setting a reasonable default. -func (ec *Client) EstimateGas(ctx context.Context, msg kowala.CallMsg) (uint64, error) { +func (ec *Client) EstimateComputationalEffort(ctx context.Context, msg kowala.CallMsg) (uint64, error) { var hex hexutil.Uint64 - err := ec.c.CallContext(ctx, &hex, "eth_estimateGas", toCallArg(msg)) + err := ec.c.CallContext(ctx, &hex, "eth_estimateComputationalEffort", toCallArg(msg)) if err != nil { return 0, err } @@ -519,11 +509,8 @@ func toCallArg(msg kowala.CallMsg) interface{} { if msg.Value != nil { arg["value"] = (*hexutil.Big)(msg.Value) } - if msg.Gas != 0 { - arg["gas"] = hexutil.Uint64(msg.Gas) - } - if msg.GasPrice != nil { - arg["gasPrice"] = (*hexutil.Big)(msg.GasPrice) + if msg.ComputeLimit != 0 { + arg["computeLimit"] = hexutil.Uint64(msg.ComputeLimit) } return arg } diff --git a/client/knode/api.go b/client/knode/api.go index 9be4ef2b3..726615d74 100644 --- a/client/knode/api.go +++ b/client/knode/api.go @@ -61,11 +61,6 @@ func NewPrivateValidatorAPI(kcoin *Kowala) *PrivateValidatorAPI { func (api *PrivateValidatorAPI) Start(deposit *big.Int) error { // Start the validator and return if !api.kcoin.IsValidating() { - // Propagate the initial price point to the transaction pool - api.kcoin.lock.RLock() - price := api.kcoin.gasPrice - api.kcoin.lock.RUnlock() - if deposit != nil { err := api.kcoin.SetDeposit(deposit) if err != nil && err != validator.ErrIsNotRunning { @@ -73,7 +68,6 @@ func (api *PrivateValidatorAPI) Start(deposit *big.Int) error { } } - api.kcoin.txPool.SetGasPrice(price) return api.kcoin.StartValidating() } return nil @@ -93,16 +87,6 @@ func (api *PrivateValidatorAPI) SetExtra(extra string) (bool, error) { return true, nil } -// SetGasPrice sets the minimum accepted gas price for the validator. -func (api *PrivateValidatorAPI) SetGasPrice(gasPrice hexutil.Big) bool { - api.kcoin.lock.Lock() - api.kcoin.gasPrice = (*big.Int)(&gasPrice) - api.kcoin.lock.Unlock() - - api.kcoin.txPool.SetGasPrice((*big.Int)(&gasPrice)) - return true -} - // SetCoinbase sets the coinbase of the validator func (api *PrivateValidatorAPI) SetCoinbase(coinbase common.Address) bool { api.kcoin.SetCoinbase(coinbase) diff --git a/client/knode/api_backend.go b/client/knode/api_backend.go index 1d73c3497..35c287802 100644 --- a/client/knode/api_backend.go +++ b/client/knode/api_backend.go @@ -2,7 +2,6 @@ package knode import ( "context" - "math/big" "github.com/kowala-tech/kcoin/client/accounts" "github.com/kowala-tech/kcoin/client/common" @@ -16,7 +15,6 @@ import ( "github.com/kowala-tech/kcoin/client/event" "github.com/kowala-tech/kcoin/client/kcoindb" "github.com/kowala-tech/kcoin/client/knode/downloader" - "github.com/kowala-tech/kcoin/client/knode/gasprice" "github.com/kowala-tech/kcoin/client/params" "github.com/kowala-tech/kcoin/client/rpc" ) @@ -24,7 +22,6 @@ import ( // KowalaAPIBackend implements kcoinapi.Backend for full nodes type KowalaAPIBackend struct { kcoin *Kowala - gpo *gasprice.Oracle } // ChainConfig returns the active chain configuration. @@ -111,12 +108,12 @@ func (b *KowalaAPIBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]* return logs, nil } -func (b *KowalaAPIBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header, vmCfg vm.Config) (*vm.EVM, func() error, error) { +func (b *KowalaAPIBackend) GetVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header, vmCfg vm.Config) (*vm.VM, func() error, error) { state.SetBalance(msg.From(), math.MaxBig256) vmError := func() error { return nil } - context := core.NewEVMContext(msg, header, b.kcoin.BlockChain(), nil) - return vm.NewEVM(context, state, b.kcoin.chainConfig, vmCfg), vmError, nil + context := core.NewVMContext(msg, header, b.kcoin.BlockChain(), nil) + return vm.New(context, state, b.kcoin.chainConfig, vmCfg), vmError, nil } func (b *KowalaAPIBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription { @@ -143,16 +140,13 @@ func (b *KowalaAPIBackend) SendTx(ctx context.Context, signedTx *types.Transacti return b.kcoin.txPool.AddLocal(signedTx) } -func (b *KowalaAPIBackend) GetPoolTransactions() (types.Transactions, error) { - pending, err := b.kcoin.txPool.Pending() - if err != nil { - return nil, err - } +func (b *KowalaAPIBackend) GetPoolTransactions() types.Transactions { + pending := b.kcoin.txPool.Pending() var txs types.Transactions for _, batch := range pending { txs = append(txs, batch...) } - return txs, nil + return txs } func (b *KowalaAPIBackend) GetPoolTransaction(hash common.Hash) *types.Transaction { @@ -183,10 +177,6 @@ func (b *KowalaAPIBackend) ProtocolVersion() int { return b.kcoin.EthVersion() } -func (b *KowalaAPIBackend) SuggestPrice(ctx context.Context) (*big.Int, error) { - return b.gpo.SuggestPrice(ctx) -} - func (b *KowalaAPIBackend) ChainDb() kcoindb.Database { return b.kcoin.ChainDb() } diff --git a/client/knode/api_tracer.go b/client/knode/api_tracer.go index 7d8e9e0c7..7f78a700a 100644 --- a/client/knode/api_tracer.go +++ b/client/knode/api_tracer.go @@ -90,7 +90,7 @@ type txTraceTask struct { index int // Transaction offset in the block } -// TraceChain returns the structured logs created during the execution of EVM +// TraceChain returns the structured logs created during the execution of VM // between two blocks (excluding start) and returns them as a JSON object. func (api *PrivateDebugAPI) TraceChain(ctx context.Context, start, end rpc.BlockNumber, config *TraceConfig) (*rpc.Subscription, error) { // Fetch the block interval that we want to trace @@ -194,7 +194,7 @@ func (api *PrivateDebugAPI) traceChain(ctx context.Context, start, end *types.Bl // Trace all the transactions contained within for i, tx := range task.block.Transactions() { msg, _ := tx.AsMessage(signer) - vmctx := core.NewEVMContext(msg, task.block.Header(), api.kcoin.blockchain, nil) + vmctx := core.NewVMContext(msg, task.block.Header(), api.kcoin.blockchain, nil) res, err := api.traceTx(ctx, msg, vmctx, task.statedb, config) if err != nil { @@ -336,7 +336,7 @@ func (api *PrivateDebugAPI) traceChain(ctx context.Context, start, end *types.Bl } // TraceBlockByNumber returns the structured logs created during the execution of -// EVM and returns them as a JSON object. +// VM and returns them as a JSON object. func (api *PrivateDebugAPI) TraceBlockByNumber(ctx context.Context, number rpc.BlockNumber, config *TraceConfig) ([]*txTraceResult, error) { // Fetch the block that we want to trace var block *types.Block @@ -357,7 +357,7 @@ func (api *PrivateDebugAPI) TraceBlockByNumber(ctx context.Context, number rpc.B } // TraceBlockByHash returns the structured logs created during the execution of -// EVM and returns them as a JSON object. +// VM and returns them as a JSON object. func (api *PrivateDebugAPI) TraceBlockByHash(ctx context.Context, hash common.Hash, config *TraceConfig) ([]*txTraceResult, error) { block := api.kcoin.blockchain.GetBlockByHash(hash) if block == nil { @@ -366,7 +366,7 @@ func (api *PrivateDebugAPI) TraceBlockByHash(ctx context.Context, hash common.Ha return api.traceBlock(ctx, block, config) } -// TraceBlock returns the structured logs created during the execution of EVM +// TraceBlock returns the structured logs created during the execution of VM // and returns them as a JSON object. func (api *PrivateDebugAPI) TraceBlock(ctx context.Context, blob []byte, config *TraceConfig) ([]*txTraceResult, error) { block := new(types.Block) @@ -377,7 +377,7 @@ func (api *PrivateDebugAPI) TraceBlock(ctx context.Context, blob []byte, config } // TraceBlockFromFile returns the structured logs created during the execution of -// EVM and returns them as a JSON object. +// VM and returns them as a JSON object. func (api *PrivateDebugAPI) TraceBlockFromFile(ctx context.Context, file string, config *TraceConfig) ([]*txTraceResult, error) { blob, err := ioutil.ReadFile(file) if err != nil { @@ -428,7 +428,7 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block, // Fetch and execute the next transaction trace tasks for task := range jobs { msg, _ := txs[task.index].AsMessage(signer) - vmctx := core.NewEVMContext(msg, block.Header(), api.kcoin.blockchain, nil) + vmctx := core.NewVMContext(msg, block.Header(), api.kcoin.blockchain, nil) res, err := api.traceTx(ctx, msg, vmctx, task.statedb, config) if err != nil { @@ -447,10 +447,10 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block, // Generate the next state snapshot fast without tracing msg, _ := tx.AsMessage(signer) - vmctx := core.NewEVMContext(msg, block.Header(), api.kcoin.blockchain, nil) + vmctx := core.NewVMContext(msg, block.Header(), api.kcoin.blockchain, nil) - vmenv := vm.NewEVM(vmctx, statedb, api.config, vm.Config{}) - if _, _, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas())); err != nil { + vmenv := vm.New(vmctx, statedb, api.config, vm.Config{}) + if _, _, _, err := core.ApplyMessage(vmenv, msg, new(core.ComputationalResourcePool).AddResource(msg.ComputeLimit())); err != nil { failed = err break } @@ -534,10 +534,10 @@ func (api *PrivateDebugAPI) computeStateDB(block *types.Block, reexec uint64) (* return statedb, nil } -// TraceTransaction returns the structured logs created during the execution of EVM +// TraceTransaction returns the structured logs created during the execution of VM // and returns them as a JSON object. func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, hash common.Hash, config *TraceConfig) (interface{}, error) { - // Retrieve the transaction and assemble its EVM context + // Retrieve the transaction and assemble its VM context tx, blockHash, _, index := rawdb.ReadTransaction(api.kcoin.ChainDb(), hash) if tx == nil { return nil, fmt.Errorf("transaction %x not found", hash) @@ -591,9 +591,9 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, v tracer = vm.NewStructLogger(config.LogConfig) } // Run the transaction with tracing enabled. - vmenv := vm.NewEVM(vmctx, statedb, api.config, vm.Config{Debug: true, Tracer: tracer}) + vmenv := vm.New(vmctx, statedb, api.config, vm.Config{Debug: true, Tracer: tracer}) - ret, gas, failed, err := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas())) + ret, resourceUsage, failed, err := core.ApplyMessage(vmenv, message, new(core.ComputationalResourcePool).AddResource(message.ComputeLimit())) if err != nil { return nil, fmt.Errorf("tracing failed: %v", err) } @@ -601,10 +601,10 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, v switch tracer := tracer.(type) { case *vm.StructLogger: return &kcoinapi.ExecutionResult{ - Gas: gas, - Failed: failed, - ReturnValue: fmt.Sprintf("%x", ret), - StructLogs: kcoinapi.FormatLogs(tracer.StructLogs()), + ResourceUsage: resourceUsage, + Failed: failed, + ReturnValue: fmt.Sprintf("%x", ret), + StructLogs: kcoinapi.FormatLogs(tracer.StructLogs()), }, nil case *tracers.Tracer: @@ -636,13 +636,13 @@ func (api *PrivateDebugAPI) computeTxEnv(blockHash common.Hash, txIndex int, ree for idx, tx := range block.Transactions() { // Assemble the transaction call message and return if the requested offset msg, _ := tx.AsMessage(signer) - context := core.NewEVMContext(msg, block.Header(), api.kcoin.blockchain, nil) + context := core.NewVMContext(msg, block.Header(), api.kcoin.blockchain, nil) if idx == txIndex { return msg, context, statedb, nil } // Not yet the searched for transaction, execute on top of the current state - vmenv := vm.NewEVM(context, statedb, api.config, vm.Config{}) - if _, _, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil { + vmenv := vm.New(context, statedb, api.config, vm.Config{}) + if _, _, _, err := core.ApplyMessage(vmenv, msg, new(core.ComputationalResourcePool).AddResource(tx.ComputeLimit())); err != nil { return nil, vm.Context{}, nil, fmt.Errorf("tx %x failed: %v", tx.Hash(), err) } // Ensure any modifications are committed to the state diff --git a/client/knode/bind.go b/client/knode/bind.go index 053a3367b..3529c04c3 100644 --- a/client/knode/bind.go +++ b/client/knode/bind.go @@ -41,12 +41,12 @@ func (b *ContractBackend) CodeAt(ctx context.Context, contract common.Address, b return b.bcapi.GetCode(ctx, contract, toBlockNumber(blockNum)) } -// CodeAt retrieves any code associated with the contract from the local API. +// PendingCodeAt retrieves any code associated with the contract from the local API. func (b *ContractBackend) PendingCodeAt(ctx context.Context, contract common.Address) ([]byte, error) { return b.bcapi.GetCode(ctx, contract, rpc.PendingBlockNumber) } -// ContractCall implements bind.ContractCaller executing an Kowala contract +// CallContract implements bind.ContractCaller executing an Kowala contract // call with the specified data as the input. The pending flag requests execution // against the pending block, not the stable head of the chain. func (b *ContractBackend) CallContract(ctx context.Context, msg kowala.CallMsg, blockNum *big.Int) ([]byte, error) { @@ -54,7 +54,7 @@ func (b *ContractBackend) CallContract(ctx context.Context, msg kowala.CallMsg, return out, err } -// ContractCall implements bind.ContractCaller executing an Kowala contract +// PendingCallContract implements bind.ContractCaller executing an Kowala contract // call with the specified data as the input. The pending flag requests execution // against the pending block, not the stable head of the chain. func (b *ContractBackend) PendingCallContract(ctx context.Context, msg kowala.CallMsg) ([]byte, error) { @@ -64,13 +64,10 @@ func (b *ContractBackend) PendingCallContract(ctx context.Context, msg kowala.Ca func toCallArgs(msg kowala.CallMsg) kcoinapi.CallArgs { args := kcoinapi.CallArgs{ - To: msg.To, - From: msg.From, - Data: msg.Data, - Gas: hexutil.Uint64(msg.Gas), - } - if msg.GasPrice != nil { - args.GasPrice = hexutil.Big(*msg.GasPrice) + To: msg.To, + From: msg.From, + Data: msg.Data, + ComputeLimit: hexutil.Uint64(msg.ComputeLimit), } if msg.Value != nil { args.Value = hexutil.Big(*msg.Value) @@ -85,7 +82,7 @@ func toBlockNumber(num *big.Int) rpc.BlockNumber { return rpc.BlockNumber(num.Int64()) } -// PendingAccountNonce implements bind.ContractTransactor retrieving the current +// PendingNonceAt implements bind.ContractTransactor retrieving the current // pending nonce associated with an account. func (b *ContractBackend) PendingNonceAt(ctx context.Context, account common.Address) (nonce uint64, err error) { out, err := b.txapi.GetTransactionCount(ctx, account, rpc.PendingBlockNumber) @@ -95,19 +92,13 @@ func (b *ContractBackend) PendingNonceAt(ctx context.Context, account common.Add return nonce, err } -// SuggestGasPrice implements bind.ContractTransactor retrieving the currently -// suggested gas price to allow a timely execution of a transaction. -func (b *ContractBackend) SuggestGasPrice(ctx context.Context) (*big.Int, error) { - return b.eapi.GasPrice(ctx) -} - -// EstimateGasLimit implements bind.ContractTransactor triing to estimate the gas -// needed to execute a specific transaction based on 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 validators, but it -// should provide a basis for setting a reasonable default. -func (b *ContractBackend) EstimateGas(ctx context.Context, msg kowala.CallMsg) (uint64, error) { - out, err := b.bcapi.EstimateGas(ctx, toCallArgs(msg)) +// EstimateComputationalEffort implements bind.ContractTransactor trying to estimate the required +// computational effort to execute a specific transaction based on the current pending state of +// the backend blockchain. There is no guarantee that this is the true computational effort +// requirement as other transactions may be added or removed by validators, but it should provide +// a basis for setting a reasonable default. +func (b *ContractBackend) EstimateComputationalEffort(ctx context.Context, msg kowala.CallMsg) (uint64, error) { + out, err := b.bcapi.EstimateComputationalEffort(ctx, toCallArgs(msg)) if err != nil { return 0, err } diff --git a/client/knode/config.go b/client/knode/config.go index abaed9630..7329342c2 100644 --- a/client/knode/config.go +++ b/client/knode/config.go @@ -8,28 +8,20 @@ import ( "github.com/kowala-tech/kcoin/client/common/hexutil" "github.com/kowala-tech/kcoin/client/core" "github.com/kowala-tech/kcoin/client/knode/downloader" - "github.com/kowala-tech/kcoin/client/knode/gasprice" "github.com/kowala-tech/kcoin/client/params" ) -const KUSD = "kusd" - // DefaultConfig contains default settings for use on the Kowala main net. var DefaultConfig = Config{ - SyncMode: downloader.FastSync, - NetworkId: params.MainnetChainConfig.ChainID.Uint64(), - LightPeers: 20, + SyncMode: downloader.FastSync, + NetworkId: params.MainnetChainConfig.ChainID.Uint64(), + DatabaseCache: 128, TrieCache: 256, TrieTimeout: 60 * time.Minute, - GasPrice: big.NewInt(1), - TxPool: core.DefaultTxPoolConfig, - GPO: gasprice.Config{ - Blocks: 20, - Percentile: 60, - }, - Currency: KUSD, + TxPool: core.DefaultTxPoolConfig, + Currency: params.KUSD, } //go:generate gencodec -type Config -field-override configMarshaling -formats toml -out gen_config.go @@ -44,10 +36,6 @@ type Config struct { SyncMode downloader.SyncMode NoPruning bool - // Light client options - LightServ int `toml:",omitempty"` // Maximum percentage of time allowed for serving LES requests - LightPeers int `toml:",omitempty"` // Maximum number of LES client peers - // Database options SkipBcVersionCheck bool `toml:"-"` DatabaseHandles int `toml:"-"` @@ -59,14 +47,10 @@ type Config struct { Coinbase common.Address `toml:",omitempty"` Deposit *big.Int `toml:",omitempty"` ExtraData []byte `toml:",omitempty"` - GasPrice *big.Int // Transaction pool options TxPool core.TxPoolConfig - // Gas Price Oracle options - GPO gasprice.Config - // Enables tracking of SHA3 preimages in the VM EnablePreimageRecording bool diff --git a/client/knode/gasprice/gasprice.go b/client/knode/gasprice/gasprice.go deleted file mode 100644 index 7a67fe6cf..000000000 --- a/client/knode/gasprice/gasprice.go +++ /dev/null @@ -1,173 +0,0 @@ -package gasprice - -import ( - "context" - "math/big" - "sort" - "sync" - - "github.com/kowala-tech/kcoin/client/common" - "github.com/kowala-tech/kcoin/client/core/types" - "github.com/kowala-tech/kcoin/client/internal/kcoinapi" - "github.com/kowala-tech/kcoin/client/params" - "github.com/kowala-tech/kcoin/client/rpc" -) - -var maxPrice = big.NewInt(500 * params.Shannon) - -type Config struct { - Blocks int - Percentile int - Default *big.Int `toml:",omitempty"` -} - -// Oracle recommends gas prices based on the content of recent -// blocks. Suitable for both light and full clients. -type Oracle struct { - backend kcoinapi.Backend - lastHead common.Hash - lastPrice *big.Int - cacheLock sync.RWMutex - fetchLock sync.Mutex - - checkBlocks, maxEmpty, maxBlocks int - percentile int -} - -// NewOracle returns a new oracle. -func NewOracle(backend kcoinapi.Backend, params Config) *Oracle { - blocks := params.Blocks - if blocks < 1 { - blocks = 1 - } - percent := params.Percentile - if percent < 0 { - percent = 0 - } - if percent > 100 { - percent = 100 - } - return &Oracle{ - backend: backend, - lastPrice: params.Default, - checkBlocks: blocks, - maxEmpty: blocks / 2, - maxBlocks: blocks * 5, - percentile: percent, - } -} - -// SuggestPrice returns the recommended gas price. -func (gpo *Oracle) SuggestPrice(ctx context.Context) (*big.Int, error) { - gpo.cacheLock.RLock() - lastHead := gpo.lastHead - lastPrice := gpo.lastPrice - gpo.cacheLock.RUnlock() - - head, _ := gpo.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber) - headHash := head.Hash() - if headHash == lastHead { - return lastPrice, nil - } - - gpo.fetchLock.Lock() - defer gpo.fetchLock.Unlock() - - // try checking the cache again, maybe the last fetch fetched what we need - gpo.cacheLock.RLock() - lastHead = gpo.lastHead - lastPrice = gpo.lastPrice - gpo.cacheLock.RUnlock() - if headHash == lastHead { - return lastPrice, nil - } - - blockNum := head.Number.Uint64() - ch := make(chan getBlockPricesResult, gpo.checkBlocks) - sent := 0 - exp := 0 - var blockPrices []*big.Int - for sent < gpo.checkBlocks && blockNum > 0 { - go gpo.getBlockPrices(ctx, types.MakeSigner(gpo.backend.ChainConfig(), big.NewInt(int64(blockNum))), blockNum, ch) - sent++ - exp++ - blockNum-- - } - maxEmpty := gpo.maxEmpty - for exp > 0 { - res := <-ch - if res.err != nil { - return lastPrice, res.err - } - exp-- - if res.price != nil { - blockPrices = append(blockPrices, res.price) - continue - } - if maxEmpty > 0 { - maxEmpty-- - continue - } - if blockNum > 0 && sent < gpo.maxBlocks { - go gpo.getBlockPrices(ctx, types.MakeSigner(gpo.backend.ChainConfig(), big.NewInt(int64(blockNum))), blockNum, ch) - sent++ - exp++ - blockNum-- - } - } - price := lastPrice - if len(blockPrices) > 0 { - sort.Sort(bigIntArray(blockPrices)) - price = blockPrices[(len(blockPrices)-1)*gpo.percentile/100] - } - if price.Cmp(maxPrice) > 0 { - price = new(big.Int).Set(maxPrice) - } - - gpo.cacheLock.Lock() - gpo.lastHead = headHash - gpo.lastPrice = price - gpo.cacheLock.Unlock() - return price, nil -} - -type getBlockPricesResult struct { - price *big.Int - err error -} - -type transactionsByGasPrice []*types.Transaction - -func (t transactionsByGasPrice) Len() int { return len(t) } -func (t transactionsByGasPrice) Swap(i, j int) { t[i], t[j] = t[j], t[i] } -func (t transactionsByGasPrice) Less(i, j int) bool { return t[i].GasPrice().Cmp(t[j].GasPrice()) < 0 } - -// getBlockPrices calculates the lowest transaction gas price in a given block -// and sends it to the result channel. If the block is empty, price is nil. -func (gpo *Oracle) getBlockPrices(ctx context.Context, signer types.Signer, blockNum uint64, ch chan getBlockPricesResult) { - block, err := gpo.backend.BlockByNumber(ctx, rpc.BlockNumber(blockNum)) - if block == nil { - ch <- getBlockPricesResult{nil, err} - return - } - - blockTxs := block.Transactions() - txs := make([]*types.Transaction, len(blockTxs)) - copy(txs, blockTxs) - sort.Sort(transactionsByGasPrice(txs)) - - for _, tx := range txs { - sender, err := types.TxSender(signer, tx) - if err == nil && sender != block.Coinbase() { - ch <- getBlockPricesResult{tx.GasPrice(), nil} - return - } - } - ch <- getBlockPricesResult{nil, nil} -} - -type bigIntArray []*big.Int - -func (s bigIntArray) Len() int { return len(s) } -func (s bigIntArray) Less(i, j int) bool { return s[i].Cmp(s[j]) < 0 } -func (s bigIntArray) Swap(i, j int) { s[i], s[j] = s[j], s[i] } diff --git a/client/knode/gen_config.go b/client/knode/gen_config.go index 2cf0cc0bf..316ecacf1 100644 --- a/client/knode/gen_config.go +++ b/client/knode/gen_config.go @@ -10,7 +10,6 @@ import ( "github.com/kowala-tech/kcoin/client/common/hexutil" "github.com/kowala-tech/kcoin/client/core" "github.com/kowala-tech/kcoin/client/knode/downloader" - "github.com/kowala-tech/kcoin/client/knode/gasprice" ) var _ = (*configMarshaling)(nil) @@ -22,8 +21,6 @@ func (c Config) MarshalTOML() (interface{}, error) { NetworkId uint64 SyncMode downloader.SyncMode NoPruning bool - LightServ int `toml:",omitempty"` - LightPeers int `toml:",omitempty"` SkipBcVersionCheck bool `toml:"-"` DatabaseHandles int `toml:"-"` DatabaseCache int @@ -32,9 +29,7 @@ func (c Config) MarshalTOML() (interface{}, error) { Coinbase common.Address `toml:",omitempty"` Deposit *big.Int `toml:",omitempty"` ExtraData hexutil.Bytes `toml:",omitempty"` - GasPrice *big.Int TxPool core.TxPoolConfig - GPO gasprice.Config EnablePreimageRecording bool DocRoot string `toml:"-"` Currency string @@ -44,8 +39,6 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.NetworkId = c.NetworkId enc.SyncMode = c.SyncMode enc.NoPruning = c.NoPruning - enc.LightServ = c.LightServ - enc.LightPeers = c.LightPeers enc.SkipBcVersionCheck = c.SkipBcVersionCheck enc.DatabaseHandles = c.DatabaseHandles enc.DatabaseCache = c.DatabaseCache @@ -54,9 +47,7 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.Coinbase = c.Coinbase enc.Deposit = c.Deposit enc.ExtraData = c.ExtraData - enc.GasPrice = c.GasPrice enc.TxPool = c.TxPool - enc.GPO = c.GPO enc.EnablePreimageRecording = c.EnablePreimageRecording enc.DocRoot = c.DocRoot enc.Currency = c.Currency @@ -70,8 +61,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { NetworkId *uint64 SyncMode *downloader.SyncMode NoPruning *bool - LightServ *int `toml:",omitempty"` - LightPeers *int `toml:",omitempty"` SkipBcVersionCheck *bool `toml:"-"` DatabaseHandles *int `toml:"-"` DatabaseCache *int @@ -80,9 +69,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { Coinbase *common.Address `toml:",omitempty"` Deposit *big.Int `toml:",omitempty"` ExtraData *hexutil.Bytes `toml:",omitempty"` - GasPrice *big.Int TxPool *core.TxPoolConfig - GPO *gasprice.Config EnablePreimageRecording *bool DocRoot *string `toml:"-"` Currency *string @@ -103,12 +90,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.NoPruning != nil { c.NoPruning = *dec.NoPruning } - if dec.LightServ != nil { - c.LightServ = *dec.LightServ - } - if dec.LightPeers != nil { - c.LightPeers = *dec.LightPeers - } if dec.SkipBcVersionCheck != nil { c.SkipBcVersionCheck = *dec.SkipBcVersionCheck } @@ -133,15 +114,9 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.ExtraData != nil { c.ExtraData = *dec.ExtraData } - if dec.GasPrice != nil { - c.GasPrice = dec.GasPrice - } if dec.TxPool != nil { c.TxPool = *dec.TxPool } - if dec.GPO != nil { - c.GPO = *dec.GPO - } if dec.EnablePreimageRecording != nil { c.EnablePreimageRecording = *dec.EnablePreimageRecording } diff --git a/client/knode/genesis/generator.go b/client/knode/genesis/generator.go index 2406dbe79..aea082212 100644 --- a/client/knode/genesis/generator.go +++ b/client/knode/genesis/generator.go @@ -84,7 +84,6 @@ func (gen *generator) Generate(opts Options) (*core.Genesis, error) { genesis := &core.Genesis{ Number: validOptions.blockNumber, Timestamp: uint64(genesisTimestamp), - GasLimit: 4700000, Alloc: gen.alloc, Config: ¶ms.ChainConfig{ ChainID: getNetwork(validOptions.network), @@ -127,7 +126,7 @@ func (gen *generator) deployContracts(opts *validGenesisOptions) error { for _, contract := range gen.contracts { // @NOTE (rgeraldes) - storage needs to be addressed in the end as // contracts can interact with each other modifying each other's state - contract.storage = contract.runtimeCfg.EVMConfig.Tracer.(*vmTracer).data[contract.address] + contract.storage = contract.runtimeCfg.VMConfig.Tracer.(*vmTracer).data[contract.address] gen.alloc[contract.address] = contract.AsGenesisAccount() } @@ -138,7 +137,7 @@ func (gen *generator) getDefaultRuntimeConfig() *runtime.Config { return &runtime.Config{ State: gen.sharedState, BlockNumber: common.Big0, - EVMConfig: vm.Config{ + VMConfig: vm.Config{ Debug: true, Tracer: gen.sharedTracer, }, diff --git a/client/knode/genesis/networks.go b/client/knode/genesis/networks.go index e52a36e11..10dc15285 100644 --- a/client/knode/genesis/networks.go +++ b/client/knode/genesis/networks.go @@ -1,9 +1,11 @@ package genesis -import "github.com/kowala-tech/kcoin/client/knode" +import ( + "github.com/kowala-tech/kcoin/client/params" +) var Networks = map[string]map[string]Options{ - knode.KUSD: { + params.KUSD: { MainNetwork: Options{ Network: MainNetwork, BlockNumber: 0, diff --git a/client/knode/genesis/testfiles/genesis.json.golden b/client/knode/genesis/testfiles/genesis.json.golden index 4570aebe3..58dbc2b10 100644 --- a/client/knode/genesis/testfiles/genesis.json.golden +++ b/client/knode/genesis/testfiles/genesis.json.golden @@ -1 +1 @@ -{"config":{"chainID":1,"konsensus":{}},"timestamp":"0x5b228222","extraData":"0x4b6f77616c61277320666972737420626c6f636b000000000000000000000000","gasLimit":"0x47b760","coinbase":"0x0000000000000000000000000000000000000000","alloc":{"0000000000000000000000000000000000000000":{"balance":"0x1"},"0000000000000000000000000000000000000001":{"balance":"0x1"},"0000000000000000000000000000000000000002":{"balance":"0x1"},"0000000000000000000000000000000000000003":{"balance":"0x1"},"0000000000000000000000000000000000000004":{"balance":"0x1"},"0000000000000000000000000000000000000005":{"balance":"0x1"},"0000000000000000000000000000000000000006":{"balance":"0x1"},"0000000000000000000000000000000000000007":{"balance":"0x1"},"0000000000000000000000000000000000000008":{"balance":"0x1"},"0000000000000000000000000000000000000009":{"balance":"0x1"},"000000000000000000000000000000000000000a":{"balance":"0x1"},"000000000000000000000000000000000000000b":{"balance":"0x1"},"000000000000000000000000000000000000000c":{"balance":"0x1"},"000000000000000000000000000000000000000d":{"balance":"0x1"},"000000000000000000000000000000000000000e":{"balance":"0x1"},"000000000000000000000000000000000000000f":{"balance":"0x1"},"0000000000000000000000000000000000000010":{"balance":"0x1"},"0000000000000000000000000000000000000011":{"balance":"0x1"},"0000000000000000000000000000000000000012":{"balance":"0x1"},"0000000000000000000000000000000000000013":{"balance":"0x1"},"0000000000000000000000000000000000000014":{"balance":"0x1"},"0000000000000000000000000000000000000015":{"balance":"0x1"},"0000000000000000000000000000000000000016":{"balance":"0x1"},"0000000000000000000000000000000000000017":{"balance":"0x1"},"0000000000000000000000000000000000000018":{"balance":"0x1"},"0000000000000000000000000000000000000019":{"balance":"0x1"},"000000000000000000000000000000000000001a":{"balance":"0x1"},"000000000000000000000000000000000000001b":{"balance":"0x1"},"000000000000000000000000000000000000001c":{"balance":"0x1"},"000000000000000000000000000000000000001d":{"balance":"0x1"},"000000000000000000000000000000000000001e":{"balance":"0x1"},"000000000000000000000000000000000000001f":{"balance":"0x1"},"0000000000000000000000000000000000000020":{"balance":"0x1"},"0000000000000000000000000000000000000021":{"balance":"0x1"},"0000000000000000000000000000000000000022":{"balance":"0x1"},"0000000000000000000000000000000000000023":{"balance":"0x1"},"0000000000000000000000000000000000000024":{"balance":"0x1"},"0000000000000000000000000000000000000025":{"balance":"0x1"},"0000000000000000000000000000000000000026":{"balance":"0x1"},"0000000000000000000000000000000000000027":{"balance":"0x1"},"0000000000000000000000000000000000000028":{"balance":"0x1"},"0000000000000000000000000000000000000029":{"balance":"0x1"},"000000000000000000000000000000000000002a":{"balance":"0x1"},"000000000000000000000000000000000000002b":{"balance":"0x1"},"000000000000000000000000000000000000002c":{"balance":"0x1"},"000000000000000000000000000000000000002d":{"balance":"0x1"},"000000000000000000000000000000000000002e":{"balance":"0x1"},"000000000000000000000000000000000000002f":{"balance":"0x1"},"0000000000000000000000000000000000000030":{"balance":"0x1"},"0000000000000000000000000000000000000031":{"balance":"0x1"},"0000000000000000000000000000000000000032":{"balance":"0x1"},"0000000000000000000000000000000000000033":{"balance":"0x1"},"0000000000000000000000000000000000000034":{"balance":"0x1"},"0000000000000000000000000000000000000035":{"balance":"0x1"},"0000000000000000000000000000000000000036":{"balance":"0x1"},"0000000000000000000000000000000000000037":{"balance":"0x1"},"0000000000000000000000000000000000000038":{"balance":"0x1"},"0000000000000000000000000000000000000039":{"balance":"0x1"},"000000000000000000000000000000000000003a":{"balance":"0x1"},"000000000000000000000000000000000000003b":{"balance":"0x1"},"000000000000000000000000000000000000003c":{"balance":"0x1"},"000000000000000000000000000000000000003d":{"balance":"0x1"},"000000000000000000000000000000000000003e":{"balance":"0x1"},"000000000000000000000000000000000000003f":{"balance":"0x1"},"0000000000000000000000000000000000000040":{"balance":"0x1"},"0000000000000000000000000000000000000041":{"balance":"0x1"},"0000000000000000000000000000000000000042":{"balance":"0x1"},"0000000000000000000000000000000000000043":{"balance":"0x1"},"0000000000000000000000000000000000000044":{"balance":"0x1"},"0000000000000000000000000000000000000045":{"balance":"0x1"},"0000000000000000000000000000000000000046":{"balance":"0x1"},"0000000000000000000000000000000000000047":{"balance":"0x1"},"0000000000000000000000000000000000000048":{"balance":"0x1"},"0000000000000000000000000000000000000049":{"balance":"0x1"},"000000000000000000000000000000000000004a":{"balance":"0x1"},"000000000000000000000000000000000000004b":{"balance":"0x1"},"000000000000000000000000000000000000004c":{"balance":"0x1"},"000000000000000000000000000000000000004d":{"balance":"0x1"},"000000000000000000000000000000000000004e":{"balance":"0x1"},"000000000000000000000000000000000000004f":{"balance":"0x1"},"0000000000000000000000000000000000000050":{"balance":"0x1"},"0000000000000000000000000000000000000051":{"balance":"0x1"},"0000000000000000000000000000000000000052":{"balance":"0x1"},"0000000000000000000000000000000000000053":{"balance":"0x1"},"0000000000000000000000000000000000000054":{"balance":"0x1"},"0000000000000000000000000000000000000055":{"balance":"0x1"},"0000000000000000000000000000000000000056":{"balance":"0x1"},"0000000000000000000000000000000000000057":{"balance":"0x1"},"0000000000000000000000000000000000000058":{"balance":"0x1"},"0000000000000000000000000000000000000059":{"balance":"0x1"},"000000000000000000000000000000000000005a":{"balance":"0x1"},"000000000000000000000000000000000000005b":{"balance":"0x1"},"000000000000000000000000000000000000005c":{"balance":"0x1"},"000000000000000000000000000000000000005d":{"balance":"0x1"},"000000000000000000000000000000000000005e":{"balance":"0x1"},"000000000000000000000000000000000000005f":{"balance":"0x1"},"0000000000000000000000000000000000000060":{"balance":"0x1"},"0000000000000000000000000000000000000061":{"balance":"0x1"},"0000000000000000000000000000000000000062":{"balance":"0x1"},"0000000000000000000000000000000000000063":{"balance":"0x1"},"0000000000000000000000000000000000000064":{"balance":"0x1"},"0000000000000000000000000000000000000065":{"balance":"0x1"},"0000000000000000000000000000000000000066":{"balance":"0x1"},"0000000000000000000000000000000000000067":{"balance":"0x1"},"0000000000000000000000000000000000000068":{"balance":"0x1"},"0000000000000000000000000000000000000069":{"balance":"0x1"},"000000000000000000000000000000000000006a":{"balance":"0x1"},"000000000000000000000000000000000000006b":{"balance":"0x1"},"000000000000000000000000000000000000006c":{"balance":"0x1"},"000000000000000000000000000000000000006d":{"balance":"0x1"},"000000000000000000000000000000000000006e":{"balance":"0x1"},"000000000000000000000000000000000000006f":{"balance":"0x1"},"0000000000000000000000000000000000000070":{"balance":"0x1"},"0000000000000000000000000000000000000071":{"balance":"0x1"},"0000000000000000000000000000000000000072":{"balance":"0x1"},"0000000000000000000000000000000000000073":{"balance":"0x1"},"0000000000000000000000000000000000000074":{"balance":"0x1"},"0000000000000000000000000000000000000075":{"balance":"0x1"},"0000000000000000000000000000000000000076":{"balance":"0x1"},"0000000000000000000000000000000000000077":{"balance":"0x1"},"0000000000000000000000000000000000000078":{"balance":"0x1"},"0000000000000000000000000000000000000079":{"balance":"0x1"},"000000000000000000000000000000000000007a":{"balance":"0x1"},"000000000000000000000000000000000000007b":{"balance":"0x1"},"000000000000000000000000000000000000007c":{"balance":"0x1"},"000000000000000000000000000000000000007d":{"balance":"0x1"},"000000000000000000000000000000000000007e":{"balance":"0x1"},"000000000000000000000000000000000000007f":{"balance":"0x1"},"0000000000000000000000000000000000000080":{"balance":"0x1"},"0000000000000000000000000000000000000081":{"balance":"0x1"},"0000000000000000000000000000000000000082":{"balance":"0x1"},"0000000000000000000000000000000000000083":{"balance":"0x1"},"0000000000000000000000000000000000000084":{"balance":"0x1"},"0000000000000000000000000000000000000085":{"balance":"0x1"},"0000000000000000000000000000000000000086":{"balance":"0x1"},"0000000000000000000000000000000000000087":{"balance":"0x1"},"0000000000000000000000000000000000000088":{"balance":"0x1"},"0000000000000000000000000000000000000089":{"balance":"0x1"},"000000000000000000000000000000000000008a":{"balance":"0x1"},"000000000000000000000000000000000000008b":{"balance":"0x1"},"000000000000000000000000000000000000008c":{"balance":"0x1"},"000000000000000000000000000000000000008d":{"balance":"0x1"},"000000000000000000000000000000000000008e":{"balance":"0x1"},"000000000000000000000000000000000000008f":{"balance":"0x1"},"0000000000000000000000000000000000000090":{"balance":"0x1"},"0000000000000000000000000000000000000091":{"balance":"0x1"},"0000000000000000000000000000000000000092":{"balance":"0x1"},"0000000000000000000000000000000000000093":{"balance":"0x1"},"0000000000000000000000000000000000000094":{"balance":"0x1"},"0000000000000000000000000000000000000095":{"balance":"0x1"},"0000000000000000000000000000000000000096":{"balance":"0x1"},"0000000000000000000000000000000000000097":{"balance":"0x1"},"0000000000000000000000000000000000000098":{"balance":"0x1"},"0000000000000000000000000000000000000099":{"balance":"0x1"},"000000000000000000000000000000000000009a":{"balance":"0x1"},"000000000000000000000000000000000000009b":{"balance":"0x1"},"000000000000000000000000000000000000009c":{"balance":"0x1"},"000000000000000000000000000000000000009d":{"balance":"0x1"},"000000000000000000000000000000000000009e":{"balance":"0x1"},"000000000000000000000000000000000000009f":{"balance":"0x1"},"00000000000000000000000000000000000000a0":{"balance":"0x1"},"00000000000000000000000000000000000000a1":{"balance":"0x1"},"00000000000000000000000000000000000000a2":{"balance":"0x1"},"00000000000000000000000000000000000000a3":{"balance":"0x1"},"00000000000000000000000000000000000000a4":{"balance":"0x1"},"00000000000000000000000000000000000000a5":{"balance":"0x1"},"00000000000000000000000000000000000000a6":{"balance":"0x1"},"00000000000000000000000000000000000000a7":{"balance":"0x1"},"00000000000000000000000000000000000000a8":{"balance":"0x1"},"00000000000000000000000000000000000000a9":{"balance":"0x1"},"00000000000000000000000000000000000000aa":{"balance":"0x1"},"00000000000000000000000000000000000000ab":{"balance":"0x1"},"00000000000000000000000000000000000000ac":{"balance":"0x1"},"00000000000000000000000000000000000000ad":{"balance":"0x1"},"00000000000000000000000000000000000000ae":{"balance":"0x1"},"00000000000000000000000000000000000000af":{"balance":"0x1"},"00000000000000000000000000000000000000b0":{"balance":"0x1"},"00000000000000000000000000000000000000b1":{"balance":"0x1"},"00000000000000000000000000000000000000b2":{"balance":"0x1"},"00000000000000000000000000000000000000b3":{"balance":"0x1"},"00000000000000000000000000000000000000b4":{"balance":"0x1"},"00000000000000000000000000000000000000b5":{"balance":"0x1"},"00000000000000000000000000000000000000b6":{"balance":"0x1"},"00000000000000000000000000000000000000b7":{"balance":"0x1"},"00000000000000000000000000000000000000b8":{"balance":"0x1"},"00000000000000000000000000000000000000b9":{"balance":"0x1"},"00000000000000000000000000000000000000ba":{"balance":"0x1"},"00000000000000000000000000000000000000bb":{"balance":"0x1"},"00000000000000000000000000000000000000bc":{"balance":"0x1"},"00000000000000000000000000000000000000bd":{"balance":"0x1"},"00000000000000000000000000000000000000be":{"balance":"0x1"},"00000000000000000000000000000000000000bf":{"balance":"0x1"},"00000000000000000000000000000000000000c0":{"balance":"0x1"},"00000000000000000000000000000000000000c1":{"balance":"0x1"},"00000000000000000000000000000000000000c2":{"balance":"0x1"},"00000000000000000000000000000000000000c3":{"balance":"0x1"},"00000000000000000000000000000000000000c4":{"balance":"0x1"},"00000000000000000000000000000000000000c5":{"balance":"0x1"},"00000000000000000000000000000000000000c6":{"balance":"0x1"},"00000000000000000000000000000000000000c7":{"balance":"0x1"},"00000000000000000000000000000000000000c8":{"balance":"0x1"},"00000000000000000000000000000000000000c9":{"balance":"0x1"},"00000000000000000000000000000000000000ca":{"balance":"0x1"},"00000000000000000000000000000000000000cb":{"balance":"0x1"},"00000000000000000000000000000000000000cc":{"balance":"0x1"},"00000000000000000000000000000000000000cd":{"balance":"0x1"},"00000000000000000000000000000000000000ce":{"balance":"0x1"},"00000000000000000000000000000000000000cf":{"balance":"0x1"},"00000000000000000000000000000000000000d0":{"balance":"0x1"},"00000000000000000000000000000000000000d1":{"balance":"0x1"},"00000000000000000000000000000000000000d2":{"balance":"0x1"},"00000000000000000000000000000000000000d3":{"balance":"0x1"},"00000000000000000000000000000000000000d4":{"balance":"0x1"},"00000000000000000000000000000000000000d5":{"balance":"0x1"},"00000000000000000000000000000000000000d6":{"balance":"0x1"},"00000000000000000000000000000000000000d7":{"balance":"0x1"},"00000000000000000000000000000000000000d8":{"balance":"0x1"},"00000000000000000000000000000000000000d9":{"balance":"0x1"},"00000000000000000000000000000000000000da":{"balance":"0x1"},"00000000000000000000000000000000000000db":{"balance":"0x1"},"00000000000000000000000000000000000000dc":{"balance":"0x1"},"00000000000000000000000000000000000000dd":{"balance":"0x1"},"00000000000000000000000000000000000000de":{"balance":"0x1"},"00000000000000000000000000000000000000df":{"balance":"0x1"},"00000000000000000000000000000000000000e0":{"balance":"0x1"},"00000000000000000000000000000000000000e1":{"balance":"0x1"},"00000000000000000000000000000000000000e2":{"balance":"0x1"},"00000000000000000000000000000000000000e3":{"balance":"0x1"},"00000000000000000000000000000000000000e4":{"balance":"0x1"},"00000000000000000000000000000000000000e5":{"balance":"0x1"},"00000000000000000000000000000000000000e6":{"balance":"0x1"},"00000000000000000000000000000000000000e7":{"balance":"0x1"},"00000000000000000000000000000000000000e8":{"balance":"0x1"},"00000000000000000000000000000000000000e9":{"balance":"0x1"},"00000000000000000000000000000000000000ea":{"balance":"0x1"},"00000000000000000000000000000000000000eb":{"balance":"0x1"},"00000000000000000000000000000000000000ec":{"balance":"0x1"},"00000000000000000000000000000000000000ed":{"balance":"0x1"},"00000000000000000000000000000000000000ee":{"balance":"0x1"},"00000000000000000000000000000000000000ef":{"balance":"0x1"},"00000000000000000000000000000000000000f0":{"balance":"0x1"},"00000000000000000000000000000000000000f1":{"balance":"0x1"},"00000000000000000000000000000000000000f2":{"balance":"0x1"},"00000000000000000000000000000000000000f3":{"balance":"0x1"},"00000000000000000000000000000000000000f4":{"balance":"0x1"},"00000000000000000000000000000000000000f5":{"balance":"0x1"},"00000000000000000000000000000000000000f6":{"balance":"0x1"},"00000000000000000000000000000000000000f7":{"balance":"0x1"},"00000000000000000000000000000000000000f8":{"balance":"0x1"},"00000000000000000000000000000000000000f9":{"balance":"0x1"},"00000000000000000000000000000000000000fa":{"balance":"0x1"},"00000000000000000000000000000000000000fb":{"balance":"0x1"},"00000000000000000000000000000000000000fc":{"balance":"0x1"},"00000000000000000000000000000000000000fd":{"balance":"0x1"},"00000000000000000000000000000000000000fe":{"balance":"0x1"},"00000000000000000000000000000000000000ff":{"balance":"0x1"},"0090137110f43c6666b7bd641fcf5ca5dd989539":{"code":"0x60806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633659cfe6146100775780634f1ef286146100ba5780635c60da1b146101085780638f2839701461015f578063f851a440146101a2575b6100756101f9565b005b34801561008357600080fd5b506100b8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610213565b005b610106600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001908201803590602001919091929391929390505050610268565b005b34801561011457600080fd5b5061011d610308565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561016b57600080fd5b506101a0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610360565b005b3480156101ae57600080fd5b506101b761051e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610201610576565b61021161020c610651565b610682565b565b61021b6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025c57610257816106d9565b610265565b6102646101f9565b5b50565b6102706106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fa576102ac836106d9565b3073ffffffffffffffffffffffffffffffffffffffff163483836040518083838082843782019150509250505060006040518083038185875af19250505015156102f557600080fd5b610303565b6103026101f9565b5b505050565b60006103126106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103545761034d610651565b905061035d565b61035c6101f9565b5b90565b6103686106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561051257600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610466576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001807f43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f81526020017f787920746f20746865207a65726f20616464726573730000000000000000000081525060400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61048f6106a8565b82604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a161050d81610748565b61051b565b61051a6101f9565b5b50565b60006105286106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561056a576105636106a8565b9050610573565b6105726101f9565b5b90565b61057e6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151515610647576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001807f43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e20667281526020017f6f6d207468652070726f78792061646d696e000000000000000000000000000081525060400191505060405180910390fd5b61064f610777565b565b6000807f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c36001029050805491505090565b3660008037600080366000845af43d6000803e80600081146106a3573d6000f35b3d6000fd5b6000807f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b6001029050805491505090565b6106e281610779565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b60010290508181555050565b565b60006107848261084b565b151561081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001807f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f81526020017f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000081525060400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c360010290508181555050565b600080823b9050600081119150509190505600a165627a7a72305820b31d41a72e81559b9fbd6f52c3db76ab77aeacd5de378d37ab93861a9b684f120029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x0000000000000000000001000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001":"0x00000000000000000000000000000000000000000000065a4da25d3016c00000","0x0000000000000000000000000000000000000000000000000000000000000002":"0x00000000000000000000000000000000000000000000000000000000000001f4","0x0000000000000000000000000000000000000000000000000000000000000003":"0x0000000000000000000000000000000000000000000000000000000000015180","0x0000000000000000000000000000000000000000000000000000000000000004":"0x2ff4bbb8a7bdf978bccd784e7eeed6a065ff1a7a86caa9d93fff1d4b37addec4","0x0000000000000000000000000000000000000000000000000000000000000005":"0xc99f18ca33e10b0236fe4fd62bfd9a8eb6ceee10bf8dad1b0d121d5e6a2bf3ba","0x0000000000000000000000000000000000000000000000000000000000000006":"0x00000000000000000000000000000000000000000004f68ca6d8cd91c6000000","0x0000000000000000000000000000000000000000000000000000000000000007":"0x00000000000000000000000001e1056f6a829e53dadeb8a5a6189a9333bd1d63","0x0000000000000000000000000000000000000000000000000000000000000009":"0x0000000000000000000000000000000000000000000000000000000000000001","0x000000000000000000000000000000000000000000000000000000000000000a":"0x0000000000000000000000006ad6b24c43a622d58e2959474e3912ba94dfd957","0x000000000000000000000000000000000000000000000000000000000000000b":"0x00000000000000000000000000000000000000000000065a4da25d3016c00000","0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b":"0x000000000000000000000000ff9dfbd395cd1c4a4f23c16aa8a5c44109bc17df","0x1d5591f7b65bd8059a423253186881b3d932200e53c2c265d512fab5f166496d":"0x00000000000000000000000000000000000000000000065a4da25d3016c00000","0x1d5591f7b65bd8059a423253186881b3d932200e53c2c265d512fab5f166496e":"0x0000000000000000000000000000000000000000000000000000000000000000","0x6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af":"0x0000000000000000000000006ad6b24c43a622d58e2959474e3912ba94dfd957","0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3":"0x000000000000000000000000b5822d5f8d221ce2dc73e388629eca256b0aa4f2","0xa2dcbca414a2b283753bfd046a448ad06f34c483e6a942f2b13331deeee6b7b9":"0x0000000000000000000000000000000000000000000000000000000000000000","0xa2dcbca414a2b283753bfd046a448ad06f34c483e6a942f2b13331deeee6b7ba":"0x0000000000000000000000000000000000000000000000000000000000000101","0xa2dcbca414a2b283753bfd046a448ad06f34c483e6a942f2b13331deeee6b7bb":"0x0000000000000000000000000000000000000000000000000000000000000001"},"balance":"0x0"},"01e1056f6a829e53dadeb8a5a6189a9333bd1d63":{"code":"0x60806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633659cfe6146100775780634f1ef286146100ba5780635c60da1b146101085780638f2839701461015f578063f851a440146101a2575b6100756101f9565b005b34801561008357600080fd5b506100b8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610213565b005b610106600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001908201803590602001919091929391929390505050610268565b005b34801561011457600080fd5b5061011d610308565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561016b57600080fd5b506101a0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610360565b005b3480156101ae57600080fd5b506101b761051e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610201610576565b61021161020c610651565b610682565b565b61021b6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025c57610257816106d9565b610265565b6102646101f9565b5b50565b6102706106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fa576102ac836106d9565b3073ffffffffffffffffffffffffffffffffffffffff163483836040518083838082843782019150509250505060006040518083038185875af19250505015156102f557600080fd5b610303565b6103026101f9565b5b505050565b60006103126106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103545761034d610651565b905061035d565b61035c6101f9565b5b90565b6103686106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561051257600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610466576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001807f43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f81526020017f787920746f20746865207a65726f20616464726573730000000000000000000081525060400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61048f6106a8565b82604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a161050d81610748565b61051b565b61051a6101f9565b5b50565b60006105286106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561056a576105636106a8565b9050610573565b6105726101f9565b5b90565b61057e6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151515610647576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001807f43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e20667281526020017f6f6d207468652070726f78792061646d696e000000000000000000000000000081525060400191505060405180910390fd5b61064f610777565b565b6000807f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c36001029050805491505090565b3660008037600080366000845af43d6000803e80600081146106a3573d6000f35b3d6000fd5b6000807f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b6001029050805491505090565b6106e281610779565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b60010290508181555050565b565b60006107848261084b565b151561081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001807f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f81526020017f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000081525060400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c360010290508181555050565b600080823b9050600081119150509190505600a165627a7a72305820b31d41a72e81559b9fbd6f52c3db76ab77aeacd5de378d37ab93861a9b684f120029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x00000000000000000000004195b06a6e4d5bedde15165e01a64f324f03d5d101","0x0aa9b499df4e99716f35c650af5247f98c5dc1bef63f3a923d9f13a6e945b800":"0x000000000000000000000000426f2e2baa6030668b799c2d9193319dface6b7a","0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b":"0x000000000000000000000000ff9dfbd395cd1c4a4f23c16aa8a5c44109bc17df","0x6f7bca21f817d86a5b85f307683ec061c9c10f572e1c3ca5e8312058e1c3f5e7":"0x000000000000000000000000dfcb946fd93a0ae4056d7d6dca59d59fd830f8a5","0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3":"0x0000000000000000000000007f0de05687a7cb9a05399a26f4d1519ba6afc95f","0x86b51839584f7178845a4241ea004c1f5fcaa1a8c0141b741967e2b99d943641":"0x0000000000000000000000000090137110f43c6666b7bd641fcf5ca5dd989539","0xd485b3e3671c35d525826a03b001f5c3d40c5cfcad1d19ecc0c924f943cb06c8":"0x000000000000000000000000c497f7ad7105db9f4138de92b13a0883b19ee0fa","0xf4b8bad9907850b244478fd4ce9bd72dbd061f18d6e4c56d102809e23bf83642":"0x000000000000000000000000485fa6d2f818145a23ace24d84cdc966d8d2de22"},"balance":"0x0"},"049ec8777b4806eff0bb6039551690d8f650b25a":{"balance":"0x8ac7230489e80000"},"0e5d0fd336650e663c710ef420f85fb081e21415":{"code":"0x60806040526004361061011d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063025e7c2714610177578063173825d9146101e457806320ea8d86146102275780632f54bf6e146102545780633411c81c146102af57806354741525146103145780637065cb4814610363578063784547a7146103a65780638b51d13f146103eb5780639ace38c21461042c578063a0e67e2b14610517578063a8abe69a14610583578063b5dc40c314610627578063b77bf600146106a9578063ba51a6df146106d4578063c01a8c8414610701578063c64274741461072e578063d74f8edd146107d5578063dc8452cd14610800578063e20056e61461082b578063ee22610b1461088e575b6000341115610175573373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a25b005b34801561018357600080fd5b506101a2600480360381019080803590602001909291905050506108bb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156101f057600080fd5b50610225600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506108f9565b005b34801561023357600080fd5b5061025260048036038101908080359060200190929190505050610b92565b005b34801561026057600080fd5b50610295600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610d3a565b604051808215151515815260200191505060405180910390f35b3480156102bb57600080fd5b506102fa60048036038101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610d5a565b604051808215151515815260200191505060405180910390f35b34801561032057600080fd5b5061034d600480360381019080803515159060200190929190803515159060200190929190505050610d89565b6040518082815260200191505060405180910390f35b34801561036f57600080fd5b506103a4600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610e1b565b005b3480156103b257600080fd5b506103d160048036038101908080359060200190929190505050611020565b604051808215151515815260200191505060405180910390f35b3480156103f757600080fd5b5061041660048036038101908080359060200190929190505050611105565b6040518082815260200191505060405180910390f35b34801561043857600080fd5b50610457600480360381019080803590602001909291905050506111d0565b604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018060200183151515158152602001828103825284818151815260200191508051906020019080838360005b838110156104d95780820151818401526020810190506104be565b50505050905090810190601f1680156105065780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b34801561052357600080fd5b5061052c6112c5565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561056f578082015181840152602081019050610554565b505050509050019250505060405180910390f35b34801561058f57600080fd5b506105d06004803603810190808035906020019092919080359060200190929190803515159060200190929190803515159060200190929190505050611353565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156106135780820151818401526020810190506105f8565b505050509050019250505060405180910390f35b34801561063357600080fd5b50610652600480360381019080803590602001909291905050506114c4565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561069557808201518184015260208101905061067a565b505050509050019250505060405180910390f35b3480156106b557600080fd5b506106be611701565b6040518082815260200191505060405180910390f35b3480156106e057600080fd5b506106ff60048036038101908080359060200190929190505050611707565b005b34801561070d57600080fd5b5061072c600480360381019080803590602001909291905050506117c1565b005b34801561073a57600080fd5b506107bf600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929050505061199e565b6040518082815260200191505060405180910390f35b3480156107e157600080fd5b506107ea6119bd565b6040518082815260200191505060405180910390f35b34801561080c57600080fd5b506108156119c2565b6040518082815260200191505060405180910390f35b34801561083757600080fd5b5061088c600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506119c8565b005b34801561089a57600080fd5b506108b960048036038101908080359060200190929190505050611cdd565b005b6003818154811015156108ca57fe5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561093557600080fd5b81600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561098e57600080fd5b6000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600091505b600160038054905003821015610b13578273ffffffffffffffffffffffffffffffffffffffff16600383815481101515610a2157fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610b06576003600160038054905003815481101515610a7f57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600383815481101515610ab957fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610b13565b81806001019250506109eb565b6001600381818054905003915081610b2b91906120ff565b506003805490506004541115610b4a57610b49600380549050611707565b5b8273ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405160405180910390a2505050565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610beb57600080fd5b81336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610c5657600080fd5b8360008082815260200190815260200160002060030160009054906101000a900460ff16151515610c8657600080fd5b60006001600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550843373ffffffffffffffffffffffffffffffffffffffff167ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e960405160405180910390a35050505050565b60026020528060005260406000206000915054906101000a900460ff1681565b60016020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b600080600090505b600554811015610e1457838015610dc8575060008082815260200190815260200160002060030160009054906101000a900460ff16155b80610dfb5750828015610dfa575060008082815260200190815260200160002060030160009054906101000a900460ff165b5b15610e07576001820191505b8080600101915050610d91565b5092915050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610e5557600080fd5b80600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151515610eaf57600080fd5b8160008173ffffffffffffffffffffffffffffffffffffffff1614151515610ed657600080fd5b60016003805490500160045460328211158015610ef35750818111155b8015610f00575060008114155b8015610f0d575060008214155b1515610f1857600080fd5b6001600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060038590806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550508473ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405160405180910390a25050505050565b6000806000809150600090505b6003805490508110156110fd5760016000858152602001908152602001600020600060038381548110151561105e57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156110dd576001820191505b6004548214156110f057600192506110fe565b808060010191505061102d565b5b5050919050565b600080600090505b6003805490508110156111ca5760016000848152602001908152602001600020600060038381548110151561113e57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156111bd576001820191505b808060010191505061110d565b50919050565b60006020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001015490806002018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156112a85780601f1061127d576101008083540402835291602001916112a8565b820191906000526020600020905b81548152906001019060200180831161128b57829003601f168201915b5050505050908060030160009054906101000a900460ff16905084565b6060600380548060200260200160405190810160405280929190818152602001828054801561134957602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116112ff575b5050505050905090565b60608060008060055460405190808252806020026020018201604052801561138a5781602001602082028038833980820191505090505b50925060009150600090505b600554811015611436578580156113cd575060008082815260200190815260200160002060030160009054906101000a900460ff16155b8061140057508480156113ff575060008082815260200190815260200160002060030160009054906101000a900460ff165b5b156114295780838381518110151561141457fe5b90602001906020020181815250506001820191505b8080600101915050611396565b8787036040519080825280602002602001820160405280156114675781602001602082028038833980820191505090505b5093508790505b868110156114b957828181518110151561148457fe5b906020019060200201518489830381518110151561149e57fe5b9060200190602002018181525050808060010191505061146e565b505050949350505050565b6060806000806003805490506040519080825280602002602001820160405280156114fe5781602001602082028038833980820191505090505b50925060009150600090505b60038054905081101561164b5760016000868152602001908152602001600020600060038381548110151561153b57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561163e576003818154811015156115c257fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683838151811015156115fb57fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506001820191505b808060010191505061150a565b8160405190808252806020026020018201604052801561167a5781602001602082028038833980820191505090505b509350600090505b818110156116f957828181518110151561169857fe5b9060200190602002015184828151811015156116b057fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508080600101915050611682565b505050919050565b60055481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561174157600080fd5b60038054905081603282111580156117595750818111155b8015611766575060008114155b8015611773575060008214155b151561177e57600080fd5b826004819055507fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a836040518082815260200191505060405180910390a1505050565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561181a57600080fd5b81600080600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415151561187657600080fd5b82336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515156118e257600080fd5b600180600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550843373ffffffffffffffffffffffffffffffffffffffff167f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef60405160405180910390a361199785611cdd565b5050505050565b60006119ab848484611f85565b90506119b6816117c1565b9392505050565b603281565b60045481565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611a0457600080fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611a5d57600080fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151515611ab757600080fd5b600092505b600380549050831015611ba0578473ffffffffffffffffffffffffffffffffffffffff16600384815481101515611aef57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611b935783600384815481101515611b4657fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611ba0565b8280600101935050611abc565b6000600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508473ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405160405180910390a28373ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405160405180910390a25050505050565b600033600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611d3857600080fd5b82336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611da357600080fd5b8460008082815260200190815260200160002060030160009054906101000a900460ff16151515611dd357600080fd5b611ddc86611020565b15611f7d57600080878152602001908152602001600020945060018560030160006101000a81548160ff021916908315150217905550611efa8560000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16866001015487600201805460018160011615610100020316600290049050886002018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611ef05780601f10611ec557610100808354040283529160200191611ef0565b820191906000526020600020905b815481529060010190602001808311611ed357829003601f168201915b50505050506120d7565b15611f3157857f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7560405160405180910390a2611f7c565b857f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923660405160405180910390a260008560030160006101000a81548160ff0219169083151502179055505b5b505050505050565b60008360008173ffffffffffffffffffffffffffffffffffffffff1614151515611fae57600080fd5b60055491506080604051908101604052808673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018481526020016000151581525060008084815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010155604082015181600201908051906020019061206d92919061212b565b5060608201518160030160006101000a81548160ff0219169083151502179055509050506001600560008282540192505081905550817fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5160405160405180910390a2509392505050565b6000806040516020840160008287838a8c62054bdc5a03f19250505080915050949350505050565b8154818355818111156121265781836000526020600020918201910161212591906121ab565b5b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061216c57805160ff191683800117855561219a565b8280016001018555821561219a579182015b8281111561219957825182559160200191906001019061217e565b5b5090506121a791906121ab565b5090565b6121cd91905b808211156121c95760008160009055506001016121b1565b5090565b905600a165627a7a72305820b9132d118b85ee91b3ef33d8346c1ba518df422ee90630ed557599092709a7670029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000003":"0x0000000000000000000000000000000000000000000000000000000000000003","0x0000000000000000000000000000000000000000000000000000000000000004":"0x0000000000000000000000000000000000000000000000000000000000000002","0xa19cbe59d468f3fb5b320edc5e49298d3f391d6304c436497c6a7f03ca25515c":"0x0000000000000000000000000000000000000000000000000000000000000001","0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b":"0x0000000000000000000000006d5e05684c737d42f313d5b82a88090136e831f8","0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c":"0x000000000000000000000000049ec8777b4806eff0bb6039551690d8f650b25a","0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85d":"0x000000000000000000000000902f069af381a650b7f18ff28ffdad0f11eb425b","0xf5a9159dd7a73776c0d06b82c491e439b0f434ee7f48db2184c62b8a0915f8f5":"0x0000000000000000000000000000000000000000000000000000000000000001","0xf662ac89672a6f91a243a9cf313e14d1828bf7f3a3ab7938a1f979da6f908864":"0x0000000000000000000000000000000000000000000000000000000000000001"},"balance":"0x0"},"2d7465b88a0a5a1bbff2671c8ed78f7506465ddc":{"code":"0x732d7465b88a0a5a1bbff2671c8ed78f7506465ddc30146080604052600080fd00a165627a7a72305820de029ffd61fdb3181f53609fdbaafec7c7b031427512423ba1afef4928177f300029","balance":"0x0"},"3b058a1a62e59d185618f64bebbaf3c52bf099e0":{"code":"0x733b058a1a62e59d185618f64bebbaf3c52bf099e03014608060405260043610610058576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063098799621461005d575b600080fd5b6100b7600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506100d5565b60405180826000191660001916815260200191505060405180910390f35b60006100df610599565b60006100e9610599565b606060006100f6876102c3565b945060006001029350610108856102f1565b15156102b65761014c6040805190810160405280600181526020017f2e000000000000000000000000000000000000000000000000000000000000008152506102c3565b92506001610163848761030190919063ffffffff16565b0160405190808252806020026020018201604052801561019757816020015b60608152602001906001900390816101825790505b509150600090505b81518110156101eb576101c36101be848761037890919063ffffffff16565b610392565b82828151811015156101d157fe5b90602001906020020181905250808060010191505061019f565b600090505b81518110156102b55783826001838551030381518110151561020e57fe5b906020019060200201516040518082805190602001908083835b60208310151561024d5780518252602082019150602081019050602083039250610228565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206040518083600019166000191681526020018260001916600019168152602001925050506040518091039020935080806001019150506101f0565b5b8395505050505050919050565b6102cb610599565b600060208301905060408051908101604052808451815260200182815250915050919050565b6000808260000151149050919050565b600080826000015161032585600001518660200151866000015187602001516103f4565b0190505b83600001518460200151018111151561037157818060010192505082600001516103698560200151830386600001510383866000015187602001516103f4565b019050610329565b5092915050565b610380610599565b61038b8383836104b0565b5092915050565b606080600083600001516040519080825280601f01601f1916602001820160405280156103ce5781602001602082028038833980820191505090505b5091506020820190506103ea818560200151866000015161054e565b8192505050919050565b6000806000806000888711151561049e576020871115156104555760018760200360080260020a031980875116888b038a018a96505b81838851161461044a5760018701965080600188031061042a578b8b0196505b5050508394506104a4565b8686209150879350600092505b8689038311151561049d57868420905080600019168260001916141561048a578394506104a4565b6001840193508280600101935050610462565b5b88880194505b50505050949350505050565b6104b8610599565b60006104d685600001518660200151866000015187602001516103f4565b90508460200151836020018181525050846020015181038360000181815250508460000151856020015101811415610518576000856000018181525050610543565b8360000151836000015101856000018181510391508181525050836000015181018560200181815250505b829150509392505050565b60005b6020821015156105765782518452602084019350602083019250602082039150610551565b6001826020036101000a0390508019835116818551168181178652505050505050565b6040805190810160405280600081526020016000815250905600a165627a7a72305820bdb7fa7f1254d03496a55a35a971f38f891e40961a467acc8100eadce57bdad70029","balance":"0x0"},"4195b06a6e4d5bedde15165e01a64f324f03d5d1":{"code":"0x60806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633659cfe6146100775780634f1ef286146100ba5780635c60da1b146101085780638f2839701461015f578063f851a440146101a2575b6100756101f9565b005b34801561008357600080fd5b506100b8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610213565b005b610106600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001908201803590602001919091929391929390505050610268565b005b34801561011457600080fd5b5061011d610308565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561016b57600080fd5b506101a0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610360565b005b3480156101ae57600080fd5b506101b761051e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610201610576565b61021161020c610651565b610682565b565b61021b6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025c57610257816106d9565b610265565b6102646101f9565b5b50565b6102706106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fa576102ac836106d9565b3073ffffffffffffffffffffffffffffffffffffffff163483836040518083838082843782019150509250505060006040518083038185875af19250505015156102f557600080fd5b610303565b6103026101f9565b5b505050565b60006103126106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103545761034d610651565b905061035d565b61035c6101f9565b5b90565b6103686106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561051257600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610466576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001807f43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f81526020017f787920746f20746865207a65726f20616464726573730000000000000000000081525060400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61048f6106a8565b82604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a161050d81610748565b61051b565b61051a6101f9565b5b50565b60006105286106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561056a576105636106a8565b9050610573565b6105726101f9565b5b90565b61057e6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151515610647576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001807f43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e20667281526020017f6f6d207468652070726f78792061646d696e000000000000000000000000000081525060400191505060405180910390fd5b61064f610777565b565b6000807f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c36001029050805491505090565b3660008037600080366000845af43d6000803e80600081146106a3573d6000f35b3d6000fd5b6000807f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b6001029050805491505090565b6106e281610779565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b60010290508181555050565b565b60006107848261084b565b151561081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001807f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f81526020017f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000081525060400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c360010290508181555050565b600080823b9050600081119150509190505600a165627a7a72305820b31d41a72e81559b9fbd6f52c3db76ab77aeacd5de378d37ab93861a9b684f120029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x0000000000000000000000000000000000000000000000000000000000000001","0x0aa9b499df4e99716f35c650af5247f98c5dc1bef63f3a923d9f13a6e945b800":"0x0000000000000000000000006d5e05684c737d42f313d5b82a88090136e831f8","0x0aa9b499df4e99716f35c650af5247f98c5dc1bef63f3a923d9f13a6e945b801":"0x00000000000000000000000001e1056f6a829e53dadeb8a5a6189a9333bd1d63","0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b":"0x000000000000000000000000ff9dfbd395cd1c4a4f23c16aa8a5c44109bc17df","0x6793bdf4379ec85ee52adbbe524203920c00866a03f73066b816feb521b95a0f":"0x000000000000000000000000e1adb6075619f52fc00bdd50def1b754b9e7bd17","0x6f7bca21f817d86a5b85f307683ec061c9c10f572e1c3ca5e8312058e1c3f5e7":"0x0000000000000000000000006d5e05684c737d42f313d5b82a88090136e831f8","0x6f7bca21f817d86a5b85f307683ec061c9c10f572e1c3ca5e8312058e1c3f5e8":"0x00000000000000000000000001e1056f6a829e53dadeb8a5a6189a9333bd1d63","0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3":"0x000000000000000000000000bfb47d8008d1ccdcaf3a36110a9338a274e86343","0x86b51839584f7178845a4241ea004c1f5fcaa1a8c0141b741967e2b99d943641":"0x0000000000000000000000006d5e05684c737d42f313d5b82a88090136e831f8","0x86b51839584f7178845a4241ea004c1f5fcaa1a8c0141b741967e2b99d943642":"0x00000000000000000000000001e1056f6a829e53dadeb8a5a6189a9333bd1d63","0xa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb49":"0x0000000000000000000000000e5d0fd336650e663c710ef420f85fb081e21415","0xd485b3e3671c35d525826a03b001f5c3d40c5cfcad1d19ecc0c924f943cb06c8":"0x0000000000000000000000006d5e05684c737d42f313d5b82a88090136e831f8","0xd485b3e3671c35d525826a03b001f5c3d40c5cfcad1d19ecc0c924f943cb06c9":"0x00000000000000000000000001e1056f6a829e53dadeb8a5a6189a9333bd1d63","0xf4b8bad9907850b244478fd4ce9bd72dbd061f18d6e4c56d102809e23bf83642":"0x0000000000000000000000006d5e05684c737d42f313d5b82a88090136e831f8","0xf4b8bad9907850b244478fd4ce9bd72dbd061f18d6e4c56d102809e23bf83643":"0x00000000000000000000000001e1056f6a829e53dadeb8a5a6189a9333bd1d63"},"balance":"0x0"},"426f2e2baa6030668b799c2d9193319dface6b7a":{"code":"0x60806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633659cfe6146100775780634f1ef286146100ba5780635c60da1b146101085780638f2839701461015f578063f851a440146101a2575b6100756101f9565b005b34801561008357600080fd5b506100b8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610213565b005b610106600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001908201803590602001919091929391929390505050610268565b005b34801561011457600080fd5b5061011d610308565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561016b57600080fd5b506101a0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610360565b005b3480156101ae57600080fd5b506101b761051e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610201610576565b61021161020c610651565b610682565b565b61021b6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025c57610257816106d9565b610265565b6102646101f9565b5b50565b6102706106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fa576102ac836106d9565b3073ffffffffffffffffffffffffffffffffffffffff163483836040518083838082843782019150509250505060006040518083038185875af19250505015156102f557600080fd5b610303565b6103026101f9565b5b505050565b60006103126106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103545761034d610651565b905061035d565b61035c6101f9565b5b90565b6103686106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561051257600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610466576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001807f43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f81526020017f787920746f20746865207a65726f20616464726573730000000000000000000081525060400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61048f6106a8565b82604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a161050d81610748565b61051b565b61051a6101f9565b5b50565b60006105286106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561056a576105636106a8565b9050610573565b6105726101f9565b5b90565b61057e6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151515610647576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001807f43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e20667281526020017f6f6d207468652070726f78792061646d696e000000000000000000000000000081525060400191505060405180910390fd5b61064f610777565b565b6000807f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c36001029050805491505090565b3660008037600080366000845af43d6000803e80600081146106a3573d6000f35b3d6000fd5b6000807f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b6001029050805491505090565b6106e281610779565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b60010290508181555050565b565b60006107848261084b565b151561081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001807f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f81526020017f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000081525060400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c360010290508181555050565b600080823b9050600081119150509190505600a165627a7a72305820b31d41a72e81559b9fbd6f52c3db76ab77aeacd5de378d37ab93861a9b684f120029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x0000000000000000000001000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001":"0x0000000000000000000000000000000000000000000000000000000000000032","0x0000000000000000000000000000000000000000000000000000000000000002":"0x0000000000000000000000000000000000000000000000000000000000000258","0x0000000000000000000000000000000000000000000000000000000000000003":"0x000000000000000000000000000000000000000000000000000000000000001e","0x0000000000000000000000000000000000000000000000000000000000000005":"0x0000000000000000000000000090137110f43c6666b7bd641fcf5ca5dd989539","0x0000000000000000000000000000000000000000000000000000000000000006":"0x13a02f7cebf86cd2a5bc43aab96f2b5c4dd7406102f5a3b3e734a749ce84ea87","0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b":"0x000000000000000000000000ff9dfbd395cd1c4a4f23c16aa8a5c44109bc17df","0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3":"0x000000000000000000000000616a77ba32adc911dba37f5883e4013b5278a279"},"balance":"0x0"},"485fa6d2f818145a23ace24d84cdc966d8d2de22":{"code":"0x60806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633659cfe6146100775780634f1ef286146100ba5780635c60da1b146101085780638f2839701461015f578063f851a440146101a2575b6100756101f9565b005b34801561008357600080fd5b506100b8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610213565b005b610106600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001908201803590602001919091929391929390505050610268565b005b34801561011457600080fd5b5061011d610308565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561016b57600080fd5b506101a0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610360565b005b3480156101ae57600080fd5b506101b761051e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610201610576565b61021161020c610651565b610682565b565b61021b6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025c57610257816106d9565b610265565b6102646101f9565b5b50565b6102706106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fa576102ac836106d9565b3073ffffffffffffffffffffffffffffffffffffffff163483836040518083838082843782019150509250505060006040518083038185875af19250505015156102f557600080fd5b610303565b6103026101f9565b5b505050565b60006103126106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103545761034d610651565b905061035d565b61035c6101f9565b5b90565b6103686106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561051257600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610466576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001807f43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f81526020017f787920746f20746865207a65726f20616464726573730000000000000000000081525060400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61048f6106a8565b82604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a161050d81610748565b61051b565b61051a6101f9565b5b50565b60006105286106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561056a576105636106a8565b9050610573565b6105726101f9565b5b90565b61057e6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151515610647576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001807f43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e20667281526020017f6f6d207468652070726f78792061646d696e000000000000000000000000000081525060400191505060405180910390fd5b61064f610777565b565b6000807f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c36001029050805491505090565b3660008037600080366000845af43d6000803e80600081146106a3573d6000f35b3d6000fd5b6000807f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b6001029050805491505090565b6106e281610779565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b60010290508181555050565b565b60006107848261084b565b151561081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001807f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f81526020017f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000081525060400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c360010290508181555050565b600080823b9050600081119150509190505600a165627a7a72305820b31d41a72e81559b9fbd6f52c3db76ab77aeacd5de378d37ab93861a9b684f120029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x0000000000000000000001000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001":"0x0000000000000000000000000000000000000000000000056bc75e2d63100000","0x0000000000000000000000000000000000000000000000000000000000000002":"0x000000000000000000000000c3c45781031885313d5a598042950d6d7be96350","0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b":"0x000000000000000000000000ff9dfbd395cd1c4a4f23c16aa8a5c44109bc17df","0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3":"0x000000000000000000000000cdca8b1b7edfb0827f10f4ed3968d98fa5c90ea0"},"balance":"0x0"},"616a77ba32adc911dba37f5883e4013b5278a279":{"code":"0x60806040526004361061011c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168062fe7b111461012157806309fe9d391461014c578063158ef93e146101b95780631f8d519d146101e8578063339d2590146102495780633f4ba83a146102535780633f4e42511461026a5780635c975abb14610295578063715018a6146102c45780638456cb59146102db5780638da5cb5b146102f2578063986fcbe914610349578063a035b1fe14610376578063a2207c6a146103a1578063a83627de146103f8578063a97e5c9314610423578063c48c1a711461047e578063c8104e01146104a9578063cdee7e071461051d578063f2fde38b14610548578063f93a2eb21461058b575b600080fd5b34801561012d57600080fd5b506101366105a2565b6040518082815260200191505060405180910390f35b34801561015857600080fd5b50610177600480360381019080803590602001909291905050506105a8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156101c557600080fd5b506101ce61062e565b604051808215151515815260200191505060405180910390f35b3480156101f457600080fd5b50610247600480360381019080803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610641565b005b610251610878565b005b34801561025f57600080fd5b50610268610a7e565b005b34801561027657600080fd5b5061027f610b3c565b6040518082815260200191505060405180910390f35b3480156102a157600080fd5b506102aa610b49565b604051808215151515815260200191505060405180910390f35b3480156102d057600080fd5b506102d9610b5c565b005b3480156102e757600080fd5b506102f0610c5e565b005b3480156102fe57600080fd5b50610307610d1e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561035557600080fd5b5061037460048036038101908080359060200190929190505050610d43565b005b34801561038257600080fd5b5061038b610ed9565b6040518082815260200191505060405180910390f35b3480156103ad57600080fd5b506103b6610edf565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561040457600080fd5b5061040d610f05565b6040518082815260200191505060405180910390f35b34801561042f57600080fd5b50610464600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610f0b565b604051808215151515815260200191505060405180910390f35b34801561048a57600080fd5b50610493610f64565b6040518082815260200191505060405180910390f35b3480156104b557600080fd5b506104d460048036038101908080359060200190929190505050610f71565b604051808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390f35b34801561052957600080fd5b50610532610fc9565b6040518082815260200191505060405180910390f35b34801561055457600080fd5b50610589600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610fcf565b005b34801561059757600080fd5b506105a0611036565b005b60015481565b6000806008838154811015156105ba57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169150600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905050919050565b600060159054906101000a900460ff1681565b600060159054906101000a900460ff161515156106ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001807f436f6e747261637420696e7374616e63652068617320616c726561647920626581526020017f656e20696e697469616c697a656400000000000000000000000000000000000081525060400191505060405180910390fd5b6000841115156106fb57600080fd5b6000831115610720576000821180156107145750828211155b151561071f57600080fd5b5b83600181905550826002819055508160038190555080600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550733b058a1a62e59d185618f64bebbaf3c52bf099e063098799626040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825260138152602001807f76616c696461746f726d67722e6b6f77616c610000000000000000000000000081525060200191505060206040518083038186803b15801561081257600080fd5b505af4158015610826573d6000803e3d6000fd5b505050506040513d602081101561083c57600080fd5b8101908080519060200190929190505050600681600019169055506001600060156101000a81548160ff02191690831515021790555050505050565b600060149054906101000a900460ff1615151561089457600080fd5b61089d33610f0b565b1515156108a957600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633b3b57de6006546040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b15801561094457600080fd5b505af1158015610958573d6000803e3d6000fd5b505050506040513d602081101561096e57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff16637d0e81bf336040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015610a1957600080fd5b505af1158015610a2d573d6000803e3d6000fd5b505050506040513d6020811015610a4357600080fd5b81019080805190602001909291905050501515610a5f57600080fd5b610a67611071565b1515610a7257600080fd5b610a7c3334611084565b565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610ad957600080fd5b600060149054906101000a900460ff161515610af457600080fd5b60008060146101000a81548160ff0219169083151502179055507f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3360405160405180910390a1565b6000600880549050905090565b600060149054906101000a900460ff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610bb757600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482060405160405180910390a260008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610cb957600080fd5b600060149054906101000a900460ff16151515610cd557600080fd5b6001600060146101000a81548160ff0219169083151502179055507f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62560405160405180910390a1565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060149054906101000a900460ff16151515610d5f57600080fd5b610d6833610f0b565b1515610d7357600080fd5b600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900460ff16151515610dcf57600080fd5b6001600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160016101000a81548160ff021916908315150217905550600960408051908101604052808381526020013373ffffffffffffffffffffffffffffffffffffffff16815250908060018154018082558091505090600182039060005260206000209060020201600090919290919091506000820151816000015560208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b60045481565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60035481565b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff169050919050565b6000600980549050905090565b6000806000600984815481101515610f8557fe5b90600052602060002090600202019050806000015492508060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915050915091565b60025481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561102a57600080fd5b61103381611159565b50565b600060149054906101000a900460ff1615151561105257600080fd5b61105b33610f0b565b151561106657600080fd5b61106f33611253565b565b6000806008805490506001540311905090565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600160088490806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555003816000018190555060018160010160006101000a81548160ff021916908315150217905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561119557600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000806000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020925082600001549150600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000808201600090556001820160006101000a81549060ff02191690556001820160016101000a81549060ff02191690555050600860016008805490500381548110151561132957fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060088381548110151561136657fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000181905550600880548091906001900361140a9190611411565b5050505050565b81548183558181111561143857818360005260206000209182019101611437919061143d565b5b505050565b61145f91905b8082111561145b576000816000905550600101611443565b5090565b905600a165627a7a723058206edebfea6040cf2a51a7b24a3abd4c4f5147e2cd72dc2e88c61b250d8362437b0029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x0000000000000000000000000e5d0fd336650e663c710ef420f85fb081e21415","0x0000000000000000000000000000000000000000000000000000000000000001":"0x0000000000000000000000000000000000000000000000000000000000000032","0x0000000000000000000000000000000000000000000000000000000000000002":"0x0000000000000000000000000000000000000000000000000000000000000258","0x0000000000000000000000000000000000000000000000000000000000000003":"0x000000000000000000000000000000000000000000000000000000000000001e","0x0000000000000000000000000000000000000000000000000000000000000005":"0x0000000000000000000000000090137110f43c6666b7bd641fcf5ca5dd989539","0x0000000000000000000000000000000000000000000000000000000000000006":"0x13a02f7cebf86cd2a5bc43aab96f2b5c4dd7406102f5a3b3e734a749ce84ea87"},"balance":"0x0"},"64c2a9cb0220d3e56783ed87cc1b20115bc93f96":{"code":"0x6080604052600436106100fc576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305d2035b1461010157806306fdde0314610130578063158ef93e146101c057806318160ddd146101ef578063313ce5671461021a578063355274ea1461024b57806340c10f191461027657806341658f3c146102db57806370a08231146103a1578063715018a6146103f85780637d64bcb41461040f578063893d20e81461043e5780638da5cb5b1461049557806395d89b41146104ec578063a9059cbb1461057c578063be45fd62146105e1578063f2fde38b1461068c578063f6368f8a146106cf575b600080fd5b34801561010d57600080fd5b506101166107c0565b604051808215151515815260200191505060405180910390f35b34801561013c57600080fd5b506101456107d3565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561018557808201518184015260208101905061016a565b50505050905090810190601f1680156101b25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101cc57600080fd5b506101d5610875565b604051808215151515815260200191505060405180910390f35b3480156101fb57600080fd5b50610204610888565b6040518082815260200191505060405180910390f35b34801561022657600080fd5b5061022f610892565b604051808260ff1660ff16815260200191505060405180910390f35b34801561025757600080fd5b506102606108a9565b6040518082815260200191505060405180910390f35b34801561028257600080fd5b506102c1600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506108af565b604051808215151515815260200191505060405180910390f35b3480156102e757600080fd5b5061039f600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080359060200190929190803560ff169060200190929190505050610960565b005b3480156103ad57600080fd5b506103e2600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610acb565b6040518082815260200191505060405180910390f35b34801561040457600080fd5b5061040d610b14565b005b34801561041b57600080fd5b50610424610c19565b604051808215151515815260200191505060405180910390f35b34801561044a57600080fd5b50610453610ce1565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156104a157600080fd5b506104aa610d0b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156104f857600080fd5b50610501610d31565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610541578082015181840152602081019050610526565b50505050905090810190601f16801561056e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561058857600080fd5b506105c7600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610dd3565b604051808215151515815260200191505060405180910390f35b3480156105ed57600080fd5b50610672600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610e0c565b604051808215151515815260200191505060405180910390f35b34801561069857600080fd5b506106cd600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610e43565b005b3480156106db57600080fd5b506107a6600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610eab565b604051808215151515815260200191505060405180910390f35b600760149054906101000a900460ff1681565b606060038054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561086b5780601f106108405761010080835404028352916020019161086b565b820191906000526020600020905b81548152906001019060200180831161084e57829003601f168201915b5050505050905090565b600160009054906101000a900460ff1681565b6000600654905090565b6000600560009054906101000a900460ff16905090565b60085481565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561090d57600080fd5b600760149054906101000a900460ff1615151561092957600080fd5b6008546109418360065461126890919063ffffffff16565b1115151561094e57600080fd5b6109588383611284565b905092915050565b600160009054906101000a900460ff16151515610a0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001807f436f6e747261637420696e7374616e63652068617320616c726561647920626581526020017f656e20696e697469616c697a656400000000000000000000000000000000000081525060400191505060405180910390fd5b600082111515610a1a57600080fd5b8160088190555033600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508360039080519060200190610a78929190611b11565b508260049080519060200190610a8f929190611b11565b5080600560006101000a81548160ff021916908360ff16021790555060018060006101000a81548160ff02191690831515021790555050505050565b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610b7057600080fd5b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482060405160405180910390a26000600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610c7757600080fd5b600760149054906101000a900460ff16151515610c9357600080fd5b6001600760146101000a81548160ff0219169083151502179055507fae5184fba832cb2b1f702aca6117b8d265eaf03ad33eb133f19dde0f5920fa0860405160405180910390a16001905090565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606060048054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610dc95780601f10610d9e57610100808354040283529160200191610dc9565b820191906000526020600020905b815481529060010190602001808311610dac57829003601f168201915b5050505050905090565b60006060610de084611480565b15610df757610df0848483611493565b9150610e05565b610e028484836117de565b91505b5092915050565b6000610e1784611480565b15610e2e57610e27848484611493565b9050610e3c565b610e398484846117de565b90505b9392505050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610e9f57600080fd5b610ea8816119fc565b50565b6000610eb685611480565b156112525783610ec533610acb565b1015610ed057600080fd5b610f2284600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611af890919063ffffffff16565b600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610fb784600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461126890919063ffffffff16565b600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508473ffffffffffffffffffffffffffffffffffffffff166000836040518082805190602001908083835b6020831015156110495780518252602082019150602081019050602083039250611024565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207c01000000000000000000000000000000000000000000000000000000009004903387876040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828051906020019080838360005b8381101561112a57808201518184015260208101905061110f565b50505050905090810190601f1680156111575780820380516001836020036101000a031916815260200191505b50935050505060006040518083038185885af19350505050151561117757fe5b8473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c1686866040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561120e5780820151818401526020810190506111f3565b50505050905090810190601f16801561123b5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a360019050611260565b61125d8585856117de565b90505b949350505050565b6000818301905082811015151561127b57fe5b80905092915050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156112e257600080fd5b600760149054906101000a900460ff161515156112fe57600080fd5b6113138260065461126890919063ffffffff16565b60068190555061136b82600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461126890919063ffffffff16565b600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885836040518082815260200191505060405180910390a28273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c168460405180828152602001806020018281038252600081526020016020019250505060405180910390a36001905092915050565b600080823b905060008111915050919050565b600080836114a033610acb565b10156114ab57600080fd5b6114fd84600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611af890919063ffffffff16565b600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061159284600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461126890919063ffffffff16565b600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508490508073ffffffffffffffffffffffffffffffffffffffff1663c0ee0b8a3386866040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561169a57808201518184015260208101905061167f565b50505050905090810190601f1680156116c75780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156116e857600080fd5b505af11580156116fc573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c1686866040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561179757808201518184015260208101905061177c565b50505050905090810190601f1680156117c45780820380516001836020036101000a031916815260200191505b50935050505060405180910390a360019150509392505050565b6000826117ea33610acb565b10156117f557600080fd5b61184783600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611af890919063ffffffff16565b600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506118dc83600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461126890919063ffffffff16565b600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c1685856040518083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156119b657808201518184015260208101905061199b565b50505050905090810190601f1680156119e35780820380516001836020036101000a031916815260200191505b50935050505060405180910390a3600190509392505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515611a3857600080fd5b8073ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000828211151515611b0657fe5b818303905092915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611b5257805160ff1916838001178555611b80565b82800160010185558215611b80579182015b82811115611b7f578251825591602001919060010190611b64565b5b509050611b8d9190611b91565b5090565b611bb391905b80821115611baf576000816000905550600101611b97565b5090565b905600a165627a7a723058205e5cc50b54a1435f03d0f8490f628e5477e3c71169f264d34c47d0a49253bbfc0029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000003":"0x6d55534400000000000000000000000000000000000000000000000000000008","0x0000000000000000000000000000000000000000000000000000000000000004":"0x6d55534400000000000000000000000000000000000000000000000000000008","0x0000000000000000000000000000000000000000000000000000000000000005":"0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000007":"0x0000000000000000000000000e5d0fd336650e663c710ef420f85fb081e21415","0x0000000000000000000000000000000000000000000000000000000000000008":"0x000000000000000000000000000000000000000003782dace9d9000000000000"},"balance":"0x0"},"6ad6b24c43a622d58e2959474e3912ba94dfd957":{"balance":"0x8ac7230489e80000"},"6d5e05684c737d42f313d5b82a88090136e831f8":{"balance":"0x21e19e0c9bab2400000"},"7a5727e94bbb559e0eafc399354dd30dbd51d2aa":{"code":"0x60806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806325b5672714610051578063c6e8b4f3146100f4575b600080fd5b34801561005d57600080fd5b506100b2600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101d0565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61018e600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929050505061029b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6000806101dc836103fa565b90508073ffffffffffffffffffffffffffffffffffffffff16638f283970856040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b15801561027957600080fd5b505af115801561028d573d6000803e3d6000fd5b505050508091505092915050565b6000806102a7846103fa565b90508073ffffffffffffffffffffffffffffffffffffffff16638f283970866040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b15801561034457600080fd5b505af1158015610358573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff16348460405180828051906020019080838360005b838110156103a2578082015181840152602081019050610387565b50505050905090810190601f1680156103cf5780820380516001836020036101000a031916815260200191505b5091505060006040518083038185875af19250505015156103ef57600080fd5b809150509392505050565b600080826104066104c6565b808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050604051809103906000f080158015610458573d6000803e3d6000fd5b5090507efffc2da0b561cae30d9826d37709e9421c4725faebc226cbbb7ef5fc5e734981604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a180915050919050565b604051610b27806104d7833901905600608060405234801561001057600080fd5b50604051602080610b27833981018060405281019080805190602001909291905050508060405180807f6f72672e7a657070656c696e6f732e70726f78792e696d706c656d656e74617481526020017f696f6e000000000000000000000000000000000000000000000000000000000081525060230190506040518091039020600019167f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3600102600019161415156100c557fe5b6100dd81610167640100000000026401000000009004565b5060405180807f6f72672e7a657070656c696e6f732e70726f78792e61646d696e000000000000815250601a0190506040518091039020600019167f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b6001026000191614151561014957fe5b6101613361024c640100000000026401000000009004565b5061028e565b60006101858261027b6401000000000261084b176401000000009004565b151561021f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001807f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f81526020017f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000081525060400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c360010290508181555050565b60007f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b60010290508181555050565b600080823b905060008111915050919050565b61088a8061029d6000396000f30060806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633659cfe6146100775780634f1ef286146100ba5780635c60da1b146101085780638f2839701461015f578063f851a440146101a2575b6100756101f9565b005b34801561008357600080fd5b506100b8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610213565b005b610106600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001908201803590602001919091929391929390505050610268565b005b34801561011457600080fd5b5061011d610308565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561016b57600080fd5b506101a0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610360565b005b3480156101ae57600080fd5b506101b761051e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610201610576565b61021161020c610651565b610682565b565b61021b6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025c57610257816106d9565b610265565b6102646101f9565b5b50565b6102706106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fa576102ac836106d9565b3073ffffffffffffffffffffffffffffffffffffffff163483836040518083838082843782019150509250505060006040518083038185875af19250505015156102f557600080fd5b610303565b6103026101f9565b5b505050565b60006103126106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103545761034d610651565b905061035d565b61035c6101f9565b5b90565b6103686106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561051257600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610466576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001807f43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f81526020017f787920746f20746865207a65726f20616464726573730000000000000000000081525060400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61048f6106a8565b82604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a161050d81610748565b61051b565b61051a6101f9565b5b50565b60006105286106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561056a576105636106a8565b9050610573565b6105726101f9565b5b90565b61057e6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151515610647576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001807f43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e20667281526020017f6f6d207468652070726f78792061646d696e000000000000000000000000000081525060400191505060405180910390fd5b61064f610777565b565b6000807f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c36001029050805491505090565b3660008037600080366000845af43d6000803e80600081146106a3573d6000f35b3d6000fd5b6000807f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b6001029050805491505090565b6106e281610779565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b60010290508181555050565b565b60006107848261084b565b151561081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001807f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f81526020017f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000081525060400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c360010290508181555050565b600080823b9050600081119150509190505600a165627a7a72305820b31d41a72e81559b9fbd6f52c3db76ab77aeacd5de378d37ab93861a9b684f120029a165627a7a7230582075bac8779341600a0dbcebbbdf6fb8487503343b22b6218c9bd744b22b6435780029","balance":"0x0"},"7f0de05687a7cb9a05399a26f4d1519ba6afc95f":{"code":"0x6080604052600436106100f1576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806301ffc9a7146100f657806310f13a8c1461015a578063158ef93e146102175780632203ab561461024657806329cd62ea146103015780632dff69411461034e5780633b3b57de1461039b57806359d1d43c1461040c578063623195b0146104fc578063691f34311461057d5780637737221314610627578063aa4cb5471461069e578063c3d014d614610715578063c4d66de814610754578063c869023314610797578063d5fa2b00146107f3578063e89401a114610844575b600080fd5b34801561010257600080fd5b5061014060048036038101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690602001909291905050506108ee565b604051808215151515815260200191505060405180910390f35b34801561016657600080fd5b506102156004803603810190808035600019169060200190929190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610c48565b005b34801561022357600080fd5b5061022c610f06565b604051808215151515815260200191505060405180910390f35b34801561025257600080fd5b5061027f600480360381019080803560001916906020019092919080359060200190929190505050610f18565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156102c55780820151818401526020810190506102aa565b50505050905090810190601f1680156102f25780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b34801561030d57600080fd5b5061034c60048036038101908080356000191690602001909291908035600019169060200190929190803560001916906020019092919050505061105b565b005b34801561035a57600080fd5b5061037d6004803603810190808035600019169060200190929190505050611221565b60405180826000191660001916815260200191505060405180910390f35b3480156103a757600080fd5b506103ca6004803603810190808035600019169060200190929190505050611249565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561041857600080fd5b506104816004803603810190808035600019169060200190929190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050611291565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156104c15780820151818401526020810190506104a6565b50505050905090810190601f1680156104ee5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561050857600080fd5b5061057b600480360381019080803560001916906020019092919080359060200190929190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506113bb565b005b34801561058957600080fd5b506105ac6004803603810190808035600019169060200190929190505050611559565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156105ec5780820151818401526020810190506105d1565b50505050905090810190601f1680156106195780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561063357600080fd5b5061069c6004803603810190808035600019169060200190929190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050611619565b005b3480156106aa57600080fd5b506107136004803603810190808035600019169060200190929190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050611800565b005b34801561072157600080fd5b50610752600480360381019080803560001916906020019092919080356000191690602001909291905050506119e7565b005b34801561076057600080fd5b50610795600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611b65565b005b3480156107a357600080fd5b506107c66004803603810190808035600019169060200190929190505050611c6d565b60405180836000191660001916815260200182600019166000191681526020019250505060405180910390f35b3480156107ff57600080fd5b506108426004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611cbd565b005b34801561085057600080fd5b506108736004803603810190808035600019169060200190929190505050611e95565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156108b3578082015181840152602081019050610898565b50505050905090810190601f1680156108e05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000633b3b57de7c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806109bf575063d8389dc57c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610a2a575063691f34317c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610a955750632203ab567c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610b00575063c86902337c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610b6b57506359d1d43c7c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610bd6575063e89401a17c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610c4157506301ffc9a77c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b823373ffffffffffffffffffffffffffffffffffffffff16600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b158015610cf957600080fd5b505af1158015610d0d573d6000803e3d6000fd5b505050506040513d6020811015610d2357600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff16141515610d5657600080fd5b81600160008660001916600019168152602001908152602001600020600501846040518082805190602001908083835b602083101515610dab5780518252602082019150602081019050602083039250610d86565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405180910390209080519060200190610df1929190611f55565b5083600019167fd8c9334b1a9c2f9da342a0a2b32629c1a229b6445dad78947f674b44444a75508485604051808060200180602001838103835285818151815260200191508051906020019080838360005b83811015610e5e578082015181840152602081019050610e43565b50505050905090810190601f168015610e8b5780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015610ec4578082015181840152602081019050610ea9565b50505050905090810190601f168015610ef15780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a250505050565b6000809054906101000a900460ff1681565b6000606060006001600086600019166000191681526020019081526020016000209050600192505b838311151561104e57600084841614158015610f8557506000816006016000858152602001908152602001600020805460018160011615610100020316600290049050115b1561103f578060060160008481526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156110335780601f1061100857610100808354040283529160200191611033565b820191906000526020600020905b81548152906001019060200180831161101657829003601f168201915b50505050509150611053565b6001839060020a029250610f40565b600092505b509250929050565b823373ffffffffffffffffffffffffffffffffffffffff16600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b15801561110c57600080fd5b505af1158015611120573d6000803e3d6000fd5b505050506040513d602081101561113657600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1614151561116957600080fd5b6040805190810160405280846000191681526020018360001916815250600160008660001916600019168152602001908152602001600020600301600082015181600001906000191690556020820151816001019060001916905590505083600019167f1d6f5e03d3f63eb58751986629a5439baee5079ff04f345becb66e23eb154e46848460405180836000191660001916815260200182600019166000191681526020019250505060405180910390a250505050565b6000600160008360001916600019168152602001908152602001600020600101549050919050565b600060016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6060600160008460001916600019168152602001908152602001600020600501826040518082805190602001908083835b6020831015156112e757805182526020820191506020810190506020830392506112c2565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405180910390208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156113ae5780601f10611383576101008083540402835291602001916113ae565b820191906000526020600020905b81548152906001019060200180831161139157829003601f168201915b5050505050905092915050565b823373ffffffffffffffffffffffffffffffffffffffff16600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b15801561146c57600080fd5b505af1158015611480573d6000803e3d6000fd5b505050506040513d602081101561149657600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff161415156114c957600080fd5b60008360018503161415156114dd57600080fd5b8160016000866000191660001916815260200190815260200160002060060160008581526020019081526020016000209080519060200190611520929190611fd5565b508284600019167faa121bbeef5f32f5961a2a28966e769023910fc9479059ee3495d4c1a696efe360405160405180910390a350505050565b60606001600083600019166000191681526020019081526020016000206002018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561160d5780601f106115e25761010080835404028352916020019161160d565b820191906000526020600020905b8154815290600101906020018083116115f057829003601f168201915b50505050509050919050565b813373ffffffffffffffffffffffffffffffffffffffff16600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1580156116ca57600080fd5b505af11580156116de573d6000803e3d6000fd5b505050506040513d60208110156116f457600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1614151561172757600080fd5b816001600085600019166000191681526020019081526020016000206002019080519060200190611759929190611f55565b5082600019167fb7d29e911041e8d9b843369e890bcb72c9388692ba48b65ac54e7214c4c348f7836040518080602001828103825283818151815260200191508051906020019080838360005b838110156117c15780820151818401526020810190506117a6565b50505050905090810190601f1680156117ee5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505050565b813373ffffffffffffffffffffffffffffffffffffffff16600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1580156118b157600080fd5b505af11580156118c5573d6000803e3d6000fd5b505050506040513d60208110156118db57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1614151561190e57600080fd5b816001600085600019166000191681526020019081526020016000206007019080519060200190611940929190611fd5565b5082600019167fc0b0fc07269fc2749adada3221c095a1d2187b2d075b51c915857b520f3a5021836040518080602001828103825283818151815260200191508051906020019080838360005b838110156119a857808201518184015260208101905061198d565b50505050905090810190601f1680156119d55780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505050565b813373ffffffffffffffffffffffffffffffffffffffff16600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b158015611a9857600080fd5b505af1158015611aac573d6000803e3d6000fd5b505050506040513d6020811015611ac257600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff16141515611af557600080fd5b81600160008560001916600019168152602001908152602001600020600101816000191690555082600019167f0424b6fe0d9c3bdbece0e7879dc241bb0c22e900be8b6c168b4ee08bd9bf83bc8360405180826000191660001916815260200191505060405180910390a2505050565b6000809054906101000a900460ff16151515611c0f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001807f436f6e747261637420696e7374616e63652068617320616c726561647920626581526020017f656e20696e697469616c697a656400000000000000000000000000000000000081525060400191505060405180910390fd5b80600060016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060016000806101000a81548160ff02191690831515021790555050565b600080600160008460001916600019168152602001908152602001600020600301600001546001600085600019166000191681526020019081526020016000206003016001015491509150915091565b813373ffffffffffffffffffffffffffffffffffffffff16600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b158015611d6e57600080fd5b505af1158015611d82573d6000803e3d6000fd5b505050506040513d6020811015611d9857600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff16141515611dcb57600080fd5b8160016000856000191660001916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600019167f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd283604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a2505050565b60606001600083600019166000191681526020019081526020016000206007018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611f495780601f10611f1e57610100808354040283529160200191611f49565b820191906000526020600020905b815481529060010190602001808311611f2c57829003601f168201915b50505050509050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611f9657805160ff1916838001178555611fc4565b82800160010185558215611fc4579182015b82811115611fc3578251825591602001919060010190611fa8565b5b509050611fd19190612055565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061201657805160ff1916838001178555612044565b82800160010185558215612044579182015b82811115612043578251825591602001919060010190612028565b5b5090506120519190612055565b5090565b61207791905b8082111561207357600081600090555060010161205b565b5090565b905600a165627a7a72305820027c05d350dcea72c694473f4a996d01df5e087012864c93d8c8fb87b44584380029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x0000000000000000000000000000000000000000000000000000000000000000"},"balance":"0x0"},"902f069af381a650b7f18ff28ffdad0f11eb425b":{"balance":"0x8ac7230489e80000"},"b5822d5f8d221ce2dc73e388629eca256b0aa4f2":{"code":"0x60806040526004361061016a576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063035cf1421461016f5780630a3cb6631461019a578063158ef93e146101c55780632086ca25146101f4578063268331481461021f5780633ed0a3731461024a5780633f4ba83a146102925780635c975abb146102a957806369474625146102d85780636a911ccf146103035780637071688a1461031a578063715018a6146103455780637d0e81bf1461035c5780638456cb59146103b75780638da5cb5b146103ce5780639363a1411461042557806397584b3e146104505780639abee7d01461047f5780639bb2ea5a146104cc578063a2207c6a146104f9578063aded41ec14610550578063b774cb1e14610567578063c22a933c1461059a578063ccd65296146105c7578063cefddda914610632578063e7a60a9c1461068d578063f2fde38b14610701578063facd743b14610744575b600080fd5b34801561017b57600080fd5b5061018461079f565b6040518082815260200191505060405180910390f35b3480156101a657600080fd5b506101af610872565b6040518082815260200191505060405180910390f35b3480156101d157600080fd5b506101da610878565b604051808215151515815260200191505060405180910390f35b34801561020057600080fd5b5061020961088b565b6040518082815260200191505060405180910390f35b34801561022b57600080fd5b50610234610891565b6040518082815260200191505060405180910390f35b34801561025657600080fd5b5061027560048036038101908080359060200190929190505050610897565b604051808381526020018281526020019250505060405180910390f35b34801561029e57600080fd5b506102a761090f565b005b3480156102b557600080fd5b506102be6109cd565b604051808215151515815260200191505060405180910390f35b3480156102e457600080fd5b506102ed6109e0565b6040518082815260200191505060405180910390f35b34801561030f57600080fd5b506103186109e6565b005b34801561032657600080fd5b5061032f610a21565b6040518082815260200191505060405180910390f35b34801561035157600080fd5b5061035a610a2e565b005b34801561036857600080fd5b5061039d600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b30565b604051808215151515815260200191505060405180910390f35b3480156103c357600080fd5b506103cc610bc4565b005b3480156103da57600080fd5b506103e3610c84565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561043157600080fd5b5061043a610ca9565b6040518082815260200191505060405180910390f35b34801561045c57600080fd5b50610465610cf6565b604051808215151515815260200191505060405180910390f35b34801561048b57600080fd5b506104ca600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610d09565b005b3480156104d857600080fd5b506104f760048036038101908080359060200190929190505050610d96565b005b34801561050557600080fd5b5061050e610e3a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561055c57600080fd5b50610565610e60565b005b34801561057357600080fd5b5061057c611135565b60405180826000191660001916815260200191505060405180910390f35b3480156105a657600080fd5b506105c56004803603810190808035906020019092919050505061113b565b005b3480156105d357600080fd5b5061063060048036038101908080359060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506111a0565b005b34801561063e57600080fd5b50610673600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506113bf565b604051808215151515815260200191505060405180910390f35b34801561069957600080fd5b506106b860048036038101908080359060200190929190505050611418565b604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390f35b34801561070d57600080fd5b50610742600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506114cf565b005b34801561075057600080fd5b50610785600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611536565b604051808215151515815260200191505060405180910390f35b6000806107aa610cf6565b156107b957600154915061086e565b6008600060096001600980549050038154811015156107d457fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600181600201600183600201805490500381548110151561085857fe5b9060005260206000209060020201600001540191505b5090565b60035481565b600060159054906101000a900460ff1681565b60025481565b60065481565b6000806000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201848154811015156108eb57fe5b90600052602060002090600202019050806000015481600101549250925050915091565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561096a57600080fd5b600060149054906101000a900460ff16151561098557600080fd5b60008060146101000a81548160ff0219169083151502179055507f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3360405160405180910390a1565b600060149054906101000a900460ff1681565b60015481565b600060149054906101000a900460ff16151515610a0257600080fd5b610a0b33611536565b1515610a1657600080fd5b610a1f3361158f565b565b6000600980549050905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610a8957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482060405160405180910390a260008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600080610b3c83611536565b1515610b4b5760009150610bbe565b600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002019050600654816001838054905003815481101515610ba757fe5b906000526020600020906002020160000154101591505b50919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610c1f57600080fd5b600060149054906101000a900460ff16151515610c3b57600080fd5b6001600060146101000a81548160ff0219169083151502179055507f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62560405160405180910390a1565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020180549050905090565b6000806009805490506002540311905090565b60408051908101604052808373ffffffffffffffffffffffffffffffffffffffff16815260200182815250600a60008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010155905050610d92611701565b5050565b6000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610df457600080fd5b600980549050831015610e2e5782600980549050039150600090505b81811015610e2d57610e206117bf565b8080600101915050610e10565b5b82600281905550505050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600080600060149054906101000a900460ff16151515610e8257600080fd5b6000935060009250600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020191505b818054905083108015610f02575060008284815481101515610eed57fe5b90600052602060002090600202016001015414155b15610f64578183815481101515610f1557fe5b906000526020600020906002020160010154421015610f3357610f64565b8183815481101515610f4157fe5b906000526020600020906002020160000154840193508280600101935050610ecf565b610f6e338461180b565b600084111561112f57600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633b3b57de6005546040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b15801561101257600080fd5b505af1158015611026573d6000803e3d6000fd5b505050506040513d602081101561103c57600080fd5b810190808051906020019092919050505090508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33866040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156110f257600080fd5b505af1158015611106573d6000803e3d6000fd5b505050506040513d602081101561111c57600080fd5b8101908080519060200190929190505050505b50505050565b60045481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561119657600080fd5b8060018190555050565b600060159054906101000a900460ff1615151561124b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001807f436f6e747261637420696e7374616e63652068617320616c726561647920626581526020017f656e20696e697469616c697a656400000000000000000000000000000000000081525060400191505060405180910390fd5b60008411151561125a57600080fd5b84600181905550836002819055506201518083026003819055508160068190555080600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550733b058a1a62e59d185618f64bebbaf3c52bf099e063098799626040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825260128152602001807f6d696e696e67746f6b656e2e6b6f77616c61000000000000000000000000000081525060200191505060206040518083038186803b15801561135857600080fd5b505af415801561136c573d6000803e3d6000fd5b505050506040513d602081101561138257600080fd5b8101908080519060200190929190505050600581600019169055506001600060156101000a81548160ff0219169083151502179055505050505050565b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900460ff169050919050565b600080600060098481548110151561142c57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169250600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060020160018260020180549050038154811015156114b557fe5b906000526020600020906002020160000154915050915091565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561152a57600080fd5b611533816118f8565b50565b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff169050919050565b600080600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209150816000015490505b60016009805490500381101561168c576009600182018154811015156115fd57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660098281548110151561163757fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080806001019150506115db565b60098054809190600190036116a19190611db9565b5060008260010160006101000a81548160ff02191690831515021790555060035442018260020160018460020180549050038154811015156116df57fe5b9060005260206000209060020201600101819055506116fc6119f2565b505050565b600060149054906101000a900460ff1615151561171d57600080fd5b61174b600a60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16611536565b15151561175757600080fd5b61175f61079f565b600a600101541015151561177257600080fd5b61177a610cf6565b1515611789576117886117bf565b5b6117bd600a60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600a60010154611a75565b565b61180960096001600980549050038154811015156117d957fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661158f565b565b60008060008084141561181d576118f1565b600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209250600091508390505b82600201805490508110156118df57826002018181548110151561188657fe5b906000526020600020906002020183600201838154811015156118a557fe5b9060005260206000209060020201600082015481600001556001820154816001015590505081806001019250508080600101915050611866565b8183600201816118ef9190611de5565b505b5050505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561193457600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6009604051808280548015611a5c57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611a12575b5050915050604051809103902060048160001916905550565b600080600080600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209350600160098790806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555003846000018190555060018460010160006101000a81548160ff0219169083151502179055506000431415611b705760018460010160016101000a81548160ff0219169083151502179055505b8360020160408051908101604052808781526020016000815250908060018154018082558091505090600182039060005260206000209060020201600090919290919091506000820151816000015560208201518160010155505050836000015492505b6000831115611da95760086000600960018603815481101515611bf357fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209150816002016001836002018054905003815481101515611c7557fe5b90600052602060002090600202019050806000015485111515611c9757611da9565b600960018403815481101515611ca957fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600984815481101515611ce357fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555085600960018503815481101515611d3e57fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828260000181905550600183038460000181905550828060019003935050611bd4565b611db16119f2565b505050505050565b815481835581811115611de057818360005260206000209182019101611ddf9190611e17565b5b505050565b815481835581811115611e1257600202816002028360005260206000209182019101611e119190611e3c565b5b505050565b611e3991905b80821115611e35576000816000905550600101611e1d565b5090565b90565b611e6891905b80821115611e6457600080820160009055600182016000905550600201611e42565b5090565b905600a165627a7a72305820191fba81bca640eb79ed9424e349e31a1a476c3140d3d27c954efbfec8e60f0b0029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x0000000000000000000000000e5d0fd336650e663c710ef420f85fb081e21415","0x0000000000000000000000000000000000000000000000000000000000000001":"0x00000000000000000000000000000000000000000000065a4da25d3016c00000","0x0000000000000000000000000000000000000000000000000000000000000002":"0x00000000000000000000000000000000000000000000000000000000000001f4","0x0000000000000000000000000000000000000000000000000000000000000003":"0x0000000000000000000000000000000000000000000000000000000000015180","0x0000000000000000000000000000000000000000000000000000000000000005":"0xc99f18ca33e10b0236fe4fd62bfd9a8eb6ceee10bf8dad1b0d121d5e6a2bf3ba","0x0000000000000000000000000000000000000000000000000000000000000006":"0x00000000000000000000000000000000000000000004f68ca6d8cd91c6000000","0x0000000000000000000000000000000000000000000000000000000000000007":"0x00000000000000000000000001e1056f6a829e53dadeb8a5a6189a9333bd1d63"},"balance":"0x0"},"bfb47d8008d1ccdcaf3a36110a9338a274e86343":{"code":"0x608060405260043610610099576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630178b8bf1461009e57806302571be31461010f57806306ab59231461018057806314ab9038146101df578063158ef93e1461022457806316a25cbd146102535780631896f70a146102ac5780635b0fc9c3146102fd578063c4d66de81461034e575b600080fd5b3480156100aa57600080fd5b506100cd6004803603810190808035600019169060200190929190505050610391565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561011b57600080fd5b5061013e60048036038101908080356000191690602001909291905050506103d9565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561018c57600080fd5b506101dd60048036038101908080356000191690602001909291908035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610421565b005b3480156101eb57600080fd5b506102226004803603810190808035600019169060200190929190803567ffffffffffffffff16906020019092919050505061059d565b005b34801561023057600080fd5b506102396106b0565b604051808215151515815260200191505060405180910390f35b34801561025f57600080fd5b5061028260048036038101908080356000191690602001909291905050506106c2565b604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390f35b3480156102b857600080fd5b506102fb6004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506106fe565b005b34801561030957600080fd5b5061034c6004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610841565b005b34801561035a57600080fd5b5061038f600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610984565b005b600060016000836000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600060016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000833373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561049c57600080fd5b848460405180836000191660001916815260200182600019166000191681526020019250505060405180910390209150836000191685600019167fce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e8285604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a38260016000846000191660001916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b813373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561061657600080fd5b82600019167f1d4f9bbfc9cab89d66e1a1562f2233ccbf1308cb4f63de2ead5787adddb8fa6883604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390a28160016000856000191660001916815260200190815260200160002060010160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505050565b6000809054906101000a900460ff1681565b600060016000836000191660001916815260200190815260200160002060010160149054906101000a900467ffffffffffffffff169050919050565b813373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561077757600080fd5b82600019167f335721b01866dc23fbee8b6b2c7b1e14d6f05c28cd35a2c934239f94095602a083604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a28160016000856000191660001916815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b813373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156108ba57600080fd5b82600019167fd4735d920b0f87494915f556dd9b54c8f309026070caea5c737245152564d26683604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a28160016000856000191660001916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b6000809054906101000a900460ff16151515610a2e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001807f436f6e747261637420696e7374616e63652068617320616c726561647920626581526020017f656e20696e697469616c697a656400000000000000000000000000000000000081525060400191505060405180910390fd5b80600160008060010260001916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060016000806101000a81548160ff021916908315150217905550505600a165627a7a72305820e6c94ed3c260b949380eb0a722b651d424262e08f3c684546711633d9eb70ec10029","storage":{"0xa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb49":"0x0000000000000000000000000e5d0fd336650e663c710ef420f85fb081e21415"},"balance":"0x0"},"c3c45781031885313d5a598042950d6d7be96350":{"code":"0x6080604052600436106100a3576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168062bf32ca146100a8578063158ef93e146100e957806321873631146101185780632af4f9c0146101435780632d3802421461016e5780636df566d714610199578063a035b1fe146101c4578063b0c6363d146101ef578063e4a301161461021a578063fc634f4b14610251575b600080fd5b3480156100b457600080fd5b506100d36004803603810190808035906020019092919050505061027c565b6040518082815260200191505060405180910390f35b3480156100f557600080fd5b506100fe610295565b604051808215151515815260200191505060405180910390f35b34801561012457600080fd5b5061012d6102a7565b6040518082815260200191505060405180910390f35b34801561014f57600080fd5b506101586102d7565b6040518082815260200191505060405180910390f35b34801561017a57600080fd5b506101836102dd565b6040518082815260200191505060405180910390f35b3480156101a557600080fd5b506101ae610365565b6040518082815260200191505060405180910390f35b3480156101d057600080fd5b506101d961036b565b6040518082815260200191505060405180910390f35b3480156101fb57600080fd5b50610204610375565b6040518082815260200191505060405180910390f35b34801561022657600080fd5b5061024f600480360381019080803590602001909291908035906020019092919050505061037b565b005b34801561025d57600080fd5b5061026661045f565b6040518082815260200191505060405180910390f35b600060648260040281151561028d57fe5b049050919050565b6000809054906101000a900460ff1681565b60006102d2670de0b6b3a76400003073ffffffffffffffffffffffffffffffffffffffff1631610465565b905090565b60045481565b600080600180430114156102fc57680246ddf979766800009150610361565b61271060045481151561030b57fe5b04905060015460025411801561032a5750670de0b6b3a7640000600154115b1561034b57610344816004540161033f61047e565b610465565b9150610361565b61035e816004540364e8d4a510006104bf565b91505b5090565b60025481565b6000600254905090565b60035481565b6000809054906101000a900460ff16151515610425576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001807f436f6e747261637420696e7374616e63652068617320616c726561647920626581526020017f656e20696e697469616c697a656400000000000000000000000000000000000081525060400191505060405180910390fd5b8160018190555081600281905550806004819055508060038190555060016000806101000a81548160ff0219169083151502179055505050565b60015481565b60008183106104745781610476565b825b905092915050565b6000600180430111801561049657506104956104d9565b5b6104a957680471fa858b9e0800006104ba565b6127106003548115156104b857fe5b045b905090565b6000818310156104cf57816104d1565b825b905092915050565b600069d3c21bcecceda100000060035410159050905600a165627a7a723058206fe4f1f991942cb71ef574c8d7fffd57bd4a05e408f7df2f2c0ecd8fe40406390029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000001":"0x0000000000000000000000000000000000000000000000000de0b6b3a7640000","0x0000000000000000000000000000000000000000000000000000000000000002":"0x0000000000000000000000000000000000000000000000000de0b6b3a7640000","0x0000000000000000000000000000000000000000000000000000000000000003":"0x00000000000000000000000000000000000000000000021fba3632c84ff80000","0x0000000000000000000000000000000000000000000000000000000000000004":"0x00000000000000000000000000000000000000000000021fba3632c84ff80000"},"balance":"0x0"},"c497f7ad7105db9f4138de92b13a0883b19ee0fa":{"code":"0x60806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633659cfe6146100775780634f1ef286146100ba5780635c60da1b146101085780638f2839701461015f578063f851a440146101a2575b6100756101f9565b005b34801561008357600080fd5b506100b8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610213565b005b610106600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001908201803590602001919091929391929390505050610268565b005b34801561011457600080fd5b5061011d610308565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561016b57600080fd5b506101a0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610360565b005b3480156101ae57600080fd5b506101b761051e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610201610576565b61021161020c610651565b610682565b565b61021b6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025c57610257816106d9565b610265565b6102646101f9565b5b50565b6102706106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fa576102ac836106d9565b3073ffffffffffffffffffffffffffffffffffffffff163483836040518083838082843782019150509250505060006040518083038185875af19250505015156102f557600080fd5b610303565b6103026101f9565b5b505050565b60006103126106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103545761034d610651565b905061035d565b61035c6101f9565b5b90565b6103686106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561051257600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610466576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001807f43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f81526020017f787920746f20746865207a65726f20616464726573730000000000000000000081525060400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61048f6106a8565b82604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a161050d81610748565b61051b565b61051a6101f9565b5b50565b60006105286106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561056a576105636106a8565b9050610573565b6105726101f9565b5b90565b61057e6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151515610647576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001807f43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e20667281526020017f6f6d207468652070726f78792061646d696e000000000000000000000000000081525060400191505060405180910390fd5b61064f610777565b565b6000807f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c36001029050805491505090565b3660008037600080366000845af43d6000803e80600081146106a3573d6000f35b3d6000fd5b6000807f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b6001029050805491505090565b6106e281610779565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b60010290508181555050565b565b60006107848261084b565b151561081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001807f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f81526020017f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000081525060400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c360010290508181555050565b600080823b9050600081119150509190505600a165627a7a72305820b31d41a72e81559b9fbd6f52c3db76ab77aeacd5de378d37ab93861a9b684f120029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000001":"0x0000000000000000000000000000000000000000000000000de0b6b3a7640000","0x0000000000000000000000000000000000000000000000000000000000000002":"0x0000000000000000000000000000000000000000000000000de0b6b3a7640000","0x0000000000000000000000000000000000000000000000000000000000000003":"0x00000000000000000000000000000000000000000000021fba3632c84ff80000","0x0000000000000000000000000000000000000000000000000000000000000004":"0x00000000000000000000000000000000000000000000021fba3632c84ff80000","0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b":"0x000000000000000000000000ff9dfbd395cd1c4a4f23c16aa8a5c44109bc17df","0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3":"0x000000000000000000000000c3c45781031885313d5a598042950d6d7be96350"},"balance":"0x0"},"cdca8b1b7edfb0827f10f4ed3968d98fa5c90ea0":{"code":"0x6080604052600436106100c5576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063158ef93e146100ca5780633f4ba83a146100f9578063402300461461011057806341b3d185146101845780635c975abb146101af57806366419970146101de578063715018a6146102095780638456cb59146102205780638da5cb5b146102375780638f449a051461028e578063da35a26f14610298578063f2fde38b146102e5578063fcae448414610328575b600080fd5b3480156100d657600080fd5b506100df61033f565b604051808215151515815260200191505060405180910390f35b34801561010557600080fd5b5061010e610352565b005b34801561011c57600080fd5b5061013b60048036038101908080359060200190929190505050610410565b604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390f35b34801561019057600080fd5b5061019961049f565b6040518082815260200191505060405180910390f35b3480156101bb57600080fd5b506101c46104a5565b604051808215151515815260200191505060405180910390f35b3480156101ea57600080fd5b506101f36104b8565b6040518082815260200191505060405180910390f35b34801561021557600080fd5b5061021e6104c5565b005b34801561022c57600080fd5b506102356105c7565b005b34801561024357600080fd5b5061024c610687565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102966106ac565b005b3480156102a457600080fd5b506102e360048036038101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061073b565b005b3480156102f157600080fd5b50610326600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061084d565b005b34801561033457600080fd5b5061033d6108b4565b005b600060159054906101000a900460ff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156103ad57600080fd5b600060149054906101000a900460ff1615156103c857600080fd5b60008060146101000a81548160ff0219169083151502179055507f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3360405160405180910390a1565b600080600060048481548110151561042457fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169250600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060020154915050915091565b60015481565b600060149054906101000a900460ff1681565b6000600480549050905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561052057600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482060405160405180910390a260008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561062257600080fd5b600060149054906101000a900460ff1615151561063e57600080fd5b6001600060146101000a81548160ff0219169083151502179055507f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62560405160405180910390a1565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060149054906101000a900460ff161515156106c957600080fd5b6106d233610b9b565b1561072f57600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050348160020160008282540192505081905550610738565b610737610bf4565b5b50565b600060159054906101000a900460ff161515156107e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001807f436f6e747261637420696e7374616e63652068617320616c726561647920626581526020017f656e20696e697469616c697a656400000000000000000000000000000000000081525060400191505060405180910390fd5b8160018190555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600060156101000a81548160ff0219169083151502179055505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156108a857600080fd5b6108b181610ce1565b50565b60008060006108c233610b9b565b15156108cd57600080fd5b670de0b6b3a7640000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a035b1fe6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561095c57600080fd5b505af1158015610970573d6000803e3d6000fd5b505050506040513d602081101561098657600080fd5b8101908080519060200190929190505050101515156109a457600080fd5b600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209250826000015491503373ffffffffffffffffffffffffffffffffffffffff166108fc84600201549081150290604051600060405180830381858888f19350505050158015610a36573d6000803e3d6000fd5b50600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000808201600090556001820160006101000a81549060ff0219169055600282016000905550506004600160048054905003815481101515610ab457fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905080600483815481101515610af157fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001819055506004805480919060019003610b959190610ddb565b50505050565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff169050919050565b60006001543410151515610c0757600080fd5b600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600160043390806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555003816000018190555060018160010160006101000a81548160ff02191690831515021790555034816002018190555050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610d1d57600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b815481835581811115610e0257818360005260206000209182019101610e019190610e07565b5b505050565b610e2991905b80821115610e25576000816000905550600101610e0d565b5090565b905600a165627a7a7230582003e9f8a667889c71192d8deb1e6aa5493e226a18e8f0762c904236c8053c7c100029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x0000000000000000000000000e5d0fd336650e663c710ef420f85fb081e21415","0x0000000000000000000000000000000000000000000000000000000000000001":"0x0000000000000000000000000000000000000000000000056bc75e2d63100000","0x0000000000000000000000000000000000000000000000000000000000000002":"0x000000000000000000000000c3c45781031885313d5a598042950d6d7be96350"},"balance":"0x0"},"dfcb946fd93a0ae4056d7d6dca59d59fd830f8a5":{"code":"0x60806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633659cfe6146100775780634f1ef286146100ba5780635c60da1b146101085780638f2839701461015f578063f851a440146101a2575b6100756101f9565b005b34801561008357600080fd5b506100b8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610213565b005b610106600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001908201803590602001919091929391929390505050610268565b005b34801561011457600080fd5b5061011d610308565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561016b57600080fd5b506101a0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610360565b005b3480156101ae57600080fd5b506101b761051e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610201610576565b61021161020c610651565b610682565b565b61021b6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025c57610257816106d9565b610265565b6102646101f9565b5b50565b6102706106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fa576102ac836106d9565b3073ffffffffffffffffffffffffffffffffffffffff163483836040518083838082843782019150509250505060006040518083038185875af19250505015156102f557600080fd5b610303565b6103026101f9565b5b505050565b60006103126106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103545761034d610651565b905061035d565b61035c6101f9565b5b90565b6103686106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561051257600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610466576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001807f43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f81526020017f787920746f20746865207a65726f20616464726573730000000000000000000081525060400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61048f6106a8565b82604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a161050d81610748565b61051b565b61051a6101f9565b5b50565b60006105286106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561056a576105636106a8565b9050610573565b6105726101f9565b5b90565b61057e6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151515610647576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001807f43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e20667281526020017f6f6d207468652070726f78792061646d696e000000000000000000000000000081525060400191505060405180910390fd5b61064f610777565b565b6000807f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c36001029050805491505090565b3660008037600080366000845af43d6000803e80600081146106a3573d6000f35b3d6000fd5b6000807f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b6001029050805491505090565b6106e281610779565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b60010290508181555050565b565b60006107848261084b565b151561081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001807f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f81526020017f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000081525060400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c360010290508181555050565b600080823b9050600081119150509190505600a165627a7a72305820b31d41a72e81559b9fbd6f52c3db76ab77aeacd5de378d37ab93861a9b684f120029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000001":"0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000003":"0x6d55534400000000000000000000000000000000000000000000000000000008","0x0000000000000000000000000000000000000000000000000000000000000004":"0x6d55534400000000000000000000000000000000000000000000000000000008","0x0000000000000000000000000000000000000000000000000000000000000005":"0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000006":"0x00000000000000000000000000000000000000000000065a4da25d3016c00000","0x0000000000000000000000000000000000000000000000000000000000000007":"0x0000000000000000000000000e5d0fd336650e663c710ef420f85fb081e21415","0x0000000000000000000000000000000000000000000000000000000000000008":"0x000000000000000000000000000000000000000003782dace9d9000000000000","0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b":"0x000000000000000000000000ff9dfbd395cd1c4a4f23c16aa8a5c44109bc17df","0x4cf2bf7c4513f31bb90f26db288d81637a55e0204ce44ed81fd8bd44cf72e94d":"0x0000000000000000000000000000000000000000000000000000000000000000","0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3":"0x00000000000000000000000064c2a9cb0220d3e56783ed87cc1b20115bc93f96","0x83a6ad9b45a481c71774303d5fe0197831d788806fafa3028fb2edd9e977cd46":"0x00000000000000000000000000000000000000000000065a4da25d3016c00000"},"balance":"0x0"},"e1adb6075619f52fc00bdd50def1b754b9e7bd17":{"code":"0x60806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633659cfe6146100775780634f1ef286146100ba5780635c60da1b146101085780638f2839701461015f578063f851a440146101a2575b6100756101f9565b005b34801561008357600080fd5b506100b8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610213565b005b610106600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001908201803590602001919091929391929390505050610268565b005b34801561011457600080fd5b5061011d610308565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561016b57600080fd5b506101a0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610360565b005b3480156101ae57600080fd5b506101b761051e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610201610576565b61021161020c610651565b610682565b565b61021b6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025c57610257816106d9565b610265565b6102646101f9565b5b50565b6102706106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fa576102ac836106d9565b3073ffffffffffffffffffffffffffffffffffffffff163483836040518083838082843782019150509250505060006040518083038185875af19250505015156102f557600080fd5b610303565b6103026101f9565b5b505050565b60006103126106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103545761034d610651565b905061035d565b61035c6101f9565b5b90565b6103686106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561051257600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610466576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001807f43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f81526020017f787920746f20746865207a65726f20616464726573730000000000000000000081525060400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61048f6106a8565b82604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a161050d81610748565b61051b565b61051a6101f9565b5b50565b60006105286106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561056a576105636106a8565b9050610573565b6105726101f9565b5b90565b61057e6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151515610647576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001807f43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e20667281526020017f6f6d207468652070726f78792061646d696e000000000000000000000000000081525060400191505060405180910390fd5b61064f610777565b565b6000807f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c36001029050805491505090565b3660008037600080366000845af43d6000803e80600081146106a3573d6000f35b3d6000fd5b6000807f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b6001029050805491505090565b6106e281610779565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b60010290508181555050565b565b60006107848261084b565b151561081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001807f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f81526020017f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000081525060400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c360010290508181555050565b600080823b9050600081119150509190505600a165627a7a72305820b31d41a72e81559b9fbd6f52c3db76ab77aeacd5de378d37ab93861a9b684f120029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x00000000000000000000004195b06a6e4d5bedde15165e01a64f324f03d5d101","0x0000000000000000000000000000000000000000000000000000000000000001":"0xbc25ce339c62a23a50c9bdae4aba9cb6dab4cefd53d1501dcbf2eec2583d200e","0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b":"0x000000000000000000000000ff9dfbd395cd1c4a4f23c16aa8a5c44109bc17df","0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3":"0x000000000000000000000000e95d0d373e2fd320b84aac705434b67b905092ae"},"balance":"0x0"},"e95d0d373e2fd320b84aac705434b67b905092ae":{"code":"0x608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063158ef93e1461005c578063be13f47c1461008b578063d22057a9146100dc575b600080fd5b34801561006857600080fd5b5061007161012d565b604051808215151515815260200191505060405180910390f35b34801561009757600080fd5b506100da600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560001916906020019092919050505061013f565b005b3480156100e857600080fd5b5061012b6004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610253565b005b6000809054906101000a900460ff1681565b6000809054906101000a900460ff161515156101e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001807f436f6e747261637420696e7374616e63652068617320616c726561647920626581526020017f656e20696e697469616c697a656400000000000000000000000000000000000081525060400191505060405180910390fd5b81600060016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806001816000191690555060016000806101000a81548160ff0219169083151502179055505050565b8160008060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be36001548460405180836000191660001916815260200182600019166000191681526020019250505060405180910390206040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b15801561031d57600080fd5b505af1158015610331573d6000803e3d6000fd5b505050506040513d602081101561034757600080fd5b8101908080519060200190929190505050905060008173ffffffffffffffffffffffffffffffffffffffff1614806103aa57503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b15156103b557600080fd5b600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306ab592360015486866040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180846000191660001916815260200183600019166000191681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019350505050600060405180830381600087803b15801561049457600080fd5b505af11580156104a8573d6000803e3d6000fd5b50505050505050505600a165627a7a723058205053cd7ff3b82a7e6e8531ed12a7195800886445328be2a9911c057f02b1f0cf0029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001":"0x0000000000000000000000000000000000000000000000000000000000000000"},"balance":"0x0"}},"number":"0x0","gasUsed":"0x0","parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000"} +{"config":{"chainID":1,"konsensus":{}},"timestamp":"0x5b228222","extraData":"0x4b6f77616c61277320666972737420626c6f636b000000000000000000000000","coinbase":"0x0000000000000000000000000000000000000000","alloc":{"0000000000000000000000000000000000000000":{"balance":"0x1"},"0000000000000000000000000000000000000001":{"balance":"0x1"},"0000000000000000000000000000000000000002":{"balance":"0x1"},"0000000000000000000000000000000000000003":{"balance":"0x1"},"0000000000000000000000000000000000000004":{"balance":"0x1"},"0000000000000000000000000000000000000005":{"balance":"0x1"},"0000000000000000000000000000000000000006":{"balance":"0x1"},"0000000000000000000000000000000000000007":{"balance":"0x1"},"0000000000000000000000000000000000000008":{"balance":"0x1"},"0000000000000000000000000000000000000009":{"balance":"0x1"},"000000000000000000000000000000000000000a":{"balance":"0x1"},"000000000000000000000000000000000000000b":{"balance":"0x1"},"000000000000000000000000000000000000000c":{"balance":"0x1"},"000000000000000000000000000000000000000d":{"balance":"0x1"},"000000000000000000000000000000000000000e":{"balance":"0x1"},"000000000000000000000000000000000000000f":{"balance":"0x1"},"0000000000000000000000000000000000000010":{"balance":"0x1"},"0000000000000000000000000000000000000011":{"balance":"0x1"},"0000000000000000000000000000000000000012":{"balance":"0x1"},"0000000000000000000000000000000000000013":{"balance":"0x1"},"0000000000000000000000000000000000000014":{"balance":"0x1"},"0000000000000000000000000000000000000015":{"balance":"0x1"},"0000000000000000000000000000000000000016":{"balance":"0x1"},"0000000000000000000000000000000000000017":{"balance":"0x1"},"0000000000000000000000000000000000000018":{"balance":"0x1"},"0000000000000000000000000000000000000019":{"balance":"0x1"},"000000000000000000000000000000000000001a":{"balance":"0x1"},"000000000000000000000000000000000000001b":{"balance":"0x1"},"000000000000000000000000000000000000001c":{"balance":"0x1"},"000000000000000000000000000000000000001d":{"balance":"0x1"},"000000000000000000000000000000000000001e":{"balance":"0x1"},"000000000000000000000000000000000000001f":{"balance":"0x1"},"0000000000000000000000000000000000000020":{"balance":"0x1"},"0000000000000000000000000000000000000021":{"balance":"0x1"},"0000000000000000000000000000000000000022":{"balance":"0x1"},"0000000000000000000000000000000000000023":{"balance":"0x1"},"0000000000000000000000000000000000000024":{"balance":"0x1"},"0000000000000000000000000000000000000025":{"balance":"0x1"},"0000000000000000000000000000000000000026":{"balance":"0x1"},"0000000000000000000000000000000000000027":{"balance":"0x1"},"0000000000000000000000000000000000000028":{"balance":"0x1"},"0000000000000000000000000000000000000029":{"balance":"0x1"},"000000000000000000000000000000000000002a":{"balance":"0x1"},"000000000000000000000000000000000000002b":{"balance":"0x1"},"000000000000000000000000000000000000002c":{"balance":"0x1"},"000000000000000000000000000000000000002d":{"balance":"0x1"},"000000000000000000000000000000000000002e":{"balance":"0x1"},"000000000000000000000000000000000000002f":{"balance":"0x1"},"0000000000000000000000000000000000000030":{"balance":"0x1"},"0000000000000000000000000000000000000031":{"balance":"0x1"},"0000000000000000000000000000000000000032":{"balance":"0x1"},"0000000000000000000000000000000000000033":{"balance":"0x1"},"0000000000000000000000000000000000000034":{"balance":"0x1"},"0000000000000000000000000000000000000035":{"balance":"0x1"},"0000000000000000000000000000000000000036":{"balance":"0x1"},"0000000000000000000000000000000000000037":{"balance":"0x1"},"0000000000000000000000000000000000000038":{"balance":"0x1"},"0000000000000000000000000000000000000039":{"balance":"0x1"},"000000000000000000000000000000000000003a":{"balance":"0x1"},"000000000000000000000000000000000000003b":{"balance":"0x1"},"000000000000000000000000000000000000003c":{"balance":"0x1"},"000000000000000000000000000000000000003d":{"balance":"0x1"},"000000000000000000000000000000000000003e":{"balance":"0x1"},"000000000000000000000000000000000000003f":{"balance":"0x1"},"0000000000000000000000000000000000000040":{"balance":"0x1"},"0000000000000000000000000000000000000041":{"balance":"0x1"},"0000000000000000000000000000000000000042":{"balance":"0x1"},"0000000000000000000000000000000000000043":{"balance":"0x1"},"0000000000000000000000000000000000000044":{"balance":"0x1"},"0000000000000000000000000000000000000045":{"balance":"0x1"},"0000000000000000000000000000000000000046":{"balance":"0x1"},"0000000000000000000000000000000000000047":{"balance":"0x1"},"0000000000000000000000000000000000000048":{"balance":"0x1"},"0000000000000000000000000000000000000049":{"balance":"0x1"},"000000000000000000000000000000000000004a":{"balance":"0x1"},"000000000000000000000000000000000000004b":{"balance":"0x1"},"000000000000000000000000000000000000004c":{"balance":"0x1"},"000000000000000000000000000000000000004d":{"balance":"0x1"},"000000000000000000000000000000000000004e":{"balance":"0x1"},"000000000000000000000000000000000000004f":{"balance":"0x1"},"0000000000000000000000000000000000000050":{"balance":"0x1"},"0000000000000000000000000000000000000051":{"balance":"0x1"},"0000000000000000000000000000000000000052":{"balance":"0x1"},"0000000000000000000000000000000000000053":{"balance":"0x1"},"0000000000000000000000000000000000000054":{"balance":"0x1"},"0000000000000000000000000000000000000055":{"balance":"0x1"},"0000000000000000000000000000000000000056":{"balance":"0x1"},"0000000000000000000000000000000000000057":{"balance":"0x1"},"0000000000000000000000000000000000000058":{"balance":"0x1"},"0000000000000000000000000000000000000059":{"balance":"0x1"},"000000000000000000000000000000000000005a":{"balance":"0x1"},"000000000000000000000000000000000000005b":{"balance":"0x1"},"000000000000000000000000000000000000005c":{"balance":"0x1"},"000000000000000000000000000000000000005d":{"balance":"0x1"},"000000000000000000000000000000000000005e":{"balance":"0x1"},"000000000000000000000000000000000000005f":{"balance":"0x1"},"0000000000000000000000000000000000000060":{"balance":"0x1"},"0000000000000000000000000000000000000061":{"balance":"0x1"},"0000000000000000000000000000000000000062":{"balance":"0x1"},"0000000000000000000000000000000000000063":{"balance":"0x1"},"0000000000000000000000000000000000000064":{"balance":"0x1"},"0000000000000000000000000000000000000065":{"balance":"0x1"},"0000000000000000000000000000000000000066":{"balance":"0x1"},"0000000000000000000000000000000000000067":{"balance":"0x1"},"0000000000000000000000000000000000000068":{"balance":"0x1"},"0000000000000000000000000000000000000069":{"balance":"0x1"},"000000000000000000000000000000000000006a":{"balance":"0x1"},"000000000000000000000000000000000000006b":{"balance":"0x1"},"000000000000000000000000000000000000006c":{"balance":"0x1"},"000000000000000000000000000000000000006d":{"balance":"0x1"},"000000000000000000000000000000000000006e":{"balance":"0x1"},"000000000000000000000000000000000000006f":{"balance":"0x1"},"0000000000000000000000000000000000000070":{"balance":"0x1"},"0000000000000000000000000000000000000071":{"balance":"0x1"},"0000000000000000000000000000000000000072":{"balance":"0x1"},"0000000000000000000000000000000000000073":{"balance":"0x1"},"0000000000000000000000000000000000000074":{"balance":"0x1"},"0000000000000000000000000000000000000075":{"balance":"0x1"},"0000000000000000000000000000000000000076":{"balance":"0x1"},"0000000000000000000000000000000000000077":{"balance":"0x1"},"0000000000000000000000000000000000000078":{"balance":"0x1"},"0000000000000000000000000000000000000079":{"balance":"0x1"},"000000000000000000000000000000000000007a":{"balance":"0x1"},"000000000000000000000000000000000000007b":{"balance":"0x1"},"000000000000000000000000000000000000007c":{"balance":"0x1"},"000000000000000000000000000000000000007d":{"balance":"0x1"},"000000000000000000000000000000000000007e":{"balance":"0x1"},"000000000000000000000000000000000000007f":{"balance":"0x1"},"0000000000000000000000000000000000000080":{"balance":"0x1"},"0000000000000000000000000000000000000081":{"balance":"0x1"},"0000000000000000000000000000000000000082":{"balance":"0x1"},"0000000000000000000000000000000000000083":{"balance":"0x1"},"0000000000000000000000000000000000000084":{"balance":"0x1"},"0000000000000000000000000000000000000085":{"balance":"0x1"},"0000000000000000000000000000000000000086":{"balance":"0x1"},"0000000000000000000000000000000000000087":{"balance":"0x1"},"0000000000000000000000000000000000000088":{"balance":"0x1"},"0000000000000000000000000000000000000089":{"balance":"0x1"},"000000000000000000000000000000000000008a":{"balance":"0x1"},"000000000000000000000000000000000000008b":{"balance":"0x1"},"000000000000000000000000000000000000008c":{"balance":"0x1"},"000000000000000000000000000000000000008d":{"balance":"0x1"},"000000000000000000000000000000000000008e":{"balance":"0x1"},"000000000000000000000000000000000000008f":{"balance":"0x1"},"0000000000000000000000000000000000000090":{"balance":"0x1"},"0000000000000000000000000000000000000091":{"balance":"0x1"},"0000000000000000000000000000000000000092":{"balance":"0x1"},"0000000000000000000000000000000000000093":{"balance":"0x1"},"0000000000000000000000000000000000000094":{"balance":"0x1"},"0000000000000000000000000000000000000095":{"balance":"0x1"},"0000000000000000000000000000000000000096":{"balance":"0x1"},"0000000000000000000000000000000000000097":{"balance":"0x1"},"0000000000000000000000000000000000000098":{"balance":"0x1"},"0000000000000000000000000000000000000099":{"balance":"0x1"},"000000000000000000000000000000000000009a":{"balance":"0x1"},"000000000000000000000000000000000000009b":{"balance":"0x1"},"000000000000000000000000000000000000009c":{"balance":"0x1"},"000000000000000000000000000000000000009d":{"balance":"0x1"},"000000000000000000000000000000000000009e":{"balance":"0x1"},"000000000000000000000000000000000000009f":{"balance":"0x1"},"00000000000000000000000000000000000000a0":{"balance":"0x1"},"00000000000000000000000000000000000000a1":{"balance":"0x1"},"00000000000000000000000000000000000000a2":{"balance":"0x1"},"00000000000000000000000000000000000000a3":{"balance":"0x1"},"00000000000000000000000000000000000000a4":{"balance":"0x1"},"00000000000000000000000000000000000000a5":{"balance":"0x1"},"00000000000000000000000000000000000000a6":{"balance":"0x1"},"00000000000000000000000000000000000000a7":{"balance":"0x1"},"00000000000000000000000000000000000000a8":{"balance":"0x1"},"00000000000000000000000000000000000000a9":{"balance":"0x1"},"00000000000000000000000000000000000000aa":{"balance":"0x1"},"00000000000000000000000000000000000000ab":{"balance":"0x1"},"00000000000000000000000000000000000000ac":{"balance":"0x1"},"00000000000000000000000000000000000000ad":{"balance":"0x1"},"00000000000000000000000000000000000000ae":{"balance":"0x1"},"00000000000000000000000000000000000000af":{"balance":"0x1"},"00000000000000000000000000000000000000b0":{"balance":"0x1"},"00000000000000000000000000000000000000b1":{"balance":"0x1"},"00000000000000000000000000000000000000b2":{"balance":"0x1"},"00000000000000000000000000000000000000b3":{"balance":"0x1"},"00000000000000000000000000000000000000b4":{"balance":"0x1"},"00000000000000000000000000000000000000b5":{"balance":"0x1"},"00000000000000000000000000000000000000b6":{"balance":"0x1"},"00000000000000000000000000000000000000b7":{"balance":"0x1"},"00000000000000000000000000000000000000b8":{"balance":"0x1"},"00000000000000000000000000000000000000b9":{"balance":"0x1"},"00000000000000000000000000000000000000ba":{"balance":"0x1"},"00000000000000000000000000000000000000bb":{"balance":"0x1"},"00000000000000000000000000000000000000bc":{"balance":"0x1"},"00000000000000000000000000000000000000bd":{"balance":"0x1"},"00000000000000000000000000000000000000be":{"balance":"0x1"},"00000000000000000000000000000000000000bf":{"balance":"0x1"},"00000000000000000000000000000000000000c0":{"balance":"0x1"},"00000000000000000000000000000000000000c1":{"balance":"0x1"},"00000000000000000000000000000000000000c2":{"balance":"0x1"},"00000000000000000000000000000000000000c3":{"balance":"0x1"},"00000000000000000000000000000000000000c4":{"balance":"0x1"},"00000000000000000000000000000000000000c5":{"balance":"0x1"},"00000000000000000000000000000000000000c6":{"balance":"0x1"},"00000000000000000000000000000000000000c7":{"balance":"0x1"},"00000000000000000000000000000000000000c8":{"balance":"0x1"},"00000000000000000000000000000000000000c9":{"balance":"0x1"},"00000000000000000000000000000000000000ca":{"balance":"0x1"},"00000000000000000000000000000000000000cb":{"balance":"0x1"},"00000000000000000000000000000000000000cc":{"balance":"0x1"},"00000000000000000000000000000000000000cd":{"balance":"0x1"},"00000000000000000000000000000000000000ce":{"balance":"0x1"},"00000000000000000000000000000000000000cf":{"balance":"0x1"},"00000000000000000000000000000000000000d0":{"balance":"0x1"},"00000000000000000000000000000000000000d1":{"balance":"0x1"},"00000000000000000000000000000000000000d2":{"balance":"0x1"},"00000000000000000000000000000000000000d3":{"balance":"0x1"},"00000000000000000000000000000000000000d4":{"balance":"0x1"},"00000000000000000000000000000000000000d5":{"balance":"0x1"},"00000000000000000000000000000000000000d6":{"balance":"0x1"},"00000000000000000000000000000000000000d7":{"balance":"0x1"},"00000000000000000000000000000000000000d8":{"balance":"0x1"},"00000000000000000000000000000000000000d9":{"balance":"0x1"},"00000000000000000000000000000000000000da":{"balance":"0x1"},"00000000000000000000000000000000000000db":{"balance":"0x1"},"00000000000000000000000000000000000000dc":{"balance":"0x1"},"00000000000000000000000000000000000000dd":{"balance":"0x1"},"00000000000000000000000000000000000000de":{"balance":"0x1"},"00000000000000000000000000000000000000df":{"balance":"0x1"},"00000000000000000000000000000000000000e0":{"balance":"0x1"},"00000000000000000000000000000000000000e1":{"balance":"0x1"},"00000000000000000000000000000000000000e2":{"balance":"0x1"},"00000000000000000000000000000000000000e3":{"balance":"0x1"},"00000000000000000000000000000000000000e4":{"balance":"0x1"},"00000000000000000000000000000000000000e5":{"balance":"0x1"},"00000000000000000000000000000000000000e6":{"balance":"0x1"},"00000000000000000000000000000000000000e7":{"balance":"0x1"},"00000000000000000000000000000000000000e8":{"balance":"0x1"},"00000000000000000000000000000000000000e9":{"balance":"0x1"},"00000000000000000000000000000000000000ea":{"balance":"0x1"},"00000000000000000000000000000000000000eb":{"balance":"0x1"},"00000000000000000000000000000000000000ec":{"balance":"0x1"},"00000000000000000000000000000000000000ed":{"balance":"0x1"},"00000000000000000000000000000000000000ee":{"balance":"0x1"},"00000000000000000000000000000000000000ef":{"balance":"0x1"},"00000000000000000000000000000000000000f0":{"balance":"0x1"},"00000000000000000000000000000000000000f1":{"balance":"0x1"},"00000000000000000000000000000000000000f2":{"balance":"0x1"},"00000000000000000000000000000000000000f3":{"balance":"0x1"},"00000000000000000000000000000000000000f4":{"balance":"0x1"},"00000000000000000000000000000000000000f5":{"balance":"0x1"},"00000000000000000000000000000000000000f6":{"balance":"0x1"},"00000000000000000000000000000000000000f7":{"balance":"0x1"},"00000000000000000000000000000000000000f8":{"balance":"0x1"},"00000000000000000000000000000000000000f9":{"balance":"0x1"},"00000000000000000000000000000000000000fa":{"balance":"0x1"},"00000000000000000000000000000000000000fb":{"balance":"0x1"},"00000000000000000000000000000000000000fc":{"balance":"0x1"},"00000000000000000000000000000000000000fd":{"balance":"0x1"},"00000000000000000000000000000000000000fe":{"balance":"0x1"},"00000000000000000000000000000000000000ff":{"balance":"0x1"},"0090137110f43c6666b7bd641fcf5ca5dd989539":{"code":"0x60806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633659cfe6146100775780634f1ef286146100ba5780635c60da1b146101085780638f2839701461015f578063f851a440146101a2575b6100756101f9565b005b34801561008357600080fd5b506100b8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610213565b005b610106600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001908201803590602001919091929391929390505050610268565b005b34801561011457600080fd5b5061011d610308565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561016b57600080fd5b506101a0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610360565b005b3480156101ae57600080fd5b506101b761051e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610201610576565b61021161020c610651565b610682565b565b61021b6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025c57610257816106d9565b610265565b6102646101f9565b5b50565b6102706106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fa576102ac836106d9565b3073ffffffffffffffffffffffffffffffffffffffff163483836040518083838082843782019150509250505060006040518083038185875af19250505015156102f557600080fd5b610303565b6103026101f9565b5b505050565b60006103126106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103545761034d610651565b905061035d565b61035c6101f9565b5b90565b6103686106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561051257600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610466576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001807f43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f81526020017f787920746f20746865207a65726f20616464726573730000000000000000000081525060400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61048f6106a8565b82604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a161050d81610748565b61051b565b61051a6101f9565b5b50565b60006105286106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561056a576105636106a8565b9050610573565b6105726101f9565b5b90565b61057e6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151515610647576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001807f43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e20667281526020017f6f6d207468652070726f78792061646d696e000000000000000000000000000081525060400191505060405180910390fd5b61064f610777565b565b6000807f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c36001029050805491505090565b3660008037600080366000845af43d6000803e80600081146106a3573d6000f35b3d6000fd5b6000807f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b6001029050805491505090565b6106e281610779565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b60010290508181555050565b565b60006107848261084b565b151561081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001807f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f81526020017f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000081525060400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c360010290508181555050565b600080823b9050600081119150509190505600a165627a7a72305820b31d41a72e81559b9fbd6f52c3db76ab77aeacd5de378d37ab93861a9b684f120029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x0000000000000000000001000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001":"0x00000000000000000000000000000000000000000000065a4da25d3016c00000","0x0000000000000000000000000000000000000000000000000000000000000002":"0x00000000000000000000000000000000000000000000000000000000000001f4","0x0000000000000000000000000000000000000000000000000000000000000003":"0x0000000000000000000000000000000000000000000000000000000000015180","0x0000000000000000000000000000000000000000000000000000000000000004":"0x2ff4bbb8a7bdf978bccd784e7eeed6a065ff1a7a86caa9d93fff1d4b37addec4","0x0000000000000000000000000000000000000000000000000000000000000005":"0xc99f18ca33e10b0236fe4fd62bfd9a8eb6ceee10bf8dad1b0d121d5e6a2bf3ba","0x0000000000000000000000000000000000000000000000000000000000000006":"0x00000000000000000000000000000000000000000004f68ca6d8cd91c6000000","0x0000000000000000000000000000000000000000000000000000000000000007":"0x00000000000000000000000001e1056f6a829e53dadeb8a5a6189a9333bd1d63","0x0000000000000000000000000000000000000000000000000000000000000009":"0x0000000000000000000000000000000000000000000000000000000000000001","0x000000000000000000000000000000000000000000000000000000000000000a":"0x0000000000000000000000006ad6b24c43a622d58e2959474e3912ba94dfd957","0x000000000000000000000000000000000000000000000000000000000000000b":"0x00000000000000000000000000000000000000000000065a4da25d3016c00000","0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b":"0x000000000000000000000000ff9dfbd395cd1c4a4f23c16aa8a5c44109bc17df","0x1d5591f7b65bd8059a423253186881b3d932200e53c2c265d512fab5f166496d":"0x00000000000000000000000000000000000000000000065a4da25d3016c00000","0x1d5591f7b65bd8059a423253186881b3d932200e53c2c265d512fab5f166496e":"0x0000000000000000000000000000000000000000000000000000000000000000","0x6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af":"0x0000000000000000000000006ad6b24c43a622d58e2959474e3912ba94dfd957","0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3":"0x000000000000000000000000b5822d5f8d221ce2dc73e388629eca256b0aa4f2","0xa2dcbca414a2b283753bfd046a448ad06f34c483e6a942f2b13331deeee6b7b9":"0x0000000000000000000000000000000000000000000000000000000000000000","0xa2dcbca414a2b283753bfd046a448ad06f34c483e6a942f2b13331deeee6b7ba":"0x0000000000000000000000000000000000000000000000000000000000000101","0xa2dcbca414a2b283753bfd046a448ad06f34c483e6a942f2b13331deeee6b7bb":"0x0000000000000000000000000000000000000000000000000000000000000001"},"balance":"0x0"},"01e1056f6a829e53dadeb8a5a6189a9333bd1d63":{"code":"0x60806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633659cfe6146100775780634f1ef286146100ba5780635c60da1b146101085780638f2839701461015f578063f851a440146101a2575b6100756101f9565b005b34801561008357600080fd5b506100b8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610213565b005b610106600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001908201803590602001919091929391929390505050610268565b005b34801561011457600080fd5b5061011d610308565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561016b57600080fd5b506101a0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610360565b005b3480156101ae57600080fd5b506101b761051e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610201610576565b61021161020c610651565b610682565b565b61021b6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025c57610257816106d9565b610265565b6102646101f9565b5b50565b6102706106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fa576102ac836106d9565b3073ffffffffffffffffffffffffffffffffffffffff163483836040518083838082843782019150509250505060006040518083038185875af19250505015156102f557600080fd5b610303565b6103026101f9565b5b505050565b60006103126106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103545761034d610651565b905061035d565b61035c6101f9565b5b90565b6103686106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561051257600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610466576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001807f43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f81526020017f787920746f20746865207a65726f20616464726573730000000000000000000081525060400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61048f6106a8565b82604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a161050d81610748565b61051b565b61051a6101f9565b5b50565b60006105286106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561056a576105636106a8565b9050610573565b6105726101f9565b5b90565b61057e6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151515610647576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001807f43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e20667281526020017f6f6d207468652070726f78792061646d696e000000000000000000000000000081525060400191505060405180910390fd5b61064f610777565b565b6000807f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c36001029050805491505090565b3660008037600080366000845af43d6000803e80600081146106a3573d6000f35b3d6000fd5b6000807f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b6001029050805491505090565b6106e281610779565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b60010290508181555050565b565b60006107848261084b565b151561081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001807f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f81526020017f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000081525060400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c360010290508181555050565b600080823b9050600081119150509190505600a165627a7a72305820b31d41a72e81559b9fbd6f52c3db76ab77aeacd5de378d37ab93861a9b684f120029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x00000000000000000000004195b06a6e4d5bedde15165e01a64f324f03d5d101","0x0aa9b499df4e99716f35c650af5247f98c5dc1bef63f3a923d9f13a6e945b800":"0x000000000000000000000000426f2e2baa6030668b799c2d9193319dface6b7a","0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b":"0x000000000000000000000000ff9dfbd395cd1c4a4f23c16aa8a5c44109bc17df","0x6f7bca21f817d86a5b85f307683ec061c9c10f572e1c3ca5e8312058e1c3f5e7":"0x000000000000000000000000dfcb946fd93a0ae4056d7d6dca59d59fd830f8a5","0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3":"0x0000000000000000000000007f0de05687a7cb9a05399a26f4d1519ba6afc95f","0x86b51839584f7178845a4241ea004c1f5fcaa1a8c0141b741967e2b99d943641":"0x0000000000000000000000000090137110f43c6666b7bd641fcf5ca5dd989539","0xd485b3e3671c35d525826a03b001f5c3d40c5cfcad1d19ecc0c924f943cb06c8":"0x000000000000000000000000c497f7ad7105db9f4138de92b13a0883b19ee0fa","0xf4b8bad9907850b244478fd4ce9bd72dbd061f18d6e4c56d102809e23bf83642":"0x000000000000000000000000485fa6d2f818145a23ace24d84cdc966d8d2de22"},"balance":"0x0"},"049ec8777b4806eff0bb6039551690d8f650b25a":{"balance":"0x8ac7230489e80000"},"0e5d0fd336650e663c710ef420f85fb081e21415":{"code":"0x60806040526004361061011d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063025e7c2714610177578063173825d9146101e457806320ea8d86146102275780632f54bf6e146102545780633411c81c146102af57806354741525146103145780637065cb4814610363578063784547a7146103a65780638b51d13f146103eb5780639ace38c21461042c578063a0e67e2b14610517578063a8abe69a14610583578063b5dc40c314610627578063b77bf600146106a9578063ba51a6df146106d4578063c01a8c8414610701578063c64274741461072e578063d74f8edd146107d5578063dc8452cd14610800578063e20056e61461082b578063ee22610b1461088e575b6000341115610175573373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a25b005b34801561018357600080fd5b506101a2600480360381019080803590602001909291905050506108bb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156101f057600080fd5b50610225600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506108f9565b005b34801561023357600080fd5b5061025260048036038101908080359060200190929190505050610b92565b005b34801561026057600080fd5b50610295600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610d3a565b604051808215151515815260200191505060405180910390f35b3480156102bb57600080fd5b506102fa60048036038101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610d5a565b604051808215151515815260200191505060405180910390f35b34801561032057600080fd5b5061034d600480360381019080803515159060200190929190803515159060200190929190505050610d89565b6040518082815260200191505060405180910390f35b34801561036f57600080fd5b506103a4600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610e1b565b005b3480156103b257600080fd5b506103d160048036038101908080359060200190929190505050611020565b604051808215151515815260200191505060405180910390f35b3480156103f757600080fd5b5061041660048036038101908080359060200190929190505050611105565b6040518082815260200191505060405180910390f35b34801561043857600080fd5b50610457600480360381019080803590602001909291905050506111d0565b604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018060200183151515158152602001828103825284818151815260200191508051906020019080838360005b838110156104d95780820151818401526020810190506104be565b50505050905090810190601f1680156105065780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b34801561052357600080fd5b5061052c6112c5565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561056f578082015181840152602081019050610554565b505050509050019250505060405180910390f35b34801561058f57600080fd5b506105d06004803603810190808035906020019092919080359060200190929190803515159060200190929190803515159060200190929190505050611353565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156106135780820151818401526020810190506105f8565b505050509050019250505060405180910390f35b34801561063357600080fd5b50610652600480360381019080803590602001909291905050506114c4565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561069557808201518184015260208101905061067a565b505050509050019250505060405180910390f35b3480156106b557600080fd5b506106be611701565b6040518082815260200191505060405180910390f35b3480156106e057600080fd5b506106ff60048036038101908080359060200190929190505050611707565b005b34801561070d57600080fd5b5061072c600480360381019080803590602001909291905050506117c1565b005b34801561073a57600080fd5b506107bf600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929050505061199e565b6040518082815260200191505060405180910390f35b3480156107e157600080fd5b506107ea6119bd565b6040518082815260200191505060405180910390f35b34801561080c57600080fd5b506108156119c2565b6040518082815260200191505060405180910390f35b34801561083757600080fd5b5061088c600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506119c8565b005b34801561089a57600080fd5b506108b960048036038101908080359060200190929190505050611cdd565b005b6003818154811015156108ca57fe5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561093557600080fd5b81600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561098e57600080fd5b6000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600091505b600160038054905003821015610b13578273ffffffffffffffffffffffffffffffffffffffff16600383815481101515610a2157fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610b06576003600160038054905003815481101515610a7f57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600383815481101515610ab957fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610b13565b81806001019250506109eb565b6001600381818054905003915081610b2b91906120ff565b506003805490506004541115610b4a57610b49600380549050611707565b5b8273ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405160405180910390a2505050565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610beb57600080fd5b81336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610c5657600080fd5b8360008082815260200190815260200160002060030160009054906101000a900460ff16151515610c8657600080fd5b60006001600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550843373ffffffffffffffffffffffffffffffffffffffff167ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e960405160405180910390a35050505050565b60026020528060005260406000206000915054906101000a900460ff1681565b60016020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b600080600090505b600554811015610e1457838015610dc8575060008082815260200190815260200160002060030160009054906101000a900460ff16155b80610dfb5750828015610dfa575060008082815260200190815260200160002060030160009054906101000a900460ff165b5b15610e07576001820191505b8080600101915050610d91565b5092915050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610e5557600080fd5b80600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151515610eaf57600080fd5b8160008173ffffffffffffffffffffffffffffffffffffffff1614151515610ed657600080fd5b60016003805490500160045460328211158015610ef35750818111155b8015610f00575060008114155b8015610f0d575060008214155b1515610f1857600080fd5b6001600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060038590806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550508473ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405160405180910390a25050505050565b6000806000809150600090505b6003805490508110156110fd5760016000858152602001908152602001600020600060038381548110151561105e57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156110dd576001820191505b6004548214156110f057600192506110fe565b808060010191505061102d565b5b5050919050565b600080600090505b6003805490508110156111ca5760016000848152602001908152602001600020600060038381548110151561113e57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156111bd576001820191505b808060010191505061110d565b50919050565b60006020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001015490806002018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156112a85780601f1061127d576101008083540402835291602001916112a8565b820191906000526020600020905b81548152906001019060200180831161128b57829003601f168201915b5050505050908060030160009054906101000a900460ff16905084565b6060600380548060200260200160405190810160405280929190818152602001828054801561134957602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116112ff575b5050505050905090565b60608060008060055460405190808252806020026020018201604052801561138a5781602001602082028038833980820191505090505b50925060009150600090505b600554811015611436578580156113cd575060008082815260200190815260200160002060030160009054906101000a900460ff16155b8061140057508480156113ff575060008082815260200190815260200160002060030160009054906101000a900460ff165b5b156114295780838381518110151561141457fe5b90602001906020020181815250506001820191505b8080600101915050611396565b8787036040519080825280602002602001820160405280156114675781602001602082028038833980820191505090505b5093508790505b868110156114b957828181518110151561148457fe5b906020019060200201518489830381518110151561149e57fe5b9060200190602002018181525050808060010191505061146e565b505050949350505050565b6060806000806003805490506040519080825280602002602001820160405280156114fe5781602001602082028038833980820191505090505b50925060009150600090505b60038054905081101561164b5760016000868152602001908152602001600020600060038381548110151561153b57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561163e576003818154811015156115c257fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683838151811015156115fb57fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506001820191505b808060010191505061150a565b8160405190808252806020026020018201604052801561167a5781602001602082028038833980820191505090505b509350600090505b818110156116f957828181518110151561169857fe5b9060200190602002015184828151811015156116b057fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508080600101915050611682565b505050919050565b60055481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561174157600080fd5b60038054905081603282111580156117595750818111155b8015611766575060008114155b8015611773575060008214155b151561177e57600080fd5b826004819055507fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a836040518082815260200191505060405180910390a1505050565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561181a57600080fd5b81600080600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415151561187657600080fd5b82336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515156118e257600080fd5b600180600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550843373ffffffffffffffffffffffffffffffffffffffff167f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef60405160405180910390a361199785611cdd565b5050505050565b60006119ab848484611f85565b90506119b6816117c1565b9392505050565b603281565b60045481565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611a0457600080fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611a5d57600080fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151515611ab757600080fd5b600092505b600380549050831015611ba0578473ffffffffffffffffffffffffffffffffffffffff16600384815481101515611aef57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611b935783600384815481101515611b4657fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611ba0565b8280600101935050611abc565b6000600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508473ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405160405180910390a28373ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405160405180910390a25050505050565b600033600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611d3857600080fd5b82336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611da357600080fd5b8460008082815260200190815260200160002060030160009054906101000a900460ff16151515611dd357600080fd5b611ddc86611020565b15611f7d57600080878152602001908152602001600020945060018560030160006101000a81548160ff021916908315150217905550611efa8560000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16866001015487600201805460018160011615610100020316600290049050886002018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611ef05780601f10611ec557610100808354040283529160200191611ef0565b820191906000526020600020905b815481529060010190602001808311611ed357829003601f168201915b50505050506120d7565b15611f3157857f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7560405160405180910390a2611f7c565b857f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923660405160405180910390a260008560030160006101000a81548160ff0219169083151502179055505b5b505050505050565b60008360008173ffffffffffffffffffffffffffffffffffffffff1614151515611fae57600080fd5b60055491506080604051908101604052808673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018481526020016000151581525060008084815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010155604082015181600201908051906020019061206d92919061212b565b5060608201518160030160006101000a81548160ff0219169083151502179055509050506001600560008282540192505081905550817fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5160405160405180910390a2509392505050565b6000806040516020840160008287838a8c62054bdc5a03f19250505080915050949350505050565b8154818355818111156121265781836000526020600020918201910161212591906121ab565b5b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061216c57805160ff191683800117855561219a565b8280016001018555821561219a579182015b8281111561219957825182559160200191906001019061217e565b5b5090506121a791906121ab565b5090565b6121cd91905b808211156121c95760008160009055506001016121b1565b5090565b905600a165627a7a72305820b9132d118b85ee91b3ef33d8346c1ba518df422ee90630ed557599092709a7670029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000003":"0x0000000000000000000000000000000000000000000000000000000000000003","0x0000000000000000000000000000000000000000000000000000000000000004":"0x0000000000000000000000000000000000000000000000000000000000000002","0xa19cbe59d468f3fb5b320edc5e49298d3f391d6304c436497c6a7f03ca25515c":"0x0000000000000000000000000000000000000000000000000000000000000001","0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b":"0x0000000000000000000000006d5e05684c737d42f313d5b82a88090136e831f8","0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c":"0x000000000000000000000000049ec8777b4806eff0bb6039551690d8f650b25a","0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85d":"0x000000000000000000000000902f069af381a650b7f18ff28ffdad0f11eb425b","0xf5a9159dd7a73776c0d06b82c491e439b0f434ee7f48db2184c62b8a0915f8f5":"0x0000000000000000000000000000000000000000000000000000000000000001","0xf662ac89672a6f91a243a9cf313e14d1828bf7f3a3ab7938a1f979da6f908864":"0x0000000000000000000000000000000000000000000000000000000000000001"},"balance":"0x0"},"2d7465b88a0a5a1bbff2671c8ed78f7506465ddc":{"code":"0x732d7465b88a0a5a1bbff2671c8ed78f7506465ddc30146080604052600080fd00a165627a7a72305820de029ffd61fdb3181f53609fdbaafec7c7b031427512423ba1afef4928177f300029","balance":"0x0"},"3b058a1a62e59d185618f64bebbaf3c52bf099e0":{"code":"0x733b058a1a62e59d185618f64bebbaf3c52bf099e03014608060405260043610610058576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063098799621461005d575b600080fd5b6100b7600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506100d5565b60405180826000191660001916815260200191505060405180910390f35b60006100df610599565b60006100e9610599565b606060006100f6876102c3565b945060006001029350610108856102f1565b15156102b65761014c6040805190810160405280600181526020017f2e000000000000000000000000000000000000000000000000000000000000008152506102c3565b92506001610163848761030190919063ffffffff16565b0160405190808252806020026020018201604052801561019757816020015b60608152602001906001900390816101825790505b509150600090505b81518110156101eb576101c36101be848761037890919063ffffffff16565b610392565b82828151811015156101d157fe5b90602001906020020181905250808060010191505061019f565b600090505b81518110156102b55783826001838551030381518110151561020e57fe5b906020019060200201516040518082805190602001908083835b60208310151561024d5780518252602082019150602081019050602083039250610228565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206040518083600019166000191681526020018260001916600019168152602001925050506040518091039020935080806001019150506101f0565b5b8395505050505050919050565b6102cb610599565b600060208301905060408051908101604052808451815260200182815250915050919050565b6000808260000151149050919050565b600080826000015161032585600001518660200151866000015187602001516103f4565b0190505b83600001518460200151018111151561037157818060010192505082600001516103698560200151830386600001510383866000015187602001516103f4565b019050610329565b5092915050565b610380610599565b61038b8383836104b0565b5092915050565b606080600083600001516040519080825280601f01601f1916602001820160405280156103ce5781602001602082028038833980820191505090505b5091506020820190506103ea818560200151866000015161054e565b8192505050919050565b6000806000806000888711151561049e576020871115156104555760018760200360080260020a031980875116888b038a018a96505b81838851161461044a5760018701965080600188031061042a578b8b0196505b5050508394506104a4565b8686209150879350600092505b8689038311151561049d57868420905080600019168260001916141561048a578394506104a4565b6001840193508280600101935050610462565b5b88880194505b50505050949350505050565b6104b8610599565b60006104d685600001518660200151866000015187602001516103f4565b90508460200151836020018181525050846020015181038360000181815250508460000151856020015101811415610518576000856000018181525050610543565b8360000151836000015101856000018181510391508181525050836000015181018560200181815250505b829150509392505050565b60005b6020821015156105765782518452602084019350602083019250602082039150610551565b6001826020036101000a0390508019835116818551168181178652505050505050565b6040805190810160405280600081526020016000815250905600a165627a7a72305820bdb7fa7f1254d03496a55a35a971f38f891e40961a467acc8100eadce57bdad70029","balance":"0x0"},"4195b06a6e4d5bedde15165e01a64f324f03d5d1":{"code":"0x60806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633659cfe6146100775780634f1ef286146100ba5780635c60da1b146101085780638f2839701461015f578063f851a440146101a2575b6100756101f9565b005b34801561008357600080fd5b506100b8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610213565b005b610106600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001908201803590602001919091929391929390505050610268565b005b34801561011457600080fd5b5061011d610308565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561016b57600080fd5b506101a0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610360565b005b3480156101ae57600080fd5b506101b761051e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610201610576565b61021161020c610651565b610682565b565b61021b6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025c57610257816106d9565b610265565b6102646101f9565b5b50565b6102706106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fa576102ac836106d9565b3073ffffffffffffffffffffffffffffffffffffffff163483836040518083838082843782019150509250505060006040518083038185875af19250505015156102f557600080fd5b610303565b6103026101f9565b5b505050565b60006103126106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103545761034d610651565b905061035d565b61035c6101f9565b5b90565b6103686106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561051257600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610466576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001807f43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f81526020017f787920746f20746865207a65726f20616464726573730000000000000000000081525060400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61048f6106a8565b82604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a161050d81610748565b61051b565b61051a6101f9565b5b50565b60006105286106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561056a576105636106a8565b9050610573565b6105726101f9565b5b90565b61057e6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151515610647576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001807f43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e20667281526020017f6f6d207468652070726f78792061646d696e000000000000000000000000000081525060400191505060405180910390fd5b61064f610777565b565b6000807f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c36001029050805491505090565b3660008037600080366000845af43d6000803e80600081146106a3573d6000f35b3d6000fd5b6000807f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b6001029050805491505090565b6106e281610779565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b60010290508181555050565b565b60006107848261084b565b151561081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001807f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f81526020017f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000081525060400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c360010290508181555050565b600080823b9050600081119150509190505600a165627a7a72305820b31d41a72e81559b9fbd6f52c3db76ab77aeacd5de378d37ab93861a9b684f120029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x0000000000000000000000000000000000000000000000000000000000000001","0x0aa9b499df4e99716f35c650af5247f98c5dc1bef63f3a923d9f13a6e945b800":"0x0000000000000000000000006d5e05684c737d42f313d5b82a88090136e831f8","0x0aa9b499df4e99716f35c650af5247f98c5dc1bef63f3a923d9f13a6e945b801":"0x00000000000000000000000001e1056f6a829e53dadeb8a5a6189a9333bd1d63","0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b":"0x000000000000000000000000ff9dfbd395cd1c4a4f23c16aa8a5c44109bc17df","0x6793bdf4379ec85ee52adbbe524203920c00866a03f73066b816feb521b95a0f":"0x000000000000000000000000e1adb6075619f52fc00bdd50def1b754b9e7bd17","0x6f7bca21f817d86a5b85f307683ec061c9c10f572e1c3ca5e8312058e1c3f5e7":"0x0000000000000000000000006d5e05684c737d42f313d5b82a88090136e831f8","0x6f7bca21f817d86a5b85f307683ec061c9c10f572e1c3ca5e8312058e1c3f5e8":"0x00000000000000000000000001e1056f6a829e53dadeb8a5a6189a9333bd1d63","0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3":"0x000000000000000000000000bfb47d8008d1ccdcaf3a36110a9338a274e86343","0x86b51839584f7178845a4241ea004c1f5fcaa1a8c0141b741967e2b99d943641":"0x0000000000000000000000006d5e05684c737d42f313d5b82a88090136e831f8","0x86b51839584f7178845a4241ea004c1f5fcaa1a8c0141b741967e2b99d943642":"0x00000000000000000000000001e1056f6a829e53dadeb8a5a6189a9333bd1d63","0xa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb49":"0x0000000000000000000000000e5d0fd336650e663c710ef420f85fb081e21415","0xd485b3e3671c35d525826a03b001f5c3d40c5cfcad1d19ecc0c924f943cb06c8":"0x0000000000000000000000006d5e05684c737d42f313d5b82a88090136e831f8","0xd485b3e3671c35d525826a03b001f5c3d40c5cfcad1d19ecc0c924f943cb06c9":"0x00000000000000000000000001e1056f6a829e53dadeb8a5a6189a9333bd1d63","0xf4b8bad9907850b244478fd4ce9bd72dbd061f18d6e4c56d102809e23bf83642":"0x0000000000000000000000006d5e05684c737d42f313d5b82a88090136e831f8","0xf4b8bad9907850b244478fd4ce9bd72dbd061f18d6e4c56d102809e23bf83643":"0x00000000000000000000000001e1056f6a829e53dadeb8a5a6189a9333bd1d63"},"balance":"0x0"},"426f2e2baa6030668b799c2d9193319dface6b7a":{"code":"0x60806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633659cfe6146100775780634f1ef286146100ba5780635c60da1b146101085780638f2839701461015f578063f851a440146101a2575b6100756101f9565b005b34801561008357600080fd5b506100b8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610213565b005b610106600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001908201803590602001919091929391929390505050610268565b005b34801561011457600080fd5b5061011d610308565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561016b57600080fd5b506101a0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610360565b005b3480156101ae57600080fd5b506101b761051e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610201610576565b61021161020c610651565b610682565b565b61021b6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025c57610257816106d9565b610265565b6102646101f9565b5b50565b6102706106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fa576102ac836106d9565b3073ffffffffffffffffffffffffffffffffffffffff163483836040518083838082843782019150509250505060006040518083038185875af19250505015156102f557600080fd5b610303565b6103026101f9565b5b505050565b60006103126106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103545761034d610651565b905061035d565b61035c6101f9565b5b90565b6103686106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561051257600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610466576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001807f43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f81526020017f787920746f20746865207a65726f20616464726573730000000000000000000081525060400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61048f6106a8565b82604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a161050d81610748565b61051b565b61051a6101f9565b5b50565b60006105286106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561056a576105636106a8565b9050610573565b6105726101f9565b5b90565b61057e6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151515610647576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001807f43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e20667281526020017f6f6d207468652070726f78792061646d696e000000000000000000000000000081525060400191505060405180910390fd5b61064f610777565b565b6000807f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c36001029050805491505090565b3660008037600080366000845af43d6000803e80600081146106a3573d6000f35b3d6000fd5b6000807f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b6001029050805491505090565b6106e281610779565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b60010290508181555050565b565b60006107848261084b565b151561081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001807f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f81526020017f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000081525060400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c360010290508181555050565b600080823b9050600081119150509190505600a165627a7a72305820b31d41a72e81559b9fbd6f52c3db76ab77aeacd5de378d37ab93861a9b684f120029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x0000000000000000000001000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001":"0x0000000000000000000000000000000000000000000000000000000000000032","0x0000000000000000000000000000000000000000000000000000000000000002":"0x0000000000000000000000000000000000000000000000000000000000000258","0x0000000000000000000000000000000000000000000000000000000000000003":"0x000000000000000000000000000000000000000000000000000000000000001e","0x0000000000000000000000000000000000000000000000000000000000000005":"0x0000000000000000000000000090137110f43c6666b7bd641fcf5ca5dd989539","0x0000000000000000000000000000000000000000000000000000000000000006":"0x13a02f7cebf86cd2a5bc43aab96f2b5c4dd7406102f5a3b3e734a749ce84ea87","0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b":"0x000000000000000000000000ff9dfbd395cd1c4a4f23c16aa8a5c44109bc17df","0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3":"0x000000000000000000000000616a77ba32adc911dba37f5883e4013b5278a279"},"balance":"0x0"},"485fa6d2f818145a23ace24d84cdc966d8d2de22":{"code":"0x60806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633659cfe6146100775780634f1ef286146100ba5780635c60da1b146101085780638f2839701461015f578063f851a440146101a2575b6100756101f9565b005b34801561008357600080fd5b506100b8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610213565b005b610106600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001908201803590602001919091929391929390505050610268565b005b34801561011457600080fd5b5061011d610308565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561016b57600080fd5b506101a0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610360565b005b3480156101ae57600080fd5b506101b761051e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610201610576565b61021161020c610651565b610682565b565b61021b6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025c57610257816106d9565b610265565b6102646101f9565b5b50565b6102706106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fa576102ac836106d9565b3073ffffffffffffffffffffffffffffffffffffffff163483836040518083838082843782019150509250505060006040518083038185875af19250505015156102f557600080fd5b610303565b6103026101f9565b5b505050565b60006103126106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103545761034d610651565b905061035d565b61035c6101f9565b5b90565b6103686106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561051257600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610466576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001807f43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f81526020017f787920746f20746865207a65726f20616464726573730000000000000000000081525060400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61048f6106a8565b82604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a161050d81610748565b61051b565b61051a6101f9565b5b50565b60006105286106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561056a576105636106a8565b9050610573565b6105726101f9565b5b90565b61057e6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151515610647576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001807f43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e20667281526020017f6f6d207468652070726f78792061646d696e000000000000000000000000000081525060400191505060405180910390fd5b61064f610777565b565b6000807f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c36001029050805491505090565b3660008037600080366000845af43d6000803e80600081146106a3573d6000f35b3d6000fd5b6000807f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b6001029050805491505090565b6106e281610779565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b60010290508181555050565b565b60006107848261084b565b151561081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001807f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f81526020017f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000081525060400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c360010290508181555050565b600080823b9050600081119150509190505600a165627a7a72305820b31d41a72e81559b9fbd6f52c3db76ab77aeacd5de378d37ab93861a9b684f120029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x0000000000000000000001000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001":"0x0000000000000000000000000000000000000000000000056bc75e2d63100000","0x0000000000000000000000000000000000000000000000000000000000000002":"0x000000000000000000000000c3c45781031885313d5a598042950d6d7be96350","0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b":"0x000000000000000000000000ff9dfbd395cd1c4a4f23c16aa8a5c44109bc17df","0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3":"0x000000000000000000000000cdca8b1b7edfb0827f10f4ed3968d98fa5c90ea0"},"balance":"0x0"},"616a77ba32adc911dba37f5883e4013b5278a279":{"code":"0x60806040526004361061011c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168062fe7b111461012157806309fe9d391461014c578063158ef93e146101b95780631f8d519d146101e8578063339d2590146102495780633f4ba83a146102535780633f4e42511461026a5780635c975abb14610295578063715018a6146102c45780638456cb59146102db5780638da5cb5b146102f2578063986fcbe914610349578063a035b1fe14610376578063a2207c6a146103a1578063a83627de146103f8578063a97e5c9314610423578063c48c1a711461047e578063c8104e01146104a9578063cdee7e071461051d578063f2fde38b14610548578063f93a2eb21461058b575b600080fd5b34801561012d57600080fd5b506101366105a2565b6040518082815260200191505060405180910390f35b34801561015857600080fd5b50610177600480360381019080803590602001909291905050506105a8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156101c557600080fd5b506101ce61062e565b604051808215151515815260200191505060405180910390f35b3480156101f457600080fd5b50610247600480360381019080803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610641565b005b610251610878565b005b34801561025f57600080fd5b50610268610a7e565b005b34801561027657600080fd5b5061027f610b3c565b6040518082815260200191505060405180910390f35b3480156102a157600080fd5b506102aa610b49565b604051808215151515815260200191505060405180910390f35b3480156102d057600080fd5b506102d9610b5c565b005b3480156102e757600080fd5b506102f0610c5e565b005b3480156102fe57600080fd5b50610307610d1e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561035557600080fd5b5061037460048036038101908080359060200190929190505050610d43565b005b34801561038257600080fd5b5061038b610ed9565b6040518082815260200191505060405180910390f35b3480156103ad57600080fd5b506103b6610edf565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561040457600080fd5b5061040d610f05565b6040518082815260200191505060405180910390f35b34801561042f57600080fd5b50610464600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610f0b565b604051808215151515815260200191505060405180910390f35b34801561048a57600080fd5b50610493610f64565b6040518082815260200191505060405180910390f35b3480156104b557600080fd5b506104d460048036038101908080359060200190929190505050610f71565b604051808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390f35b34801561052957600080fd5b50610532610fc9565b6040518082815260200191505060405180910390f35b34801561055457600080fd5b50610589600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610fcf565b005b34801561059757600080fd5b506105a0611036565b005b60015481565b6000806008838154811015156105ba57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169150600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905050919050565b600060159054906101000a900460ff1681565b600060159054906101000a900460ff161515156106ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001807f436f6e747261637420696e7374616e63652068617320616c726561647920626581526020017f656e20696e697469616c697a656400000000000000000000000000000000000081525060400191505060405180910390fd5b6000841115156106fb57600080fd5b6000831115610720576000821180156107145750828211155b151561071f57600080fd5b5b83600181905550826002819055508160038190555080600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550733b058a1a62e59d185618f64bebbaf3c52bf099e063098799626040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825260138152602001807f76616c696461746f726d67722e6b6f77616c610000000000000000000000000081525060200191505060206040518083038186803b15801561081257600080fd5b505af4158015610826573d6000803e3d6000fd5b505050506040513d602081101561083c57600080fd5b8101908080519060200190929190505050600681600019169055506001600060156101000a81548160ff02191690831515021790555050505050565b600060149054906101000a900460ff1615151561089457600080fd5b61089d33610f0b565b1515156108a957600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633b3b57de6006546040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b15801561094457600080fd5b505af1158015610958573d6000803e3d6000fd5b505050506040513d602081101561096e57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff16637d0e81bf336040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015610a1957600080fd5b505af1158015610a2d573d6000803e3d6000fd5b505050506040513d6020811015610a4357600080fd5b81019080805190602001909291905050501515610a5f57600080fd5b610a67611071565b1515610a7257600080fd5b610a7c3334611084565b565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610ad957600080fd5b600060149054906101000a900460ff161515610af457600080fd5b60008060146101000a81548160ff0219169083151502179055507f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3360405160405180910390a1565b6000600880549050905090565b600060149054906101000a900460ff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610bb757600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482060405160405180910390a260008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610cb957600080fd5b600060149054906101000a900460ff16151515610cd557600080fd5b6001600060146101000a81548160ff0219169083151502179055507f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62560405160405180910390a1565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060149054906101000a900460ff16151515610d5f57600080fd5b610d6833610f0b565b1515610d7357600080fd5b600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900460ff16151515610dcf57600080fd5b6001600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160016101000a81548160ff021916908315150217905550600960408051908101604052808381526020013373ffffffffffffffffffffffffffffffffffffffff16815250908060018154018082558091505090600182039060005260206000209060020201600090919290919091506000820151816000015560208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b60045481565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60035481565b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff169050919050565b6000600980549050905090565b6000806000600984815481101515610f8557fe5b90600052602060002090600202019050806000015492508060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915050915091565b60025481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561102a57600080fd5b61103381611159565b50565b600060149054906101000a900460ff1615151561105257600080fd5b61105b33610f0b565b151561106657600080fd5b61106f33611253565b565b6000806008805490506001540311905090565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600160088490806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555003816000018190555060018160010160006101000a81548160ff021916908315150217905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561119557600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000806000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020925082600001549150600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000808201600090556001820160006101000a81549060ff02191690556001820160016101000a81549060ff02191690555050600860016008805490500381548110151561132957fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060088381548110151561136657fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000181905550600880548091906001900361140a9190611411565b5050505050565b81548183558181111561143857818360005260206000209182019101611437919061143d565b5b505050565b61145f91905b8082111561145b576000816000905550600101611443565b5090565b905600a165627a7a723058206edebfea6040cf2a51a7b24a3abd4c4f5147e2cd72dc2e88c61b250d8362437b0029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x0000000000000000000000000e5d0fd336650e663c710ef420f85fb081e21415","0x0000000000000000000000000000000000000000000000000000000000000001":"0x0000000000000000000000000000000000000000000000000000000000000032","0x0000000000000000000000000000000000000000000000000000000000000002":"0x0000000000000000000000000000000000000000000000000000000000000258","0x0000000000000000000000000000000000000000000000000000000000000003":"0x000000000000000000000000000000000000000000000000000000000000001e","0x0000000000000000000000000000000000000000000000000000000000000005":"0x0000000000000000000000000090137110f43c6666b7bd641fcf5ca5dd989539","0x0000000000000000000000000000000000000000000000000000000000000006":"0x13a02f7cebf86cd2a5bc43aab96f2b5c4dd7406102f5a3b3e734a749ce84ea87"},"balance":"0x0"},"64c2a9cb0220d3e56783ed87cc1b20115bc93f96":{"code":"0x6080604052600436106100fc576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305d2035b1461010157806306fdde0314610130578063158ef93e146101c057806318160ddd146101ef578063313ce5671461021a578063355274ea1461024b57806340c10f191461027657806341658f3c146102db57806370a08231146103a1578063715018a6146103f85780637d64bcb41461040f578063893d20e81461043e5780638da5cb5b1461049557806395d89b41146104ec578063a9059cbb1461057c578063be45fd62146105e1578063f2fde38b1461068c578063f6368f8a146106cf575b600080fd5b34801561010d57600080fd5b506101166107c0565b604051808215151515815260200191505060405180910390f35b34801561013c57600080fd5b506101456107d3565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561018557808201518184015260208101905061016a565b50505050905090810190601f1680156101b25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101cc57600080fd5b506101d5610875565b604051808215151515815260200191505060405180910390f35b3480156101fb57600080fd5b50610204610888565b6040518082815260200191505060405180910390f35b34801561022657600080fd5b5061022f610892565b604051808260ff1660ff16815260200191505060405180910390f35b34801561025757600080fd5b506102606108a9565b6040518082815260200191505060405180910390f35b34801561028257600080fd5b506102c1600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506108af565b604051808215151515815260200191505060405180910390f35b3480156102e757600080fd5b5061039f600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080359060200190929190803560ff169060200190929190505050610960565b005b3480156103ad57600080fd5b506103e2600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610acb565b6040518082815260200191505060405180910390f35b34801561040457600080fd5b5061040d610b14565b005b34801561041b57600080fd5b50610424610c19565b604051808215151515815260200191505060405180910390f35b34801561044a57600080fd5b50610453610ce1565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156104a157600080fd5b506104aa610d0b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156104f857600080fd5b50610501610d31565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610541578082015181840152602081019050610526565b50505050905090810190601f16801561056e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561058857600080fd5b506105c7600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610dd3565b604051808215151515815260200191505060405180910390f35b3480156105ed57600080fd5b50610672600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610e0c565b604051808215151515815260200191505060405180910390f35b34801561069857600080fd5b506106cd600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610e43565b005b3480156106db57600080fd5b506107a6600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610eab565b604051808215151515815260200191505060405180910390f35b600760149054906101000a900460ff1681565b606060038054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561086b5780601f106108405761010080835404028352916020019161086b565b820191906000526020600020905b81548152906001019060200180831161084e57829003601f168201915b5050505050905090565b600160009054906101000a900460ff1681565b6000600654905090565b6000600560009054906101000a900460ff16905090565b60085481565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561090d57600080fd5b600760149054906101000a900460ff1615151561092957600080fd5b6008546109418360065461126890919063ffffffff16565b1115151561094e57600080fd5b6109588383611284565b905092915050565b600160009054906101000a900460ff16151515610a0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001807f436f6e747261637420696e7374616e63652068617320616c726561647920626581526020017f656e20696e697469616c697a656400000000000000000000000000000000000081525060400191505060405180910390fd5b600082111515610a1a57600080fd5b8160088190555033600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508360039080519060200190610a78929190611b11565b508260049080519060200190610a8f929190611b11565b5080600560006101000a81548160ff021916908360ff16021790555060018060006101000a81548160ff02191690831515021790555050505050565b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610b7057600080fd5b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482060405160405180910390a26000600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610c7757600080fd5b600760149054906101000a900460ff16151515610c9357600080fd5b6001600760146101000a81548160ff0219169083151502179055507fae5184fba832cb2b1f702aca6117b8d265eaf03ad33eb133f19dde0f5920fa0860405160405180910390a16001905090565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606060048054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610dc95780601f10610d9e57610100808354040283529160200191610dc9565b820191906000526020600020905b815481529060010190602001808311610dac57829003601f168201915b5050505050905090565b60006060610de084611480565b15610df757610df0848483611493565b9150610e05565b610e028484836117de565b91505b5092915050565b6000610e1784611480565b15610e2e57610e27848484611493565b9050610e3c565b610e398484846117de565b90505b9392505050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610e9f57600080fd5b610ea8816119fc565b50565b6000610eb685611480565b156112525783610ec533610acb565b1015610ed057600080fd5b610f2284600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611af890919063ffffffff16565b600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610fb784600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461126890919063ffffffff16565b600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508473ffffffffffffffffffffffffffffffffffffffff166000836040518082805190602001908083835b6020831015156110495780518252602082019150602081019050602083039250611024565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207c01000000000000000000000000000000000000000000000000000000009004903387876040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828051906020019080838360005b8381101561112a57808201518184015260208101905061110f565b50505050905090810190601f1680156111575780820380516001836020036101000a031916815260200191505b50935050505060006040518083038185885af19350505050151561117757fe5b8473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c1686866040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561120e5780820151818401526020810190506111f3565b50505050905090810190601f16801561123b5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a360019050611260565b61125d8585856117de565b90505b949350505050565b6000818301905082811015151561127b57fe5b80905092915050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156112e257600080fd5b600760149054906101000a900460ff161515156112fe57600080fd5b6113138260065461126890919063ffffffff16565b60068190555061136b82600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461126890919063ffffffff16565b600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885836040518082815260200191505060405180910390a28273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c168460405180828152602001806020018281038252600081526020016020019250505060405180910390a36001905092915050565b600080823b905060008111915050919050565b600080836114a033610acb565b10156114ab57600080fd5b6114fd84600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611af890919063ffffffff16565b600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061159284600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461126890919063ffffffff16565b600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508490508073ffffffffffffffffffffffffffffffffffffffff1663c0ee0b8a3386866040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561169a57808201518184015260208101905061167f565b50505050905090810190601f1680156116c75780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156116e857600080fd5b505af11580156116fc573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c1686866040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561179757808201518184015260208101905061177c565b50505050905090810190601f1680156117c45780820380516001836020036101000a031916815260200191505b50935050505060405180910390a360019150509392505050565b6000826117ea33610acb565b10156117f557600080fd5b61184783600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611af890919063ffffffff16565b600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506118dc83600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461126890919063ffffffff16565b600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c1685856040518083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156119b657808201518184015260208101905061199b565b50505050905090810190601f1680156119e35780820380516001836020036101000a031916815260200191505b50935050505060405180910390a3600190509392505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515611a3857600080fd5b8073ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000828211151515611b0657fe5b818303905092915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611b5257805160ff1916838001178555611b80565b82800160010185558215611b80579182015b82811115611b7f578251825591602001919060010190611b64565b5b509050611b8d9190611b91565b5090565b611bb391905b80821115611baf576000816000905550600101611b97565b5090565b905600a165627a7a723058205e5cc50b54a1435f03d0f8490f628e5477e3c71169f264d34c47d0a49253bbfc0029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000003":"0x6d55534400000000000000000000000000000000000000000000000000000008","0x0000000000000000000000000000000000000000000000000000000000000004":"0x6d55534400000000000000000000000000000000000000000000000000000008","0x0000000000000000000000000000000000000000000000000000000000000005":"0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000007":"0x0000000000000000000000000e5d0fd336650e663c710ef420f85fb081e21415","0x0000000000000000000000000000000000000000000000000000000000000008":"0x000000000000000000000000000000000000000003782dace9d9000000000000"},"balance":"0x0"},"6ad6b24c43a622d58e2959474e3912ba94dfd957":{"balance":"0x8ac7230489e80000"},"6d5e05684c737d42f313d5b82a88090136e831f8":{"balance":"0x21e19e0c9bab2400000"},"7a5727e94bbb559e0eafc399354dd30dbd51d2aa":{"code":"0x60806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806325b5672714610051578063c6e8b4f3146100f4575b600080fd5b34801561005d57600080fd5b506100b2600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101d0565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61018e600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929050505061029b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6000806101dc836103fa565b90508073ffffffffffffffffffffffffffffffffffffffff16638f283970856040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b15801561027957600080fd5b505af115801561028d573d6000803e3d6000fd5b505050508091505092915050565b6000806102a7846103fa565b90508073ffffffffffffffffffffffffffffffffffffffff16638f283970866040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b15801561034457600080fd5b505af1158015610358573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff16348460405180828051906020019080838360005b838110156103a2578082015181840152602081019050610387565b50505050905090810190601f1680156103cf5780820380516001836020036101000a031916815260200191505b5091505060006040518083038185875af19250505015156103ef57600080fd5b809150509392505050565b600080826104066104c6565b808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050604051809103906000f080158015610458573d6000803e3d6000fd5b5090507efffc2da0b561cae30d9826d37709e9421c4725faebc226cbbb7ef5fc5e734981604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a180915050919050565b604051610b27806104d7833901905600608060405234801561001057600080fd5b50604051602080610b27833981018060405281019080805190602001909291905050508060405180807f6f72672e7a657070656c696e6f732e70726f78792e696d706c656d656e74617481526020017f696f6e000000000000000000000000000000000000000000000000000000000081525060230190506040518091039020600019167f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3600102600019161415156100c557fe5b6100dd81610167640100000000026401000000009004565b5060405180807f6f72672e7a657070656c696e6f732e70726f78792e61646d696e000000000000815250601a0190506040518091039020600019167f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b6001026000191614151561014957fe5b6101613361024c640100000000026401000000009004565b5061028e565b60006101858261027b6401000000000261084b176401000000009004565b151561021f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001807f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f81526020017f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000081525060400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c360010290508181555050565b60007f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b60010290508181555050565b600080823b905060008111915050919050565b61088a8061029d6000396000f30060806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633659cfe6146100775780634f1ef286146100ba5780635c60da1b146101085780638f2839701461015f578063f851a440146101a2575b6100756101f9565b005b34801561008357600080fd5b506100b8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610213565b005b610106600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001908201803590602001919091929391929390505050610268565b005b34801561011457600080fd5b5061011d610308565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561016b57600080fd5b506101a0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610360565b005b3480156101ae57600080fd5b506101b761051e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610201610576565b61021161020c610651565b610682565b565b61021b6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025c57610257816106d9565b610265565b6102646101f9565b5b50565b6102706106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fa576102ac836106d9565b3073ffffffffffffffffffffffffffffffffffffffff163483836040518083838082843782019150509250505060006040518083038185875af19250505015156102f557600080fd5b610303565b6103026101f9565b5b505050565b60006103126106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103545761034d610651565b905061035d565b61035c6101f9565b5b90565b6103686106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561051257600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610466576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001807f43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f81526020017f787920746f20746865207a65726f20616464726573730000000000000000000081525060400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61048f6106a8565b82604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a161050d81610748565b61051b565b61051a6101f9565b5b50565b60006105286106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561056a576105636106a8565b9050610573565b6105726101f9565b5b90565b61057e6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151515610647576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001807f43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e20667281526020017f6f6d207468652070726f78792061646d696e000000000000000000000000000081525060400191505060405180910390fd5b61064f610777565b565b6000807f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c36001029050805491505090565b3660008037600080366000845af43d6000803e80600081146106a3573d6000f35b3d6000fd5b6000807f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b6001029050805491505090565b6106e281610779565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b60010290508181555050565b565b60006107848261084b565b151561081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001807f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f81526020017f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000081525060400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c360010290508181555050565b600080823b9050600081119150509190505600a165627a7a72305820b31d41a72e81559b9fbd6f52c3db76ab77aeacd5de378d37ab93861a9b684f120029a165627a7a7230582075bac8779341600a0dbcebbbdf6fb8487503343b22b6218c9bd744b22b6435780029","balance":"0x0"},"7f0de05687a7cb9a05399a26f4d1519ba6afc95f":{"code":"0x6080604052600436106100f1576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806301ffc9a7146100f657806310f13a8c1461015a578063158ef93e146102175780632203ab561461024657806329cd62ea146103015780632dff69411461034e5780633b3b57de1461039b57806359d1d43c1461040c578063623195b0146104fc578063691f34311461057d5780637737221314610627578063aa4cb5471461069e578063c3d014d614610715578063c4d66de814610754578063c869023314610797578063d5fa2b00146107f3578063e89401a114610844575b600080fd5b34801561010257600080fd5b5061014060048036038101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690602001909291905050506108ee565b604051808215151515815260200191505060405180910390f35b34801561016657600080fd5b506102156004803603810190808035600019169060200190929190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610c48565b005b34801561022357600080fd5b5061022c610f06565b604051808215151515815260200191505060405180910390f35b34801561025257600080fd5b5061027f600480360381019080803560001916906020019092919080359060200190929190505050610f18565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156102c55780820151818401526020810190506102aa565b50505050905090810190601f1680156102f25780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b34801561030d57600080fd5b5061034c60048036038101908080356000191690602001909291908035600019169060200190929190803560001916906020019092919050505061105b565b005b34801561035a57600080fd5b5061037d6004803603810190808035600019169060200190929190505050611221565b60405180826000191660001916815260200191505060405180910390f35b3480156103a757600080fd5b506103ca6004803603810190808035600019169060200190929190505050611249565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561041857600080fd5b506104816004803603810190808035600019169060200190929190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050611291565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156104c15780820151818401526020810190506104a6565b50505050905090810190601f1680156104ee5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561050857600080fd5b5061057b600480360381019080803560001916906020019092919080359060200190929190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506113bb565b005b34801561058957600080fd5b506105ac6004803603810190808035600019169060200190929190505050611559565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156105ec5780820151818401526020810190506105d1565b50505050905090810190601f1680156106195780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561063357600080fd5b5061069c6004803603810190808035600019169060200190929190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050611619565b005b3480156106aa57600080fd5b506107136004803603810190808035600019169060200190929190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050611800565b005b34801561072157600080fd5b50610752600480360381019080803560001916906020019092919080356000191690602001909291905050506119e7565b005b34801561076057600080fd5b50610795600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611b65565b005b3480156107a357600080fd5b506107c66004803603810190808035600019169060200190929190505050611c6d565b60405180836000191660001916815260200182600019166000191681526020019250505060405180910390f35b3480156107ff57600080fd5b506108426004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611cbd565b005b34801561085057600080fd5b506108736004803603810190808035600019169060200190929190505050611e95565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156108b3578082015181840152602081019050610898565b50505050905090810190601f1680156108e05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000633b3b57de7c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806109bf575063d8389dc57c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610a2a575063691f34317c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610a955750632203ab567c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610b00575063c86902337c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610b6b57506359d1d43c7c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610bd6575063e89401a17c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610c4157506301ffc9a77c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b823373ffffffffffffffffffffffffffffffffffffffff16600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b158015610cf957600080fd5b505af1158015610d0d573d6000803e3d6000fd5b505050506040513d6020811015610d2357600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff16141515610d5657600080fd5b81600160008660001916600019168152602001908152602001600020600501846040518082805190602001908083835b602083101515610dab5780518252602082019150602081019050602083039250610d86565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405180910390209080519060200190610df1929190611f55565b5083600019167fd8c9334b1a9c2f9da342a0a2b32629c1a229b6445dad78947f674b44444a75508485604051808060200180602001838103835285818151815260200191508051906020019080838360005b83811015610e5e578082015181840152602081019050610e43565b50505050905090810190601f168015610e8b5780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015610ec4578082015181840152602081019050610ea9565b50505050905090810190601f168015610ef15780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a250505050565b6000809054906101000a900460ff1681565b6000606060006001600086600019166000191681526020019081526020016000209050600192505b838311151561104e57600084841614158015610f8557506000816006016000858152602001908152602001600020805460018160011615610100020316600290049050115b1561103f578060060160008481526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156110335780601f1061100857610100808354040283529160200191611033565b820191906000526020600020905b81548152906001019060200180831161101657829003601f168201915b50505050509150611053565b6001839060020a029250610f40565b600092505b509250929050565b823373ffffffffffffffffffffffffffffffffffffffff16600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b15801561110c57600080fd5b505af1158015611120573d6000803e3d6000fd5b505050506040513d602081101561113657600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1614151561116957600080fd5b6040805190810160405280846000191681526020018360001916815250600160008660001916600019168152602001908152602001600020600301600082015181600001906000191690556020820151816001019060001916905590505083600019167f1d6f5e03d3f63eb58751986629a5439baee5079ff04f345becb66e23eb154e46848460405180836000191660001916815260200182600019166000191681526020019250505060405180910390a250505050565b6000600160008360001916600019168152602001908152602001600020600101549050919050565b600060016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6060600160008460001916600019168152602001908152602001600020600501826040518082805190602001908083835b6020831015156112e757805182526020820191506020810190506020830392506112c2565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405180910390208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156113ae5780601f10611383576101008083540402835291602001916113ae565b820191906000526020600020905b81548152906001019060200180831161139157829003601f168201915b5050505050905092915050565b823373ffffffffffffffffffffffffffffffffffffffff16600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b15801561146c57600080fd5b505af1158015611480573d6000803e3d6000fd5b505050506040513d602081101561149657600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff161415156114c957600080fd5b60008360018503161415156114dd57600080fd5b8160016000866000191660001916815260200190815260200160002060060160008581526020019081526020016000209080519060200190611520929190611fd5565b508284600019167faa121bbeef5f32f5961a2a28966e769023910fc9479059ee3495d4c1a696efe360405160405180910390a350505050565b60606001600083600019166000191681526020019081526020016000206002018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561160d5780601f106115e25761010080835404028352916020019161160d565b820191906000526020600020905b8154815290600101906020018083116115f057829003601f168201915b50505050509050919050565b813373ffffffffffffffffffffffffffffffffffffffff16600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1580156116ca57600080fd5b505af11580156116de573d6000803e3d6000fd5b505050506040513d60208110156116f457600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1614151561172757600080fd5b816001600085600019166000191681526020019081526020016000206002019080519060200190611759929190611f55565b5082600019167fb7d29e911041e8d9b843369e890bcb72c9388692ba48b65ac54e7214c4c348f7836040518080602001828103825283818151815260200191508051906020019080838360005b838110156117c15780820151818401526020810190506117a6565b50505050905090810190601f1680156117ee5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505050565b813373ffffffffffffffffffffffffffffffffffffffff16600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1580156118b157600080fd5b505af11580156118c5573d6000803e3d6000fd5b505050506040513d60208110156118db57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1614151561190e57600080fd5b816001600085600019166000191681526020019081526020016000206007019080519060200190611940929190611fd5565b5082600019167fc0b0fc07269fc2749adada3221c095a1d2187b2d075b51c915857b520f3a5021836040518080602001828103825283818151815260200191508051906020019080838360005b838110156119a857808201518184015260208101905061198d565b50505050905090810190601f1680156119d55780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505050565b813373ffffffffffffffffffffffffffffffffffffffff16600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b158015611a9857600080fd5b505af1158015611aac573d6000803e3d6000fd5b505050506040513d6020811015611ac257600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff16141515611af557600080fd5b81600160008560001916600019168152602001908152602001600020600101816000191690555082600019167f0424b6fe0d9c3bdbece0e7879dc241bb0c22e900be8b6c168b4ee08bd9bf83bc8360405180826000191660001916815260200191505060405180910390a2505050565b6000809054906101000a900460ff16151515611c0f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001807f436f6e747261637420696e7374616e63652068617320616c726561647920626581526020017f656e20696e697469616c697a656400000000000000000000000000000000000081525060400191505060405180910390fd5b80600060016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060016000806101000a81548160ff02191690831515021790555050565b600080600160008460001916600019168152602001908152602001600020600301600001546001600085600019166000191681526020019081526020016000206003016001015491509150915091565b813373ffffffffffffffffffffffffffffffffffffffff16600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b158015611d6e57600080fd5b505af1158015611d82573d6000803e3d6000fd5b505050506040513d6020811015611d9857600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff16141515611dcb57600080fd5b8160016000856000191660001916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600019167f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd283604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a2505050565b60606001600083600019166000191681526020019081526020016000206007018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611f495780601f10611f1e57610100808354040283529160200191611f49565b820191906000526020600020905b815481529060010190602001808311611f2c57829003601f168201915b50505050509050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611f9657805160ff1916838001178555611fc4565b82800160010185558215611fc4579182015b82811115611fc3578251825591602001919060010190611fa8565b5b509050611fd19190612055565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061201657805160ff1916838001178555612044565b82800160010185558215612044579182015b82811115612043578251825591602001919060010190612028565b5b5090506120519190612055565b5090565b61207791905b8082111561207357600081600090555060010161205b565b5090565b905600a165627a7a72305820027c05d350dcea72c694473f4a996d01df5e087012864c93d8c8fb87b44584380029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x0000000000000000000000000000000000000000000000000000000000000000"},"balance":"0x0"},"902f069af381a650b7f18ff28ffdad0f11eb425b":{"balance":"0x8ac7230489e80000"},"b5822d5f8d221ce2dc73e388629eca256b0aa4f2":{"code":"0x60806040526004361061016a576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063035cf1421461016f5780630a3cb6631461019a578063158ef93e146101c55780632086ca25146101f4578063268331481461021f5780633ed0a3731461024a5780633f4ba83a146102925780635c975abb146102a957806369474625146102d85780636a911ccf146103035780637071688a1461031a578063715018a6146103455780637d0e81bf1461035c5780638456cb59146103b75780638da5cb5b146103ce5780639363a1411461042557806397584b3e146104505780639abee7d01461047f5780639bb2ea5a146104cc578063a2207c6a146104f9578063aded41ec14610550578063b774cb1e14610567578063c22a933c1461059a578063ccd65296146105c7578063cefddda914610632578063e7a60a9c1461068d578063f2fde38b14610701578063facd743b14610744575b600080fd5b34801561017b57600080fd5b5061018461079f565b6040518082815260200191505060405180910390f35b3480156101a657600080fd5b506101af610872565b6040518082815260200191505060405180910390f35b3480156101d157600080fd5b506101da610878565b604051808215151515815260200191505060405180910390f35b34801561020057600080fd5b5061020961088b565b6040518082815260200191505060405180910390f35b34801561022b57600080fd5b50610234610891565b6040518082815260200191505060405180910390f35b34801561025657600080fd5b5061027560048036038101908080359060200190929190505050610897565b604051808381526020018281526020019250505060405180910390f35b34801561029e57600080fd5b506102a761090f565b005b3480156102b557600080fd5b506102be6109cd565b604051808215151515815260200191505060405180910390f35b3480156102e457600080fd5b506102ed6109e0565b6040518082815260200191505060405180910390f35b34801561030f57600080fd5b506103186109e6565b005b34801561032657600080fd5b5061032f610a21565b6040518082815260200191505060405180910390f35b34801561035157600080fd5b5061035a610a2e565b005b34801561036857600080fd5b5061039d600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b30565b604051808215151515815260200191505060405180910390f35b3480156103c357600080fd5b506103cc610bc4565b005b3480156103da57600080fd5b506103e3610c84565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561043157600080fd5b5061043a610ca9565b6040518082815260200191505060405180910390f35b34801561045c57600080fd5b50610465610cf6565b604051808215151515815260200191505060405180910390f35b34801561048b57600080fd5b506104ca600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610d09565b005b3480156104d857600080fd5b506104f760048036038101908080359060200190929190505050610d96565b005b34801561050557600080fd5b5061050e610e3a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561055c57600080fd5b50610565610e60565b005b34801561057357600080fd5b5061057c611135565b60405180826000191660001916815260200191505060405180910390f35b3480156105a657600080fd5b506105c56004803603810190808035906020019092919050505061113b565b005b3480156105d357600080fd5b5061063060048036038101908080359060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506111a0565b005b34801561063e57600080fd5b50610673600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506113bf565b604051808215151515815260200191505060405180910390f35b34801561069957600080fd5b506106b860048036038101908080359060200190929190505050611418565b604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390f35b34801561070d57600080fd5b50610742600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506114cf565b005b34801561075057600080fd5b50610785600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611536565b604051808215151515815260200191505060405180910390f35b6000806107aa610cf6565b156107b957600154915061086e565b6008600060096001600980549050038154811015156107d457fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600181600201600183600201805490500381548110151561085857fe5b9060005260206000209060020201600001540191505b5090565b60035481565b600060159054906101000a900460ff1681565b60025481565b60065481565b6000806000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201848154811015156108eb57fe5b90600052602060002090600202019050806000015481600101549250925050915091565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561096a57600080fd5b600060149054906101000a900460ff16151561098557600080fd5b60008060146101000a81548160ff0219169083151502179055507f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3360405160405180910390a1565b600060149054906101000a900460ff1681565b60015481565b600060149054906101000a900460ff16151515610a0257600080fd5b610a0b33611536565b1515610a1657600080fd5b610a1f3361158f565b565b6000600980549050905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610a8957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482060405160405180910390a260008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600080610b3c83611536565b1515610b4b5760009150610bbe565b600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002019050600654816001838054905003815481101515610ba757fe5b906000526020600020906002020160000154101591505b50919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610c1f57600080fd5b600060149054906101000a900460ff16151515610c3b57600080fd5b6001600060146101000a81548160ff0219169083151502179055507f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62560405160405180910390a1565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020180549050905090565b6000806009805490506002540311905090565b60408051908101604052808373ffffffffffffffffffffffffffffffffffffffff16815260200182815250600a60008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010155905050610d92611701565b5050565b6000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610df457600080fd5b600980549050831015610e2e5782600980549050039150600090505b81811015610e2d57610e206117bf565b8080600101915050610e10565b5b82600281905550505050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600080600060149054906101000a900460ff16151515610e8257600080fd5b6000935060009250600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020191505b818054905083108015610f02575060008284815481101515610eed57fe5b90600052602060002090600202016001015414155b15610f64578183815481101515610f1557fe5b906000526020600020906002020160010154421015610f3357610f64565b8183815481101515610f4157fe5b906000526020600020906002020160000154840193508280600101935050610ecf565b610f6e338461180b565b600084111561112f57600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633b3b57de6005546040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b15801561101257600080fd5b505af1158015611026573d6000803e3d6000fd5b505050506040513d602081101561103c57600080fd5b810190808051906020019092919050505090508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33866040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156110f257600080fd5b505af1158015611106573d6000803e3d6000fd5b505050506040513d602081101561111c57600080fd5b8101908080519060200190929190505050505b50505050565b60045481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561119657600080fd5b8060018190555050565b600060159054906101000a900460ff1615151561124b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001807f436f6e747261637420696e7374616e63652068617320616c726561647920626581526020017f656e20696e697469616c697a656400000000000000000000000000000000000081525060400191505060405180910390fd5b60008411151561125a57600080fd5b84600181905550836002819055506201518083026003819055508160068190555080600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550733b058a1a62e59d185618f64bebbaf3c52bf099e063098799626040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825260128152602001807f6d696e696e67746f6b656e2e6b6f77616c61000000000000000000000000000081525060200191505060206040518083038186803b15801561135857600080fd5b505af415801561136c573d6000803e3d6000fd5b505050506040513d602081101561138257600080fd5b8101908080519060200190929190505050600581600019169055506001600060156101000a81548160ff0219169083151502179055505050505050565b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900460ff169050919050565b600080600060098481548110151561142c57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169250600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060020160018260020180549050038154811015156114b557fe5b906000526020600020906002020160000154915050915091565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561152a57600080fd5b611533816118f8565b50565b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff169050919050565b600080600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209150816000015490505b60016009805490500381101561168c576009600182018154811015156115fd57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660098281548110151561163757fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080806001019150506115db565b60098054809190600190036116a19190611db9565b5060008260010160006101000a81548160ff02191690831515021790555060035442018260020160018460020180549050038154811015156116df57fe5b9060005260206000209060020201600101819055506116fc6119f2565b505050565b600060149054906101000a900460ff1615151561171d57600080fd5b61174b600a60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16611536565b15151561175757600080fd5b61175f61079f565b600a600101541015151561177257600080fd5b61177a610cf6565b1515611789576117886117bf565b5b6117bd600a60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600a60010154611a75565b565b61180960096001600980549050038154811015156117d957fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661158f565b565b60008060008084141561181d576118f1565b600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209250600091508390505b82600201805490508110156118df57826002018181548110151561188657fe5b906000526020600020906002020183600201838154811015156118a557fe5b9060005260206000209060020201600082015481600001556001820154816001015590505081806001019250508080600101915050611866565b8183600201816118ef9190611de5565b505b5050505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561193457600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6009604051808280548015611a5c57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611a12575b5050915050604051809103902060048160001916905550565b600080600080600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209350600160098790806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555003846000018190555060018460010160006101000a81548160ff0219169083151502179055506000431415611b705760018460010160016101000a81548160ff0219169083151502179055505b8360020160408051908101604052808781526020016000815250908060018154018082558091505090600182039060005260206000209060020201600090919290919091506000820151816000015560208201518160010155505050836000015492505b6000831115611da95760086000600960018603815481101515611bf357fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209150816002016001836002018054905003815481101515611c7557fe5b90600052602060002090600202019050806000015485111515611c9757611da9565b600960018403815481101515611ca957fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600984815481101515611ce357fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555085600960018503815481101515611d3e57fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828260000181905550600183038460000181905550828060019003935050611bd4565b611db16119f2565b505050505050565b815481835581811115611de057818360005260206000209182019101611ddf9190611e17565b5b505050565b815481835581811115611e1257600202816002028360005260206000209182019101611e119190611e3c565b5b505050565b611e3991905b80821115611e35576000816000905550600101611e1d565b5090565b90565b611e6891905b80821115611e6457600080820160009055600182016000905550600201611e42565b5090565b905600a165627a7a72305820191fba81bca640eb79ed9424e349e31a1a476c3140d3d27c954efbfec8e60f0b0029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x0000000000000000000000000e5d0fd336650e663c710ef420f85fb081e21415","0x0000000000000000000000000000000000000000000000000000000000000001":"0x00000000000000000000000000000000000000000000065a4da25d3016c00000","0x0000000000000000000000000000000000000000000000000000000000000002":"0x00000000000000000000000000000000000000000000000000000000000001f4","0x0000000000000000000000000000000000000000000000000000000000000003":"0x0000000000000000000000000000000000000000000000000000000000015180","0x0000000000000000000000000000000000000000000000000000000000000005":"0xc99f18ca33e10b0236fe4fd62bfd9a8eb6ceee10bf8dad1b0d121d5e6a2bf3ba","0x0000000000000000000000000000000000000000000000000000000000000006":"0x00000000000000000000000000000000000000000004f68ca6d8cd91c6000000","0x0000000000000000000000000000000000000000000000000000000000000007":"0x00000000000000000000000001e1056f6a829e53dadeb8a5a6189a9333bd1d63"},"balance":"0x0"},"bfb47d8008d1ccdcaf3a36110a9338a274e86343":{"code":"0x608060405260043610610099576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630178b8bf1461009e57806302571be31461010f57806306ab59231461018057806314ab9038146101df578063158ef93e1461022457806316a25cbd146102535780631896f70a146102ac5780635b0fc9c3146102fd578063c4d66de81461034e575b600080fd5b3480156100aa57600080fd5b506100cd6004803603810190808035600019169060200190929190505050610391565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561011b57600080fd5b5061013e60048036038101908080356000191690602001909291905050506103d9565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561018c57600080fd5b506101dd60048036038101908080356000191690602001909291908035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610421565b005b3480156101eb57600080fd5b506102226004803603810190808035600019169060200190929190803567ffffffffffffffff16906020019092919050505061059d565b005b34801561023057600080fd5b506102396106b0565b604051808215151515815260200191505060405180910390f35b34801561025f57600080fd5b5061028260048036038101908080356000191690602001909291905050506106c2565b604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390f35b3480156102b857600080fd5b506102fb6004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506106fe565b005b34801561030957600080fd5b5061034c6004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610841565b005b34801561035a57600080fd5b5061038f600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610984565b005b600060016000836000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600060016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000833373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561049c57600080fd5b848460405180836000191660001916815260200182600019166000191681526020019250505060405180910390209150836000191685600019167fce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e8285604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a38260016000846000191660001916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b813373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561061657600080fd5b82600019167f1d4f9bbfc9cab89d66e1a1562f2233ccbf1308cb4f63de2ead5787adddb8fa6883604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390a28160016000856000191660001916815260200190815260200160002060010160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505050565b6000809054906101000a900460ff1681565b600060016000836000191660001916815260200190815260200160002060010160149054906101000a900467ffffffffffffffff169050919050565b813373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561077757600080fd5b82600019167f335721b01866dc23fbee8b6b2c7b1e14d6f05c28cd35a2c934239f94095602a083604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a28160016000856000191660001916815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b813373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156108ba57600080fd5b82600019167fd4735d920b0f87494915f556dd9b54c8f309026070caea5c737245152564d26683604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a28160016000856000191660001916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b6000809054906101000a900460ff16151515610a2e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001807f436f6e747261637420696e7374616e63652068617320616c726561647920626581526020017f656e20696e697469616c697a656400000000000000000000000000000000000081525060400191505060405180910390fd5b80600160008060010260001916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060016000806101000a81548160ff021916908315150217905550505600a165627a7a72305820e6c94ed3c260b949380eb0a722b651d424262e08f3c684546711633d9eb70ec10029","storage":{"0xa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb49":"0x0000000000000000000000000e5d0fd336650e663c710ef420f85fb081e21415"},"balance":"0x0"},"c3c45781031885313d5a598042950d6d7be96350":{"code":"0x6080604052600436106100a3576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168062bf32ca146100a8578063158ef93e146100e957806321873631146101185780632af4f9c0146101435780632d3802421461016e5780636df566d714610199578063a035b1fe146101c4578063b0c6363d146101ef578063e4a301161461021a578063fc634f4b14610251575b600080fd5b3480156100b457600080fd5b506100d36004803603810190808035906020019092919050505061027c565b6040518082815260200191505060405180910390f35b3480156100f557600080fd5b506100fe610295565b604051808215151515815260200191505060405180910390f35b34801561012457600080fd5b5061012d6102a7565b6040518082815260200191505060405180910390f35b34801561014f57600080fd5b506101586102d7565b6040518082815260200191505060405180910390f35b34801561017a57600080fd5b506101836102dd565b6040518082815260200191505060405180910390f35b3480156101a557600080fd5b506101ae610365565b6040518082815260200191505060405180910390f35b3480156101d057600080fd5b506101d961036b565b6040518082815260200191505060405180910390f35b3480156101fb57600080fd5b50610204610375565b6040518082815260200191505060405180910390f35b34801561022657600080fd5b5061024f600480360381019080803590602001909291908035906020019092919050505061037b565b005b34801561025d57600080fd5b5061026661045f565b6040518082815260200191505060405180910390f35b600060648260040281151561028d57fe5b049050919050565b6000809054906101000a900460ff1681565b60006102d2670de0b6b3a76400003073ffffffffffffffffffffffffffffffffffffffff1631610465565b905090565b60045481565b600080600180430114156102fc57680246ddf979766800009150610361565b61271060045481151561030b57fe5b04905060015460025411801561032a5750670de0b6b3a7640000600154115b1561034b57610344816004540161033f61047e565b610465565b9150610361565b61035e816004540364e8d4a510006104bf565b91505b5090565b60025481565b6000600254905090565b60035481565b6000809054906101000a900460ff16151515610425576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001807f436f6e747261637420696e7374616e63652068617320616c726561647920626581526020017f656e20696e697469616c697a656400000000000000000000000000000000000081525060400191505060405180910390fd5b8160018190555081600281905550806004819055508060038190555060016000806101000a81548160ff0219169083151502179055505050565b60015481565b60008183106104745781610476565b825b905092915050565b6000600180430111801561049657506104956104d9565b5b6104a957680471fa858b9e0800006104ba565b6127106003548115156104b857fe5b045b905090565b6000818310156104cf57816104d1565b825b905092915050565b600069d3c21bcecceda100000060035410159050905600a165627a7a723058206fe4f1f991942cb71ef574c8d7fffd57bd4a05e408f7df2f2c0ecd8fe40406390029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000001":"0x0000000000000000000000000000000000000000000000000de0b6b3a7640000","0x0000000000000000000000000000000000000000000000000000000000000002":"0x0000000000000000000000000000000000000000000000000de0b6b3a7640000","0x0000000000000000000000000000000000000000000000000000000000000003":"0x00000000000000000000000000000000000000000000021fba3632c84ff80000","0x0000000000000000000000000000000000000000000000000000000000000004":"0x00000000000000000000000000000000000000000000021fba3632c84ff80000"},"balance":"0x0"},"c497f7ad7105db9f4138de92b13a0883b19ee0fa":{"code":"0x60806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633659cfe6146100775780634f1ef286146100ba5780635c60da1b146101085780638f2839701461015f578063f851a440146101a2575b6100756101f9565b005b34801561008357600080fd5b506100b8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610213565b005b610106600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001908201803590602001919091929391929390505050610268565b005b34801561011457600080fd5b5061011d610308565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561016b57600080fd5b506101a0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610360565b005b3480156101ae57600080fd5b506101b761051e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610201610576565b61021161020c610651565b610682565b565b61021b6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025c57610257816106d9565b610265565b6102646101f9565b5b50565b6102706106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fa576102ac836106d9565b3073ffffffffffffffffffffffffffffffffffffffff163483836040518083838082843782019150509250505060006040518083038185875af19250505015156102f557600080fd5b610303565b6103026101f9565b5b505050565b60006103126106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103545761034d610651565b905061035d565b61035c6101f9565b5b90565b6103686106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561051257600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610466576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001807f43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f81526020017f787920746f20746865207a65726f20616464726573730000000000000000000081525060400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61048f6106a8565b82604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a161050d81610748565b61051b565b61051a6101f9565b5b50565b60006105286106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561056a576105636106a8565b9050610573565b6105726101f9565b5b90565b61057e6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151515610647576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001807f43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e20667281526020017f6f6d207468652070726f78792061646d696e000000000000000000000000000081525060400191505060405180910390fd5b61064f610777565b565b6000807f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c36001029050805491505090565b3660008037600080366000845af43d6000803e80600081146106a3573d6000f35b3d6000fd5b6000807f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b6001029050805491505090565b6106e281610779565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b60010290508181555050565b565b60006107848261084b565b151561081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001807f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f81526020017f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000081525060400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c360010290508181555050565b600080823b9050600081119150509190505600a165627a7a72305820b31d41a72e81559b9fbd6f52c3db76ab77aeacd5de378d37ab93861a9b684f120029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000001":"0x0000000000000000000000000000000000000000000000000de0b6b3a7640000","0x0000000000000000000000000000000000000000000000000000000000000002":"0x0000000000000000000000000000000000000000000000000de0b6b3a7640000","0x0000000000000000000000000000000000000000000000000000000000000003":"0x00000000000000000000000000000000000000000000021fba3632c84ff80000","0x0000000000000000000000000000000000000000000000000000000000000004":"0x00000000000000000000000000000000000000000000021fba3632c84ff80000","0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b":"0x000000000000000000000000ff9dfbd395cd1c4a4f23c16aa8a5c44109bc17df","0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3":"0x000000000000000000000000c3c45781031885313d5a598042950d6d7be96350"},"balance":"0x0"},"cdca8b1b7edfb0827f10f4ed3968d98fa5c90ea0":{"code":"0x6080604052600436106100c5576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063158ef93e146100ca5780633f4ba83a146100f9578063402300461461011057806341b3d185146101845780635c975abb146101af57806366419970146101de578063715018a6146102095780638456cb59146102205780638da5cb5b146102375780638f449a051461028e578063da35a26f14610298578063f2fde38b146102e5578063fcae448414610328575b600080fd5b3480156100d657600080fd5b506100df61033f565b604051808215151515815260200191505060405180910390f35b34801561010557600080fd5b5061010e610352565b005b34801561011c57600080fd5b5061013b60048036038101908080359060200190929190505050610410565b604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390f35b34801561019057600080fd5b5061019961049f565b6040518082815260200191505060405180910390f35b3480156101bb57600080fd5b506101c46104a5565b604051808215151515815260200191505060405180910390f35b3480156101ea57600080fd5b506101f36104b8565b6040518082815260200191505060405180910390f35b34801561021557600080fd5b5061021e6104c5565b005b34801561022c57600080fd5b506102356105c7565b005b34801561024357600080fd5b5061024c610687565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102966106ac565b005b3480156102a457600080fd5b506102e360048036038101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061073b565b005b3480156102f157600080fd5b50610326600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061084d565b005b34801561033457600080fd5b5061033d6108b4565b005b600060159054906101000a900460ff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156103ad57600080fd5b600060149054906101000a900460ff1615156103c857600080fd5b60008060146101000a81548160ff0219169083151502179055507f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3360405160405180910390a1565b600080600060048481548110151561042457fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169250600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060020154915050915091565b60015481565b600060149054906101000a900460ff1681565b6000600480549050905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561052057600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482060405160405180910390a260008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561062257600080fd5b600060149054906101000a900460ff1615151561063e57600080fd5b6001600060146101000a81548160ff0219169083151502179055507f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62560405160405180910390a1565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060149054906101000a900460ff161515156106c957600080fd5b6106d233610b9b565b1561072f57600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050348160020160008282540192505081905550610738565b610737610bf4565b5b50565b600060159054906101000a900460ff161515156107e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001807f436f6e747261637420696e7374616e63652068617320616c726561647920626581526020017f656e20696e697469616c697a656400000000000000000000000000000000000081525060400191505060405180910390fd5b8160018190555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600060156101000a81548160ff0219169083151502179055505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156108a857600080fd5b6108b181610ce1565b50565b60008060006108c233610b9b565b15156108cd57600080fd5b670de0b6b3a7640000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a035b1fe6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561095c57600080fd5b505af1158015610970573d6000803e3d6000fd5b505050506040513d602081101561098657600080fd5b8101908080519060200190929190505050101515156109a457600080fd5b600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209250826000015491503373ffffffffffffffffffffffffffffffffffffffff166108fc84600201549081150290604051600060405180830381858888f19350505050158015610a36573d6000803e3d6000fd5b50600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000808201600090556001820160006101000a81549060ff0219169055600282016000905550506004600160048054905003815481101515610ab457fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905080600483815481101515610af157fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001819055506004805480919060019003610b959190610ddb565b50505050565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff169050919050565b60006001543410151515610c0757600080fd5b600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600160043390806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555003816000018190555060018160010160006101000a81548160ff02191690831515021790555034816002018190555050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610d1d57600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b815481835581811115610e0257818360005260206000209182019101610e019190610e07565b5b505050565b610e2991905b80821115610e25576000816000905550600101610e0d565b5090565b905600a165627a7a7230582003e9f8a667889c71192d8deb1e6aa5493e226a18e8f0762c904236c8053c7c100029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x0000000000000000000000000e5d0fd336650e663c710ef420f85fb081e21415","0x0000000000000000000000000000000000000000000000000000000000000001":"0x0000000000000000000000000000000000000000000000056bc75e2d63100000","0x0000000000000000000000000000000000000000000000000000000000000002":"0x000000000000000000000000c3c45781031885313d5a598042950d6d7be96350"},"balance":"0x0"},"dfcb946fd93a0ae4056d7d6dca59d59fd830f8a5":{"code":"0x60806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633659cfe6146100775780634f1ef286146100ba5780635c60da1b146101085780638f2839701461015f578063f851a440146101a2575b6100756101f9565b005b34801561008357600080fd5b506100b8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610213565b005b610106600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001908201803590602001919091929391929390505050610268565b005b34801561011457600080fd5b5061011d610308565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561016b57600080fd5b506101a0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610360565b005b3480156101ae57600080fd5b506101b761051e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610201610576565b61021161020c610651565b610682565b565b61021b6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025c57610257816106d9565b610265565b6102646101f9565b5b50565b6102706106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fa576102ac836106d9565b3073ffffffffffffffffffffffffffffffffffffffff163483836040518083838082843782019150509250505060006040518083038185875af19250505015156102f557600080fd5b610303565b6103026101f9565b5b505050565b60006103126106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103545761034d610651565b905061035d565b61035c6101f9565b5b90565b6103686106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561051257600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610466576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001807f43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f81526020017f787920746f20746865207a65726f20616464726573730000000000000000000081525060400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61048f6106a8565b82604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a161050d81610748565b61051b565b61051a6101f9565b5b50565b60006105286106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561056a576105636106a8565b9050610573565b6105726101f9565b5b90565b61057e6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151515610647576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001807f43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e20667281526020017f6f6d207468652070726f78792061646d696e000000000000000000000000000081525060400191505060405180910390fd5b61064f610777565b565b6000807f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c36001029050805491505090565b3660008037600080366000845af43d6000803e80600081146106a3573d6000f35b3d6000fd5b6000807f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b6001029050805491505090565b6106e281610779565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b60010290508181555050565b565b60006107848261084b565b151561081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001807f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f81526020017f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000081525060400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c360010290508181555050565b600080823b9050600081119150509190505600a165627a7a72305820b31d41a72e81559b9fbd6f52c3db76ab77aeacd5de378d37ab93861a9b684f120029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000001":"0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000003":"0x6d55534400000000000000000000000000000000000000000000000000000008","0x0000000000000000000000000000000000000000000000000000000000000004":"0x6d55534400000000000000000000000000000000000000000000000000000008","0x0000000000000000000000000000000000000000000000000000000000000005":"0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000006":"0x00000000000000000000000000000000000000000000065a4da25d3016c00000","0x0000000000000000000000000000000000000000000000000000000000000007":"0x0000000000000000000000000e5d0fd336650e663c710ef420f85fb081e21415","0x0000000000000000000000000000000000000000000000000000000000000008":"0x000000000000000000000000000000000000000003782dace9d9000000000000","0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b":"0x000000000000000000000000ff9dfbd395cd1c4a4f23c16aa8a5c44109bc17df","0x4cf2bf7c4513f31bb90f26db288d81637a55e0204ce44ed81fd8bd44cf72e94d":"0x0000000000000000000000000000000000000000000000000000000000000000","0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3":"0x00000000000000000000000064c2a9cb0220d3e56783ed87cc1b20115bc93f96","0x83a6ad9b45a481c71774303d5fe0197831d788806fafa3028fb2edd9e977cd46":"0x00000000000000000000000000000000000000000000065a4da25d3016c00000"},"balance":"0x0"},"e1adb6075619f52fc00bdd50def1b754b9e7bd17":{"code":"0x60806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633659cfe6146100775780634f1ef286146100ba5780635c60da1b146101085780638f2839701461015f578063f851a440146101a2575b6100756101f9565b005b34801561008357600080fd5b506100b8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610213565b005b610106600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001908201803590602001919091929391929390505050610268565b005b34801561011457600080fd5b5061011d610308565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561016b57600080fd5b506101a0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610360565b005b3480156101ae57600080fd5b506101b761051e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610201610576565b61021161020c610651565b610682565b565b61021b6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025c57610257816106d9565b610265565b6102646101f9565b5b50565b6102706106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fa576102ac836106d9565b3073ffffffffffffffffffffffffffffffffffffffff163483836040518083838082843782019150509250505060006040518083038185875af19250505015156102f557600080fd5b610303565b6103026101f9565b5b505050565b60006103126106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103545761034d610651565b905061035d565b61035c6101f9565b5b90565b6103686106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561051257600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610466576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001807f43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f81526020017f787920746f20746865207a65726f20616464726573730000000000000000000081525060400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61048f6106a8565b82604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a161050d81610748565b61051b565b61051a6101f9565b5b50565b60006105286106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561056a576105636106a8565b9050610573565b6105726101f9565b5b90565b61057e6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151515610647576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001807f43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e20667281526020017f6f6d207468652070726f78792061646d696e000000000000000000000000000081525060400191505060405180910390fd5b61064f610777565b565b6000807f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c36001029050805491505090565b3660008037600080366000845af43d6000803e80600081146106a3573d6000f35b3d6000fd5b6000807f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b6001029050805491505090565b6106e281610779565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b60010290508181555050565b565b60006107848261084b565b151561081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001807f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f81526020017f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000081525060400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c360010290508181555050565b600080823b9050600081119150509190505600a165627a7a72305820b31d41a72e81559b9fbd6f52c3db76ab77aeacd5de378d37ab93861a9b684f120029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x00000000000000000000004195b06a6e4d5bedde15165e01a64f324f03d5d101","0x0000000000000000000000000000000000000000000000000000000000000001":"0xbc25ce339c62a23a50c9bdae4aba9cb6dab4cefd53d1501dcbf2eec2583d200e","0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b":"0x000000000000000000000000ff9dfbd395cd1c4a4f23c16aa8a5c44109bc17df","0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3":"0x000000000000000000000000e95d0d373e2fd320b84aac705434b67b905092ae"},"balance":"0x0"},"e95d0d373e2fd320b84aac705434b67b905092ae":{"code":"0x608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063158ef93e1461005c578063be13f47c1461008b578063d22057a9146100dc575b600080fd5b34801561006857600080fd5b5061007161012d565b604051808215151515815260200191505060405180910390f35b34801561009757600080fd5b506100da600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560001916906020019092919050505061013f565b005b3480156100e857600080fd5b5061012b6004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610253565b005b6000809054906101000a900460ff1681565b6000809054906101000a900460ff161515156101e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001807f436f6e747261637420696e7374616e63652068617320616c726561647920626581526020017f656e20696e697469616c697a656400000000000000000000000000000000000081525060400191505060405180910390fd5b81600060016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806001816000191690555060016000806101000a81548160ff0219169083151502179055505050565b8160008060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be36001548460405180836000191660001916815260200182600019166000191681526020019250505060405180910390206040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b15801561031d57600080fd5b505af1158015610331573d6000803e3d6000fd5b505050506040513d602081101561034757600080fd5b8101908080519060200190929190505050905060008173ffffffffffffffffffffffffffffffffffffffff1614806103aa57503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b15156103b557600080fd5b600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306ab592360015486866040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180846000191660001916815260200183600019166000191681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019350505050600060405180830381600087803b15801561049457600080fd5b505af11580156104a8573d6000803e3d6000fd5b50505050505050505600a165627a7a723058205053cd7ff3b82a7e6e8531ed12a7195800886445328be2a9911c057f02b1f0cf0029","storage":{"0x0000000000000000000000000000000000000000000000000000000000000000":"0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001":"0x0000000000000000000000000000000000000000000000000000000000000000"},"balance":"0x0"}},"number":"0x0","parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000"} diff --git a/client/knode/genesis/tracer.go b/client/knode/genesis/tracer.go index 20999d1ac..49bcc2a02 100644 --- a/client/knode/genesis/tracer.go +++ b/client/knode/genesis/tracer.go @@ -22,7 +22,7 @@ func newVmTracer() *vmTracer { } } -func (vmt *vmTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error { +func (vmt *vmTracer) CaptureState(env *vm.VM, pc uint64, op vm.OpCode, resource, cost uint64, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error { if err != nil { return err } @@ -52,14 +52,14 @@ func (vmt *vmTracer) setAddrStorage(contractAddress common.Address, addrStorage vmt.Unlock() } -func (vmt *vmTracer) CaptureStart(from common.Address, to common.Address, call bool, input []byte, gas uint64, value *big.Int) error { +func (vmt *vmTracer) CaptureStart(from common.Address, to common.Address, call bool, input []byte, resource uint64, value *big.Int) error { return nil } -func (vmt *vmTracer) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error { +func (vmt *vmTracer) CaptureEnd(output []byte, resourceUsage uint64, t time.Duration, err error) error { return nil } -func (vmt *vmTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error { +func (vmt *vmTracer) CaptureFault(env *vm.VM, pc uint64, op vm.OpCode, resource, cost uint64, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error { return nil } diff --git a/client/knode/protocol.go b/client/knode/protocol.go index b3f791be4..77b732ac2 100644 --- a/client/knode/protocol.go +++ b/client/knode/protocol.go @@ -66,14 +66,13 @@ var errorToString = map[int]string{ ErrSuspendedPeer: "Suspended peer", } - type txPool interface { // AddRemotes should add the given transactions to the pool. AddRemotes([]*types.Transaction) []error // Pending should return pending transactions. // The slice should be modifiable by the caller. - Pending() (map[common.Address]types.Transactions, error) + Pending() map[common.Address]types.Transactions // SubscribeNewTxsEvent should return an event subscription of // NewTxsEvent and send events to the given channel. diff --git a/client/knode/service.go b/client/knode/service.go index 975ab6d1c..87225ccd9 100644 --- a/client/knode/service.go +++ b/client/knode/service.go @@ -31,7 +31,6 @@ import ( "github.com/kowala-tech/kcoin/client/kcoindb" "github.com/kowala-tech/kcoin/client/knode/downloader" "github.com/kowala-tech/kcoin/client/knode/filters" - "github.com/kowala-tech/kcoin/client/knode/gasprice" "github.com/kowala-tech/kcoin/client/knode/protocol" "github.com/kowala-tech/kcoin/client/knode/validator" "github.com/kowala-tech/kcoin/client/log" @@ -78,14 +77,13 @@ type Kowala struct { bindingFuncs []BindingConstructor // binding constructors (in dependency order) contracts map[reflect.Type]bindings.Binding - gasPrice *big.Int coinbase common.Address deposit *big.Int networkID uint64 netRPCService *kcoinapi.PublicNetAPI - lock sync.RWMutex // Protects the variadic fields (e.g. gas price and coinbase) + lock sync.RWMutex // Protects the variadic fields (e.g. coinbase) serverPool *serverPool } @@ -116,7 +114,6 @@ func New(ctx *node.ServiceContext, config *Config) (*Kowala, error) { accountManager: ctx.AccountManager, shutdownChan: make(chan bool), networkID: config.NetworkId, - gasPrice: config.GasPrice, coinbase: config.Coinbase, deposit: config.Deposit, bloomRequests: make(chan chan *bloombits.Retrieval), @@ -132,7 +129,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Kowala, error) { log.Info("Initialising Kowala protocol", "versions", protocol.Constants.Versions, "network", config.NetworkId) - kcoin.apiBackend = &KowalaAPIBackend{kcoin, nil} + kcoin.apiBackend = &KowalaAPIBackend{kcoin} // consensus engine kcoin.engine = CreateConsensusEngine(ctx, kcoin.config, kcoin.chainConfig, kcoin.chainDb) @@ -192,12 +189,6 @@ func New(ctx *node.ServiceContext, config *Config) (*Kowala, error) { } kcoin.txPool = core.NewTxPool(config.TxPool, kcoin.chainConfig, kcoin.blockchain) - gpoParams := config.GPO - if gpoParams.Default == nil { - gpoParams.Default = config.GasPrice - } - kcoin.apiBackend.gpo = gasprice.NewOracle(kcoin.apiBackend, gpoParams) - kcoin.validator = validator.New(kcoin, kcoin.consensus, kcoin.chainConfig, kcoin.EventMux(), kcoin.engine, vmConfig) kcoin.validator.SetExtra(makeExtraData(config.ExtraData)) @@ -466,12 +457,6 @@ func (s *Kowala) Start(srvr *p2p.Server) error { // Figure out a max peers count based on the server limits maxPeers := srvr.MaxPeers - if s.config.LightServ > 0 { - maxPeers -= s.config.LightPeers - if maxPeers < srvr.MaxPeers/2 { - maxPeers = srvr.MaxPeers / 2 - } - } //fixme: should be removed after develop light client if srvr.DiscoveryV5 { diff --git a/client/knode/sync.go b/client/knode/sync.go index 1799c99fa..eb8234a39 100644 --- a/client/knode/sync.go +++ b/client/knode/sync.go @@ -29,8 +29,7 @@ type txsync struct { // syncTransactions starts sending all currently pending transactions to the given peer. func (pm *ProtocolManager) syncTransactions(p *peer) { var txs types.Transactions - pending, _ := pm.txpool.Pending() - for _, batch := range pending { + for _, batch := range pm.txpool.Pending() { txs = append(txs, batch...) } if len(txs) == 0 { diff --git a/client/knode/tracers/tracer.go b/client/knode/tracers/tracer.go index dce5d6997..e59292177 100644 --- a/client/knode/tracers/tracer.go +++ b/client/knode/tracers/tracer.go @@ -277,7 +277,7 @@ func (cw *contractWrapper) pushObject(vm *duktape.Context) { // Tracer provides an implementation of Tracer that evaluates a Javascript // function for each VM execution step. type Tracer struct { - inited bool // Flag whether the context was already inited from the EVM + initialized bool // Flag whether the context was already initialized from the VM vm *duktape.Context // Javascript VM instance @@ -290,11 +290,11 @@ type Tracer struct { contractWrapper *contractWrapper // Wrapper around the contract object dbWrapper *dbWrapper // Wrapper around the VM environment - pcValue *uint // Swappable pc value wrapped by a log accessor - gasValue *uint // Swappable gas value wrapped by a log accessor - costValue *uint // Swappable cost value wrapped by a log accessor - depthValue *uint // Swappable depth value wrapped by a log accessor - errorValue *string // Swappable error value wrapped by a log accessor + pcValue *uint // Swappable pc value wrapped by a log accessor + resourceValue *uint // Swappable resource value wrapped by a log accessor + costValue *uint // Swappable cost value wrapped by a log accessor + depthValue *uint // Swappable depth value wrapped by a log accessor + errorValue *string // Swappable error value wrapped by a log accessor ctx map[string]interface{} // Transaction context gathered throughout execution err error // Error, if one has occurred @@ -320,7 +320,7 @@ func New(code string) (*Tracer, error) { contractWrapper: new(contractWrapper), dbWrapper: new(dbWrapper), pcValue: new(uint), - gasValue: new(uint), + resourceValue: new(uint), costValue: new(uint), depthValue: new(uint), } @@ -433,8 +433,8 @@ func New(code string) (*Tracer, error) { tracer.vm.PushGoFunction(func(ctx *duktape.Context) int { ctx.PushUint(*tracer.pcValue); return 1 }) tracer.vm.PutPropString(logObject, "getPC") - tracer.vm.PushGoFunction(func(ctx *duktape.Context) int { ctx.PushUint(*tracer.gasValue); return 1 }) - tracer.vm.PutPropString(logObject, "getGas") + tracer.vm.PushGoFunction(func(ctx *duktape.Context) int { ctx.PushUint(*tracer.resourceValue); return 1 }) + tracer.vm.PutPropString(logObject, "getResource") tracer.vm.PushGoFunction(func(ctx *duktape.Context) int { ctx.PushUint(*tracer.costValue); return 1 }) tracer.vm.PutPropString(logObject, "getCost") @@ -495,7 +495,7 @@ func wrapError(context string, err error) error { } // CaptureStart implements the Tracer interface to initialize the tracing operation. -func (jst *Tracer) CaptureStart(from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) error { +func (jst *Tracer) CaptureStart(from common.Address, to common.Address, create bool, input []byte, resource uint64, value *big.Int) error { jst.ctx["type"] = "CALL" if create { jst.ctx["type"] = "CREATE" @@ -503,19 +503,19 @@ func (jst *Tracer) CaptureStart(from common.Address, to common.Address, create b jst.ctx["from"] = from jst.ctx["to"] = to jst.ctx["input"] = input - jst.ctx["gas"] = gas + jst.ctx["resource"] = resource jst.ctx["value"] = value return nil } // CaptureState implements the Tracer interface to trace a single step of VM execution. -func (jst *Tracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error { +func (jst *Tracer) CaptureState(env *vm.VM, pc uint64, op vm.OpCode, resource, cost uint64, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error { if jst.err == nil { // Initialize the context if it wasn't done yet - if !jst.inited { + if !jst.initialized { jst.ctx["block"] = env.BlockNumber.Uint64() - jst.inited = true + jst.initialized = true } // If tracing was interrupted, set the error and stop if atomic.LoadUint32(&jst.interrupt) > 0 { @@ -529,7 +529,7 @@ func (jst *Tracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost jst.dbWrapper.db = env.StateDB *jst.pcValue = uint(pc) - *jst.gasValue = uint(gas) + *jst.resourceValue = uint(resource) *jst.costValue = uint(cost) *jst.depthValue = uint(depth) @@ -548,7 +548,7 @@ func (jst *Tracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost // CaptureFault implements the Tracer interface to trace an execution fault // while running an opcode. -func (jst *Tracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error { +func (jst *Tracer) CaptureFault(env *vm.VM, pc uint64, op vm.OpCode, resource, cost uint64, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error { if jst.err == nil { // Apart from the error, everything matches the previous invocation jst.errorValue = new(string) @@ -563,9 +563,9 @@ func (jst *Tracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost } // CaptureEnd is called after the call finishes to finalize the tracing. -func (jst *Tracer) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error { +func (jst *Tracer) CaptureEnd(output []byte, resourceUsage uint64, t time.Duration, err error) error { jst.ctx["output"] = output - jst.ctx["gasUsed"] = gasUsed + jst.ctx["resourceUsage"] = resourceUsage jst.ctx["time"] = t.String() if err != nil { diff --git a/client/knode/tracers/tracer_test.go b/client/knode/tracers/tracer_test.go index 21d3460ff..a1efcfd51 100644 --- a/client/knode/tracers/tracer_test.go +++ b/client/knode/tracers/tracer_test.go @@ -39,12 +39,12 @@ func (account) SetBalance(*big.Int) {} func (account) SetNonce(uint64) {} func (account) Balance() *big.Int { return nil } func (account) Address() common.Address { return common.Address{} } -func (account) ReturnGas(*big.Int) {} +func (account) ReturnResourceUsage(*big.Int) {} func (account) SetCode(common.Hash, []byte) {} func (account) ForEachStorage(cb func(key, value common.Hash) bool) {} func runTrace(tracer *Tracer) (json.RawMessage, error) { - env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) + env := vm.New(vm.Context{BlockNumber: big.NewInt(1)}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) contract := vm.NewContract(account{}, account{}, big.NewInt(0), 10000) contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0} @@ -126,7 +126,7 @@ func TestHaltBetweenSteps(t *testing.T) { t.Fatal(err) } - env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) + env := vm.New(vm.Context{BlockNumber: big.NewInt(1)}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) contract := vm.NewContract(&account{}, &account{}, big.NewInt(0), 0) tracer.CaptureState(env, 0, 0, 0, 0, nil, nil, contract, 0, nil) diff --git a/client/knode/tracers/tracers_test.go b/client/knode/tracers/tracers_test.go deleted file mode 100644 index f0649ac2c..000000000 --- a/client/knode/tracers/tracers_test.go +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package tracers - -import ( - "encoding/json" - "io/ioutil" - "math/big" - "path/filepath" - "reflect" - "strings" - "testing" - - "github.com/kowala-tech/kcoin/client/common" - "github.com/kowala-tech/kcoin/client/common/hexutil" - "github.com/kowala-tech/kcoin/client/common/math" - "github.com/kowala-tech/kcoin/client/core" - "github.com/kowala-tech/kcoin/client/core/types" - "github.com/kowala-tech/kcoin/client/core/vm" - "github.com/kowala-tech/kcoin/client/kcoindb" - "github.com/kowala-tech/kcoin/client/rlp" - "github.com/kowala-tech/kcoin/client/tests" -) - -// To generate a new callTracer test, copy paste the makeTest method below into -// a Geth console and call it with a transaction hash you which to export. - -/* -// makeTest generates a callTracer test by running a prestate reassembled and a -// call trace run, assembling all the gathered information into a test case. -var makeTest = function(tx, rewind) { - // Generate the genesis block from the block, transaction and prestate data - var block = eth.getBlock(eth.getTransaction(tx).blockHash); - var genesis = eth.getBlock(block.parentHash); - - delete genesis.gasUsed; - delete genesis.logsBloom; - delete genesis.parentHash; - delete genesis.receiptsRoot; - delete genesis.sha3Uncles; - delete genesis.size; - delete genesis.transactions; - delete genesis.transactionsRoot; - delete genesis.uncles; - - genesis.gasLimit = genesis.gasLimit.toString(); - genesis.number = genesis.number.toString(); - genesis.timestamp = genesis.timestamp.toString(); - - genesis.alloc = debug.traceTransaction(tx, {tracer: "prestateTracer", rewind: rewind}); - for (var key in genesis.alloc) { - genesis.alloc[key].nonce = genesis.alloc[key].nonce.toString(); - } - genesis.config = admin.nodeInfo.protocols.eth.config; - - // Generate the call trace and produce the test input - var result = debug.traceTransaction(tx, {tracer: "callTracer", rewind: rewind}); - delete result.time; - - console.log(JSON.stringify({ - genesis: genesis, - context: { - number: block.number.toString(), - difficulty: block.difficulty, - timestamp: block.timestamp.toString(), - gasLimit: block.gasLimit.toString(), - miner: block.miner, - }, - input: eth.getRawTransaction(tx), - result: result, - }, null, 2)); -} -*/ - -// callTrace is the result of a callTracer run. -type callTrace struct { - Type string `json:"type"` - From common.Address `json:"from"` - To common.Address `json:"to"` - Input hexutil.Bytes `json:"input"` - Output hexutil.Bytes `json:"output"` - Gas *hexutil.Uint64 `json:"gas,omitempty"` - GasUsed *hexutil.Uint64 `json:"gasUsed,omitempty"` - Value *hexutil.Big `json:"value,omitempty"` - Error string `json:"error,omitempty"` - Calls []callTrace `json:"calls,omitempty"` -} - -type callContext struct { - Number math.HexOrDecimal64 `json:"number"` - Difficulty *math.HexOrDecimal256 `json:"difficulty"` - Time math.HexOrDecimal64 `json:"timestamp"` - GasLimit math.HexOrDecimal64 `json:"gasLimit"` - Miner common.Address `json:"miner"` -} - -// callTracerTest defines a single test to check the call tracer against. -type callTracerTest struct { - Genesis *core.Genesis `json:"genesis"` - Context *callContext `json:"context"` - Input string `json:"input"` - Result *callTrace `json:"result"` -} - -// Iterates over all the input-output datasets in the tracer test harness and -// runs the JavaScript tracers against them. -func TestCallTracer(t *testing.T) { - files, err := ioutil.ReadDir("testdata") - if err != nil { - t.Fatalf("failed to retrieve tracer test suite: %v", err) - } - for _, file := range files { - if !strings.HasPrefix(file.Name(), "call_tracer_") { - continue - } - file := file // capture range variable - t.Run(camel(strings.TrimSuffix(strings.TrimPrefix(file.Name(), "call_tracer_"), ".json")), func(t *testing.T) { - t.Parallel() - - // Call tracer test found, read if from disk - blob, err := ioutil.ReadFile(filepath.Join("testdata", file.Name())) - if err != nil { - t.Fatalf("failed to read testcase: %v", err) - } - test := new(callTracerTest) - if err := json.Unmarshal(blob, test); err != nil { - t.Fatalf("failed to parse testcase: %v", err) - } - // Configure a blockchain with the given prestate - tx := new(types.Transaction) - if err := rlp.DecodeBytes(common.FromHex(test.Input), tx); err != nil { - t.Fatalf("failed to parse testcase input: %v", err) - } - signer := types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number))) - origin, _ := signer.Sender(tx) - - context := vm.Context{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, - Origin: origin, - Coinbase: test.Context.Miner, - BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)), - Time: new(big.Int).SetUint64(uint64(test.Context.Time)), - Difficulty: (*big.Int)(test.Context.Difficulty), - GasLimit: uint64(test.Context.GasLimit), - GasPrice: tx.GasPrice(), - } - statedb := tests.MakePreState(kcoindb.NewMemDatabase(), test.Genesis.Alloc) - - // Create the tracer, the EVM environment and run it - tracer, err := New("callTracer") - if err != nil { - t.Fatalf("failed to create call tracer: %v", err) - } - evm := vm.NewEVM(context, statedb, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer}) - - msg, err := tx.AsMessage(signer) - if err != nil { - t.Fatalf("failed to prepare transaction for tracing: %v", err) - } - st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) - if _, _, _, err = st.TransitionDb(); err != nil { - t.Fatalf("failed to execute transaction: %v", err) - } - // Retrieve the trace result and compare against the etalon - res, err := tracer.GetResult() - if err != nil { - t.Fatalf("failed to retrieve trace result: %v", err) - } - ret := new(callTrace) - if err := json.Unmarshal(res, ret); err != nil { - t.Fatalf("failed to unmarshal trace result: %v", err) - } - if !reflect.DeepEqual(ret, test.Result) { - t.Fatalf("trace mismatch: have %+v, want %+v", ret, test.Result) - } - }) - } -} diff --git a/client/knode/validator/validator.go b/client/knode/validator/validator.go index 8d476d2e6..b760a79eb 100644 --- a/client/knode/validator/validator.go +++ b/client/knode/validator/validator.go @@ -326,8 +326,8 @@ func (val *validator) AddVote(vote *types.Vote) error { return nil } -func (val *validator) commitTransactions(mux *event.TypeMux, txs *types.TransactionsByPriceAndNonce, bc *core.BlockChain, coinbase common.Address) { - gp := new(core.GasPool).AddGas(val.header.GasLimit) +func (val *validator) commitTransactions(mux *event.TypeMux, txs *core.TransactionsByTimestampAndNonce, bc *core.BlockChain, coinbase common.Address) { + crpool := new(core.ComputationalResourcePool).AddResource(params.ComputeCapacity) var coalescedLogs []*types.Log @@ -339,17 +339,15 @@ func (val *validator) commitTransactions(mux *event.TypeMux, txs *types.Transact } // Error may be ignored here. The error has already been checked // during transaction acceptance is the transaction pool. - // - // We use the eip155 signer regardless of the current hf. from, _ := types.TxSender(val.signer, tx) // Start executing the transaction val.state.Prepare(tx.Hash(), common.Hash{}, val.tcount) - err, logs := val.commitTransaction(tx, bc, coinbase, gp) + logs, err := val.commitTransaction(tx, bc, coinbase, crpool) switch err { - case core.ErrGasLimitReached: - // Pop the current out-of-gas transaction without shifting in the next from the account + case core.ErrComputeCapacityReached: + // Pop the current out-of-computational-resource transaction without shifting in the next from the account log.Trace("Gas limit exceeded for current block", "sender", from) txs.Pop() @@ -360,7 +358,7 @@ func (val *validator) commitTransactions(mux *event.TypeMux, txs *types.Transact case core.ErrNonceTooHigh: // Reorg notification data race between the transaction pool and miner, skip account = - log.Trace("Skipping account with hight nonce", "sender", from, "nonce", tx.Nonce()) + log.Trace("Skipping account with high nonce", "sender", from, "nonce", tx.Nonce()) txs.Pop() case nil: @@ -397,18 +395,18 @@ func (val *validator) commitTransactions(mux *event.TypeMux, txs *types.Transact } } -func (val *validator) commitTransaction(tx *types.Transaction, bc *core.BlockChain, coinbase common.Address, gp *core.GasPool) (error, []*types.Log) { +func (val *validator) commitTransaction(tx *types.Transaction, bc *core.BlockChain, coinbase common.Address, crpool *core.ComputationalResourcePool) ([]*types.Log, error) { snap := val.state.Snapshot() - receipt, _, err := core.ApplyTransaction(val.config, bc, &coinbase, gp, val.state, val.header, tx, &val.header.GasUsed, vm.Config{}) + receipt, _, err := core.ApplyTransaction(val.config, bc, &coinbase, crpool, val.state, val.header, tx, &val.header.ResourceUsage, vm.Config{}) if err != nil { val.state.RevertToSnapshot(snap) - return err, nil + return nil, err } val.txs = append(val.txs, tx) val.receipts = append(val.receipts, receipt) - return nil, receipt.Logs + return receipt.Logs, nil } func (val *validator) leave() { @@ -435,6 +433,9 @@ func (val *validator) createProposalBlock() *types.Block { func (val *validator) createBlock() *types.Block { log.Info("Creating a new block") + + var err error + // new block header parent := val.chain.CurrentBlock() blockNumber := parent.Number() @@ -447,7 +448,6 @@ func (val *validator) createBlock() *types.Block { ParentHash: parent.Hash(), Coinbase: val.walletAccount.Account().Address, Number: blockNumber.Add(blockNumber, common.Big1), - GasLimit: core.CalcGasLimit(parent), Time: big.NewInt(tstamp), ValidatorsHash: val.voters.Hash(), } @@ -474,13 +474,7 @@ func (val *validator) createBlock() *types.Block { return nil } - pending, err := val.backend.TxPool().Pending() - if err != nil { - log.Crit("Failed to fetch pending transactions", "err", err) - } - - txs := types.NewTransactionsByPriceAndNonce(val.signer, pending) - val.commitTransactions(val.eventMux, txs, val.chain, val.walletAccount.Account().Address) + val.commitTransactions(val.eventMux, val.backend.TxPool().Transactions(), val.chain, val.walletAccount.Account().Address) // Create the new block to seal with the consensus engine var block *types.Block diff --git a/client/node/config.go b/client/node/config.go index a7a122a02..43bd20589 100644 --- a/client/node/config.go +++ b/client/node/config.go @@ -410,12 +410,6 @@ func makeAccountManager(conf *Config) (*accounts.Manager, string, error) { } else { backends = append(backends, ledgerhub) } - // Start a USB hub for Trezor hardware wallets - if trezorhub, err := usbwallet.NewTrezorHub(); err != nil { - log.Warn(fmt.Sprintf("Failed to start Trezor hub, disabling: %v", err)) - } else { - backends = append(backends, trezorhub) - } } return accounts.NewManager(backends...), ephemeral, nil } diff --git a/client/params/config.go b/client/params/config.go index a1fb3bbac..9455b655a 100644 --- a/client/params/config.go +++ b/client/params/config.go @@ -5,6 +5,7 @@ import ( "math/big" "github.com/kowala-tech/kcoin/client/common" + "github.com/kowala-tech/kcoin/client/params/effort" ) var ( @@ -73,11 +74,11 @@ func (c *ChainConfig) String() string { ) } -// GasTable returns the gas table corresponding to the current phase (andromeda). +// ComputationalRequirements returns the computational requirements table corresponding to the current phase (andromeda). // -// The returned GasTable's fields shouldn't, under any circumstances, be changed. -func (c *ChainConfig) GasTable(num *big.Int) GasTable { - return GasTableAndromeda +// The returned Table's fields shouldn't, under any circumstances, be changed. +func (c *ChainConfig) ComputationalRequirements(num *big.Int) effort.Table { + return effort.TableAndromeda } // CheckCompatible checks whether scheduled fork transitions have been imported diff --git a/client/params/currency.go b/client/params/currency.go new file mode 100644 index 000000000..39dc5ef35 --- /dev/null +++ b/client/params/currency.go @@ -0,0 +1,5 @@ +package params + +const ( + KUSD = "kusd" +) diff --git a/client/params/effort/comp_effort.go b/client/params/effort/comp_effort.go new file mode 100644 index 000000000..8ef0eb1f7 --- /dev/null +++ b/client/params/effort/comp_effort.go @@ -0,0 +1,47 @@ +package effort + +// computational effort for different operations +const ( + ExpByte uint64 = 10 // Times ceil(log256(exponent)) for the EXP instruction. + Sload uint64 = 50 // Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added. + CallValueTransfer uint64 = 9000 // Paid for CALL when the value transfer is non-zero. + CallNewAccount uint64 = 25000 // Paid for CALL when the destination address didn't exist prior. + Tx uint64 = 21000 // Per transaction not creating a contract. NOTE: Not payable on data of calls between transactions. + TxContractCreation uint64 = 53000 // Per transaction that creates a contract. NOTE: Not payable on data of calls between transactions. + TxDataZero uint64 = 4 // Per byte of data attached to a transaction that equals zero. NOTE: Not payable on data of calls between transactions. + QuadCoeffDiv uint64 = 512 // Divisor for the quadratic particle of the memory cost equation. + SstoreSet uint64 = 20000 // Once per SLOAD operation. + LogData uint64 = 8 // Per byte in a LOG* operation's data. + CallStipend uint64 = 2300 // Free computational resources given at beginning of call. + + Sha3 uint64 = 30 // Once per SHA3 operation. + Sha3Word uint64 = 6 // Once per word of the SHA3 operation's data. + SstoreReset uint64 = 5000 // Once per SSTORE operation if the zeroness changes from zero. + SstoreClear uint64 = 5000 // Once per SSTORE operation if the zeroness doesn't change. + SstoreRefund uint64 = 15000 // Once per SSTORE operation if the zeroness changes to zero. + Jumpdest uint64 = 1 // Refunded computational resources, once per SSTORE operation if the zeroness changes to zero. + Call uint64 = 40 // Once per CALL operation & message call transaction. + CreateData uint64 = 200 // + Exp uint64 = 10 // Once per EXP instruction + Log uint64 = 375 // Per LOG* operation. + Copy uint64 = 3 // + TierStep uint64 = 0 // Once per operation, for a selection of them. + LogTopic uint64 = 375 // Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas. + Create uint64 = 32000 // Once per CREATE operation & contract-creation transaction. + SuicideRefund uint64 = 24000 // Refunded following a suicide operation. + Memory uint64 = 3 // Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL. + TxDataNonZero uint64 = 68 // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions. + + Ecrecover uint64 = 3000 // Elliptic curve sender recovery computational effort + Sha256Base uint64 = 60 // Base price for a SHA256 operation + Sha256PerWord uint64 = 12 // Per-word price for a SHA256 operation + Ripemd160Base uint64 = 600 // Base price for a RIPEMD160 operation + Ripemd160PerWord uint64 = 120 // Per-word price for a RIPEMD160 operation + IdentityBase uint64 = 15 // Base price for a data copy operation + IdentityPerWord uint64 = 3 // Per-work price for a data copy operation + ModExpQuadCoeffDiv uint64 = 20 // Divisor for the quadratic particle of the big int modular exponentiation + Bn256Add uint64 = 500 // computational resources needed for an elliptic curve addition + Bn256ScalarMul uint64 = 40000 // computational resources needed for an elliptic curve scalar multiplication + Bn256PairingBase uint64 = 100000 // Base price for an elliptic curve pairing check + Bn256PairingPerPoint uint64 = 80000 // Per-point price for an elliptic curve pairing check +) diff --git a/client/params/gas_table.go b/client/params/effort/table.go similarity index 73% rename from client/params/gas_table.go rename to client/params/effort/table.go index 0e8aa75b7..88bec67cc 100644 --- a/client/params/gas_table.go +++ b/client/params/effort/table.go @@ -1,7 +1,7 @@ -package params +package effort -// GasTable organizes gas prices for different kowala phases. -type GasTable struct { +// Table organizes computational requirements for different kowala phases. +type Table struct { ExtcodeSize uint64 ExtcodeCopy uint64 Balance uint64 @@ -20,9 +20,9 @@ type GasTable struct { } var ( - // GasTableAndromeda contain the gas prices for + // TableAndromeda contains the computational requirements for // the andromeda phase. - GasTableAndromeda = GasTable{ + TableAndromeda = Table{ ExtcodeSize: 700, ExtcodeCopy: 700, Balance: 400, diff --git a/client/params/network.go b/client/params/network.go new file mode 100644 index 000000000..1721b53fc --- /dev/null +++ b/client/params/network.go @@ -0,0 +1,33 @@ +package params + +import "math/big" + +// These are network parameters that need to be constant between clients, but +// aren't necesarilly consensus related. + +var ( + // ComputeUnitPrice represents the networks' fixed compute unit price (400 Gwei/Shannon) + ComputeUnitPrice = new(big.Int).Mul(new(big.Int).SetUint64(400), new(big.Int).SetUint64(Shannon)) +) + +const ( + // ComputeCapacity represents the network's compute capacity per block + ComputeCapacity uint64 = 4712388 + + // MinComputeCapacity is the minimum the compute capacity that may ever be. + MinComputeCapacity uint64 = 5000 + + // HDCoinType hierarchical deterministic wallet coin_type (SLIP-44) + HDCoinType = 91927009 + + // BloomBitsBlocks is the number of blocks a single bloom bit section vector + // contains. + BloomBitsBlocks uint64 = 4096 + + // MaximumExtraDataSize maximum size extra data may be after Genesis. + MaximumExtraDataSize uint64 = 32 + + MaxCodeSize = 24576 + + EpochDuration uint64 = 30000 +) diff --git a/client/params/network_params.go b/client/params/network_params.go deleted file mode 100644 index 31d081a17..000000000 --- a/client/params/network_params.go +++ /dev/null @@ -1,15 +0,0 @@ -package params - -// These are network parameters that need to be constant between clients, but -// aren't necesarilly consensus related. -const ( - // BloomBitsBlocks is the number of blocks a single bloom bit section vector - // contains. - BloomBitsBlocks uint64 = 4096 - // MaximumExtraDataSize maximum size extra data may be after Genesis. - MaximumExtraDataSize uint64 = 32 - MaxCodeSize = 24576 - EpochDuration uint64 = 30000 - // HDCoinType hierarchical deterministic wallet coin_type (SLIP-44) - HDCoinType = 91927009 -) diff --git a/client/params/protocol.go b/client/params/protocol.go new file mode 100644 index 000000000..9a82f9fd5 --- /dev/null +++ b/client/params/protocol.go @@ -0,0 +1,20 @@ +package params + +// Proof-of-stake timeouts +const ( + ProposeDuration uint64 = 500 + ProposeDeltaDuration uint64 = 25 + PreVoteDuration uint64 = 200 + PreVoteDeltaDuration uint64 = 25 + PreCommitDuration uint64 = 200 + PreCommitDeltaDuration uint64 = 25 + BlockTime uint64 = 1000 +) + +const ( + // CallCreateDepth maximum depth of call/create stack + CallCreateDepth uint64 = 1024 + + // StackLimit is the maximum size of VM stack allowed. + StackLimit uint64 = 1024 +) diff --git a/client/params/protocol_params.go b/client/params/protocol_params.go deleted file mode 100644 index 570197067..000000000 --- a/client/params/protocol_params.go +++ /dev/null @@ -1,67 +0,0 @@ -package params - -var ( - TargetGasLimit = GenesisGasLimit // The artificial target -) - -const ( - GasLimitBoundDivisor uint64 = 1024 // The bound divisor of the gas limit, used in update calculations. - MinGasLimit uint64 = 5000 // Minimum the gas limit may ever be. - GenesisGasLimit uint64 = 4712388 // Gas limit of the Genesis block. - - ExpByteGas uint64 = 10 // Times ceil(log256(exponent)) for the EXP instruction. - SloadGas uint64 = 50 // Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added. - CallValueTransferGas uint64 = 9000 // Paid for CALL when the value transfer is non-zero. - CallNewAccountGas uint64 = 25000 // Paid for CALL when the destination address didn't exist prior. - TxGas uint64 = 21000 // Per transaction not creating a contract. NOTE: Not payable on data of calls between transactions. - TxGasContractCreation uint64 = 53000 // Per transaction that creates a contract. NOTE: Not payable on data of calls between transactions. - TxDataZeroGas uint64 = 4 // Per byte of data attached to a transaction that equals zero. NOTE: Not payable on data of calls between transactions. - QuadCoeffDiv uint64 = 512 // Divisor for the quadratic particle of the memory cost equation. - SstoreSetGas uint64 = 20000 // Once per SLOAD operation. - LogDataGas uint64 = 8 // Per byte in a LOG* operation's data. - CallStipend uint64 = 2300 // Free gas given at beginning of call. - - Sha3Gas uint64 = 30 // Once per SHA3 operation. - Sha3WordGas uint64 = 6 // Once per word of the SHA3 operation's data. - SstoreResetGas uint64 = 5000 // Once per SSTORE operation if the zeroness changes from zero. - SstoreClearGas uint64 = 5000 // Once per SSTORE operation if the zeroness doesn't change. - SstoreRefundGas uint64 = 15000 // Once per SSTORE operation if the zeroness changes to zero. - JumpdestGas uint64 = 1 // Refunded gas, once per SSTORE operation if the zeroness changes to zero. - CallGas uint64 = 40 // Once per CALL operation & message call transaction. - CreateDataGas uint64 = 200 // - CallCreateDepth uint64 = 1024 // Maximum depth of call/create stack. - ExpGas uint64 = 10 // Once per EXP instruction - LogGas uint64 = 375 // Per LOG* operation. - CopyGas uint64 = 3 // - StackLimit uint64 = 1024 // Maximum size of VM stack allowed. - TierStepGas uint64 = 0 // Once per operation, for a selection of them. - LogTopicGas uint64 = 375 // Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas. - CreateGas uint64 = 32000 // Once per CREATE operation & contract-creation transaction. - SuicideRefundGas uint64 = 24000 // Refunded following a suicide operation. - MemoryGas uint64 = 3 // Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL. - TxDataNonZeroGas uint64 = 68 // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions. - - // Precompiled contract gas prices - - EcrecoverGas uint64 = 3000 // Elliptic curve sender recovery gas price - Sha256BaseGas uint64 = 60 // Base price for a SHA256 operation - Sha256PerWordGas uint64 = 12 // Per-word price for a SHA256 operation - Ripemd160BaseGas uint64 = 600 // Base price for a RIPEMD160 operation - Ripemd160PerWordGas uint64 = 120 // Per-word price for a RIPEMD160 operation - IdentityBaseGas uint64 = 15 // Base price for a data copy operation - IdentityPerWordGas uint64 = 3 // Per-work price for a data copy operation - ModExpQuadCoeffDiv uint64 = 20 // Divisor for the quadratic particle of the big int modular exponentiation - Bn256AddGas uint64 = 500 // Gas needed for an elliptic curve addition - Bn256ScalarMulGas uint64 = 40000 // Gas needed for an elliptic curve scalar multiplication - Bn256PairingBaseGas uint64 = 100000 // Base price for an elliptic curve pairing check - Bn256PairingPerPointGas uint64 = 80000 // Per-point price for an elliptic curve pairing check - - // Proof of Stake - timeouts - ProposeDuration uint64 = 500 - ProposeDeltaDuration uint64 = 25 - PreVoteDuration uint64 = 200 - PreVoteDeltaDuration uint64 = 25 - PreCommitDuration uint64 = 200 - PreCommitDeltaDuration uint64 = 25 - BlockTime uint64 = 1000 -) diff --git a/client/stats/stats.go b/client/stats/stats.go index fd8c6d384..50f1b11d6 100644 --- a/client/stats/stats.go +++ b/client/stats/stats.go @@ -2,7 +2,6 @@ package stats import ( - "context" "encoding/json" "errors" "fmt" @@ -471,8 +470,7 @@ type blockStats struct { ParentHash common.Hash `json:"parentHash"` Timestamp *big.Int `json:"timestamp"` Validator common.Address `json:"validator"` - GasUsed uint64 `json:"gasUsed"` - GasLimit uint64 `json:"gasLimit"` + ResourceUsage uint64 `json:"resourceUsage"` Txs []txStats `json:"transactions"` TxHash common.Hash `json:"transactionsRoot"` Root common.Hash `json:"stateRoot"` @@ -574,8 +572,7 @@ func (s *Service) assembleBlockStats(block *types.Block) (*blockStats, error) { ParentHash: header.ParentHash, Timestamp: header.Time, Validator: author, - GasUsed: header.GasUsed, - GasLimit: header.GasLimit, + ResourceUsage: header.ResourceUsage, Txs: txs, TxHash: header.TxHash, Root: header.Root, @@ -676,7 +673,6 @@ type nodeStats struct { Syncing bool `json:"syncing"` Validating bool `json:"validating"` Peers int `json:"peers"` - GasPrice int `json:"gasPrice"` Uptime int `json:"uptime"` } @@ -687,7 +683,6 @@ func (s *Service) reportStats(conn *websocket.Conn) error { var ( validating bool syncing bool - gasprice int ) validating = s.kcoin.Validator().Validating() @@ -695,9 +690,6 @@ func (s *Service) reportStats(conn *websocket.Conn) error { sync := s.kcoin.Downloader().Progress() syncing = s.kcoin.BlockChain().CurrentHeader().Number.Uint64() >= sync.HighestBlock - price, _ := s.kcoin.APIBackend().SuggestPrice(context.Background()) - gasprice = int(price.Uint64()) - // Assemble the node stats and send it to the server log.Trace("Sending node details to kcoinstats") @@ -707,7 +699,6 @@ func (s *Service) reportStats(conn *websocket.Conn) error { Active: true, Validating: validating, Peers: s.server.PeerCount(), - GasPrice: gasprice, Syncing: syncing, Uptime: 100, }, diff --git a/docs/docs/advanced/types/block.md b/docs/docs/advanced/types/block.md index d054c3b0b..1ff3a8dfe 100644 --- a/docs/docs/advanced/types/block.md +++ b/docs/docs/advanced/types/block.md @@ -18,7 +18,7 @@ transactions that compose the block. | Field | Description | | -------------- | ------------------------------------------------------------------------------------------------------------------ | | Number | Number of ancestor blocks. The genesis block has a number of zero | -| Parent Hash | Hash of the previous block's header ("parent block") | +| ParentHash | Hash of the previous block's header ("parent block") | | Coinbase | Account registered by the validator(proposer) who's responsible for the block creation | | Root | Hash of the root node of the state trie, after all transactions are executed and finalisations applied | | TxHash | Hash of the root node of the trie structure populated with the transactions of the block | @@ -27,8 +27,7 @@ transactions that compose the block. | ValidatorsHash | Hash of the current set of validators for the current block | | Time | Time at the block inception | | Bloom | The bloom filter(space-efficient probabilistic data structure) for the logs of the block | -| Gas Limit | current limit of gas expenditure per block | -| Gas Used | Total gas used in transactions in this block | +| ResourceUsage | Total of computational resource (in compute units) used in transactions in this block | #### Context @@ -66,12 +65,7 @@ transactions that compose the block. Instead, because the ERC20 specification shoot of a log for every transfer, you can just search the blockchain for these logs! -- GasLimit - defines the maximum amount of gas (computational effort) that all - the trasactions included in the block can consume. Its purpose is to keep block - propagation and processing time low. Note that this value in bitcoin is constant - but it's variable in Ethereum. - -- GasUsed - The fact that the block can handle a certain limit does not mean +- ResourceUsage - The fact that the block can handle a certain limit does not mean that we will have enough transactions to fill the block. ### Block Body diff --git a/docs/docs/advanced/types/receipt.md b/docs/docs/advanced/types/receipt.md new file mode 100644 index 000000000..862ac979e --- /dev/null +++ b/docs/docs/advanced/types/receipt.md @@ -0,0 +1,18 @@ +# Receipt + +The purpose of the receipt is to provide information about the transaction +execution - contains information that is only available once a transaction has +been executed. + +## Receipt Specification + +| Field | Description | +| ----------------------- | -------------------------------------------------------------------------------------------------------- | +| PostState | Post transaction state | +| Status | Transaction execution status (failed/succeeded) | +| CumulativeResourceUsage | Sum of computational resources used by this transaction and all preceding transactions in the same block | +| Bloom | | +| Logs | | +| TxHash | Transaction Hash | +| ContractAddress | Address assigned to the new contract (only for contract creation transactions) | +| ResourceUsage | Computational resources usage (in compute units) | diff --git a/docs/docs/advanced/types/tx.md b/docs/docs/advanced/types/tx.md index 81a64addf..46b419d15 100644 --- a/docs/docs/advanced/types/tx.md +++ b/docs/docs/advanced/types/tx.md @@ -8,18 +8,17 @@ sequence numbers (Nonce). ## Transaction Specification -| Field | Description | -| ------------ | --------------------------------------------------------------- | -| AccountNonce | Represents the number of transactions sent from a given address | -| Recipient | The address to which we are directing this message | -| Amount | Total kUSD that you want to send | -| Payload | Data field in a transaction | -| GasLimit | The maximum amount of gas that this transaction can consume | -| Price | Price per unit of gas | +| Field | Description | +| ------------ | -------------------------------------------------------------------------------------- | +| AccountNonce | Represents the number of transactions sent from a given address | +| ComputeLimit | The compute units that this transaction can use (not required for simple transactions) | +| Recipient | The address to which we are directing this message (nil for contract creation) | +| Amount | Total kUSD that you want to send | +| Payload | Data field in a transaction | ### Context -- Nonce, is used to enforce some rules such as: +- AccountNonce, is used to enforce some rules such as: - Transactions must be in order. This field prevents double-spends as the nonce is the order transactions go in. The transaction with a nonce value of 3 @@ -28,11 +27,7 @@ sequence numbers (Nonce). - Amount, If you are executing a transaction to send kUSD to another person or a contract, you set this value. -- Payload is Either a byte string containing the associated data of the message, +- Payload is either a byte string containing the associated data of the message, or in the case of a contract-creation transaction, the initialisation code. -- Price - If you want to spend less on a transaction, you can do so by lowering - the amount you pay per unit of gas. The price you pay for each unit increases or - decreases how quickly your transaction will be mined. -

diff --git a/docs/docs/advanced/types/tx_pool.md b/docs/docs/advanced/types/tx_pool.md new file mode 100644 index 000000000..eec902341 --- /dev/null +++ b/docs/docs/advanced/types/tx_pool.md @@ -0,0 +1,61 @@ +# Transaction Pool + +Kowala's transaction pool contains all currently known transactions. + +Since Kowala has a fixed compute unit price, there aren't stale transactions as +in Ethereum due to network congestion, thus the concept of replacing stale +transactions does not exist - there's no urgency factor. Additionally, +transactions are not sorted by price - all transactions are treated in the same +way; miners process all the transactions which decreases the propagation time of +a transaction which leads to faster transaction confirmations. + +The transaction pool ensures that its content is valid with regard to the chain +state upon a new block. The process consists in removing any transactions that +have been included in the block or that have been invalidated because of another +transaction, updating all the accounts to the latest pending nonce and moving +future transactions over to the executable list. + +## Transaction life cycle + +1 - Transactions enter the pool when they are received from the network or +submitted locally. + +Note: by default the distiction between local and remote transactions is +enabled, but it can be disabled via config. + +2 - Insert the transaction into the future queue: + +- If the transaction is already known, discard it. +- If the transaction fails basic validation, discard it: + - heuristic limit - size. + - transactions cannot be negative. + - ensure that transaction does not exceed the network compute capacity. + - make sure that the transaction is signed properly. + - ensure that the transaction has a valid nonce. + - sender should have enough balance to cover the (maximum) costs. + - compute limit must cover the transaction's intrinsic computational effort. +- If the new transaction overlaps a known transaction, discard it. +- If the transaction is local, add it to the local pool. +- Add the transaction to the local disk journal. + +3 - Transaction is promoted to the set of pending transactions - contains the +expected account nonce. + +Kowala transactions contain a field called account nonce, which is a transaction +counter that should be attached for each transaction. The account nonce prevents +replay attacks and each node processes transactions from a specific account in a +strict order according to the value of its nonce. Let's say that the latest +transaction nonce was 4: if we send a new transaction from the same account with +the same nonce or below, the transaction pool will reject it; If we send a new +transaction with a nonce of 6, there's a gap and thus the new transaction will +not be processed until this gap is closed. If the gap stays open for too long, +the transaction is removed from the pool. + +If there's a sequential increasing list of transactions starting at the expected +nonce, all of them are promoted. + +4 - Transaction is executed and if does not trigger an error, it is included in the +block by the proposer. + +5 - Block is committed by the miners - transaction confirmation; Transaction pool +removes the transaction. diff --git a/docs/docs/getting-started/pricing.md b/docs/docs/getting-started/pricing.md new file mode 100644 index 000000000..b385b39e4 --- /dev/null +++ b/docs/docs/getting-started/pricing.md @@ -0,0 +1,40 @@ +# Kowala Pricing + +This section covers the network pricing. + +- With Kowala you pay per transaction. The transaction fee is debited from the + source account - be advised that the amount debited from the source account will + be slightly larger than that credited to the target account. + +- Kowala does not support transaction prioritisation - first come, first served + as the major payment networks; transaction prioritisation was born out of the need + to prioritise transactions due to network congestion (Ex: Ethereum network). + +- Different operations require different computational efforts. The price of the + compute unit is currently set to k$0.0000004. + +With that said, that are two types of transactions: + +## kUSD Transactions + +The simplest transactions are kUSD transfer transactions. + +These transactions have a fixed base cost, k$0.0084. + +## Contract Transactions + +Contract transactions have variable costs because the blockchain state is not +static and different operations require different computational efforts. For that +reason, users must provide a compute limit - Kowala provide tools to calculate an +estimated limit - which is the maximum amount of computational resource the sender is +willing to pay for this transaction. + +Additionally, the following points must be considered: + +- The miners will stop the transaction execution as soon as they run out of + computational resource (limit). + +- If there's any computational resource left over (compute limit - resource usage), + the correspondent cost will be immediatly refunded to the user's account. + +

diff --git a/e2e/cluster/kcoin_node_builder.go b/e2e/cluster/kcoin_node_builder.go index 18f99ad15..a8317205a 100644 --- a/e2e/cluster/kcoin_node_builder.go +++ b/e2e/cluster/kcoin_node_builder.go @@ -37,7 +37,6 @@ func NewKcoinNodeBuilder() *KcoinNodeBuilder { func (builder *KcoinNodeBuilder) NodeSpec() *NodeSpec { cmd := []string{ "--testnet", - "--gasprice", "1", "--networkid", builder.networkId, "--bootnodesv5", builder.bootnode, "--syncmode", builder.syncMode, diff --git a/e2e/impl/transactions.go b/e2e/impl/transactions.go index e0c2e6935..a5e0ff852 100644 --- a/e2e/impl/transactions.go +++ b/e2e/impl/transactions.go @@ -173,37 +173,31 @@ func (ctx *Context) transactionBlock(tx *types.Transaction) (*types.Block, error } func (ctx *Context) buildTx(from, to accounts.Account, kcoin int64) (*types.Transaction, error) { - nonce, gp, gas, err := ctx.getTxParams(from, to, kcoin) + nonce, computeLimit, err := ctx.getTxParams(from, to, kcoin) if err != nil { return nil, err } - tx := types.NewTransaction(nonce, to.Address, toWei(kcoin), gas, gp, nil) + tx := types.NewTransaction(nonce, to.Address, toWei(kcoin), computeLimit, nil) return ctx.AccountsStorage.SignTx(from, tx, ctx.chainID) } -func (ctx *Context) getTxParams(from, to accounts.Account, kcoin int64) (uint64, *big.Int, uint64, error) { +func (ctx *Context) getTxParams(from, to accounts.Account, kcoin int64) (uint64, uint64, error) { nonce, err := ctx.client.NonceAt(context.Background(), from.Address, nil) if err != nil { - return 0, nil, 0, err + return 0, 0, err } - gasPrice, err := ctx.client.SuggestGasPrice(context.Background()) - if err != nil { - return 0, nil, 0, err - } - - gas, err := ctx.client.EstimateGas(context.Background(), kowala.CallMsg{ - From: from.Address, - To: &to.Address, - Value: toWei(kcoin), - GasPrice: gasPrice, + effort, err := ctx.client.EstimateComputationalEffort(context.Background(), kowala.CallMsg{ + From: from.Address, + To: &to.Address, + Value: toWei(kcoin), }) if err != nil { - return 0, nil, 0, err + return 0, 0, err } - return nonce, gasPrice, gas, nil + return nonce, effort, nil } func (ctx *Context) sendFunds(from, to accounts.Account, kcoin int64) (*types.Transaction, error) { diff --git a/notifications/blockchain/kcoin.go b/notifications/blockchain/kcoin.go index ad2299e12..cbff36d20 100644 --- a/notifications/blockchain/kcoin.go +++ b/notifications/blockchain/kcoin.go @@ -144,14 +144,13 @@ func (k *kcoin) wrapBlock(block *types.Block) *Block { } transactions[i] = &protocolbuffer.Transaction{ - To: to, - From: from.String(), - Amount: tx.Value().Int64(), - Hash: tx.Hash().String(), - Timestamp: block.Time().Int64(), - GasUsed: int64(block.GasUsed()), - GasPrice: tx.GasPrice().Int64(), - BlockHeight: block.Number().Int64(), + To: to, + From: from.String(), + Amount: tx.Value().Int64(), + Hash: tx.Hash().String(), + Timestamp: block.Time().Int64(), + ResourceUsage: int64(block.ResourceUsage()), + BlockHeight: block.Number().Int64(), } } return &Block{ diff --git a/notifications/persistence/redis_integration_test.go b/notifications/persistence/redis_integration_test.go index 5dcb7ef19..b45c61da8 100644 --- a/notifications/persistence/redis_integration_test.go +++ b/notifications/persistence/redis_integration_test.go @@ -29,14 +29,13 @@ func TestSaveAndGetTransaction(t *testing.T) { amount := big.NewInt(12345) tx := &protocolbuffer.Transaction{ - Hash: hash.String(), - Amount: amount.Int64(), - From: address.String(), - To: to.String(), - GasUsed: 1000, - GasPrice: 2000, - BlockHeight: 1050, - Timestamp: time.Now().Unix(), + Hash: hash.String(), + Amount: amount.Int64(), + From: address.String(), + To: to.String(), + ResourceUsage: 1000, + BlockHeight: 1050, + Timestamp: time.Now().Unix(), } t.Run("Get a unexisting transaction", func(t *testing.T) { @@ -89,14 +88,13 @@ func TestGetTransactionsFromAccount(t *testing.T) { amount := big.NewInt(12345) fromAccountTransaction := &protocolbuffer.Transaction{ - Hash: hash.String(), - Amount: amount.Int64(), - From: targetAccount.String(), - To: account.String(), - GasUsed: 1000, - GasPrice: 2000, - BlockHeight: 1050, - Timestamp: time.Now().Unix(), + Hash: hash.String(), + Amount: amount.Int64(), + From: targetAccount.String(), + To: account.String(), + ResourceUsage: 1000, + BlockHeight: 1050, + Timestamp: time.Now().Unix(), } t.Run("Get transactions with account with one from transaction", func(t *testing.T) { @@ -119,14 +117,13 @@ func TestGetTransactionsFromAccount(t *testing.T) { account2 := common.HexToAddress("0xdbdfdbce9a34c3ac5546657f651146d88d1bcaca") toAccountTransaction := &protocolbuffer.Transaction{ - Hash: toHash.String(), - Amount: amount.Int64(), - From: account2.String(), - To: targetAccount.String(), - GasUsed: 1000, - GasPrice: 2000, - BlockHeight: 1050, - Timestamp: time.Now().Unix(), + Hash: toHash.String(), + Amount: amount.Int64(), + From: account2.String(), + To: targetAccount.String(), + ResourceUsage: 1000, + BlockHeight: 1050, + Timestamp: time.Now().Unix(), } t.Run("Get transactions with 1 from 1 to", func(t *testing.T) { diff --git a/notifications/protocolbuffer/api.pb.go b/notifications/protocolbuffer/api.pb.go index 7fb85d631..47b7f6359 100644 --- a/notifications/protocolbuffer/api.pb.go +++ b/notifications/protocolbuffer/api.pb.go @@ -250,8 +250,7 @@ type Transaction struct { Hash string `protobuf:"bytes,4,opt,name=hash,proto3" json:"hash,omitempty"` Timestamp int64 `protobuf:"varint,5,opt,name=timestamp,proto3" json:"timestamp,omitempty"` BlockHeight int64 `protobuf:"varint,6,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` - GasUsed int64 `protobuf:"varint,7,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"` - GasPrice int64 `protobuf:"varint,8,opt,name=gas_price,json=gasPrice,proto3" json:"gas_price,omitempty"` + ResourceUsage int64 `protobuf:"varint,7,opt,name=resource_usage,json=resourceUsage,proto3" json:"resource_usage,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -323,16 +322,9 @@ func (m *Transaction) GetBlockHeight() int64 { return 0 } -func (m *Transaction) GetGasUsed() int64 { +func (m *Transaction) GetResourceUsage() int64 { if m != nil { - return m.GasUsed - } - return 0 -} - -func (m *Transaction) GetGasPrice() int64 { - if m != nil { - return m.GasPrice + return m.ResourceUsage } return 0 } @@ -519,31 +511,30 @@ var _TransactionService_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) } var fileDescriptor_00212fb1f9d3bf1c = []byte{ - // 405 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0x5d, 0x8f, 0xd2, 0x40, - 0x14, 0xb5, 0xb0, 0x0b, 0xf4, 0x82, 0xdb, 0xec, 0xcd, 0x66, 0x33, 0xb2, 0x9a, 0x5d, 0x1a, 0x63, - 0x48, 0x4c, 0x78, 0xa8, 0x3f, 0x80, 0x27, 0xa3, 0x0f, 0x9a, 0x98, 0x2a, 0xf1, 0x91, 0x0c, 0x65, - 0x68, 0x27, 0xb6, 0x9d, 0x71, 0x66, 0x2a, 0xe1, 0x5f, 0xf9, 0x6b, 0xfc, 0x3d, 0x66, 0x06, 0x1a, - 0x4a, 0xf1, 0x63, 0x9f, 0x98, 0x73, 0xee, 0xb9, 0xe7, 0xd2, 0x7b, 0x2e, 0xf8, 0x54, 0xf2, 0x99, - 0x54, 0xc2, 0x08, 0xbc, 0x72, 0x3f, 0x89, 0xc8, 0x57, 0xd5, 0x66, 0xc3, 0x54, 0x38, 0x87, 0x20, - 0x66, 0x29, 0xd7, 0x86, 0xa9, 0x98, 0x7d, 0xaf, 0x98, 0x36, 0x78, 0x0b, 0xbd, 0x2d, 0xcd, 0x73, - 0x66, 0x88, 0xf7, 0xe0, 0x4d, 0xfd, 0xf8, 0x80, 0xf0, 0x06, 0x2e, 0x59, 0x41, 0x79, 0x4e, 0x3a, - 0x8e, 0xde, 0x83, 0xf0, 0x35, 0x5c, 0x2f, 0x4a, 0xf5, 0x38, 0x8b, 0x30, 0x80, 0xa7, 0xc7, 0x69, - 0x32, 0xdf, 0x85, 0xd7, 0x10, 0x34, 0xbb, 0x2d, 0x15, 0xc1, 0xed, 0x3b, 0x66, 0xbe, 0x28, 0x5a, - 0x6a, 0x9a, 0x18, 0x2e, 0x4a, 0x5d, 0xbb, 0x12, 0xe8, 0xd3, 0x24, 0x11, 0x55, 0x59, 0xdb, 0xd6, - 0x30, 0xfc, 0x0a, 0x37, 0x67, 0x3d, 0x32, 0xdf, 0xe1, 0x1c, 0x46, 0xa6, 0x41, 0x12, 0xef, 0xa1, - 0x3b, 0x1d, 0x46, 0x77, 0xb3, 0xd3, 0x25, 0xcc, 0x1a, 0x8d, 0xf1, 0x49, 0x43, 0xf8, 0xcb, 0x83, - 0x61, 0xa3, 0x8a, 0x57, 0xd0, 0x31, 0xe2, 0x30, 0xbd, 0x63, 0x84, 0xfd, 0x50, 0x5a, 0xb8, 0x7f, - 0x64, 0x97, 0xd2, 0x8d, 0x0f, 0x08, 0x11, 0x2e, 0x36, 0x4a, 0x14, 0xa4, 0xeb, 0x94, 0xee, 0x6d, - 0xb9, 0x8c, 0xea, 0x8c, 0x5c, 0xec, 0x39, 0xfb, 0xc6, 0xe7, 0xe0, 0x1b, 0x5e, 0x30, 0x6d, 0x68, - 0x21, 0xc9, 0xa5, 0xb3, 0x38, 0x12, 0x38, 0x81, 0xd1, 0x2a, 0x17, 0xc9, 0xb7, 0x65, 0xc6, 0x78, - 0x9a, 0x19, 0xd2, 0x73, 0x82, 0xa1, 0xe3, 0xde, 0x3b, 0x0a, 0x9f, 0xc1, 0x20, 0xa5, 0x7a, 0x59, - 0x69, 0xb6, 0x26, 0x7d, 0x57, 0xee, 0xa7, 0x54, 0x2f, 0x34, 0x5b, 0xe3, 0x1d, 0xf8, 0xb6, 0x24, - 0x15, 0x4f, 0x18, 0x19, 0xb8, 0x9a, 0xd5, 0x7e, 0xb2, 0x38, 0xfa, 0xe9, 0xc1, 0xe8, 0xad, 0x0d, - 0xf0, 0x23, 0x95, 0x92, 0x97, 0x29, 0x7e, 0x80, 0x41, 0x1d, 0x0d, 0xde, 0xb7, 0x17, 0xd4, 0x3a, - 0x91, 0xf1, 0x8b, 0xbf, 0x0b, 0x6c, 0x84, 0x4f, 0x30, 0x06, 0x38, 0xe6, 0x8a, 0x93, 0xb6, 0xfc, - 0xec, 0x62, 0xc6, 0xf7, 0xff, 0x92, 0x38, 0xcf, 0x68, 0x0b, 0xd8, 0x88, 0xe2, 0x33, 0x53, 0x3f, - 0x78, 0xc2, 0x90, 0x42, 0xd0, 0x8a, 0x1e, 0x5f, 0xb5, 0xbd, 0xfe, 0x7c, 0x4f, 0xe3, 0x97, 0xff, - 0xd5, 0xb9, 0xc1, 0xab, 0x9e, 0x93, 0xbd, 0xf9, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x53, 0xf2, 0x8d, - 0xc8, 0x47, 0x03, 0x00, 0x00, + // 390 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xcf, 0xae, 0xd2, 0x40, + 0x14, 0xc6, 0x2d, 0x7f, 0xe5, 0xf0, 0xa7, 0xe1, 0x84, 0x90, 0x09, 0x6a, 0x80, 0x46, 0x0d, 0x89, + 0x09, 0x8b, 0xfa, 0x00, 0xac, 0x8c, 0x2e, 0x74, 0x53, 0x25, 0x2e, 0xc9, 0xd0, 0x0c, 0xed, 0xc4, + 0xb6, 0x53, 0x67, 0xa6, 0x12, 0xde, 0xca, 0x97, 0xf0, 0xbd, 0xcc, 0x0c, 0x34, 0x94, 0xa2, 0xf7, + 0xde, 0x55, 0xe7, 0xfc, 0xfa, 0x9d, 0x6f, 0xda, 0xf3, 0x1d, 0xe8, 0xd1, 0x9c, 0xaf, 0x73, 0x29, + 0xb4, 0xc0, 0x91, 0x7d, 0x84, 0x22, 0xd9, 0x17, 0x87, 0x03, 0x93, 0xde, 0x06, 0xdc, 0x80, 0x45, + 0x5c, 0x69, 0x26, 0x03, 0xf6, 0xb3, 0x60, 0x4a, 0xe3, 0x14, 0x3a, 0x47, 0x9a, 0x24, 0x4c, 0x13, + 0x67, 0xe1, 0xac, 0x7a, 0xc1, 0xa5, 0xc2, 0x09, 0xb4, 0x59, 0x4a, 0x79, 0x42, 0x1a, 0x16, 0x9f, + 0x0b, 0xef, 0x1d, 0x8c, 0xb7, 0x99, 0x7c, 0x9a, 0x85, 0xe7, 0xc2, 0xf0, 0x7a, 0x5b, 0x9e, 0x9c, + 0xbc, 0x31, 0xb8, 0xd5, 0x6e, 0x83, 0x7c, 0x98, 0x7e, 0x64, 0xfa, 0x9b, 0xa4, 0x99, 0xa2, 0xa1, + 0xe6, 0x22, 0x53, 0xa5, 0x2b, 0x81, 0x2e, 0x0d, 0x43, 0x51, 0x64, 0xa5, 0x6d, 0x59, 0x7a, 0xdf, + 0x61, 0x72, 0xd7, 0x93, 0x27, 0x27, 0xdc, 0xc0, 0x40, 0x57, 0x20, 0x71, 0x16, 0xcd, 0x55, 0xdf, + 0x7f, 0xb1, 0xbe, 0x1d, 0xc2, 0xba, 0xd2, 0x18, 0xdc, 0x34, 0x78, 0x7f, 0x1c, 0xe8, 0x57, 0xde, + 0xe2, 0x08, 0x1a, 0x5a, 0x5c, 0x6e, 0x6f, 0x68, 0x61, 0x7e, 0x94, 0xa6, 0xf6, 0x8b, 0xcc, 0x50, + 0x9a, 0xc1, 0xa5, 0x42, 0x84, 0xd6, 0x41, 0x8a, 0x94, 0x34, 0xad, 0xd2, 0x9e, 0x0d, 0x8b, 0xa9, + 0x8a, 0x49, 0xeb, 0xcc, 0xcc, 0x19, 0x5f, 0x42, 0x4f, 0xf3, 0x94, 0x29, 0x4d, 0xd3, 0x9c, 0xb4, + 0xad, 0xc5, 0x15, 0xe0, 0x12, 0x06, 0xfb, 0x44, 0x84, 0x3f, 0x76, 0x31, 0xe3, 0x51, 0xac, 0x49, + 0xc7, 0x0a, 0xfa, 0x96, 0x7d, 0xb2, 0x08, 0xdf, 0xc0, 0x48, 0x32, 0x25, 0x0a, 0x19, 0xb2, 0x5d, + 0xa1, 0x68, 0xc4, 0x48, 0xd7, 0x8a, 0x86, 0x25, 0xdd, 0x1a, 0xe8, 0xff, 0x76, 0x60, 0xf0, 0xc1, + 0xe4, 0xf5, 0x85, 0xe6, 0x39, 0xcf, 0x22, 0xfc, 0x0c, 0xcf, 0xcb, 0x24, 0x70, 0x5e, 0x9f, 0x47, + 0x6d, 0x23, 0x66, 0xaf, 0xfe, 0x2f, 0x30, 0x89, 0x3d, 0xc3, 0x00, 0xe0, 0x1a, 0x23, 0x2e, 0xeb, + 0xf2, 0xbb, 0x05, 0x99, 0xcd, 0x1f, 0x92, 0x58, 0x4f, 0xff, 0x08, 0x58, 0x99, 0xfc, 0x57, 0x26, + 0x7f, 0xf1, 0x90, 0x21, 0x05, 0xb7, 0x96, 0x34, 0xbe, 0xad, 0x7b, 0xfd, 0x7b, 0x7d, 0x66, 0xaf, + 0x1f, 0xd5, 0xd9, 0x8b, 0xf7, 0x1d, 0x2b, 0x7b, 0xff, 0x37, 0x00, 0x00, 0xff, 0xff, 0x8f, 0xf6, + 0x3c, 0x96, 0x36, 0x03, 0x00, 0x00, } diff --git a/notifications/protocolbuffer/api.proto b/notifications/protocolbuffer/api.proto index 1852b8649..587f6a824 100644 --- a/notifications/protocolbuffer/api.proto +++ b/notifications/protocolbuffer/api.proto @@ -40,6 +40,5 @@ message Transaction { string hash = 4; int64 timestamp = 5; int64 block_height = 6; - int64 gas_used = 7; - int64 gas_price = 8; + int64 resource_usage = 7; } diff --git a/toolbox/testnet/genesis_validator.go b/toolbox/testnet/genesis_validator.go index 9fa935ff7..004fe318a 100644 --- a/toolbox/testnet/genesis_validator.go +++ b/toolbox/testnet/genesis_validator.go @@ -36,7 +36,6 @@ func NewGenesisValidator(dockerEngine DockerEngine, networkID string, bootNode s WithBootnode(bootNode). WithGenesis(genesis). WithSyncMode("full"). - WithGasPrice("1"). WithAccount(coinbase, rawCoinbase). WithDeposit(big.NewInt(1)). WithVerbosity("4"). diff --git a/toolbox/testnet/node_spec.go b/toolbox/testnet/node_spec.go index 24fd5b856..7701b83e5 100644 --- a/toolbox/testnet/node_spec.go +++ b/toolbox/testnet/node_spec.go @@ -97,12 +97,6 @@ func (n *NodeSpecBuilder) WithBootnode(bootnodeAddr string) *NodeSpecBuilder { return n } -//WithGasPrice sets the price of the given node. -func (n *NodeSpecBuilder) WithGasPrice(gasPrice string) *NodeSpecBuilder { - n.addCmdArgs([]string{"--gasprice", gasPrice}) - return n -} - //WithVerbosity sets the level of verbosity that the node will have. func (n *NodeSpecBuilder) WithVerbosity(level string) *NodeSpecBuilder { n.addCmdArgs([]string{"--verbosity", level}) diff --git a/toolbox/testnet/node_spec_test.go b/toolbox/testnet/node_spec_test.go index 7ece21e38..f2cc77535 100644 --- a/toolbox/testnet/node_spec_test.go +++ b/toolbox/testnet/node_spec_test.go @@ -91,18 +91,6 @@ func TestNodeSpecBuilder(t *testing.T) { assert.Len(t, nodeSpec.Cmd, 2) }) - t.Run("We can specify the gas price.", func(t *testing.T) { - builder := getBuilderWithDefaults() - builder.WithGasPrice("1") - - nodeSpec := buildNodeSpecWithoutError(t, builder) - - assert.Contains(t, nodeSpec.Cmd, "--gasprice") - assert.Contains(t, nodeSpec.Cmd, "1") - - assert.Len(t, nodeSpec.Cmd, 2) - }) - t.Run("We can set verbosity", func(t *testing.T) { builder := getBuilderWithDefaults() builder.WithVerbosity("3") diff --git a/wallet-backend/application/command/transactions.go b/wallet-backend/application/command/transactions.go index 3c724b5f7..455d2f2e3 100644 --- a/wallet-backend/application/command/transactions.go +++ b/wallet-backend/application/command/transactions.go @@ -39,14 +39,13 @@ func (h *GetTransactionsHandler) Handle(ctx context.Context, cmd GetTransactions txs = append( txs, &blockchain.Transaction{ - Hash: tx.Hash, - From: tx.From, - To: tx.To, - Amount: big.NewInt(tx.Amount), - Timestamp: big.NewInt(tx.Timestamp), - BlockHeight: big.NewInt(tx.BlockHeight), - GasUsed: big.NewInt(tx.GasUsed), - GasPrice: big.NewInt(tx.GasPrice), + Hash: tx.Hash, + From: tx.From, + To: tx.To, + Amount: big.NewInt(tx.Amount), + Timestamp: big.NewInt(tx.Timestamp), + BlockHeight: big.NewInt(tx.BlockHeight), + ResourceUsage: big.NewInt(tx.ResourceUsage), }, ) } diff --git a/wallet-backend/blockchain/transaction.go b/wallet-backend/blockchain/transaction.go index 4d41800d4..79e603ce2 100644 --- a/wallet-backend/blockchain/transaction.go +++ b/wallet-backend/blockchain/transaction.go @@ -4,12 +4,11 @@ import "math/big" //Transaction represents a transaction inside the domain of the wallet backend. type Transaction struct { - Hash string `json:"hash"` - From string `json:"from"` - To string `json:"to"` - Amount *big.Int `json:"amount"` - Timestamp *big.Int `json:"timestamp"` - BlockHeight *big.Int `json:"block_height"` - GasUsed *big.Int `json:"gas_used"` - GasPrice *big.Int `json:"gas_price"` + Hash string `json:"hash"` + From string `json:"from"` + To string `json:"to"` + Amount *big.Int `json:"amount"` + Timestamp *big.Int `json:"timestamp"` + BlockHeight *big.Int `json:"block_height"` + ResourceUsage *big.Int `json:"resource_usage"` } diff --git a/wallet-backend/protocolbuffer/api.pb.go b/wallet-backend/protocolbuffer/api.pb.go index 7fb85d631..47b7f6359 100644 --- a/wallet-backend/protocolbuffer/api.pb.go +++ b/wallet-backend/protocolbuffer/api.pb.go @@ -250,8 +250,7 @@ type Transaction struct { Hash string `protobuf:"bytes,4,opt,name=hash,proto3" json:"hash,omitempty"` Timestamp int64 `protobuf:"varint,5,opt,name=timestamp,proto3" json:"timestamp,omitempty"` BlockHeight int64 `protobuf:"varint,6,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` - GasUsed int64 `protobuf:"varint,7,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"` - GasPrice int64 `protobuf:"varint,8,opt,name=gas_price,json=gasPrice,proto3" json:"gas_price,omitempty"` + ResourceUsage int64 `protobuf:"varint,7,opt,name=resource_usage,json=resourceUsage,proto3" json:"resource_usage,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -323,16 +322,9 @@ func (m *Transaction) GetBlockHeight() int64 { return 0 } -func (m *Transaction) GetGasUsed() int64 { +func (m *Transaction) GetResourceUsage() int64 { if m != nil { - return m.GasUsed - } - return 0 -} - -func (m *Transaction) GetGasPrice() int64 { - if m != nil { - return m.GasPrice + return m.ResourceUsage } return 0 } @@ -519,31 +511,30 @@ var _TransactionService_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) } var fileDescriptor_00212fb1f9d3bf1c = []byte{ - // 405 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0x5d, 0x8f, 0xd2, 0x40, - 0x14, 0xb5, 0xb0, 0x0b, 0xf4, 0x82, 0xdb, 0xec, 0xcd, 0x66, 0x33, 0xb2, 0x9a, 0x5d, 0x1a, 0x63, - 0x48, 0x4c, 0x78, 0xa8, 0x3f, 0x80, 0x27, 0xa3, 0x0f, 0x9a, 0x98, 0x2a, 0xf1, 0x91, 0x0c, 0x65, - 0x68, 0x27, 0xb6, 0x9d, 0x71, 0x66, 0x2a, 0xe1, 0x5f, 0xf9, 0x6b, 0xfc, 0x3d, 0x66, 0x06, 0x1a, - 0x4a, 0xf1, 0x63, 0x9f, 0x98, 0x73, 0xee, 0xb9, 0xe7, 0xd2, 0x7b, 0x2e, 0xf8, 0x54, 0xf2, 0x99, - 0x54, 0xc2, 0x08, 0xbc, 0x72, 0x3f, 0x89, 0xc8, 0x57, 0xd5, 0x66, 0xc3, 0x54, 0x38, 0x87, 0x20, - 0x66, 0x29, 0xd7, 0x86, 0xa9, 0x98, 0x7d, 0xaf, 0x98, 0x36, 0x78, 0x0b, 0xbd, 0x2d, 0xcd, 0x73, - 0x66, 0x88, 0xf7, 0xe0, 0x4d, 0xfd, 0xf8, 0x80, 0xf0, 0x06, 0x2e, 0x59, 0x41, 0x79, 0x4e, 0x3a, - 0x8e, 0xde, 0x83, 0xf0, 0x35, 0x5c, 0x2f, 0x4a, 0xf5, 0x38, 0x8b, 0x30, 0x80, 0xa7, 0xc7, 0x69, - 0x32, 0xdf, 0x85, 0xd7, 0x10, 0x34, 0xbb, 0x2d, 0x15, 0xc1, 0xed, 0x3b, 0x66, 0xbe, 0x28, 0x5a, - 0x6a, 0x9a, 0x18, 0x2e, 0x4a, 0x5d, 0xbb, 0x12, 0xe8, 0xd3, 0x24, 0x11, 0x55, 0x59, 0xdb, 0xd6, - 0x30, 0xfc, 0x0a, 0x37, 0x67, 0x3d, 0x32, 0xdf, 0xe1, 0x1c, 0x46, 0xa6, 0x41, 0x12, 0xef, 0xa1, - 0x3b, 0x1d, 0x46, 0x77, 0xb3, 0xd3, 0x25, 0xcc, 0x1a, 0x8d, 0xf1, 0x49, 0x43, 0xf8, 0xcb, 0x83, - 0x61, 0xa3, 0x8a, 0x57, 0xd0, 0x31, 0xe2, 0x30, 0xbd, 0x63, 0x84, 0xfd, 0x50, 0x5a, 0xb8, 0x7f, - 0x64, 0x97, 0xd2, 0x8d, 0x0f, 0x08, 0x11, 0x2e, 0x36, 0x4a, 0x14, 0xa4, 0xeb, 0x94, 0xee, 0x6d, - 0xb9, 0x8c, 0xea, 0x8c, 0x5c, 0xec, 0x39, 0xfb, 0xc6, 0xe7, 0xe0, 0x1b, 0x5e, 0x30, 0x6d, 0x68, - 0x21, 0xc9, 0xa5, 0xb3, 0x38, 0x12, 0x38, 0x81, 0xd1, 0x2a, 0x17, 0xc9, 0xb7, 0x65, 0xc6, 0x78, - 0x9a, 0x19, 0xd2, 0x73, 0x82, 0xa1, 0xe3, 0xde, 0x3b, 0x0a, 0x9f, 0xc1, 0x20, 0xa5, 0x7a, 0x59, - 0x69, 0xb6, 0x26, 0x7d, 0x57, 0xee, 0xa7, 0x54, 0x2f, 0x34, 0x5b, 0xe3, 0x1d, 0xf8, 0xb6, 0x24, - 0x15, 0x4f, 0x18, 0x19, 0xb8, 0x9a, 0xd5, 0x7e, 0xb2, 0x38, 0xfa, 0xe9, 0xc1, 0xe8, 0xad, 0x0d, - 0xf0, 0x23, 0x95, 0x92, 0x97, 0x29, 0x7e, 0x80, 0x41, 0x1d, 0x0d, 0xde, 0xb7, 0x17, 0xd4, 0x3a, - 0x91, 0xf1, 0x8b, 0xbf, 0x0b, 0x6c, 0x84, 0x4f, 0x30, 0x06, 0x38, 0xe6, 0x8a, 0x93, 0xb6, 0xfc, - 0xec, 0x62, 0xc6, 0xf7, 0xff, 0x92, 0x38, 0xcf, 0x68, 0x0b, 0xd8, 0x88, 0xe2, 0x33, 0x53, 0x3f, - 0x78, 0xc2, 0x90, 0x42, 0xd0, 0x8a, 0x1e, 0x5f, 0xb5, 0xbd, 0xfe, 0x7c, 0x4f, 0xe3, 0x97, 0xff, - 0xd5, 0xb9, 0xc1, 0xab, 0x9e, 0x93, 0xbd, 0xf9, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x53, 0xf2, 0x8d, - 0xc8, 0x47, 0x03, 0x00, 0x00, + // 390 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xcf, 0xae, 0xd2, 0x40, + 0x14, 0xc6, 0x2d, 0x7f, 0xe5, 0xf0, 0xa7, 0xe1, 0x84, 0x90, 0x09, 0x6a, 0x80, 0x46, 0x0d, 0x89, + 0x09, 0x8b, 0xfa, 0x00, 0xac, 0x8c, 0x2e, 0x74, 0x53, 0x25, 0x2e, 0xc9, 0xd0, 0x0c, 0xed, 0xc4, + 0xb6, 0x53, 0x67, 0xa6, 0x12, 0xde, 0xca, 0x97, 0xf0, 0xbd, 0xcc, 0x0c, 0x34, 0x94, 0xa2, 0xf7, + 0xde, 0x55, 0xe7, 0xfc, 0xfa, 0x9d, 0x6f, 0xda, 0xf3, 0x1d, 0xe8, 0xd1, 0x9c, 0xaf, 0x73, 0x29, + 0xb4, 0xc0, 0x91, 0x7d, 0x84, 0x22, 0xd9, 0x17, 0x87, 0x03, 0x93, 0xde, 0x06, 0xdc, 0x80, 0x45, + 0x5c, 0x69, 0x26, 0x03, 0xf6, 0xb3, 0x60, 0x4a, 0xe3, 0x14, 0x3a, 0x47, 0x9a, 0x24, 0x4c, 0x13, + 0x67, 0xe1, 0xac, 0x7a, 0xc1, 0xa5, 0xc2, 0x09, 0xb4, 0x59, 0x4a, 0x79, 0x42, 0x1a, 0x16, 0x9f, + 0x0b, 0xef, 0x1d, 0x8c, 0xb7, 0x99, 0x7c, 0x9a, 0x85, 0xe7, 0xc2, 0xf0, 0x7a, 0x5b, 0x9e, 0x9c, + 0xbc, 0x31, 0xb8, 0xd5, 0x6e, 0x83, 0x7c, 0x98, 0x7e, 0x64, 0xfa, 0x9b, 0xa4, 0x99, 0xa2, 0xa1, + 0xe6, 0x22, 0x53, 0xa5, 0x2b, 0x81, 0x2e, 0x0d, 0x43, 0x51, 0x64, 0xa5, 0x6d, 0x59, 0x7a, 0xdf, + 0x61, 0x72, 0xd7, 0x93, 0x27, 0x27, 0xdc, 0xc0, 0x40, 0x57, 0x20, 0x71, 0x16, 0xcd, 0x55, 0xdf, + 0x7f, 0xb1, 0xbe, 0x1d, 0xc2, 0xba, 0xd2, 0x18, 0xdc, 0x34, 0x78, 0x7f, 0x1c, 0xe8, 0x57, 0xde, + 0xe2, 0x08, 0x1a, 0x5a, 0x5c, 0x6e, 0x6f, 0x68, 0x61, 0x7e, 0x94, 0xa6, 0xf6, 0x8b, 0xcc, 0x50, + 0x9a, 0xc1, 0xa5, 0x42, 0x84, 0xd6, 0x41, 0x8a, 0x94, 0x34, 0xad, 0xd2, 0x9e, 0x0d, 0x8b, 0xa9, + 0x8a, 0x49, 0xeb, 0xcc, 0xcc, 0x19, 0x5f, 0x42, 0x4f, 0xf3, 0x94, 0x29, 0x4d, 0xd3, 0x9c, 0xb4, + 0xad, 0xc5, 0x15, 0xe0, 0x12, 0x06, 0xfb, 0x44, 0x84, 0x3f, 0x76, 0x31, 0xe3, 0x51, 0xac, 0x49, + 0xc7, 0x0a, 0xfa, 0x96, 0x7d, 0xb2, 0x08, 0xdf, 0xc0, 0x48, 0x32, 0x25, 0x0a, 0x19, 0xb2, 0x5d, + 0xa1, 0x68, 0xc4, 0x48, 0xd7, 0x8a, 0x86, 0x25, 0xdd, 0x1a, 0xe8, 0xff, 0x76, 0x60, 0xf0, 0xc1, + 0xe4, 0xf5, 0x85, 0xe6, 0x39, 0xcf, 0x22, 0xfc, 0x0c, 0xcf, 0xcb, 0x24, 0x70, 0x5e, 0x9f, 0x47, + 0x6d, 0x23, 0x66, 0xaf, 0xfe, 0x2f, 0x30, 0x89, 0x3d, 0xc3, 0x00, 0xe0, 0x1a, 0x23, 0x2e, 0xeb, + 0xf2, 0xbb, 0x05, 0x99, 0xcd, 0x1f, 0x92, 0x58, 0x4f, 0xff, 0x08, 0x58, 0x99, 0xfc, 0x57, 0x26, + 0x7f, 0xf1, 0x90, 0x21, 0x05, 0xb7, 0x96, 0x34, 0xbe, 0xad, 0x7b, 0xfd, 0x7b, 0x7d, 0x66, 0xaf, + 0x1f, 0xd5, 0xd9, 0x8b, 0xf7, 0x1d, 0x2b, 0x7b, 0xff, 0x37, 0x00, 0x00, 0xff, 0xff, 0x8f, 0xf6, + 0x3c, 0x96, 0x36, 0x03, 0x00, 0x00, }