mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-22 12:46:44 +00:00
Merge branch 'develop' into bzz
This commit is contained in:
commit
5273400437
24 changed files with 1767 additions and 514 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -13,6 +13,8 @@
|
||||||
.ethtest
|
.ethtest
|
||||||
*/**/*tx_database*
|
*/**/*tx_database*
|
||||||
*/**/*dapps*
|
*/**/*dapps*
|
||||||
|
Godeps/_workspace/pkg
|
||||||
|
Godeps/_workspace/bin
|
||||||
|
|
||||||
#*
|
#*
|
||||||
.#*
|
.#*
|
||||||
|
|
@ -21,7 +23,9 @@
|
||||||
.project
|
.project
|
||||||
.settings
|
.settings
|
||||||
|
|
||||||
cmd/ethereum/ethereum
|
geth
|
||||||
|
mist
|
||||||
|
cmd/geth/geth
|
||||||
cmd/mist/mist
|
cmd/mist/mist
|
||||||
deploy/osx/Mist.app
|
deploy/osx/Mist.app
|
||||||
deploy/osx/Mist\ Installer.dmg
|
deploy/osx/Mist\ Installer.dmg
|
||||||
|
|
|
||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
|
|
@ -1,6 +1,3 @@
|
||||||
[submodule "ethereal/assets/samplecoin"]
|
|
||||||
path = ethereal/assets/samplecoin
|
|
||||||
url = git@github.com:obscuren/SampleCoin.git
|
|
||||||
[submodule "cmd/mist/assets/ext/ethereum.js"]
|
[submodule "cmd/mist/assets/ext/ethereum.js"]
|
||||||
path = cmd/mist/assets/ext/ethereum.js
|
path = cmd/mist/assets/ext/ethereum.js
|
||||||
url = https://github.com/ethereum/ethereum.js
|
url = https://github.com/ethereum/ethereum.js
|
||||||
|
|
|
||||||
2
.mailmap
2
.mailmap
|
|
@ -10,3 +10,5 @@ Joseph Goulden <joegoulden@gmail.com>
|
||||||
Nick Savers <nicksavers@gmail.com>
|
Nick Savers <nicksavers@gmail.com>
|
||||||
|
|
||||||
Maran Hidskes <maran.hidskes@gmail.com>
|
Maran Hidskes <maran.hidskes@gmail.com>
|
||||||
|
|
||||||
|
Taylor Gerring <taylor.gerring@gmail.com> <taylor.gerring@ethereum.org>
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ install:
|
||||||
# - go get code.google.com/p/go.tools/cmd/goimports
|
# - go get code.google.com/p/go.tools/cmd/goimports
|
||||||
# - go get github.com/golang/lint/golint
|
# - go get github.com/golang/lint/golint
|
||||||
# - go get golang.org/x/tools/cmd/vet
|
# - go get golang.org/x/tools/cmd/vet
|
||||||
- if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi
|
- go get golang.org/x/tools/cmd/cover
|
||||||
- go get github.com/mattn/goveralls
|
- go get github.com/mattn/goveralls
|
||||||
before_script:
|
before_script:
|
||||||
# - gofmt -l -w .
|
# - gofmt -l -w .
|
||||||
|
|
|
||||||
|
|
@ -30,10 +30,10 @@ RUN mkdir -p $GOPATH/src/github.com/ethereum/
|
||||||
RUN git clone https://github.com/ethereum/go-ethereum $GOPATH/src/github.com/ethereum/go-ethereum
|
RUN git clone https://github.com/ethereum/go-ethereum $GOPATH/src/github.com/ethereum/go-ethereum
|
||||||
WORKDIR $GOPATH/src/github.com/ethereum/go-ethereum
|
WORKDIR $GOPATH/src/github.com/ethereum/go-ethereum
|
||||||
RUN git checkout develop
|
RUN git checkout develop
|
||||||
RUN GOPATH=$GOPATH:$GOPATH/src/github.com/ethereum/go-ethereum/Godeps/_workspace go install -v ./cmd/ethereum
|
RUN GOPATH=$GOPATH:$GOPATH/src/github.com/ethereum/go-ethereum/Godeps/_workspace go install -v ./cmd/geth
|
||||||
|
|
||||||
## Run & expose JSON RPC
|
## Run & expose JSON RPC
|
||||||
ENTRYPOINT ["ethereum", "-rpc=true", "-rpcport=8545"]
|
ENTRYPOINT ["geth", "-rpc=true", "-rpcport=8545"]
|
||||||
EXPOSE 8545
|
EXPOSE 8545
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ Ethereum Go Client © 2014 Jeffrey Wilcke.
|
||||||
|
|
||||||
| Linux | OSX | Windows | Tests
|
| Linux | OSX | Windows | Tests
|
||||||
----------|---------|-----|---------|------
|
----------|---------|-----|---------|------
|
||||||
develop | [](https://build.ethdev.com/builders/Linux%20Go%20develop%20branch/builds/-1) | [](https://build.ethdev.com/builders/OSX%20Go%20develop%20branch/builds/-1) | N/A | [](https://travis-ci.org/ethereum/go-ethereum)
|
develop | [](https://build.ethdev.com/builders/Linux%20Go%20develop%20branch/builds/-1) | [](https://build.ethdev.com/builders/OSX%20Go%20develop%20branch/builds/-1) | N/A | [](https://travis-ci.org/ethereum/go-ethereum) [](https://coveralls.io/r/ethereum/go-ethereum?branch=develop)
|
||||||
master | [](https://build.ethdev.com/builders/Linux%20Go%20master%20branch/builds/-1) | [](https://build.ethdev.com/builders/OSX%20Go%20master%20branch/builds/-1) | N/A | [](https://travis-ci.org/ethereum/go-ethereum)
|
master | [](https://build.ethdev.com/builders/Linux%20Go%20master%20branch/builds/-1) | [](https://build.ethdev.com/builders/OSX%20Go%20master%20branch/builds/-1) | N/A | [](https://travis-ci.org/ethereum/go-ethereum) [](https://coveralls.io/r/ethereum/go-ethereum?branch=master)
|
||||||
|
|
||||||
[](https://waffle.io/ethereum/go-ethereum)
|
[](https://waffle.io/ethereum/go-ethereum)
|
||||||
[](https://waffle.io/ethereum/go-ethereum)
|
[](https://waffle.io/ethereum/go-ethereum)
|
||||||
|
|
@ -22,7 +22,7 @@ Mist (GUI):
|
||||||
|
|
||||||
Geth (CLI):
|
Geth (CLI):
|
||||||
|
|
||||||
`go get github.com/ethereum/go-ethereum/cmd/ethereum`
|
`go get github.com/ethereum/go-ethereum/cmd/geth`
|
||||||
|
|
||||||
As of POC-8, go-ethereum uses [Godep](https://github.com/tools/godep) to manage dependencies. Assuming you have [your environment all set up](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum), switch to the go-ethereum repository root folder, and build/install the executable you need:
|
As of POC-8, go-ethereum uses [Godep](https://github.com/tools/godep) to manage dependencies. Assuming you have [your environment all set up](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum), switch to the go-ethereum repository root folder, and build/install the executable you need:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,18 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Execution struct {
|
type Execution struct {
|
||||||
env vm.Environment
|
env vm.Environment
|
||||||
address *common.Address
|
address *common.Address
|
||||||
input []byte
|
input []byte
|
||||||
|
evm vm.VirtualMachine
|
||||||
|
|
||||||
Gas, price, value *big.Int
|
Gas, price, value *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewExecution(env vm.Environment, address *common.Address, input []byte, gas, gasPrice, value *big.Int) *Execution {
|
func NewExecution(env vm.Environment, address *common.Address, input []byte, gas, gasPrice, value *big.Int) *Execution {
|
||||||
return &Execution{env: env, address: address, input: input, Gas: gas, price: gasPrice, value: value}
|
exe := &Execution{env: env, address: address, input: input, Gas: gas, price: gasPrice, value: value}
|
||||||
|
exe.evm = vm.NewVm(env)
|
||||||
|
return exe
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Execution) Call(codeAddr common.Address, caller vm.ContextRef) ([]byte, error) {
|
func (self *Execution) Call(codeAddr common.Address, caller vm.ContextRef) ([]byte, error) {
|
||||||
|
|
@ -28,11 +32,17 @@ func (self *Execution) Call(codeAddr common.Address, caller vm.ContextRef) ([]by
|
||||||
return self.exec(&codeAddr, code, caller)
|
return self.exec(&codeAddr, code, caller)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *Execution) Create(caller vm.ContextRef) (ret []byte, err error, account *state.StateObject) {
|
||||||
|
ret, err = self.exec(nil, self.input, caller)
|
||||||
|
account = self.env.State().GetStateObject(*self.address)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (self *Execution) exec(contextAddr *common.Address, code []byte, caller vm.ContextRef) (ret []byte, err error) {
|
func (self *Execution) exec(contextAddr *common.Address, code []byte, caller vm.ContextRef) (ret []byte, err error) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
env := self.env
|
env := self.env
|
||||||
evm := vm.NewVm(env)
|
evm := self.evm
|
||||||
if env.Depth() == vm.MaxCallDepth {
|
if env.Depth() == vm.MaxCallDepth {
|
||||||
caller.ReturnGas(self.Gas, self.price)
|
caller.ReturnGas(self.Gas, self.price)
|
||||||
|
|
||||||
|
|
@ -70,10 +80,3 @@ func (self *Execution) exec(contextAddr *common.Address, code []byte, caller vm.
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Execution) Create(caller vm.ContextRef) (ret []byte, err error, account *state.StateObject) {
|
|
||||||
ret, err = self.exec(nil, self.input, caller)
|
|
||||||
account = self.env.State().GetStateObject(*self.address)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -12,17 +12,6 @@ type AccountChange struct {
|
||||||
Address, StateAddress []byte
|
Address, StateAddress []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
type FilterOptions struct {
|
|
||||||
Earliest int64
|
|
||||||
Latest int64
|
|
||||||
|
|
||||||
Address []common.Address
|
|
||||||
Topics [][]common.Hash
|
|
||||||
|
|
||||||
Skip int
|
|
||||||
Max int
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filtering interface
|
// Filtering interface
|
||||||
type Filter struct {
|
type Filter struct {
|
||||||
eth Backend
|
eth Backend
|
||||||
|
|
@ -44,18 +33,6 @@ func NewFilter(eth Backend) *Filter {
|
||||||
return &Filter{eth: eth}
|
return &Filter{eth: eth}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetOptions copies the filter options to the filter it self. The reason for this "silly" copy
|
|
||||||
// is simply because named arguments in this case is extremely nice and readable.
|
|
||||||
func (self *Filter) SetOptions(options *FilterOptions) {
|
|
||||||
self.earliest = options.Earliest
|
|
||||||
self.latest = options.Latest
|
|
||||||
self.skip = options.Skip
|
|
||||||
self.max = options.Max
|
|
||||||
self.address = options.Address
|
|
||||||
self.topics = options.Topics
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the earliest and latest block for filtering.
|
// Set the earliest and latest block for filtering.
|
||||||
// -1 = latest block (i.e., the current block)
|
// -1 = latest block (i.e., the current block)
|
||||||
// hash = particular hash from-to
|
// hash = particular hash from-to
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ package vm
|
||||||
import (
|
import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Address interface {
|
type Address interface {
|
||||||
|
|
@ -61,15 +61,32 @@ func ripemd160Func(in []byte) []byte {
|
||||||
return common.LeftPadBytes(crypto.Ripemd160(in), 32)
|
return common.LeftPadBytes(crypto.Ripemd160(in), 32)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ecRecoverInputLength = 128
|
||||||
|
|
||||||
func ecrecoverFunc(in []byte) []byte {
|
func ecrecoverFunc(in []byte) []byte {
|
||||||
// In case of an invalid sig. Defaults to return nil
|
// "in" is (hash, v, r, s), each 32 bytes
|
||||||
defer func() { recover() }()
|
// but for ecrecover we want (r, s, v)
|
||||||
|
if len(in) < ecRecoverInputLength {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
hash := in[:32]
|
// Treat V as a 256bit integer
|
||||||
v := common.BigD(in[32:64]).Bytes()[0] - 27
|
v := new(big.Int).Sub(common.Bytes2Big(in[32:64]), big.NewInt(27))
|
||||||
sig := append(in[64:], v)
|
// Ethereum requires V to be either 0 or 1 => (27 || 28)
|
||||||
|
if !(v.Cmp(Zero) == 0 || v.Cmp(One) == 0) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
return common.LeftPadBytes(crypto.Sha3(crypto.Ecrecover(append(hash, sig...))[1:])[12:], 32)
|
// v needs to be moved to the end
|
||||||
|
rsv := append(in[64:128], byte(v.Uint64()))
|
||||||
|
pubKey := crypto.Ecrecover(in[:32], rsv)
|
||||||
|
// make sure the public key is a valid one
|
||||||
|
if pubKey == nil || len(pubKey) != 65 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// the first byte of pubkey is bitcoin heritage
|
||||||
|
return common.LeftPadBytes(crypto.Sha3(pubKey[1:])[12:], 32)
|
||||||
}
|
}
|
||||||
|
|
||||||
func memCpy(in []byte) []byte {
|
func memCpy(in []byte) []byte {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,25 @@
|
||||||
package vm
|
package vm
|
||||||
|
|
||||||
import "gopkg.in/fatih/set.v0"
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
func analyseJumpDests(code []byte) (dests *set.Set) {
|
"gopkg.in/fatih/set.v0"
|
||||||
dests = set.New()
|
)
|
||||||
|
|
||||||
|
type destinations struct {
|
||||||
|
set *set.Set
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *destinations) Has(dest *big.Int) bool {
|
||||||
|
return d.set.Has(string(dest.Bytes()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *destinations) Add(dest *big.Int) {
|
||||||
|
d.set.Add(string(dest.Bytes()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func analyseJumpDests(code []byte) (dests *destinations) {
|
||||||
|
dests = &destinations{set.New()}
|
||||||
|
|
||||||
for pc := uint64(0); pc < uint64(len(code)); pc++ {
|
for pc := uint64(0); pc < uint64(len(code)); pc++ {
|
||||||
var op OpCode = OpCode(code[pc])
|
var op OpCode = OpCode(code[pc])
|
||||||
|
|
@ -13,7 +29,7 @@ func analyseJumpDests(code []byte) (dests *set.Set) {
|
||||||
|
|
||||||
pc += a
|
pc += a
|
||||||
case JUMPDEST:
|
case JUMPDEST:
|
||||||
dests.Add(pc)
|
dests.Add(big.NewInt(int64(pc)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ var (
|
||||||
S256 = common.S256
|
S256 = common.S256
|
||||||
|
|
||||||
Zero = common.Big0
|
Zero = common.Big0
|
||||||
|
One = common.Big1
|
||||||
|
|
||||||
max = big.NewInt(math.MaxInt64)
|
max = big.NewInt(math.MaxInt64)
|
||||||
)
|
)
|
||||||
|
|
@ -80,3 +81,13 @@ func getData(data []byte, start, size *big.Int) []byte {
|
||||||
e := common.BigMin(new(big.Int).Add(s, size), dlen)
|
e := common.BigMin(new(big.Int).Add(s, size), dlen)
|
||||||
return common.RightPadBytes(data[s.Uint64():e.Uint64()], int(size.Uint64()))
|
return common.RightPadBytes(data[s.Uint64():e.Uint64()], int(size.Uint64()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func UseGas(gas, amount *big.Int) bool {
|
||||||
|
if gas.Cmp(amount) < 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sub the amount of gas from the remaining
|
||||||
|
gas.Sub(gas, amount)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package vm
|
package vm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
@ -41,29 +40,18 @@ func NewContext(caller ContextRef, object ContextRef, value, gas, price *big.Int
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) GetOp(n uint64) OpCode {
|
func (c *Context) GetOp(n *big.Int) OpCode {
|
||||||
return OpCode(c.GetByte(n))
|
return OpCode(c.GetByte(n))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) GetByte(n uint64) byte {
|
func (c *Context) GetByte(n *big.Int) byte {
|
||||||
if n < uint64(len(c.Code)) {
|
if n.Cmp(big.NewInt(int64(len(c.Code)))) < 0 {
|
||||||
return c.Code[n]
|
return c.Code[n.Int64()]
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) GetBytes(x, y int) []byte {
|
|
||||||
return c.GetRangeValue(uint64(x), uint64(y))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Context) GetRangeValue(x, size uint64) []byte {
|
|
||||||
x = uint64(math.Min(float64(x), float64(len(c.Code))))
|
|
||||||
y := uint64(math.Min(float64(x+size), float64(len(c.Code))))
|
|
||||||
|
|
||||||
return common.RightPadBytes(c.Code[x:y], int(size))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Context) Return(ret []byte) []byte {
|
func (c *Context) Return(ret []byte) []byte {
|
||||||
// Return the remaining gas to the caller
|
// Return the remaining gas to the caller
|
||||||
c.caller.ReturnGas(c.Gas, c.Price)
|
c.caller.ReturnGas(c.Gas, c.Price)
|
||||||
|
|
@ -74,16 +62,12 @@ func (c *Context) Return(ret []byte) []byte {
|
||||||
/*
|
/*
|
||||||
* Gas functions
|
* Gas functions
|
||||||
*/
|
*/
|
||||||
func (c *Context) UseGas(gas *big.Int) bool {
|
func (c *Context) UseGas(gas *big.Int) (ok bool) {
|
||||||
if c.Gas.Cmp(gas) < 0 {
|
ok = UseGas(c.Gas, gas)
|
||||||
return false
|
if ok {
|
||||||
|
c.UsedGas.Add(c.UsedGas, gas)
|
||||||
}
|
}
|
||||||
|
return
|
||||||
// Sub the amount of gas from the remaining
|
|
||||||
c.Gas.Sub(c.Gas, gas)
|
|
||||||
c.UsedGas.Add(c.UsedGas, gas)
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implement the caller interface
|
// Implement the caller interface
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,9 @@ type Vm struct {
|
||||||
Fn string
|
Fn string
|
||||||
|
|
||||||
Recoverable bool
|
Recoverable bool
|
||||||
|
|
||||||
|
// Will be called before the vm returns
|
||||||
|
After func(*Context, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(env Environment) *Vm {
|
func New(env Environment) *Vm {
|
||||||
|
|
@ -47,6 +50,10 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
|
||||||
|
|
||||||
// User defer pattern to check for an error and, based on the error being nil or not, use all gas and return.
|
// User defer pattern to check for an error and, based on the error being nil or not, use all gas and return.
|
||||||
defer func() {
|
defer func() {
|
||||||
|
if self.After != nil {
|
||||||
|
self.After(context, err)
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
self.Printf(" %v", err).Endl()
|
self.Printf(" %v", err).Endl()
|
||||||
// In case of a VM exception (known exceptions) all gas consumed (panics NOT included).
|
// In case of a VM exception (known exceptions) all gas consumed (panics NOT included).
|
||||||
|
|
@ -65,23 +72,20 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
|
||||||
var (
|
var (
|
||||||
op OpCode
|
op OpCode
|
||||||
|
|
||||||
destinations = analyseJumpDests(context.Code)
|
destinations = analyseJumpDests(context.Code)
|
||||||
mem = NewMemory()
|
mem = NewMemory()
|
||||||
stack = newStack()
|
stack = newStack()
|
||||||
pc uint64 = 0
|
pc = new(big.Int)
|
||||||
step = 0
|
statedb = self.env.State()
|
||||||
statedb = self.env.State()
|
|
||||||
|
|
||||||
jump = func(from uint64, to *big.Int) error {
|
jump = func(from *big.Int, to *big.Int) error {
|
||||||
p := to.Uint64()
|
nop := context.GetOp(to)
|
||||||
|
if !destinations.Has(to) {
|
||||||
nop := context.GetOp(p)
|
return fmt.Errorf("invalid jump destination (%v) %v", nop, to)
|
||||||
if !destinations.Has(p) {
|
|
||||||
return fmt.Errorf("invalid jump destination (%v) %v", nop, p)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.Printf(" ~> %v", to)
|
self.Printf(" ~> %v", to)
|
||||||
pc = to.Uint64()
|
pc = to
|
||||||
|
|
||||||
self.Endl()
|
self.Endl()
|
||||||
|
|
||||||
|
|
@ -98,7 +102,6 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
|
||||||
// The base for all big integer arithmetic
|
// The base for all big integer arithmetic
|
||||||
base := new(big.Int)
|
base := new(big.Int)
|
||||||
|
|
||||||
step++
|
|
||||||
// Get the memory location of pc
|
// Get the memory location of pc
|
||||||
op = context.GetOp(pc)
|
op = context.GetOp(pc)
|
||||||
|
|
||||||
|
|
@ -421,22 +424,11 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
|
||||||
|
|
||||||
self.Printf(" => %v", value)
|
self.Printf(" => %v", value)
|
||||||
case CALLDATALOAD:
|
case CALLDATALOAD:
|
||||||
var (
|
data := getData(callData, stack.pop(), common.Big32)
|
||||||
offset = stack.pop()
|
|
||||||
data = make([]byte, 32)
|
|
||||||
lenData = big.NewInt(int64(len(callData)))
|
|
||||||
)
|
|
||||||
|
|
||||||
if lenData.Cmp(offset) >= 0 {
|
|
||||||
length := new(big.Int).Add(offset, common.Big32)
|
|
||||||
length = common.BigMin(length, lenData)
|
|
||||||
|
|
||||||
copy(data, callData[offset.Int64():length.Int64()])
|
|
||||||
}
|
|
||||||
|
|
||||||
self.Printf(" => 0x%x", data)
|
self.Printf(" => 0x%x", data)
|
||||||
|
|
||||||
stack.push(common.BigD(data))
|
stack.push(common.Bytes2Big(data))
|
||||||
case CALLDATASIZE:
|
case CALLDATASIZE:
|
||||||
l := int64(len(callData))
|
l := int64(len(callData))
|
||||||
stack.push(big.NewInt(l))
|
stack.push(big.NewInt(l))
|
||||||
|
|
@ -535,13 +527,11 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
|
||||||
|
|
||||||
// 0x50 range
|
// 0x50 range
|
||||||
case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32:
|
case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32:
|
||||||
a := uint64(op - PUSH1 + 1)
|
a := big.NewInt(int64(op - PUSH1 + 1))
|
||||||
byts := context.GetRangeValue(pc+1, a)
|
byts := getData(code, new(big.Int).Add(pc, big.NewInt(1)), a)
|
||||||
// push value to stack
|
// push value to stack
|
||||||
stack.push(common.BigD(byts))
|
stack.push(common.Bytes2Big(byts))
|
||||||
pc += a
|
pc.Add(pc, a)
|
||||||
|
|
||||||
step += int(op) - int(PUSH1) + 1
|
|
||||||
|
|
||||||
self.Printf(" => 0x%x", byts)
|
self.Printf(" => 0x%x", byts)
|
||||||
case POP:
|
case POP:
|
||||||
|
|
@ -621,7 +611,8 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
|
||||||
|
|
||||||
case JUMPDEST:
|
case JUMPDEST:
|
||||||
case PC:
|
case PC:
|
||||||
stack.push(big.NewInt(int64(pc)))
|
//stack.push(big.NewInt(int64(pc)))
|
||||||
|
stack.push(pc)
|
||||||
case MSIZE:
|
case MSIZE:
|
||||||
stack.push(big.NewInt(int64(mem.Len())))
|
stack.push(big.NewInt(int64(mem.Len())))
|
||||||
case GAS:
|
case GAS:
|
||||||
|
|
@ -647,7 +638,6 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
|
||||||
|
|
||||||
self.Printf(" (*) 0x0 %v", suberr)
|
self.Printf(" (*) 0x0 %v", suberr)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// gas < len(ret) * CreateDataGas == NO_CODE
|
// gas < len(ret) * CreateDataGas == NO_CODE
|
||||||
dataGas := big.NewInt(int64(len(ret)))
|
dataGas := big.NewInt(int64(len(ret)))
|
||||||
dataGas.Mul(dataGas, GasCreateByte)
|
dataGas.Mul(dataGas, GasCreateByte)
|
||||||
|
|
@ -728,7 +718,7 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
|
||||||
return nil, fmt.Errorf("Invalid opcode %x", op)
|
return nil, fmt.Errorf("Invalid opcode %x", op)
|
||||||
}
|
}
|
||||||
|
|
||||||
pc++
|
pc.Add(pc, One)
|
||||||
|
|
||||||
self.Endl()
|
self.Endl()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,21 +54,17 @@ func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error {
|
||||||
return vm.Transfer(from, to, amount)
|
return vm.Transfer(from, to, amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *VMEnv) vm(addr *common.Address, data []byte, gas, price, value *big.Int) *Execution {
|
|
||||||
return NewExecution(self, addr, data, gas, price, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *VMEnv) Call(me vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
func (self *VMEnv) Call(me vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
||||||
exe := self.vm(&addr, data, gas, price, value)
|
exe := NewExecution(self, &addr, data, gas, price, value)
|
||||||
return exe.Call(addr, me)
|
return exe.Call(addr, me)
|
||||||
}
|
}
|
||||||
func (self *VMEnv) CallCode(me vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
func (self *VMEnv) CallCode(me vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
||||||
maddr := me.Address()
|
maddr := me.Address()
|
||||||
exe := self.vm(&maddr, data, gas, price, value)
|
exe := NewExecution(self, &maddr, data, gas, price, value)
|
||||||
return exe.Call(addr, me)
|
return exe.Call(addr, me)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *VMEnv) Create(me vm.ContextRef, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
|
func (self *VMEnv) Create(me vm.ContextRef, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
|
||||||
exe := self.vm(nil, data, gas, price, value)
|
exe := NewExecution(self, nil, data, gas, price, value)
|
||||||
return exe.Create(me)
|
return exe.Create(me)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,13 +68,8 @@ func Ripemd160(data []byte) []byte {
|
||||||
return ripemd.Sum(nil)
|
return ripemd.Sum(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Ecrecover(data []byte) []byte {
|
func Ecrecover(hash, sig []byte) []byte {
|
||||||
var in = struct {
|
r, _ := secp256k1.RecoverPubkey(hash, sig)
|
||||||
hash []byte
|
|
||||||
sig []byte
|
|
||||||
}{data[:32], data[32:]}
|
|
||||||
|
|
||||||
r, _ := secp256k1.RecoverPubkey(in.hash, in.sig)
|
|
||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
@ -151,9 +146,12 @@ func GenerateKey() (*ecdsa.PrivateKey, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func SigToPub(hash, sig []byte) *ecdsa.PublicKey {
|
func SigToPub(hash, sig []byte) *ecdsa.PublicKey {
|
||||||
s := Ecrecover(append(hash, sig...))
|
s := Ecrecover(hash, sig)
|
||||||
x, y := elliptic.Unmarshal(S256(), s)
|
if s == nil || len(s) != 65 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
x, y := elliptic.Unmarshal(S256(), s)
|
||||||
return &ecdsa.PublicKey{S256(), x, y}
|
return &ecdsa.PublicKey{S256(), x, y}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
95
rpc/api.go
95
rpc/api.go
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/xeth"
|
"github.com/ethereum/go-ethereum/xeth"
|
||||||
)
|
)
|
||||||
|
|
@ -14,7 +13,6 @@ import (
|
||||||
type EthereumApi struct {
|
type EthereumApi struct {
|
||||||
eth *xeth.XEth
|
eth *xeth.XEth
|
||||||
xethMu sync.RWMutex
|
xethMu sync.RWMutex
|
||||||
db common.Database
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEthereumApi(xeth *xeth.XEth) *EthereumApi {
|
func NewEthereumApi(xeth *xeth.XEth) *EthereumApi {
|
||||||
|
|
@ -82,10 +80,6 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := args.requirements(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
v := api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address).Balance()
|
v := api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address).Balance()
|
||||||
*reply = common.ToHex(v.Bytes())
|
*reply = common.ToHex(v.Bytes())
|
||||||
case "eth_getStorage", "eth_storageAt":
|
case "eth_getStorage", "eth_storageAt":
|
||||||
|
|
@ -94,36 +88,25 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := args.requirements(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
*reply = api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address).Storage()
|
*reply = api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address).Storage()
|
||||||
case "eth_getStorageAt":
|
case "eth_getStorageAt":
|
||||||
args := new(GetStorageAtArgs)
|
args := new(GetStorageAtArgs)
|
||||||
if err := json.Unmarshal(req.Params, &args); err != nil {
|
if err := json.Unmarshal(req.Params, &args); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := args.requirements(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
state := api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address)
|
state := api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address)
|
||||||
value := state.StorageString(args.Key)
|
value := state.StorageString(args.Key)
|
||||||
|
|
||||||
*reply = common.Bytes2Hex(value.Bytes())
|
*reply = common.ToHex(value.Bytes())
|
||||||
case "eth_getTransactionCount":
|
case "eth_getTransactionCount":
|
||||||
args := new(GetTxCountArgs)
|
args := new(GetTxCountArgs)
|
||||||
if err := json.Unmarshal(req.Params, &args); err != nil {
|
if err := json.Unmarshal(req.Params, &args); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err := args.requirements()
|
count := api.xethAtStateNum(args.BlockNumber).TxCountAt(args.Address)
|
||||||
if err != nil {
|
*reply = common.ToHex(big.NewInt(int64(count)).Bytes())
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
*reply = api.xethAtStateNum(args.BlockNumber).TxCountAt(args.Address)
|
|
||||||
case "eth_getBlockTransactionCountByHash":
|
case "eth_getBlockTransactionCountByHash":
|
||||||
args := new(GetBlockByHashArgs)
|
args := new(GetBlockByHashArgs)
|
||||||
if err := json.Unmarshal(req.Params, &args); err != nil {
|
if err := json.Unmarshal(req.Params, &args); err != nil {
|
||||||
|
|
@ -163,9 +146,6 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
|
||||||
if err := json.Unmarshal(req.Params, &args); err != nil {
|
if err := json.Unmarshal(req.Params, &args); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := args.requirements(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*reply = api.xethAtStateNum(args.BlockNumber).CodeAt(args.Address)
|
*reply = api.xethAtStateNum(args.BlockNumber).CodeAt(args.Address)
|
||||||
case "eth_sendTransaction", "eth_transact":
|
case "eth_sendTransaction", "eth_transact":
|
||||||
args := new(NewTxArgs)
|
args := new(NewTxArgs)
|
||||||
|
|
@ -173,10 +153,6 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := args.requirements(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := api.xeth().Transact(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data)
|
v, err := api.xeth().Transact(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -267,8 +243,8 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
|
||||||
return NewValidationError("Index", "does not exist")
|
return NewValidationError("Index", "does not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
uhash := br.Uncles[args.Index].Hex()
|
uhash := br.Uncles[args.Index]
|
||||||
uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash))
|
uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash.Hex()))
|
||||||
|
|
||||||
*reply = uncle
|
*reply = uncle
|
||||||
case "eth_getUncleByBlockNumberAndIndex":
|
case "eth_getUncleByBlockNumberAndIndex":
|
||||||
|
|
@ -285,8 +261,8 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
|
||||||
return NewValidationError("Index", "does not exist")
|
return NewValidationError("Index", "does not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
uhash := v.Uncles[args.Index].Hex()
|
uhash := v.Uncles[args.Index]
|
||||||
uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash))
|
uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash.Hex()))
|
||||||
|
|
||||||
*reply = uncle
|
*reply = uncle
|
||||||
case "eth_getCompilers":
|
case "eth_getCompilers":
|
||||||
|
|
@ -300,18 +276,13 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
opts := toFilterOptions(args)
|
id := api.xeth().RegisterFilter(args.Earliest, args.Latest, args.Skip, args.Max, args.Address, args.Topics)
|
||||||
id := api.xeth().RegisterFilter(opts)
|
|
||||||
*reply = common.ToHex(big.NewInt(int64(id)).Bytes())
|
*reply = common.ToHex(big.NewInt(int64(id)).Bytes())
|
||||||
case "eth_newBlockFilter":
|
case "eth_newBlockFilter":
|
||||||
args := new(FilterStringArgs)
|
args := new(FilterStringArgs)
|
||||||
if err := json.Unmarshal(req.Params, &args); err != nil {
|
if err := json.Unmarshal(req.Params, &args); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := args.requirements(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
id := api.xeth().NewFilterString(args.Word)
|
id := api.xeth().NewFilterString(args.Word)
|
||||||
*reply = common.ToHex(big.NewInt(int64(id)).Bytes())
|
*reply = common.ToHex(big.NewInt(int64(id)).Bytes())
|
||||||
case "eth_uninstallFilter":
|
case "eth_uninstallFilter":
|
||||||
|
|
@ -337,8 +308,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
|
||||||
if err := json.Unmarshal(req.Params, &args); err != nil {
|
if err := json.Unmarshal(req.Params, &args); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
opts := toFilterOptions(args)
|
*reply = NewLogsRes(api.xeth().AllLogs(args.Earliest, args.Latest, args.Skip, args.Max, args.Address, args.Topics))
|
||||||
*reply = NewLogsRes(api.xeth().AllLogs(opts))
|
|
||||||
case "eth_getWork":
|
case "eth_getWork":
|
||||||
api.xeth().SetMining(true)
|
api.xeth().SetMining(true)
|
||||||
*reply = api.xeth().RemoteMining().GetWork()
|
*reply = api.xeth().RemoteMining().GetWork()
|
||||||
|
|
@ -347,7 +317,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
|
||||||
if err := json.Unmarshal(req.Params, &args); err != nil {
|
if err := json.Unmarshal(req.Params, &args); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
*reply = api.xeth().RemoteMining().SubmitWork(args.Nonce, args.Digest, args.Header)
|
*reply = api.xeth().RemoteMining().SubmitWork(args.Nonce, common.HexToHash(args.Digest), common.HexToHash(args.Header))
|
||||||
case "db_putString":
|
case "db_putString":
|
||||||
args := new(DbArgs)
|
args := new(DbArgs)
|
||||||
if err := json.Unmarshal(req.Params, &args); err != nil {
|
if err := json.Unmarshal(req.Params, &args); err != nil {
|
||||||
|
|
@ -433,7 +403,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
opts := new(xeth.Options)
|
opts := new(xeth.Options)
|
||||||
opts.From = args.From
|
// opts.From = args.From
|
||||||
opts.To = args.To
|
opts.To = args.To
|
||||||
opts.Topics = args.Topics
|
opts.Topics = args.Topics
|
||||||
id := api.xeth().NewWhisperFilter(opts)
|
id := api.xeth().NewWhisperFilter(opts)
|
||||||
|
|
@ -483,46 +453,3 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
|
||||||
rpclogger.DebugDetailf("Reply: %T %s", reply, reply)
|
rpclogger.DebugDetailf("Reply: %T %s", reply, reply)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func toFilterOptions(options *BlockFilterArgs) *core.FilterOptions {
|
|
||||||
var opts core.FilterOptions
|
|
||||||
|
|
||||||
// Convert optional address slice/string to byte slice
|
|
||||||
if str, ok := options.Address.(string); ok {
|
|
||||||
opts.Address = []common.Address{common.HexToAddress(str)}
|
|
||||||
} else if slice, ok := options.Address.([]interface{}); ok {
|
|
||||||
bslice := make([]common.Address, len(slice))
|
|
||||||
for i, addr := range slice {
|
|
||||||
if saddr, ok := addr.(string); ok {
|
|
||||||
bslice[i] = common.HexToAddress(saddr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
opts.Address = bslice
|
|
||||||
}
|
|
||||||
|
|
||||||
opts.Earliest = options.Earliest
|
|
||||||
opts.Latest = options.Latest
|
|
||||||
|
|
||||||
topics := make([][]common.Hash, len(options.Topics))
|
|
||||||
for i, topicDat := range options.Topics {
|
|
||||||
if slice, ok := topicDat.([]interface{}); ok {
|
|
||||||
topics[i] = make([]common.Hash, len(slice))
|
|
||||||
for j, topic := range slice {
|
|
||||||
topics[i][j] = common.HexToHash(topic.(string))
|
|
||||||
}
|
|
||||||
} else if str, ok := topicDat.(string); ok {
|
|
||||||
topics[i] = []common.Hash{common.HexToHash(str)}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
opts.Topics = topics
|
|
||||||
|
|
||||||
return &opts
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Work() chan<- *types.Block
|
|
||||||
SetWorkCh(chan<- Work)
|
|
||||||
Stop()
|
|
||||||
Start()
|
|
||||||
Rate() uint64
|
|
||||||
*/
|
|
||||||
|
|
|
||||||
476
rpc/args.go
476
rpc/args.go
|
|
@ -1,16 +1,27 @@
|
||||||
package rpc
|
package rpc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func blockHeight(raw interface{}, number *int64) (err error) {
|
const (
|
||||||
|
defaultLogLimit = 100
|
||||||
|
defaultLogOffset = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
func blockHeightFromJson(msg json.RawMessage, number *int64) error {
|
||||||
|
var raw interface{}
|
||||||
|
if err := json.Unmarshal(msg, &raw); err != nil {
|
||||||
|
return NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
return blockHeight(raw, number)
|
||||||
|
}
|
||||||
|
|
||||||
|
func blockHeight(raw interface{}, number *int64) error {
|
||||||
// Parse as integer
|
// Parse as integer
|
||||||
num, ok := raw.(float64)
|
num, ok := raw.(float64)
|
||||||
if ok {
|
if ok {
|
||||||
|
|
@ -21,7 +32,7 @@ func blockHeight(raw interface{}, number *int64) (err error) {
|
||||||
// Parse as string/hexstring
|
// Parse as string/hexstring
|
||||||
str, ok := raw.(string)
|
str, ok := raw.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return NewDecodeParamError("BlockNumber is not a string")
|
return NewInvalidTypeError("", "not a number or string")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch str {
|
switch str {
|
||||||
|
|
@ -36,26 +47,55 @@ func blockHeight(raw interface{}, number *int64) (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func toNumber(v interface{}) (int64, error) {
|
func numString(raw interface{}, number *int64) error {
|
||||||
var str string
|
// Parse as integer
|
||||||
if v != nil {
|
num, ok := raw.(float64)
|
||||||
var ok bool
|
if ok {
|
||||||
str, ok = v.(string)
|
*number = int64(num)
|
||||||
if !ok {
|
return nil
|
||||||
return 0, errors.New("is not a string or undefined")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
str = "latest"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch str {
|
// Parse as string/hexstring
|
||||||
case "latest":
|
str, ok := raw.(string)
|
||||||
return -1, nil
|
if !ok {
|
||||||
default:
|
return NewInvalidTypeError("", "not a number or string")
|
||||||
return int64(common.Big(v.(string)).Int64()), nil
|
|
||||||
}
|
}
|
||||||
|
*number = common.String2Big(str).Int64()
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func toNumber(v interface{}) (int64, error) {
|
||||||
|
// var str string
|
||||||
|
// if v != nil {
|
||||||
|
// var ok bool
|
||||||
|
// str, ok = v.(string)
|
||||||
|
// if !ok {
|
||||||
|
// return 0, errors.New("is not a string or undefined")
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// str = "latest"
|
||||||
|
// }
|
||||||
|
|
||||||
|
// switch str {
|
||||||
|
// case "latest":
|
||||||
|
// return -1, nil
|
||||||
|
// default:
|
||||||
|
// return int64(common.Big(v.(string)).Int64()), nil
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func hashString(raw interface{}, hash *string) error {
|
||||||
|
// argstr, ok := raw.(string)
|
||||||
|
// if !ok {
|
||||||
|
// return NewInvalidTypeError("", "not a string")
|
||||||
|
// }
|
||||||
|
// v := common.IsHex(argstr)
|
||||||
|
// hash = &argstr
|
||||||
|
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
|
||||||
type GetBlockByHashArgs struct {
|
type GetBlockByHashArgs struct {
|
||||||
BlockHash string
|
BlockHash string
|
||||||
IncludeTxs bool
|
IncludeTxs bool
|
||||||
|
|
@ -63,8 +103,8 @@ type GetBlockByHashArgs struct {
|
||||||
|
|
||||||
func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) {
|
func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
var obj []interface{}
|
var obj []interface{}
|
||||||
r := bytes.NewReader(b)
|
|
||||||
if err := json.NewDecoder(r).Decode(&obj); err != nil {
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
return NewDecodeParamError(err.Error())
|
return NewDecodeParamError(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,7 +114,7 @@ func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
|
||||||
argstr, ok := obj[0].(string)
|
argstr, ok := obj[0].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return NewDecodeParamError("BlockHash not a string")
|
return NewInvalidTypeError("blockHash", "not a string")
|
||||||
}
|
}
|
||||||
args.BlockHash = argstr
|
args.BlockHash = argstr
|
||||||
|
|
||||||
|
|
@ -92,8 +132,7 @@ type GetBlockByNumberArgs struct {
|
||||||
|
|
||||||
func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) {
|
func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
var obj []interface{}
|
var obj []interface{}
|
||||||
r := bytes.NewReader(b)
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
if err := json.NewDecoder(r).Decode(&obj); err != nil {
|
|
||||||
return NewDecodeParamError(err.Error())
|
return NewDecodeParamError(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,8 +142,10 @@ func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
|
||||||
if v, ok := obj[0].(float64); ok {
|
if v, ok := obj[0].(float64); ok {
|
||||||
args.BlockNumber = int64(v)
|
args.BlockNumber = int64(v)
|
||||||
|
} else if v, ok := obj[0].(string); ok {
|
||||||
|
args.BlockNumber = common.Big(v).Int64()
|
||||||
} else {
|
} else {
|
||||||
args.BlockNumber = common.Big(obj[0].(string)).Int64()
|
return NewInvalidTypeError("blockNumber", "not a number or string")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(obj) > 1 {
|
if len(obj) > 1 {
|
||||||
|
|
@ -127,7 +168,14 @@ type NewTxArgs struct {
|
||||||
|
|
||||||
func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
|
func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
var obj []json.RawMessage
|
var obj []json.RawMessage
|
||||||
var ext struct{ From, To, Value, Gas, GasPrice, Data string }
|
var ext struct {
|
||||||
|
From string
|
||||||
|
To string
|
||||||
|
Value interface{}
|
||||||
|
Gas interface{}
|
||||||
|
GasPrice interface{}
|
||||||
|
Data string
|
||||||
|
}
|
||||||
|
|
||||||
// Decode byte slice to array of RawMessages
|
// Decode byte slice to array of RawMessages
|
||||||
if err := json.Unmarshal(b, &obj); err != nil {
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
|
@ -144,22 +192,45 @@ func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
return NewDecodeParamError(err.Error())
|
return NewDecodeParamError(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// var ok bool
|
if len(ext.From) == 0 {
|
||||||
|
return NewValidationError("from", "is required")
|
||||||
|
}
|
||||||
|
|
||||||
args.From = ext.From
|
args.From = ext.From
|
||||||
args.To = ext.To
|
args.To = ext.To
|
||||||
args.Value = common.String2Big(ext.Value)
|
|
||||||
args.Gas = common.String2Big(ext.Gas)
|
|
||||||
args.GasPrice = common.String2Big(ext.GasPrice)
|
|
||||||
args.Data = ext.Data
|
args.Data = ext.Data
|
||||||
|
|
||||||
|
var num int64
|
||||||
|
if ext.Value == nil {
|
||||||
|
return NewValidationError("value", "is required")
|
||||||
|
} else {
|
||||||
|
if err := numString(ext.Value, &num); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.Value = big.NewInt(num)
|
||||||
|
|
||||||
|
if ext.Gas == nil {
|
||||||
|
return NewValidationError("gas", "is required")
|
||||||
|
} else {
|
||||||
|
if err := numString(ext.Gas, &num); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.Gas = big.NewInt(num)
|
||||||
|
|
||||||
|
if ext.GasPrice == nil {
|
||||||
|
return NewValidationError("gasprice", "is required")
|
||||||
|
} else {
|
||||||
|
if err := numString(ext.GasPrice, &num); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.GasPrice = big.NewInt(num)
|
||||||
|
|
||||||
// Check for optional BlockNumber param
|
// Check for optional BlockNumber param
|
||||||
if len(obj) > 1 {
|
if len(obj) > 1 {
|
||||||
var raw interface{}
|
if err := blockHeightFromJson(obj[1], &args.BlockNumber); err != nil {
|
||||||
if err = json.Unmarshal(obj[1], &raw); err != nil {
|
|
||||||
return NewDecodeParamError(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := blockHeight(raw, &args.BlockNumber); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -167,13 +238,6 @@ func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (args *NewTxArgs) requirements() error {
|
|
||||||
if len(args.From) == 0 {
|
|
||||||
return NewValidationError("From", "Is required")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetStorageArgs struct {
|
type GetStorageArgs struct {
|
||||||
Address string
|
Address string
|
||||||
BlockNumber int64
|
BlockNumber int64
|
||||||
|
|
@ -191,7 +255,7 @@ func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
|
||||||
addstr, ok := obj[0].(string)
|
addstr, ok := obj[0].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return NewDecodeParamError("Address is not a string")
|
return NewInvalidTypeError("address", "not a string")
|
||||||
}
|
}
|
||||||
args.Address = addstr
|
args.Address = addstr
|
||||||
|
|
||||||
|
|
@ -204,13 +268,6 @@ func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (args *GetStorageArgs) requirements() error {
|
|
||||||
if len(args.Address) == 0 {
|
|
||||||
return NewValidationError("Address", "cannot be blank")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetStorageAtArgs struct {
|
type GetStorageAtArgs struct {
|
||||||
Address string
|
Address string
|
||||||
Key string
|
Key string
|
||||||
|
|
@ -229,13 +286,13 @@ func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
|
||||||
addstr, ok := obj[0].(string)
|
addstr, ok := obj[0].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return NewDecodeParamError("Address is not a string")
|
return NewInvalidTypeError("address", "not a string")
|
||||||
}
|
}
|
||||||
args.Address = addstr
|
args.Address = addstr
|
||||||
|
|
||||||
keystr, ok := obj[1].(string)
|
keystr, ok := obj[1].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return NewDecodeParamError("Key is not a string")
|
return NewInvalidTypeError("key", "not a string")
|
||||||
}
|
}
|
||||||
args.Key = keystr
|
args.Key = keystr
|
||||||
|
|
||||||
|
|
@ -248,17 +305,6 @@ func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (args *GetStorageAtArgs) requirements() error {
|
|
||||||
if len(args.Address) == 0 {
|
|
||||||
return NewValidationError("Address", "cannot be blank")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(args.Key) == 0 {
|
|
||||||
return NewValidationError("Key", "cannot be blank")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetTxCountArgs struct {
|
type GetTxCountArgs struct {
|
||||||
Address string
|
Address string
|
||||||
BlockNumber int64
|
BlockNumber int64
|
||||||
|
|
@ -276,7 +322,7 @@ func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
|
||||||
addstr, ok := obj[0].(string)
|
addstr, ok := obj[0].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return NewDecodeParamError("Address is not a string")
|
return NewInvalidTypeError("address", "not a string")
|
||||||
}
|
}
|
||||||
args.Address = addstr
|
args.Address = addstr
|
||||||
|
|
||||||
|
|
@ -289,13 +335,6 @@ func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (args *GetTxCountArgs) requirements() error {
|
|
||||||
if len(args.Address) == 0 {
|
|
||||||
return NewValidationError("Address", "cannot be blank")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetBalanceArgs struct {
|
type GetBalanceArgs struct {
|
||||||
Address string
|
Address string
|
||||||
BlockNumber int64
|
BlockNumber int64
|
||||||
|
|
@ -313,7 +352,7 @@ func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
|
||||||
addstr, ok := obj[0].(string)
|
addstr, ok := obj[0].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return NewDecodeParamError("Address is not a string")
|
return NewInvalidTypeError("address", "not a string")
|
||||||
}
|
}
|
||||||
args.Address = addstr
|
args.Address = addstr
|
||||||
|
|
||||||
|
|
@ -326,13 +365,6 @@ func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (args *GetBalanceArgs) requirements() error {
|
|
||||||
if len(args.Address) == 0 {
|
|
||||||
return NewValidationError("Address", "cannot be blank")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetDataArgs struct {
|
type GetDataArgs struct {
|
||||||
Address string
|
Address string
|
||||||
BlockNumber int64
|
BlockNumber int64
|
||||||
|
|
@ -350,7 +382,7 @@ func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
|
||||||
addstr, ok := obj[0].(string)
|
addstr, ok := obj[0].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return NewDecodeParamError("Address is not a string")
|
return NewInvalidTypeError("address", "not a string")
|
||||||
}
|
}
|
||||||
args.Address = addstr
|
args.Address = addstr
|
||||||
|
|
||||||
|
|
@ -363,13 +395,6 @@ func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (args *GetDataArgs) requirements() error {
|
|
||||||
if len(args.Address) == 0 {
|
|
||||||
return NewValidationError("Address", "cannot be blank")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type BlockNumIndexArgs struct {
|
type BlockNumIndexArgs struct {
|
||||||
BlockNumber int64
|
BlockNumber int64
|
||||||
Index int64
|
Index int64
|
||||||
|
|
@ -377,8 +402,7 @@ type BlockNumIndexArgs struct {
|
||||||
|
|
||||||
func (args *BlockNumIndexArgs) UnmarshalJSON(b []byte) (err error) {
|
func (args *BlockNumIndexArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
var obj []interface{}
|
var obj []interface{}
|
||||||
r := bytes.NewReader(b)
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
if err := json.NewDecoder(r).Decode(&obj); err != nil {
|
|
||||||
return NewDecodeParamError(err.Error())
|
return NewDecodeParamError(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -386,16 +410,14 @@ func (args *BlockNumIndexArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
return NewInsufficientParamsError(len(obj), 1)
|
return NewInsufficientParamsError(len(obj), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
arg0, ok := obj[0].(string)
|
if err := blockHeight(obj[0], &args.BlockNumber); err != nil {
|
||||||
if !ok {
|
return err
|
||||||
return NewDecodeParamError("BlockNumber is not string")
|
|
||||||
}
|
}
|
||||||
args.BlockNumber = common.Big(arg0).Int64()
|
|
||||||
|
|
||||||
if len(obj) > 1 {
|
if len(obj) > 1 {
|
||||||
arg1, ok := obj[1].(string)
|
arg1, ok := obj[1].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return NewDecodeParamError("Index not a string")
|
return NewInvalidTypeError("index", "not a string")
|
||||||
}
|
}
|
||||||
args.Index = common.Big(arg1).Int64()
|
args.Index = common.Big(arg1).Int64()
|
||||||
}
|
}
|
||||||
|
|
@ -410,8 +432,7 @@ type HashIndexArgs struct {
|
||||||
|
|
||||||
func (args *HashIndexArgs) UnmarshalJSON(b []byte) (err error) {
|
func (args *HashIndexArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
var obj []interface{}
|
var obj []interface{}
|
||||||
r := bytes.NewReader(b)
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
if err := json.NewDecoder(r).Decode(&obj); err != nil {
|
|
||||||
return NewDecodeParamError(err.Error())
|
return NewDecodeParamError(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -421,14 +442,14 @@ func (args *HashIndexArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
|
||||||
arg0, ok := obj[0].(string)
|
arg0, ok := obj[0].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return NewDecodeParamError("Hash not a string")
|
return NewInvalidTypeError("hash", "not a string")
|
||||||
}
|
}
|
||||||
args.Hash = arg0
|
args.Hash = arg0
|
||||||
|
|
||||||
if len(obj) > 1 {
|
if len(obj) > 1 {
|
||||||
arg1, ok := obj[1].(string)
|
arg1, ok := obj[1].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return NewDecodeParamError("Index not a string")
|
return NewInvalidTypeError("index", "not a string")
|
||||||
}
|
}
|
||||||
args.Index = common.Big(arg1).Int64()
|
args.Index = common.Big(arg1).Int64()
|
||||||
}
|
}
|
||||||
|
|
@ -442,36 +463,39 @@ type Sha3Args struct {
|
||||||
|
|
||||||
func (args *Sha3Args) UnmarshalJSON(b []byte) (err error) {
|
func (args *Sha3Args) UnmarshalJSON(b []byte) (err error) {
|
||||||
var obj []interface{}
|
var obj []interface{}
|
||||||
r := bytes.NewReader(b)
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
if err := json.NewDecoder(r).Decode(&obj); err != nil {
|
|
||||||
return NewDecodeParamError(err.Error())
|
return NewDecodeParamError(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(obj) < 1 {
|
if len(obj) < 1 {
|
||||||
return NewInsufficientParamsError(len(obj), 1)
|
return NewInsufficientParamsError(len(obj), 1)
|
||||||
}
|
}
|
||||||
args.Data = obj[0].(string)
|
|
||||||
|
|
||||||
|
argstr, ok := obj[0].(string)
|
||||||
|
if !ok {
|
||||||
|
return NewInvalidTypeError("data", "is not a string")
|
||||||
|
}
|
||||||
|
args.Data = argstr
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type BlockFilterArgs struct {
|
type BlockFilterArgs struct {
|
||||||
Earliest int64
|
Earliest int64
|
||||||
Latest int64
|
Latest int64
|
||||||
Address interface{}
|
Address []string
|
||||||
Topics []interface{}
|
Topics [][]string
|
||||||
Skip int
|
Skip int
|
||||||
Max int
|
Max int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (args *BlockFilterArgs) UnmarshalJSON(b []byte) (err error) {
|
func (args *BlockFilterArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
var obj []struct {
|
var obj []struct {
|
||||||
FromBlock interface{} `json:"fromBlock"`
|
FromBlock interface{} `json:"fromBlock"`
|
||||||
ToBlock interface{} `json:"toBlock"`
|
ToBlock interface{} `json:"toBlock"`
|
||||||
Limit string `json:"limit"`
|
Limit interface{} `json:"limit"`
|
||||||
Offset string `json:"offset"`
|
Offset interface{} `json:"offset"`
|
||||||
Address string `json:"address"`
|
Address interface{} `json:"address"`
|
||||||
Topics []interface{} `json:"topics"`
|
Topics interface{} `json:"topics"`
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = json.Unmarshal(b, &obj); err != nil {
|
if err = json.Unmarshal(b, &obj); err != nil {
|
||||||
|
|
@ -482,19 +506,113 @@ func (args *BlockFilterArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
return NewInsufficientParamsError(len(obj), 1)
|
return NewInsufficientParamsError(len(obj), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
args.Earliest, err = toNumber(obj[0].ToBlock)
|
// args.Earliest, err = toNumber(obj[0].ToBlock)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return NewDecodeParamError(fmt.Sprintf("FromBlock %v", err))
|
// return NewDecodeParamError(fmt.Sprintf("FromBlock %v", err))
|
||||||
|
// }
|
||||||
|
// args.Latest, err = toNumber(obj[0].FromBlock)
|
||||||
|
// if err != nil {
|
||||||
|
// return NewDecodeParamError(fmt.Sprintf("ToBlock %v", err))
|
||||||
|
|
||||||
|
var num int64
|
||||||
|
|
||||||
|
// if blank then latest
|
||||||
|
if obj[0].FromBlock == nil {
|
||||||
|
num = -1
|
||||||
|
} else {
|
||||||
|
if err := blockHeight(obj[0].FromBlock, &num); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
args.Latest, err = toNumber(obj[0].FromBlock)
|
// if -2 or other "silly" number, use latest
|
||||||
if err != nil {
|
if num < 0 {
|
||||||
return NewDecodeParamError(fmt.Sprintf("ToBlock %v", err))
|
args.Earliest = -1 //latest block
|
||||||
|
} else {
|
||||||
|
args.Earliest = num
|
||||||
}
|
}
|
||||||
|
|
||||||
args.Max = int(common.Big(obj[0].Limit).Int64())
|
// if blank than latest
|
||||||
args.Skip = int(common.Big(obj[0].Offset).Int64())
|
if obj[0].ToBlock == nil {
|
||||||
args.Address = obj[0].Address
|
num = -1
|
||||||
args.Topics = obj[0].Topics
|
} else {
|
||||||
|
if err := blockHeight(obj[0].ToBlock, &num); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.Latest = num
|
||||||
|
|
||||||
|
if obj[0].Limit == nil {
|
||||||
|
num = defaultLogLimit
|
||||||
|
} else {
|
||||||
|
if err := numString(obj[0].Limit, &num); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.Max = int(num)
|
||||||
|
|
||||||
|
if obj[0].Offset == nil {
|
||||||
|
num = defaultLogOffset
|
||||||
|
} else {
|
||||||
|
if err := numString(obj[0].Offset, &num); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.Skip = int(num)
|
||||||
|
|
||||||
|
if obj[0].Address != nil {
|
||||||
|
marg, ok := obj[0].Address.([]interface{})
|
||||||
|
if ok {
|
||||||
|
v := make([]string, len(marg))
|
||||||
|
for i, arg := range marg {
|
||||||
|
argstr, ok := arg.(string)
|
||||||
|
if !ok {
|
||||||
|
return NewInvalidTypeError(fmt.Sprintf("address[%d]", i), "is not a string")
|
||||||
|
}
|
||||||
|
v[i] = argstr
|
||||||
|
}
|
||||||
|
args.Address = v
|
||||||
|
} else {
|
||||||
|
argstr, ok := obj[0].Address.(string)
|
||||||
|
if ok {
|
||||||
|
v := make([]string, 1)
|
||||||
|
v[0] = argstr
|
||||||
|
args.Address = v
|
||||||
|
} else {
|
||||||
|
return NewInvalidTypeError("address", "is not a string or array")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if obj[0].Topics != nil {
|
||||||
|
other, ok := obj[0].Topics.([]interface{})
|
||||||
|
if ok {
|
||||||
|
topicdbl := make([][]string, len(other))
|
||||||
|
for i, iv := range other {
|
||||||
|
if argstr, ok := iv.(string); ok {
|
||||||
|
// Found a string, push into first element of array
|
||||||
|
topicsgl := make([]string, 1)
|
||||||
|
topicsgl[0] = argstr
|
||||||
|
topicdbl[i] = topicsgl
|
||||||
|
} else if argarray, ok := iv.([]interface{}); ok {
|
||||||
|
// Found an array of other
|
||||||
|
topicdbl[i] = make([]string, len(argarray))
|
||||||
|
for j, jv := range argarray {
|
||||||
|
if v, ok := jv.(string); ok {
|
||||||
|
topicdbl[i][j] = v
|
||||||
|
} else {
|
||||||
|
return NewInvalidTypeError(fmt.Sprintf("topic[%d][%d]", i, j), "is not a string")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return NewInvalidTypeError(fmt.Sprintf("topic[%d]", i), "not a string or array")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.Topics = topicdbl
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
return NewInvalidTypeError("topic", "is not a string or array")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -519,19 +637,19 @@ func (args *DbArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
var ok bool
|
var ok bool
|
||||||
|
|
||||||
if objstr, ok = obj[0].(string); !ok {
|
if objstr, ok = obj[0].(string); !ok {
|
||||||
return NewDecodeParamError("Database is not a string")
|
return NewInvalidTypeError("database", "not a string")
|
||||||
}
|
}
|
||||||
args.Database = objstr
|
args.Database = objstr
|
||||||
|
|
||||||
if objstr, ok = obj[1].(string); !ok {
|
if objstr, ok = obj[1].(string); !ok {
|
||||||
return NewDecodeParamError("Key is not a string")
|
return NewInvalidTypeError("key", "not a string")
|
||||||
}
|
}
|
||||||
args.Key = objstr
|
args.Key = objstr
|
||||||
|
|
||||||
if len(obj) > 2 {
|
if len(obj) > 2 {
|
||||||
objstr, ok = obj[2].(string)
|
objstr, ok = obj[2].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return NewDecodeParamError("Value is not a string")
|
return NewInvalidTypeError("value", "not a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
args.Value = []byte(objstr)
|
args.Value = []byte(objstr)
|
||||||
|
|
@ -570,19 +688,19 @@ func (args *DbHexArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
var ok bool
|
var ok bool
|
||||||
|
|
||||||
if objstr, ok = obj[0].(string); !ok {
|
if objstr, ok = obj[0].(string); !ok {
|
||||||
return NewDecodeParamError("Database is not a string")
|
return NewInvalidTypeError("database", "not a string")
|
||||||
}
|
}
|
||||||
args.Database = objstr
|
args.Database = objstr
|
||||||
|
|
||||||
if objstr, ok = obj[1].(string); !ok {
|
if objstr, ok = obj[1].(string); !ok {
|
||||||
return NewDecodeParamError("Key is not a string")
|
return NewInvalidTypeError("key", "not a string")
|
||||||
}
|
}
|
||||||
args.Key = objstr
|
args.Key = objstr
|
||||||
|
|
||||||
if len(obj) > 2 {
|
if len(obj) > 2 {
|
||||||
objstr, ok = obj[2].(string)
|
objstr, ok = obj[2].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return NewDecodeParamError("Value is not a string")
|
return NewInvalidTypeError("value", "not a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
args.Value = common.FromHex(objstr)
|
args.Value = common.FromHex(objstr)
|
||||||
|
|
@ -616,8 +734,8 @@ func (args *WhisperMessageArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
To string
|
To string
|
||||||
From string
|
From string
|
||||||
Topics []string
|
Topics []string
|
||||||
Priority string
|
Priority interface{}
|
||||||
Ttl string
|
Ttl interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = json.Unmarshal(b, &obj); err != nil {
|
if err = json.Unmarshal(b, &obj); err != nil {
|
||||||
|
|
@ -631,8 +749,17 @@ func (args *WhisperMessageArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
args.To = obj[0].To
|
args.To = obj[0].To
|
||||||
args.From = obj[0].From
|
args.From = obj[0].From
|
||||||
args.Topics = obj[0].Topics
|
args.Topics = obj[0].Topics
|
||||||
args.Priority = uint32(common.Big(obj[0].Priority).Int64())
|
|
||||||
args.Ttl = uint32(common.Big(obj[0].Ttl).Int64())
|
var num int64
|
||||||
|
if err := numString(obj[0].Priority, &num); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
args.Priority = uint32(num)
|
||||||
|
|
||||||
|
if err := numString(obj[0].Ttl, &num); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
args.Ttl = uint32(num)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -643,14 +770,18 @@ type CompileArgs struct {
|
||||||
|
|
||||||
func (args *CompileArgs) UnmarshalJSON(b []byte) (err error) {
|
func (args *CompileArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
var obj []interface{}
|
var obj []interface{}
|
||||||
r := bytes.NewReader(b)
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
if err := json.NewDecoder(r).Decode(&obj); err != nil {
|
|
||||||
return NewDecodeParamError(err.Error())
|
return NewDecodeParamError(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(obj) > 0 {
|
if len(obj) < 1 {
|
||||||
args.Source = obj[0].(string)
|
return NewInsufficientParamsError(len(obj), 1)
|
||||||
}
|
}
|
||||||
|
argstr, ok := obj[0].(string)
|
||||||
|
if !ok {
|
||||||
|
return NewInvalidTypeError("arg0", "is not a string")
|
||||||
|
}
|
||||||
|
args.Source = argstr
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -661,8 +792,7 @@ type FilterStringArgs struct {
|
||||||
|
|
||||||
func (args *FilterStringArgs) UnmarshalJSON(b []byte) (err error) {
|
func (args *FilterStringArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
var obj []interface{}
|
var obj []interface{}
|
||||||
r := bytes.NewReader(b)
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
if err := json.NewDecoder(r).Decode(&obj); err != nil {
|
|
||||||
return NewDecodeParamError(err.Error())
|
return NewDecodeParamError(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -673,20 +803,15 @@ func (args *FilterStringArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
var argstr string
|
var argstr string
|
||||||
argstr, ok := obj[0].(string)
|
argstr, ok := obj[0].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return NewDecodeParamError("Filter is not a string")
|
return NewInvalidTypeError("filter", "not a string")
|
||||||
}
|
}
|
||||||
args.Word = argstr
|
switch argstr {
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (args *FilterStringArgs) requirements() error {
|
|
||||||
switch args.Word {
|
|
||||||
case "latest", "pending":
|
case "latest", "pending":
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
return NewValidationError("Word", "Must be `latest` or `pending`")
|
return NewValidationError("Word", "Must be `latest` or `pending`")
|
||||||
}
|
}
|
||||||
|
args.Word = argstr
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -695,9 +820,8 @@ type FilterIdArgs struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (args *FilterIdArgs) UnmarshalJSON(b []byte) (err error) {
|
func (args *FilterIdArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
var obj []string
|
var obj []interface{}
|
||||||
r := bytes.NewReader(b)
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
if err := json.NewDecoder(r).Decode(&obj); err != nil {
|
|
||||||
return NewDecodeParamError(err.Error())
|
return NewDecodeParamError(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -705,7 +829,11 @@ func (args *FilterIdArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
return NewInsufficientParamsError(len(obj), 1)
|
return NewInsufficientParamsError(len(obj), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
args.Id = int(common.Big(obj[0]).Int64())
|
var num int64
|
||||||
|
if err := numString(obj[0], &num); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
args.Id = int(num)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -715,9 +843,8 @@ type WhisperIdentityArgs struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (args *WhisperIdentityArgs) UnmarshalJSON(b []byte) (err error) {
|
func (args *WhisperIdentityArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
var obj []string
|
var obj []interface{}
|
||||||
r := bytes.NewReader(b)
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
if err := json.NewDecoder(r).Decode(&obj); err != nil {
|
|
||||||
return NewDecodeParamError(err.Error())
|
return NewDecodeParamError(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -725,7 +852,14 @@ func (args *WhisperIdentityArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
return NewInsufficientParamsError(len(obj), 1)
|
return NewInsufficientParamsError(len(obj), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
args.Identity = obj[0]
|
argstr, ok := obj[0].(string)
|
||||||
|
if !ok {
|
||||||
|
return NewInvalidTypeError("arg0", "not a string")
|
||||||
|
}
|
||||||
|
// if !common.IsHex(argstr) {
|
||||||
|
// return NewValidationError("arg0", "not a hexstring")
|
||||||
|
// }
|
||||||
|
args.Identity = argstr
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -738,9 +872,8 @@ type WhisperFilterArgs struct {
|
||||||
|
|
||||||
func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) {
|
func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
var obj []struct {
|
var obj []struct {
|
||||||
To string
|
To interface{}
|
||||||
From string
|
Topics []interface{}
|
||||||
Topics []string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = json.Unmarshal(b, &obj); err != nil {
|
if err = json.Unmarshal(b, &obj); err != nil {
|
||||||
|
|
@ -751,17 +884,30 @@ func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
return NewInsufficientParamsError(len(obj), 1)
|
return NewInsufficientParamsError(len(obj), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
args.To = obj[0].To
|
var argstr string
|
||||||
args.From = obj[0].From
|
argstr, ok := obj[0].To.(string)
|
||||||
args.Topics = obj[0].Topics
|
if !ok {
|
||||||
|
return NewInvalidTypeError("to", "is not a string")
|
||||||
|
}
|
||||||
|
args.To = argstr
|
||||||
|
|
||||||
|
t := make([]string, len(obj[0].Topics))
|
||||||
|
for i, j := range obj[0].Topics {
|
||||||
|
argstr, ok := j.(string)
|
||||||
|
if !ok {
|
||||||
|
return NewInvalidTypeError("topics["+string(i)+"]", "is not a string")
|
||||||
|
}
|
||||||
|
t[i] = argstr
|
||||||
|
}
|
||||||
|
args.Topics = t
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type SubmitWorkArgs struct {
|
type SubmitWorkArgs struct {
|
||||||
Nonce uint64
|
Nonce uint64
|
||||||
Header common.Hash
|
Header string
|
||||||
Digest common.Hash
|
Digest string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (args *SubmitWorkArgs) UnmarshalJSON(b []byte) (err error) {
|
func (args *SubmitWorkArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
|
@ -777,21 +923,21 @@ func (args *SubmitWorkArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
var objstr string
|
var objstr string
|
||||||
var ok bool
|
var ok bool
|
||||||
if objstr, ok = obj[0].(string); !ok {
|
if objstr, ok = obj[0].(string); !ok {
|
||||||
return NewDecodeParamError("Nonce is not a string")
|
return NewInvalidTypeError("nonce", "not a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
args.Nonce = common.String2Big(objstr).Uint64()
|
args.Nonce = common.String2Big(objstr).Uint64()
|
||||||
if objstr, ok = obj[1].(string); !ok {
|
if objstr, ok = obj[1].(string); !ok {
|
||||||
return NewDecodeParamError("Header is not a string")
|
return NewInvalidTypeError("header", "not a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
args.Header = common.HexToHash(objstr)
|
args.Header = objstr
|
||||||
|
|
||||||
if objstr, ok = obj[2].(string); !ok {
|
if objstr, ok = obj[2].(string); !ok {
|
||||||
return NewDecodeParamError("Digest is not a string")
|
return NewInvalidTypeError("digest", "not a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
args.Digest = common.HexToHash(objstr)
|
args.Digest = objstr
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1366
rpc/args_test.go
1366
rpc/args_test.go
File diff suppressed because it is too large
Load diff
|
|
@ -76,7 +76,7 @@ func RpcResponse(api *EthereumApi, request *RpcRequest) *interface{} {
|
||||||
case *NotImplementedError:
|
case *NotImplementedError:
|
||||||
jsonerr := &RpcErrorObject{-32601, reserr.Error()}
|
jsonerr := &RpcErrorObject{-32601, reserr.Error()}
|
||||||
response = &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: request.Id, Error: jsonerr}
|
response = &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: request.Id, Error: jsonerr}
|
||||||
case *DecodeParamError, *InsufficientParamsError, *ValidationError:
|
case *DecodeParamError, *InsufficientParamsError, *ValidationError, *InvalidTypeError:
|
||||||
jsonerr := &RpcErrorObject{-32602, reserr.Error()}
|
jsonerr := &RpcErrorObject{-32602, reserr.Error()}
|
||||||
response = &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: request.Id, Error: jsonerr}
|
response = &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: request.Id, Error: jsonerr}
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,22 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type InvalidTypeError struct {
|
||||||
|
method string
|
||||||
|
msg string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *InvalidTypeError) Error() string {
|
||||||
|
return fmt.Sprintf("invalid type on field %s: %s", e.method, e.msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewInvalidTypeError(method, msg string) *InvalidTypeError {
|
||||||
|
return &InvalidTypeError{
|
||||||
|
method: method,
|
||||||
|
msg: msg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type InsufficientParamsError struct {
|
type InsufficientParamsError struct {
|
||||||
have int
|
have int
|
||||||
want int
|
want int
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,15 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestInvalidTypeError(t *testing.T) {
|
||||||
|
err := NewInvalidTypeError("testField", "not string")
|
||||||
|
expected := "invalid type on field testField: not string"
|
||||||
|
|
||||||
|
if err.Error() != expected {
|
||||||
|
t.Error(err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestInsufficientParamsError(t *testing.T) {
|
func TestInsufficientParamsError(t *testing.T) {
|
||||||
err := NewInsufficientParamsError(0, 1)
|
err := NewInsufficientParamsError(0, 1)
|
||||||
expected := "insufficient params, want 1 have 0"
|
expected := "insufficient params, want 1 have 0"
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ func (b *BlockRes) MarshalJSON() ([]byte, error) {
|
||||||
ext.Difficulty = common.ToHex(b.Difficulty.Bytes())
|
ext.Difficulty = common.ToHex(b.Difficulty.Bytes())
|
||||||
ext.TotalDifficulty = common.ToHex(b.TotalDifficulty.Bytes())
|
ext.TotalDifficulty = common.ToHex(b.TotalDifficulty.Bytes())
|
||||||
ext.Size = common.ToHex(b.Size.Bytes())
|
ext.Size = common.ToHex(b.Size.Bytes())
|
||||||
// ext.ExtraData = common.ToHex(b.ExtraData)
|
ext.ExtraData = common.ToHex(b.ExtraData)
|
||||||
ext.GasLimit = common.ToHex(b.GasLimit.Bytes())
|
ext.GasLimit = common.ToHex(b.GasLimit.Bytes())
|
||||||
// ext.MinGasPrice = common.ToHex(big.NewInt(b.MinGasPrice).Bytes())
|
// ext.MinGasPrice = common.ToHex(big.NewInt(b.MinGasPrice).Bytes())
|
||||||
ext.GasUsed = common.ToHex(b.GasUsed.Bytes())
|
ext.GasUsed = common.ToHex(b.GasUsed.Bytes())
|
||||||
|
|
@ -111,7 +111,7 @@ func NewBlockRes(block *types.Block) *BlockRes {
|
||||||
res.Difficulty = block.Difficulty()
|
res.Difficulty = block.Difficulty()
|
||||||
res.TotalDifficulty = block.Td
|
res.TotalDifficulty = block.Td
|
||||||
res.Size = big.NewInt(int64(block.Size()))
|
res.Size = big.NewInt(int64(block.Size()))
|
||||||
// res.ExtraData =
|
res.ExtraData = []byte(block.Header().Extra)
|
||||||
res.GasLimit = block.GasLimit()
|
res.GasLimit = block.GasLimit()
|
||||||
// res.MinGasPrice =
|
// res.MinGasPrice =
|
||||||
res.GasUsed = block.GasUsed()
|
res.GasUsed = block.GasUsed()
|
||||||
|
|
@ -243,8 +243,8 @@ func (l *LogRes) MarshalJSON() ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ext.Address = l.Address.Hex()
|
ext.Address = l.Address.Hex()
|
||||||
ext.Data = common.Bytes2Hex(l.Data)
|
ext.Data = common.ToHex(l.Data)
|
||||||
ext.Number = common.Bytes2Hex(big.NewInt(int64(l.Number)).Bytes())
|
ext.Number = common.ToHex(big.NewInt(int64(l.Number)).Bytes())
|
||||||
ext.Topics = make([]string, len(l.Topics))
|
ext.Topics = make([]string, len(l.Topics))
|
||||||
for i, v := range l.Topics {
|
for i, v := range l.Topics {
|
||||||
ext.Topics[i] = v.Hex()
|
ext.Topics[i] = v.Hex()
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ var (
|
||||||
extensions = []string{".go", ".js", ".qml"}
|
extensions = []string{".go", ".js", ".qml"}
|
||||||
|
|
||||||
// paths with any of these prefixes will be skipped
|
// paths with any of these prefixes will be skipped
|
||||||
skipPrefixes = []string{"tests/files/", "cmd/mist/assets/ext/", "cmd/mist/assets/muted/"}
|
skipPrefixes = []string{"Godeps/", "tests/files/", "cmd/mist/assets/ext/", "cmd/mist/assets/muted/"}
|
||||||
|
|
||||||
// paths with this prefix are licensed as GPL. all other files are LGPL.
|
// paths with this prefix are licensed as GPL. all other files are LGPL.
|
||||||
gplPrefixes = []string{"cmd/"}
|
gplPrefixes = []string{"cmd/"}
|
||||||
|
|
@ -190,7 +190,7 @@ func fileInfo(file string) (*info, error) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmd := exec.Command("git", "log", "--follow", "--find-copies", "--pretty=format:%aI | %aN <%aE>", "--", file)
|
cmd := exec.Command("git", "log", "--follow", "--find-copies", "--pretty=format:%ai | %aN <%aE>", "--", file)
|
||||||
err := doLines(cmd, func(line string) {
|
err := doLines(cmd, func(line string) {
|
||||||
sep := strings.IndexByte(line, '|')
|
sep := strings.IndexByte(line, '|')
|
||||||
year, name := line[:4], line[sep+2:]
|
year, name := line[:4], line[sep+2:]
|
||||||
|
|
|
||||||
42
xeth/xeth.go
42
xeth/xeth.go
|
|
@ -110,6 +110,24 @@ func (self *XEth) stop() {
|
||||||
close(self.quit)
|
close(self.quit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cAddress(a []string) []common.Address {
|
||||||
|
bslice := make([]common.Address, len(a))
|
||||||
|
for i, addr := range a {
|
||||||
|
bslice[i] = common.HexToAddress(addr)
|
||||||
|
}
|
||||||
|
return bslice
|
||||||
|
}
|
||||||
|
|
||||||
|
func cTopics(t [][]string) [][]common.Hash {
|
||||||
|
topics := make([][]common.Hash, len(t))
|
||||||
|
for i, iv := range t {
|
||||||
|
for j, jv := range iv {
|
||||||
|
topics[i][j] = common.HexToHash(jv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return topics
|
||||||
|
}
|
||||||
|
|
||||||
func (self *XEth) DefaultGas() *big.Int { return defaultGas }
|
func (self *XEth) DefaultGas() *big.Int { return defaultGas }
|
||||||
func (self *XEth) DefaultGasPrice() *big.Int { return defaultGasPrice }
|
func (self *XEth) DefaultGasPrice() *big.Int { return defaultGasPrice }
|
||||||
|
|
||||||
|
|
@ -228,15 +246,15 @@ func (self *XEth) IsMining() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *XEth) EthVersion() string {
|
func (self *XEth) EthVersion() string {
|
||||||
return string(self.backend.EthVersion())
|
return fmt.Sprintf("%d", self.backend.EthVersion())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *XEth) NetworkVersion() string {
|
func (self *XEth) NetworkVersion() string {
|
||||||
return string(self.backend.NetVersion())
|
return fmt.Sprintf("%d", self.backend.NetVersion())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *XEth) WhisperVersion() string {
|
func (self *XEth) WhisperVersion() string {
|
||||||
return string(self.backend.ShhVersion())
|
return fmt.Sprintf("%d", self.backend.ShhVersion())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *XEth) ClientVersion() string {
|
func (self *XEth) ClientVersion() string {
|
||||||
|
|
@ -301,10 +319,15 @@ func (self *XEth) SecretToAddress(key string) string {
|
||||||
return common.ToHex(pair.Address())
|
return common.ToHex(pair.Address())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *XEth) RegisterFilter(args *core.FilterOptions) int {
|
func (self *XEth) RegisterFilter(earliest, latest int64, skip, max int, address []string, topics [][]string) int {
|
||||||
var id int
|
var id int
|
||||||
filter := core.NewFilter(self.backend)
|
filter := core.NewFilter(self.backend)
|
||||||
filter.SetOptions(args)
|
filter.SetEarliestBlock(earliest)
|
||||||
|
filter.SetLatestBlock(latest)
|
||||||
|
filter.SetSkip(skip)
|
||||||
|
filter.SetMax(max)
|
||||||
|
filter.SetAddress(cAddress(address))
|
||||||
|
filter.SetTopics(cTopics(topics))
|
||||||
filter.LogsCallback = func(logs state.Logs) {
|
filter.LogsCallback = func(logs state.Logs) {
|
||||||
self.logMut.Lock()
|
self.logMut.Lock()
|
||||||
defer self.logMut.Unlock()
|
defer self.logMut.Unlock()
|
||||||
|
|
@ -380,9 +403,14 @@ func (self *XEth) Logs(id int) state.Logs {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *XEth) AllLogs(args *core.FilterOptions) state.Logs {
|
func (self *XEth) AllLogs(earliest, latest int64, skip, max int, address []string, topics [][]string) state.Logs {
|
||||||
filter := core.NewFilter(self.backend)
|
filter := core.NewFilter(self.backend)
|
||||||
filter.SetOptions(args)
|
filter.SetEarliestBlock(earliest)
|
||||||
|
filter.SetLatestBlock(latest)
|
||||||
|
filter.SetSkip(skip)
|
||||||
|
filter.SetMax(max)
|
||||||
|
filter.SetAddress(cAddress(address))
|
||||||
|
filter.SetTopics(cTopics(topics))
|
||||||
|
|
||||||
return filter.Find()
|
return filter.Find()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue