mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-22 04:36:42 +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
|
||||
*/**/*tx_database*
|
||||
*/**/*dapps*
|
||||
Godeps/_workspace/pkg
|
||||
Godeps/_workspace/bin
|
||||
|
||||
#*
|
||||
.#*
|
||||
|
|
@ -21,7 +23,9 @@
|
|||
.project
|
||||
.settings
|
||||
|
||||
cmd/ethereum/ethereum
|
||||
geth
|
||||
mist
|
||||
cmd/geth/geth
|
||||
cmd/mist/mist
|
||||
deploy/osx/Mist.app
|
||||
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"]
|
||||
path = cmd/mist/assets/ext/ethereum.js
|
||||
url = https://github.com/ethereum/ethereum.js
|
||||
|
|
|
|||
4
.mailmap
4
.mailmap
|
|
@ -9,4 +9,6 @@ Joseph Goulden <joegoulden@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 github.com/golang/lint/golint
|
||||
# - 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
|
||||
before_script:
|
||||
# - 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
|
||||
WORKDIR $GOPATH/src/github.com/ethereum/go-ethereum
|
||||
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
|
||||
ENTRYPOINT ["ethereum", "-rpc=true", "-rpcport=8545"]
|
||||
ENTRYPOINT ["geth", "-rpc=true", "-rpcport=8545"]
|
||||
EXPOSE 8545
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ Ethereum Go Client © 2014 Jeffrey Wilcke.
|
|||
|
||||
| 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)
|
||||
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)
|
||||
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) [](https://coveralls.io/r/ethereum/go-ethereum?branch=master)
|
||||
|
||||
[](https://waffle.io/ethereum/go-ethereum)
|
||||
[](https://waffle.io/ethereum/go-ethereum)
|
||||
|
|
@ -22,7 +22,7 @@ Mist (GUI):
|
|||
|
||||
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:
|
||||
|
||||
|
|
|
|||
|
|
@ -11,14 +11,18 @@ import (
|
|||
)
|
||||
|
||||
type Execution struct {
|
||||
env vm.Environment
|
||||
address *common.Address
|
||||
input []byte
|
||||
env vm.Environment
|
||||
address *common.Address
|
||||
input []byte
|
||||
evm vm.VirtualMachine
|
||||
|
||||
Gas, price, value *big.Int
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
@ -28,11 +32,17 @@ func (self *Execution) Call(codeAddr common.Address, caller vm.ContextRef) ([]by
|
|||
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) {
|
||||
start := time.Now()
|
||||
|
||||
env := self.env
|
||||
evm := vm.NewVm(env)
|
||||
evm := self.evm
|
||||
if env.Depth() == vm.MaxCallDepth {
|
||||
caller.ReturnGas(self.Gas, self.price)
|
||||
|
||||
|
|
@ -70,10 +80,3 @@ func (self *Execution) exec(contextAddr *common.Address, code []byte, caller vm.
|
|||
|
||||
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
|
||||
}
|
||||
|
||||
type FilterOptions struct {
|
||||
Earliest int64
|
||||
Latest int64
|
||||
|
||||
Address []common.Address
|
||||
Topics [][]common.Hash
|
||||
|
||||
Skip int
|
||||
Max int
|
||||
}
|
||||
|
||||
// Filtering interface
|
||||
type Filter struct {
|
||||
eth Backend
|
||||
|
|
@ -44,18 +33,6 @@ func NewFilter(eth Backend) *Filter {
|
|||
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.
|
||||
// -1 = latest block (i.e., the current block)
|
||||
// hash = particular hash from-to
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ package vm
|
|||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
)
|
||||
|
||||
type Address interface {
|
||||
|
|
@ -61,15 +61,32 @@ func ripemd160Func(in []byte) []byte {
|
|||
return common.LeftPadBytes(crypto.Ripemd160(in), 32)
|
||||
}
|
||||
|
||||
const ecRecoverInputLength = 128
|
||||
|
||||
func ecrecoverFunc(in []byte) []byte {
|
||||
// In case of an invalid sig. Defaults to return nil
|
||||
defer func() { recover() }()
|
||||
// "in" is (hash, v, r, s), each 32 bytes
|
||||
// but for ecrecover we want (r, s, v)
|
||||
if len(in) < ecRecoverInputLength {
|
||||
return nil
|
||||
}
|
||||
|
||||
hash := in[:32]
|
||||
v := common.BigD(in[32:64]).Bytes()[0] - 27
|
||||
sig := append(in[64:], v)
|
||||
// Treat V as a 256bit integer
|
||||
v := new(big.Int).Sub(common.Bytes2Big(in[32:64]), big.NewInt(27))
|
||||
// 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 {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,25 @@
|
|||
package vm
|
||||
|
||||
import "gopkg.in/fatih/set.v0"
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
func analyseJumpDests(code []byte) (dests *set.Set) {
|
||||
dests = set.New()
|
||||
"gopkg.in/fatih/set.v0"
|
||||
)
|
||||
|
||||
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++ {
|
||||
var op OpCode = OpCode(code[pc])
|
||||
|
|
@ -13,7 +29,7 @@ func analyseJumpDests(code []byte) (dests *set.Set) {
|
|||
|
||||
pc += a
|
||||
case JUMPDEST:
|
||||
dests.Add(pc)
|
||||
dests.Add(big.NewInt(int64(pc)))
|
||||
}
|
||||
}
|
||||
return
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ var (
|
|||
S256 = common.S256
|
||||
|
||||
Zero = common.Big0
|
||||
One = common.Big1
|
||||
|
||||
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)
|
||||
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
|
||||
|
||||
import (
|
||||
"math"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
|
@ -41,29 +40,18 @@ func NewContext(caller ContextRef, object ContextRef, value, gas, price *big.Int
|
|||
return c
|
||||
}
|
||||
|
||||
func (c *Context) GetOp(n uint64) OpCode {
|
||||
func (c *Context) GetOp(n *big.Int) OpCode {
|
||||
return OpCode(c.GetByte(n))
|
||||
}
|
||||
|
||||
func (c *Context) GetByte(n uint64) byte {
|
||||
if n < uint64(len(c.Code)) {
|
||||
return c.Code[n]
|
||||
func (c *Context) GetByte(n *big.Int) byte {
|
||||
if n.Cmp(big.NewInt(int64(len(c.Code)))) < 0 {
|
||||
return c.Code[n.Int64()]
|
||||
}
|
||||
|
||||
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 {
|
||||
// Return the remaining gas to the caller
|
||||
c.caller.ReturnGas(c.Gas, c.Price)
|
||||
|
|
@ -74,16 +62,12 @@ func (c *Context) Return(ret []byte) []byte {
|
|||
/*
|
||||
* Gas functions
|
||||
*/
|
||||
func (c *Context) UseGas(gas *big.Int) bool {
|
||||
if c.Gas.Cmp(gas) < 0 {
|
||||
return false
|
||||
func (c *Context) UseGas(gas *big.Int) (ok bool) {
|
||||
ok = UseGas(c.Gas, gas)
|
||||
if ok {
|
||||
c.UsedGas.Add(c.UsedGas, gas)
|
||||
}
|
||||
|
||||
// Sub the amount of gas from the remaining
|
||||
c.Gas.Sub(c.Gas, gas)
|
||||
c.UsedGas.Add(c.UsedGas, gas)
|
||||
|
||||
return true
|
||||
return
|
||||
}
|
||||
|
||||
// Implement the caller interface
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ type Vm struct {
|
|||
Fn string
|
||||
|
||||
Recoverable bool
|
||||
|
||||
// Will be called before the vm returns
|
||||
After func(*Context, error)
|
||||
}
|
||||
|
||||
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.
|
||||
defer func() {
|
||||
if self.After != nil {
|
||||
self.After(context, err)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
self.Printf(" %v", err).Endl()
|
||||
// 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 (
|
||||
op OpCode
|
||||
|
||||
destinations = analyseJumpDests(context.Code)
|
||||
mem = NewMemory()
|
||||
stack = newStack()
|
||||
pc uint64 = 0
|
||||
step = 0
|
||||
statedb = self.env.State()
|
||||
destinations = analyseJumpDests(context.Code)
|
||||
mem = NewMemory()
|
||||
stack = newStack()
|
||||
pc = new(big.Int)
|
||||
statedb = self.env.State()
|
||||
|
||||
jump = func(from uint64, to *big.Int) error {
|
||||
p := to.Uint64()
|
||||
|
||||
nop := context.GetOp(p)
|
||||
if !destinations.Has(p) {
|
||||
return fmt.Errorf("invalid jump destination (%v) %v", nop, p)
|
||||
jump = func(from *big.Int, to *big.Int) error {
|
||||
nop := context.GetOp(to)
|
||||
if !destinations.Has(to) {
|
||||
return fmt.Errorf("invalid jump destination (%v) %v", nop, to)
|
||||
}
|
||||
|
||||
self.Printf(" ~> %v", to)
|
||||
pc = to.Uint64()
|
||||
pc = to
|
||||
|
||||
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
|
||||
base := new(big.Int)
|
||||
|
||||
step++
|
||||
// Get the memory location of 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)
|
||||
case CALLDATALOAD:
|
||||
var (
|
||||
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()])
|
||||
}
|
||||
data := getData(callData, stack.pop(), common.Big32)
|
||||
|
||||
self.Printf(" => 0x%x", data)
|
||||
|
||||
stack.push(common.BigD(data))
|
||||
stack.push(common.Bytes2Big(data))
|
||||
case CALLDATASIZE:
|
||||
l := int64(len(callData))
|
||||
stack.push(big.NewInt(l))
|
||||
|
|
@ -535,13 +527,11 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
|
|||
|
||||
// 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:
|
||||
a := uint64(op - PUSH1 + 1)
|
||||
byts := context.GetRangeValue(pc+1, a)
|
||||
a := big.NewInt(int64(op - PUSH1 + 1))
|
||||
byts := getData(code, new(big.Int).Add(pc, big.NewInt(1)), a)
|
||||
// push value to stack
|
||||
stack.push(common.BigD(byts))
|
||||
pc += a
|
||||
|
||||
step += int(op) - int(PUSH1) + 1
|
||||
stack.push(common.Bytes2Big(byts))
|
||||
pc.Add(pc, a)
|
||||
|
||||
self.Printf(" => 0x%x", byts)
|
||||
case POP:
|
||||
|
|
@ -621,7 +611,8 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
|
|||
|
||||
case JUMPDEST:
|
||||
case PC:
|
||||
stack.push(big.NewInt(int64(pc)))
|
||||
//stack.push(big.NewInt(int64(pc)))
|
||||
stack.push(pc)
|
||||
case MSIZE:
|
||||
stack.push(big.NewInt(int64(mem.Len())))
|
||||
case GAS:
|
||||
|
|
@ -647,7 +638,6 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
|
|||
|
||||
self.Printf(" (*) 0x0 %v", suberr)
|
||||
} else {
|
||||
|
||||
// gas < len(ret) * CreateDataGas == NO_CODE
|
||||
dataGas := big.NewInt(int64(len(ret)))
|
||||
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)
|
||||
}
|
||||
|
||||
pc++
|
||||
pc.Add(pc, One)
|
||||
|
||||
self.Endl()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,21 +54,17 @@ func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error {
|
|||
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) {
|
||||
exe := self.vm(&addr, data, gas, price, value)
|
||||
exe := NewExecution(self, &addr, data, gas, price, value)
|
||||
return exe.Call(addr, me)
|
||||
}
|
||||
func (self *VMEnv) CallCode(me vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
||||
maddr := me.Address()
|
||||
exe := self.vm(&maddr, data, gas, price, value)
|
||||
exe := NewExecution(self, &maddr, data, gas, price, value)
|
||||
return exe.Call(addr, me)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,13 +68,8 @@ func Ripemd160(data []byte) []byte {
|
|||
return ripemd.Sum(nil)
|
||||
}
|
||||
|
||||
func Ecrecover(data []byte) []byte {
|
||||
var in = struct {
|
||||
hash []byte
|
||||
sig []byte
|
||||
}{data[:32], data[32:]}
|
||||
|
||||
r, _ := secp256k1.RecoverPubkey(in.hash, in.sig)
|
||||
func Ecrecover(hash, sig []byte) []byte {
|
||||
r, _ := secp256k1.RecoverPubkey(hash, sig)
|
||||
|
||||
return r
|
||||
}
|
||||
|
|
@ -151,9 +146,12 @@ func GenerateKey() (*ecdsa.PrivateKey, error) {
|
|||
}
|
||||
|
||||
func SigToPub(hash, sig []byte) *ecdsa.PublicKey {
|
||||
s := Ecrecover(append(hash, sig...))
|
||||
x, y := elliptic.Unmarshal(S256(), s)
|
||||
s := Ecrecover(hash, sig)
|
||||
if s == nil || len(s) != 65 {
|
||||
return nil
|
||||
}
|
||||
|
||||
x, y := elliptic.Unmarshal(S256(), s)
|
||||
return &ecdsa.PublicKey{S256(), x, y}
|
||||
}
|
||||
|
||||
|
|
|
|||
95
rpc/api.go
95
rpc/api.go
|
|
@ -6,7 +6,6 @@ import (
|
|||
"sync"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/xeth"
|
||||
)
|
||||
|
|
@ -14,7 +13,6 @@ import (
|
|||
type EthereumApi struct {
|
||||
eth *xeth.XEth
|
||||
xethMu sync.RWMutex
|
||||
db common.Database
|
||||
}
|
||||
|
||||
func NewEthereumApi(xeth *xeth.XEth) *EthereumApi {
|
||||
|
|
@ -82,10 +80,6 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
|
|||
return err
|
||||
}
|
||||
|
||||
if err := args.requirements(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
v := api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address).Balance()
|
||||
*reply = common.ToHex(v.Bytes())
|
||||
case "eth_getStorage", "eth_storageAt":
|
||||
|
|
@ -94,36 +88,25 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
|
|||
return err
|
||||
}
|
||||
|
||||
if err := args.requirements(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*reply = api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address).Storage()
|
||||
case "eth_getStorageAt":
|
||||
args := new(GetStorageAtArgs)
|
||||
if err := json.Unmarshal(req.Params, &args); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := args.requirements(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
state := api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address)
|
||||
value := state.StorageString(args.Key)
|
||||
|
||||
*reply = common.Bytes2Hex(value.Bytes())
|
||||
*reply = common.ToHex(value.Bytes())
|
||||
case "eth_getTransactionCount":
|
||||
args := new(GetTxCountArgs)
|
||||
if err := json.Unmarshal(req.Params, &args); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err := args.requirements()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*reply = api.xethAtStateNum(args.BlockNumber).TxCountAt(args.Address)
|
||||
count := api.xethAtStateNum(args.BlockNumber).TxCountAt(args.Address)
|
||||
*reply = common.ToHex(big.NewInt(int64(count)).Bytes())
|
||||
case "eth_getBlockTransactionCountByHash":
|
||||
args := new(GetBlockByHashArgs)
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
if err := args.requirements(); err != nil {
|
||||
return err
|
||||
}
|
||||
*reply = api.xethAtStateNum(args.BlockNumber).CodeAt(args.Address)
|
||||
case "eth_sendTransaction", "eth_transact":
|
||||
args := new(NewTxArgs)
|
||||
|
|
@ -173,10 +153,6 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) 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)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -267,8 +243,8 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
|
|||
return NewValidationError("Index", "does not exist")
|
||||
}
|
||||
|
||||
uhash := br.Uncles[args.Index].Hex()
|
||||
uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash))
|
||||
uhash := br.Uncles[args.Index]
|
||||
uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash.Hex()))
|
||||
|
||||
*reply = uncle
|
||||
case "eth_getUncleByBlockNumberAndIndex":
|
||||
|
|
@ -285,8 +261,8 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
|
|||
return NewValidationError("Index", "does not exist")
|
||||
}
|
||||
|
||||
uhash := v.Uncles[args.Index].Hex()
|
||||
uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash))
|
||||
uhash := v.Uncles[args.Index]
|
||||
uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash.Hex()))
|
||||
|
||||
*reply = uncle
|
||||
case "eth_getCompilers":
|
||||
|
|
@ -300,18 +276,13 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
|
|||
return err
|
||||
}
|
||||
|
||||
opts := toFilterOptions(args)
|
||||
id := api.xeth().RegisterFilter(opts)
|
||||
id := api.xeth().RegisterFilter(args.Earliest, args.Latest, args.Skip, args.Max, args.Address, args.Topics)
|
||||
*reply = common.ToHex(big.NewInt(int64(id)).Bytes())
|
||||
case "eth_newBlockFilter":
|
||||
args := new(FilterStringArgs)
|
||||
if err := json.Unmarshal(req.Params, &args); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := args.requirements(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
id := api.xeth().NewFilterString(args.Word)
|
||||
*reply = common.ToHex(big.NewInt(int64(id)).Bytes())
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
opts := toFilterOptions(args)
|
||||
*reply = NewLogsRes(api.xeth().AllLogs(opts))
|
||||
*reply = NewLogsRes(api.xeth().AllLogs(args.Earliest, args.Latest, args.Skip, args.Max, args.Address, args.Topics))
|
||||
case "eth_getWork":
|
||||
api.xeth().SetMining(true)
|
||||
*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 {
|
||||
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":
|
||||
args := new(DbArgs)
|
||||
if err := json.Unmarshal(req.Params, &args); err != nil {
|
||||
|
|
@ -433,7 +403,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
|
|||
return err
|
||||
}
|
||||
opts := new(xeth.Options)
|
||||
opts.From = args.From
|
||||
// opts.From = args.From
|
||||
opts.To = args.To
|
||||
opts.Topics = args.Topics
|
||||
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)
|
||||
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
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"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
|
||||
num, ok := raw.(float64)
|
||||
if ok {
|
||||
|
|
@ -21,7 +32,7 @@ func blockHeight(raw interface{}, number *int64) (err error) {
|
|||
// Parse as string/hexstring
|
||||
str, ok := raw.(string)
|
||||
if !ok {
|
||||
return NewDecodeParamError("BlockNumber is not a string")
|
||||
return NewInvalidTypeError("", "not a number or string")
|
||||
}
|
||||
|
||||
switch str {
|
||||
|
|
@ -36,26 +47,55 @@ func blockHeight(raw interface{}, number *int64) (err error) {
|
|||
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"
|
||||
func numString(raw interface{}, number *int64) error {
|
||||
// Parse as integer
|
||||
num, ok := raw.(float64)
|
||||
if ok {
|
||||
*number = int64(num)
|
||||
return nil
|
||||
}
|
||||
|
||||
switch str {
|
||||
case "latest":
|
||||
return -1, nil
|
||||
default:
|
||||
return int64(common.Big(v.(string)).Int64()), nil
|
||||
// Parse as string/hexstring
|
||||
str, ok := raw.(string)
|
||||
if !ok {
|
||||
return NewInvalidTypeError("", "not a number or string")
|
||||
}
|
||||
*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 {
|
||||
BlockHash string
|
||||
IncludeTxs bool
|
||||
|
|
@ -63,8 +103,8 @@ type GetBlockByHashArgs struct {
|
|||
|
||||
func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) {
|
||||
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())
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +114,7 @@ func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
|
||||
argstr, ok := obj[0].(string)
|
||||
if !ok {
|
||||
return NewDecodeParamError("BlockHash not a string")
|
||||
return NewInvalidTypeError("blockHash", "not a string")
|
||||
}
|
||||
args.BlockHash = argstr
|
||||
|
||||
|
|
@ -92,8 +132,7 @@ type GetBlockByNumberArgs struct {
|
|||
|
||||
func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) {
|
||||
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())
|
||||
}
|
||||
|
||||
|
|
@ -103,8 +142,10 @@ func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
|
||||
if v, ok := obj[0].(float64); ok {
|
||||
args.BlockNumber = int64(v)
|
||||
} else if v, ok := obj[0].(string); ok {
|
||||
args.BlockNumber = common.Big(v).Int64()
|
||||
} else {
|
||||
args.BlockNumber = common.Big(obj[0].(string)).Int64()
|
||||
return NewInvalidTypeError("blockNumber", "not a number or string")
|
||||
}
|
||||
|
||||
if len(obj) > 1 {
|
||||
|
|
@ -127,7 +168,14 @@ type NewTxArgs struct {
|
|||
|
||||
func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
|
||||
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
|
||||
if err := json.Unmarshal(b, &obj); err != nil {
|
||||
|
|
@ -144,22 +192,45 @@ func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
return NewDecodeParamError(err.Error())
|
||||
}
|
||||
|
||||
// var ok bool
|
||||
if len(ext.From) == 0 {
|
||||
return NewValidationError("from", "is required")
|
||||
}
|
||||
|
||||
args.From = ext.From
|
||||
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
|
||||
|
||||
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
|
||||
if len(obj) > 1 {
|
||||
var raw interface{}
|
||||
if err = json.Unmarshal(obj[1], &raw); err != nil {
|
||||
return NewDecodeParamError(err.Error())
|
||||
}
|
||||
|
||||
if err := blockHeight(raw, &args.BlockNumber); err != nil {
|
||||
if err := blockHeightFromJson(obj[1], &args.BlockNumber); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -167,13 +238,6 @@ func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (args *NewTxArgs) requirements() error {
|
||||
if len(args.From) == 0 {
|
||||
return NewValidationError("From", "Is required")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type GetStorageArgs struct {
|
||||
Address string
|
||||
BlockNumber int64
|
||||
|
|
@ -191,7 +255,7 @@ func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
|
||||
addstr, ok := obj[0].(string)
|
||||
if !ok {
|
||||
return NewDecodeParamError("Address is not a string")
|
||||
return NewInvalidTypeError("address", "not a string")
|
||||
}
|
||||
args.Address = addstr
|
||||
|
||||
|
|
@ -204,13 +268,6 @@ func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (args *GetStorageArgs) requirements() error {
|
||||
if len(args.Address) == 0 {
|
||||
return NewValidationError("Address", "cannot be blank")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type GetStorageAtArgs struct {
|
||||
Address string
|
||||
Key string
|
||||
|
|
@ -229,13 +286,13 @@ func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
|
||||
addstr, ok := obj[0].(string)
|
||||
if !ok {
|
||||
return NewDecodeParamError("Address is not a string")
|
||||
return NewInvalidTypeError("address", "not a string")
|
||||
}
|
||||
args.Address = addstr
|
||||
|
||||
keystr, ok := obj[1].(string)
|
||||
if !ok {
|
||||
return NewDecodeParamError("Key is not a string")
|
||||
return NewInvalidTypeError("key", "not a string")
|
||||
}
|
||||
args.Key = keystr
|
||||
|
||||
|
|
@ -248,17 +305,6 @@ func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
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 {
|
||||
Address string
|
||||
BlockNumber int64
|
||||
|
|
@ -276,7 +322,7 @@ func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
|
||||
addstr, ok := obj[0].(string)
|
||||
if !ok {
|
||||
return NewDecodeParamError("Address is not a string")
|
||||
return NewInvalidTypeError("address", "not a string")
|
||||
}
|
||||
args.Address = addstr
|
||||
|
||||
|
|
@ -289,13 +335,6 @@ func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (args *GetTxCountArgs) requirements() error {
|
||||
if len(args.Address) == 0 {
|
||||
return NewValidationError("Address", "cannot be blank")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type GetBalanceArgs struct {
|
||||
Address string
|
||||
BlockNumber int64
|
||||
|
|
@ -313,7 +352,7 @@ func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
|
||||
addstr, ok := obj[0].(string)
|
||||
if !ok {
|
||||
return NewDecodeParamError("Address is not a string")
|
||||
return NewInvalidTypeError("address", "not a string")
|
||||
}
|
||||
args.Address = addstr
|
||||
|
||||
|
|
@ -326,13 +365,6 @@ func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (args *GetBalanceArgs) requirements() error {
|
||||
if len(args.Address) == 0 {
|
||||
return NewValidationError("Address", "cannot be blank")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type GetDataArgs struct {
|
||||
Address string
|
||||
BlockNumber int64
|
||||
|
|
@ -350,7 +382,7 @@ func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
|
||||
addstr, ok := obj[0].(string)
|
||||
if !ok {
|
||||
return NewDecodeParamError("Address is not a string")
|
||||
return NewInvalidTypeError("address", "not a string")
|
||||
}
|
||||
args.Address = addstr
|
||||
|
||||
|
|
@ -363,13 +395,6 @@ func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (args *GetDataArgs) requirements() error {
|
||||
if len(args.Address) == 0 {
|
||||
return NewValidationError("Address", "cannot be blank")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type BlockNumIndexArgs struct {
|
||||
BlockNumber int64
|
||||
Index int64
|
||||
|
|
@ -377,8 +402,7 @@ type BlockNumIndexArgs struct {
|
|||
|
||||
func (args *BlockNumIndexArgs) UnmarshalJSON(b []byte) (err error) {
|
||||
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())
|
||||
}
|
||||
|
||||
|
|
@ -386,16 +410,14 @@ func (args *BlockNumIndexArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
return NewInsufficientParamsError(len(obj), 1)
|
||||
}
|
||||
|
||||
arg0, ok := obj[0].(string)
|
||||
if !ok {
|
||||
return NewDecodeParamError("BlockNumber is not string")
|
||||
if err := blockHeight(obj[0], &args.BlockNumber); err != nil {
|
||||
return err
|
||||
}
|
||||
args.BlockNumber = common.Big(arg0).Int64()
|
||||
|
||||
if len(obj) > 1 {
|
||||
arg1, ok := obj[1].(string)
|
||||
if !ok {
|
||||
return NewDecodeParamError("Index not a string")
|
||||
return NewInvalidTypeError("index", "not a string")
|
||||
}
|
||||
args.Index = common.Big(arg1).Int64()
|
||||
}
|
||||
|
|
@ -410,8 +432,7 @@ type HashIndexArgs struct {
|
|||
|
||||
func (args *HashIndexArgs) UnmarshalJSON(b []byte) (err error) {
|
||||
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())
|
||||
}
|
||||
|
||||
|
|
@ -421,14 +442,14 @@ func (args *HashIndexArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
|
||||
arg0, ok := obj[0].(string)
|
||||
if !ok {
|
||||
return NewDecodeParamError("Hash not a string")
|
||||
return NewInvalidTypeError("hash", "not a string")
|
||||
}
|
||||
args.Hash = arg0
|
||||
|
||||
if len(obj) > 1 {
|
||||
arg1, ok := obj[1].(string)
|
||||
if !ok {
|
||||
return NewDecodeParamError("Index not a string")
|
||||
return NewInvalidTypeError("index", "not a string")
|
||||
}
|
||||
args.Index = common.Big(arg1).Int64()
|
||||
}
|
||||
|
|
@ -442,36 +463,39 @@ type Sha3Args struct {
|
|||
|
||||
func (args *Sha3Args) UnmarshalJSON(b []byte) (err error) {
|
||||
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())
|
||||
}
|
||||
|
||||
if 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
|
||||
}
|
||||
|
||||
type BlockFilterArgs struct {
|
||||
Earliest int64
|
||||
Latest int64
|
||||
Address interface{}
|
||||
Topics []interface{}
|
||||
Address []string
|
||||
Topics [][]string
|
||||
Skip int
|
||||
Max int
|
||||
}
|
||||
|
||||
func (args *BlockFilterArgs) UnmarshalJSON(b []byte) (err error) {
|
||||
var obj []struct {
|
||||
FromBlock interface{} `json:"fromBlock"`
|
||||
ToBlock interface{} `json:"toBlock"`
|
||||
Limit string `json:"limit"`
|
||||
Offset string `json:"offset"`
|
||||
Address string `json:"address"`
|
||||
Topics []interface{} `json:"topics"`
|
||||
FromBlock interface{} `json:"fromBlock"`
|
||||
ToBlock interface{} `json:"toBlock"`
|
||||
Limit interface{} `json:"limit"`
|
||||
Offset interface{} `json:"offset"`
|
||||
Address interface{} `json:"address"`
|
||||
Topics interface{} `json:"topics"`
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
args.Earliest, err = toNumber(obj[0].ToBlock)
|
||||
if err != nil {
|
||||
return NewDecodeParamError(fmt.Sprintf("FromBlock %v", err))
|
||||
// args.Earliest, err = toNumber(obj[0].ToBlock)
|
||||
// if err != nil {
|
||||
// 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 err != nil {
|
||||
return NewDecodeParamError(fmt.Sprintf("ToBlock %v", err))
|
||||
// if -2 or other "silly" number, use latest
|
||||
if num < 0 {
|
||||
args.Earliest = -1 //latest block
|
||||
} else {
|
||||
args.Earliest = num
|
||||
}
|
||||
|
||||
args.Max = int(common.Big(obj[0].Limit).Int64())
|
||||
args.Skip = int(common.Big(obj[0].Offset).Int64())
|
||||
args.Address = obj[0].Address
|
||||
args.Topics = obj[0].Topics
|
||||
// if blank than latest
|
||||
if obj[0].ToBlock == nil {
|
||||
num = -1
|
||||
} 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
|
||||
}
|
||||
|
|
@ -519,19 +637,19 @@ func (args *DbArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
var ok bool
|
||||
|
||||
if objstr, ok = obj[0].(string); !ok {
|
||||
return NewDecodeParamError("Database is not a string")
|
||||
return NewInvalidTypeError("database", "not a string")
|
||||
}
|
||||
args.Database = objstr
|
||||
|
||||
if objstr, ok = obj[1].(string); !ok {
|
||||
return NewDecodeParamError("Key is not a string")
|
||||
return NewInvalidTypeError("key", "not a string")
|
||||
}
|
||||
args.Key = objstr
|
||||
|
||||
if len(obj) > 2 {
|
||||
objstr, ok = obj[2].(string)
|
||||
if !ok {
|
||||
return NewDecodeParamError("Value is not a string")
|
||||
return NewInvalidTypeError("value", "not a string")
|
||||
}
|
||||
|
||||
args.Value = []byte(objstr)
|
||||
|
|
@ -570,19 +688,19 @@ func (args *DbHexArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
var ok bool
|
||||
|
||||
if objstr, ok = obj[0].(string); !ok {
|
||||
return NewDecodeParamError("Database is not a string")
|
||||
return NewInvalidTypeError("database", "not a string")
|
||||
}
|
||||
args.Database = objstr
|
||||
|
||||
if objstr, ok = obj[1].(string); !ok {
|
||||
return NewDecodeParamError("Key is not a string")
|
||||
return NewInvalidTypeError("key", "not a string")
|
||||
}
|
||||
args.Key = objstr
|
||||
|
||||
if len(obj) > 2 {
|
||||
objstr, ok = obj[2].(string)
|
||||
if !ok {
|
||||
return NewDecodeParamError("Value is not a string")
|
||||
return NewInvalidTypeError("value", "not a string")
|
||||
}
|
||||
|
||||
args.Value = common.FromHex(objstr)
|
||||
|
|
@ -616,8 +734,8 @@ func (args *WhisperMessageArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
To string
|
||||
From string
|
||||
Topics []string
|
||||
Priority string
|
||||
Ttl string
|
||||
Priority interface{}
|
||||
Ttl interface{}
|
||||
}
|
||||
|
||||
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.From = obj[0].From
|
||||
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
|
||||
}
|
||||
|
|
@ -643,14 +770,18 @@ type CompileArgs struct {
|
|||
|
||||
func (args *CompileArgs) UnmarshalJSON(b []byte) (err error) {
|
||||
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())
|
||||
}
|
||||
|
||||
if len(obj) > 0 {
|
||||
args.Source = obj[0].(string)
|
||||
if len(obj) < 1 {
|
||||
return NewInsufficientParamsError(len(obj), 1)
|
||||
}
|
||||
argstr, ok := obj[0].(string)
|
||||
if !ok {
|
||||
return NewInvalidTypeError("arg0", "is not a string")
|
||||
}
|
||||
args.Source = argstr
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -661,8 +792,7 @@ type FilterStringArgs struct {
|
|||
|
||||
func (args *FilterStringArgs) UnmarshalJSON(b []byte) (err error) {
|
||||
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())
|
||||
}
|
||||
|
||||
|
|
@ -673,20 +803,15 @@ func (args *FilterStringArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
var argstr string
|
||||
argstr, ok := obj[0].(string)
|
||||
if !ok {
|
||||
return NewDecodeParamError("Filter is not a string")
|
||||
return NewInvalidTypeError("filter", "not a string")
|
||||
}
|
||||
args.Word = argstr
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (args *FilterStringArgs) requirements() error {
|
||||
switch args.Word {
|
||||
switch argstr {
|
||||
case "latest", "pending":
|
||||
break
|
||||
default:
|
||||
return NewValidationError("Word", "Must be `latest` or `pending`")
|
||||
}
|
||||
args.Word = argstr
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -695,9 +820,8 @@ type FilterIdArgs struct {
|
|||
}
|
||||
|
||||
func (args *FilterIdArgs) UnmarshalJSON(b []byte) (err error) {
|
||||
var obj []string
|
||||
r := bytes.NewReader(b)
|
||||
if err := json.NewDecoder(r).Decode(&obj); err != nil {
|
||||
var obj []interface{}
|
||||
if err := json.Unmarshal(b, &obj); err != nil {
|
||||
return NewDecodeParamError(err.Error())
|
||||
}
|
||||
|
||||
|
|
@ -705,7 +829,11 @@ func (args *FilterIdArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
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
|
||||
}
|
||||
|
|
@ -715,9 +843,8 @@ type WhisperIdentityArgs struct {
|
|||
}
|
||||
|
||||
func (args *WhisperIdentityArgs) UnmarshalJSON(b []byte) (err error) {
|
||||
var obj []string
|
||||
r := bytes.NewReader(b)
|
||||
if err := json.NewDecoder(r).Decode(&obj); err != nil {
|
||||
var obj []interface{}
|
||||
if err := json.Unmarshal(b, &obj); err != nil {
|
||||
return NewDecodeParamError(err.Error())
|
||||
}
|
||||
|
||||
|
|
@ -725,7 +852,14 @@ func (args *WhisperIdentityArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
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
|
||||
}
|
||||
|
|
@ -738,9 +872,8 @@ type WhisperFilterArgs struct {
|
|||
|
||||
func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) {
|
||||
var obj []struct {
|
||||
To string
|
||||
From string
|
||||
Topics []string
|
||||
To interface{}
|
||||
Topics []interface{}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
args.To = obj[0].To
|
||||
args.From = obj[0].From
|
||||
args.Topics = obj[0].Topics
|
||||
var argstr string
|
||||
argstr, ok := obj[0].To.(string)
|
||||
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
|
||||
}
|
||||
|
||||
type SubmitWorkArgs struct {
|
||||
Nonce uint64
|
||||
Header common.Hash
|
||||
Digest common.Hash
|
||||
Header string
|
||||
Digest string
|
||||
}
|
||||
|
||||
func (args *SubmitWorkArgs) UnmarshalJSON(b []byte) (err error) {
|
||||
|
|
@ -777,21 +923,21 @@ func (args *SubmitWorkArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
var objstr string
|
||||
var ok bool
|
||||
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()
|
||||
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 {
|
||||
return NewDecodeParamError("Digest is not a string")
|
||||
return NewInvalidTypeError("digest", "not a string")
|
||||
}
|
||||
|
||||
args.Digest = common.HexToHash(objstr)
|
||||
args.Digest = objstr
|
||||
|
||||
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:
|
||||
jsonerr := &RpcErrorObject{-32601, reserr.Error()}
|
||||
response = &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: request.Id, Error: jsonerr}
|
||||
case *DecodeParamError, *InsufficientParamsError, *ValidationError:
|
||||
case *DecodeParamError, *InsufficientParamsError, *ValidationError, *InvalidTypeError:
|
||||
jsonerr := &RpcErrorObject{-32602, reserr.Error()}
|
||||
response = &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: request.Id, Error: jsonerr}
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -21,6 +21,22 @@ import (
|
|||
"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 {
|
||||
have int
|
||||
want int
|
||||
|
|
|
|||
|
|
@ -4,6 +4,15 @@ import (
|
|||
"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) {
|
||||
err := NewInsufficientParamsError(0, 1)
|
||||
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.TotalDifficulty = common.ToHex(b.TotalDifficulty.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.MinGasPrice = common.ToHex(big.NewInt(b.MinGasPrice).Bytes())
|
||||
ext.GasUsed = common.ToHex(b.GasUsed.Bytes())
|
||||
|
|
@ -111,7 +111,7 @@ func NewBlockRes(block *types.Block) *BlockRes {
|
|||
res.Difficulty = block.Difficulty()
|
||||
res.TotalDifficulty = block.Td
|
||||
res.Size = big.NewInt(int64(block.Size()))
|
||||
// res.ExtraData =
|
||||
res.ExtraData = []byte(block.Header().Extra)
|
||||
res.GasLimit = block.GasLimit()
|
||||
// res.MinGasPrice =
|
||||
res.GasUsed = block.GasUsed()
|
||||
|
|
@ -243,8 +243,8 @@ func (l *LogRes) MarshalJSON() ([]byte, error) {
|
|||
}
|
||||
|
||||
ext.Address = l.Address.Hex()
|
||||
ext.Data = common.Bytes2Hex(l.Data)
|
||||
ext.Number = common.Bytes2Hex(big.NewInt(int64(l.Number)).Bytes())
|
||||
ext.Data = common.ToHex(l.Data)
|
||||
ext.Number = common.ToHex(big.NewInt(int64(l.Number)).Bytes())
|
||||
ext.Topics = make([]string, len(l.Topics))
|
||||
for i, v := range l.Topics {
|
||||
ext.Topics[i] = v.Hex()
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ var (
|
|||
extensions = []string{".go", ".js", ".qml"}
|
||||
|
||||
// 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.
|
||||
gplPrefixes = []string{"cmd/"}
|
||||
|
|
@ -190,7 +190,7 @@ func fileInfo(file string) (*info, error) {
|
|||
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) {
|
||||
sep := strings.IndexByte(line, '|')
|
||||
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)
|
||||
}
|
||||
|
||||
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) DefaultGasPrice() *big.Int { return defaultGasPrice }
|
||||
|
||||
|
|
@ -228,15 +246,15 @@ func (self *XEth) IsMining() bool {
|
|||
}
|
||||
|
||||
func (self *XEth) EthVersion() string {
|
||||
return string(self.backend.EthVersion())
|
||||
return fmt.Sprintf("%d", self.backend.EthVersion())
|
||||
}
|
||||
|
||||
func (self *XEth) NetworkVersion() string {
|
||||
return string(self.backend.NetVersion())
|
||||
return fmt.Sprintf("%d", self.backend.NetVersion())
|
||||
}
|
||||
|
||||
func (self *XEth) WhisperVersion() string {
|
||||
return string(self.backend.ShhVersion())
|
||||
return fmt.Sprintf("%d", self.backend.ShhVersion())
|
||||
}
|
||||
|
||||
func (self *XEth) ClientVersion() string {
|
||||
|
|
@ -301,10 +319,15 @@ func (self *XEth) SecretToAddress(key string) string {
|
|||
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
|
||||
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) {
|
||||
self.logMut.Lock()
|
||||
defer self.logMut.Unlock()
|
||||
|
|
@ -380,9 +403,14 @@ func (self *XEth) Logs(id int) state.Logs {
|
|||
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.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()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue