diff --git a/javascript/types.go b/javascript/types.go index 17f1b739e8..d580d14f5f 100644 --- a/javascript/types.go +++ b/javascript/types.go @@ -62,7 +62,7 @@ type JSEthereum struct { func (self *JSEthereum) Block(v interface{}) otto.Value { if number, ok := v.(int64); ok { - return self.toVal(&JSBlock{self.XEth.BlockByNumber(int32(number)), self}) + return self.toVal(&JSBlock{self.XEth.BlockByNumber(uint64(number)), self}) } else if hash, ok := v.(string); ok { return self.toVal(&JSBlock{self.XEth.BlockByHash(hash), self}) } diff --git a/rpc/api.go b/rpc/api.go index 24491833d8..35c9c51d72 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -1,14 +1,7 @@ -/* -For each request type, define the following: - -1. RpcRequest "To" method [message.go], which does basic validation and conversion to "Args" type via json.Decoder() -2. json.Decoder() calls "UnmarshalON" defined on each "Args" struct -3. EthereumApi method, taking the "Args" type and replying with an interface to be marshalled to ON - -*/ package rpc import ( + "encoding/json" "fmt" "math/big" "strings" @@ -150,16 +143,16 @@ func (self *EthereumApi) Unregister(args string, reply *interface{}) error { return nil } -func (self *EthereumApi) WatchTx(args string, reply *interface{}) error { - self.regmut.Lock() - defer self.regmut.Unlock() +// func (self *EthereumApi) WatchTx(args string, reply *interface{}) error { +// self.regmut.Lock() +// defer self.regmut.Unlock() - txs := self.register[args] - self.register[args] = nil +// txs := self.register[args] +// self.register[args] = nil - *reply = txs - return nil -} +// *reply = txs +// return nil +// } func (self *EthereumApi) NewFilter(args *FilterOptions, reply *interface{}) error { var id int @@ -241,16 +234,6 @@ func (self *EthereumApi) AllLogs(args *FilterOptions, reply *interface{}) error return nil } -func (p *EthereumApi) GetBlock(args *GetBlockArgs, reply *interface{}) error { - // This seems a bit precarious Maybe worth splitting to discrete functions - if len(args.Hash) > 0 { - *reply = p.xeth().BlockByHash(args.Hash) - } else { - *reply = p.xeth().BlockByNumber(args.BlockNumber) - } - return nil -} - func (p *EthereumApi) Transact(args *NewTxArgs, reply *interface{}) error { if args.Gas == ethutil.Big0 { args.Gas = defaultGas @@ -301,22 +284,27 @@ func (p *EthereumApi) Call(args *NewTxArgs, reply *interface{}) error { return nil } -func (p *EthereumApi) PushTx(args *PushTxArgs, reply *interface{}) error { - err := args.requirementsPushTx() - if err != nil { +func (p *EthereumApi) GetBalance(args *GetBalanceArgs, reply *interface{}) error { + if err := args.requirements(); err != nil { return err } - result, _ := p.xeth().PushTx(args.Tx) - *reply = result + state := p.xeth().State().SafeGet(args.Address) + *reply = toHex(state.Balance().Bytes()) return nil } -func (p *EthereumApi) GetStorageAt(args *GetStorageAtArgs, reply *interface{}) error { - err := args.requirements() - if err != nil { +func (p *EthereumApi) GetStorage(args *GetStorageArgs, reply *interface{}) error { + if err := args.requirements(); err != nil { return err } + *reply = p.xeth().State().SafeGet(args.Address).Storage() + return nil +} +func (p *EthereumApi) GetStorageAt(args *GetStorageAtArgs, reply *interface{}) error { + if err := args.requirements(); err != nil { + return err + } state := p.xeth().State().SafeGet(args.Address) value := state.StorageString(args.Key) @@ -333,47 +321,6 @@ func (p *EthereumApi) GetStorageAt(args *GetStorageAtArgs, reply *interface{}) e return nil } -func (p *EthereumApi) GetStorage(args *GetStorageArgs, reply *interface{}) error { - err := args.requirements() - if err != nil { - return err - } - - *reply = p.xeth().State().SafeGet(args.Address).Storage() - return nil -} - -func (p *EthereumApi) GetPeerCount(reply *interface{}) error { - c := p.xeth().PeerCount() - *reply = toHex(big.NewInt(int64(c)).Bytes()) - return nil -} - -func (p *EthereumApi) GetIsListening(reply *interface{}) error { - *reply = p.xeth().IsListening() - return nil -} - -func (p *EthereumApi) GetCoinbase(reply *interface{}) error { - *reply = p.xeth().Coinbase() - return nil -} - -func (p *EthereumApi) Accounts(reply *interface{}) error { - *reply = p.xeth().Accounts() - return nil -} - -func (p *EthereumApi) GetIsMining(reply *interface{}) error { - *reply = p.xeth().IsMining() - return nil -} - -func (p *EthereumApi) BlockNumber(reply *interface{}) error { - *reply = toHex(p.xeth().Backend().ChainManager().CurrentBlock().Number().Bytes()) - return nil -} - func (p *EthereumApi) GetTxCountAt(args *GetTxCountArgs, reply *interface{}) error { err := args.requirements() if err != nil { @@ -383,19 +330,8 @@ func (p *EthereumApi) GetTxCountAt(args *GetTxCountArgs, reply *interface{}) err return nil } -func (p *EthereumApi) GetBalanceAt(args *GetBalanceArgs, reply *interface{}) error { - err := args.requirements() - if err != nil { - return err - } - state := p.xeth().State().SafeGet(args.Address) - *reply = toHex(state.Balance().Bytes()) - return nil -} - -func (p *EthereumApi) GetCodeAt(args *GetCodeAtArgs, reply *interface{}) error { - err := args.requirements() - if err != nil { +func (p *EthereumApi) GetData(args *GetDataArgs, reply *interface{}) error { + if err := args.requirements(); err != nil { return err } *reply = p.xeth().CodeAt(args.Address) @@ -408,8 +344,8 @@ func (p *EthereumApi) GetCompilers(reply *interface{}) error { return nil } -func (p *EthereumApi) CompileSerpent(script string, reply *interface{}) error { - res, err := ethutil.Compile(script, false) +func (p *EthereumApi) CompileSerpent(args *CompileArgs, reply *interface{}) error { + res, err := ethutil.Compile(args.Source, false) if err != nil { return err } @@ -417,14 +353,8 @@ func (p *EthereumApi) CompileSerpent(script string, reply *interface{}) error { return nil } -func (p *EthereumApi) Sha3(args *Sha3Args, reply *interface{}) error { - *reply = toHex(crypto.Sha3(fromHex(args.Data))) - return nil -} - func (p *EthereumApi) DbPut(args *DbArgs, reply *interface{}) error { - err := args.requirements() - if err != nil { + if err := args.requirements(); err != nil { return err } @@ -434,8 +364,7 @@ func (p *EthereumApi) DbPut(args *DbArgs, reply *interface{}) error { } func (p *EthereumApi) DbGet(args *DbArgs, reply *interface{}) error { - err := args.requirements() - if err != nil { + if err := args.requirements(); err != nil { return err } @@ -449,14 +378,18 @@ func (p *EthereumApi) NewWhisperIdentity(reply *interface{}) error { return nil } -func (p *EthereumApi) NewWhisperFilter(args *xeth.Options, reply *interface{}) error { +func (p *EthereumApi) NewWhisperFilter(args *WhisperFilterArgs, reply *interface{}) error { var id int - args.Fn = func(msg xeth.WhisperMessage) { + opts := new(xeth.Options) + opts.From = args.From + opts.To = args.To + opts.Topics = args.Topics + opts.Fn = func(msg xeth.WhisperMessage) { p.messagesMut.Lock() defer p.messagesMut.Unlock() p.messages[id].add(msg) // = append(p.messages[id], msg) } - id = p.xeth().Whisper().Watch(args) + id = p.xeth().Whisper().Watch(opts) p.messages[id] = &whisperFilter{timeout: time.Now()} *reply = id return nil @@ -498,51 +431,50 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error rpclogger.DebugDetailf("%T %s", req.Params, req.Params) switch req.Method { case "web3_sha3": - args, err := req.ToSha3Args() - if err != nil { + args := new(Sha3Args) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.Sha3(args, reply) + *reply = toHex(crypto.Sha3(fromHex(args.Data))) case "net_listening": - return p.GetIsListening(reply) + *reply = p.xeth().IsListening() case "net_peerCount": - return p.GetPeerCount(reply) + *reply = toHex(big.NewInt(int64(p.xeth().PeerCount())).Bytes()) case "eth_coinbase": - return p.GetCoinbase(reply) + *reply = p.xeth().Coinbase() case "eth_mining": - return p.GetIsMining(reply) + *reply = p.xeth().IsMining() case "eth_gasPrice": *reply = toHex(defaultGasPrice.Bytes()) - return nil case "eth_accounts": - return p.Accounts(reply) + *reply = p.xeth().Accounts() case "eth_blockNumber": - return p.BlockNumber(reply) + *reply = toHex(p.xeth().Backend().ChainManager().CurrentBlock().Number().Bytes()) case "eth_getBalance": - // TODO handle defaultBlock - args, err := req.ToGetBalanceArgs() - if err != nil { + // TODO handle BlockNumber + args := new(GetBalanceArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.GetBalanceAt(args, reply) + return p.GetBalance(args, reply) case "eth_getStorage": - // TODO handle defaultBlock - args, err := req.ToStorageArgs() - if err != nil { + // TODO handle BlockNumber + args := new(GetStorageArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } return p.GetStorage(args, reply) case "eth_getStorageAt": - // TODO handle defaultBlock - args, err := req.ToGetStorageAtArgs() - if err != nil { + // TODO handle BlockNumber + args := new(GetStorageAtArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } return p.GetStorageAt(args, reply) case "eth_getTransactionCount": - // TODO handle defaultBlock - args, err := req.ToGetTxCountArgs() - if err != nil { + // TODO handle BlockNumber + args := new(GetTxCountArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } return p.GetTxCountAt(args, reply) @@ -552,34 +484,40 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error case "eth_getUncleCountByBlockNumber": return errNotImplemented case "eth_getData": - // TODO handle defaultBlock - args, err := req.ToGetCodeAtArgs() - if err != nil { + // TODO handle BlockNumber + args := new(GetDataArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.GetCodeAt(args, reply) + return p.GetData(args, reply) case "eth_sendTransaction": - args, err := req.ToNewTxArgs() - if err != nil { + args := new(NewTxArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } return p.Transact(args, reply) case "eth_call": - args, err := req.ToNewTxArgs() - if err != nil { + args := new(NewTxArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } return p.Call(args, reply) case "eth_flush": return errNotImplemented - case "eth_getBlockByNumber": case "eth_getBlockByHash": // TODO handle second param for "include transaction objects" - args, err := req.ToGetBlockArgs() - if err != nil { + args := new(GetBlockByHashArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.GetBlock(args, reply) + *reply = p.xeth().BlockByHash(args.BlockHash) + case "eth_getBlockByNumber": + // TODO handle second param for "include transaction objects" + args := new(GetBlockByNumberArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { + return err + } + *reply = p.xeth().BlockByNumber(args.BlockNumber) case "eth_getTransactionByHash": case "eth_getTransactionByBlockHashAndIndex": case "eth_getTransactionByBlockNumberAndIndex": @@ -592,44 +530,44 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error case "eth_compileLLL": return errNotImplemented case "eth_compileSerpent": - args, err := req.ToCompileArgs() - if err != nil { + args := new(CompileArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } return p.CompileSerpent(args, reply) case "eth_newFilter": - args, err := req.ToFilterArgs() - if err != nil { + args := new(FilterOptions) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } return p.NewFilter(args, reply) case "eth_newBlockFilter": - args, err := req.ToFilterStringArgs() - if err != nil { + args := new(FilterStringArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.NewFilterString(args, reply) + return p.NewFilterString(args.Word, reply) case "eth_uninstallFilter": - args, err := req.ToUninstallFilterArgs() - if err != nil { + args := new(FilterIdArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.UninstallFilter(args, reply) + return p.UninstallFilter(args.Id, reply) case "eth_getFilterChanges": - args, err := req.ToIdArgs() - if err != nil { + args := new(FilterIdArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.FilterChanged(args, reply) + return p.FilterChanged(args.Id, reply) case "eth_getFilterLogs": - args, err := req.ToIdArgs() - if err != nil { + args := new(FilterIdArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.Logs(args, reply) + return p.Logs(args.Id, reply) case "eth_getLogs": - args, err := req.ToFilterArgs() - if err != nil { + args := new(FilterOptions) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } return p.AllLogs(args, reply) @@ -655,54 +593,54 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error // } // return p.WatchTx(args, reply) case "db_put": - args, err := req.ToDbPutArgs() - if err != nil { + args := new(DbArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } return p.DbPut(args, reply) case "db_get": - args, err := req.ToDbGetArgs() - if err != nil { + args := new(DbArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } return p.DbGet(args, reply) case "shh_post": - args, err := req.ToWhisperPostArgs() - if err != nil { + args := new(WhisperMessageArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } return p.WhisperPost(args, reply) case "shh_newIdentity": return p.NewWhisperIdentity(reply) case "shh_hasIdentity": - args, err := req.ToWhisperHasIdentityArgs() - if err != nil { + args := new(WhisperIdentityArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.HasWhisperIdentity(args, reply) + return p.HasWhisperIdentity(args.Identity, reply) case "shh_newGroup": case "shh_addToGroup": return errNotImplemented case "shh_newFilter": - args, err := req.ToWhisperFilterArgs() - if err != nil { + args := new(WhisperFilterArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } return p.NewWhisperFilter(args, reply) case "shh_uninstallFilter": return errNotImplemented case "shh_getFilterChanges": - args, err := req.ToIdArgs() - if err != nil { + args := new(FilterIdArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.MessagesChanged(args, reply) + return p.MessagesChanged(args.Id, reply) case "shh_getMessages": - args, err := req.ToIdArgs() - if err != nil { + args := new(FilterIdArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { return err } - return p.WhisperMessages(args, reply) + return p.WhisperMessages(args.Id, reply) case "client_version": *reply = p.eth.GetClientVersion() default: diff --git a/rpc/args.go b/rpc/args.go index 42d9855b75..3284a232ac 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -1,6 +1,7 @@ package rpc import ( + "bytes" "encoding/json" "math/big" @@ -8,180 +9,248 @@ import ( "github.com/ethereum/go-ethereum/ethutil" ) -type GetBlockArgs struct { - BlockNumber int32 - Hash string +type GetBlockByHashArgs struct { + BlockHash string + Transactions bool } -func (obj *GetBlockArgs) UnmarshalJSON(b []byte) (err error) { - argint, argstr := int32(0), "" - if err = json.Unmarshal(b, &argint); err == nil { - obj.BlockNumber = argint - return +func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) { + var obj []interface{} + r := bytes.NewReader(b) + if err := json.NewDecoder(r).Decode(&obj); err != nil { + return errDecodeArgs + } + + if len(obj) < 1 { + return errArguments } - if err = json.Unmarshal(b, &argstr); err == nil { - obj.Hash = argstr - return + args.BlockHash = obj[0].(string) + + if len(obj) > 1 { + args.Transactions = obj[1].(bool) } - return errDecodeArgs + + return nil } -type NewTxArgs struct { - From string `json:"from"` - To string `json:"to"` - Value *big.Int `json:"value"` - Gas *big.Int `json:"gas"` - GasPrice *big.Int `json:"gasPrice"` - Data string `json:"data"` +type GetBlockByNumberArgs struct { + BlockNumber uint64 + Transactions bool } -func (obj *NewTxArgs) UnmarshalJSON(b []byte) (err error) { - // Data can be either specified as "data" or "code" :-/ - var ext struct { - From string - To string - Value string - Gas string - GasPrice string - Data string - // Code string +func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) { + var obj []interface{} + r := bytes.NewReader(b) + if err := json.NewDecoder(r).Decode(&obj); err != nil { + return errDecodeArgs } - if err = json.Unmarshal(b, &ext); err == nil { - // if len(ext.Data) == 0 { - // ext.Data = ext.Code - // } - obj.From = ext.From - obj.To = ext.To - obj.Value = ethutil.Big(ext.Value) - obj.Gas = ethutil.Big(ext.Gas) - obj.GasPrice = ethutil.Big(ext.GasPrice) - obj.Data = ext.Data + if len(obj) < 1 { + return errArguments + } + args.BlockNumber = ethutil.BytesToNumber(fromHex(obj[0].(string))) - return + if len(obj) > 1 { + args.Transactions = obj[1].(bool) } - return errDecodeArgs + return nil } -type PushTxArgs struct { - Tx string `json:"tx"` +type NewTxArgs struct { + From string + To string + Value *big.Int + Gas *big.Int + GasPrice *big.Int + Data string } -func (obj *PushTxArgs) UnmarshalJSON(b []byte) (err error) { - arg0 := "" - if err = json.Unmarshal(b, &arg0); err == nil { - obj.Tx = arg0 - return +func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) { + var obj []struct { + From string `json:"from"` + To string `json:"to"` + Value string `json:"value"` + Gas string `json:"gas"` + GasPrice string `json:"gasPrice"` + Data string `json:"data"` } - return errDecodeArgs -} -func (a *PushTxArgs) requirementsPushTx() error { - if a.Tx == "" { - return NewErrorWithMessage(errArguments, "PushTx requires a 'tx' as argument") + if err = json.Unmarshal(b, &obj); err != nil { + return errDecodeArgs + } + + if len(obj) < 1 { + return errArguments } + args.From = obj[0].From + args.To = obj[0].To + args.Value = ethutil.Big(obj[0].Value) + args.Gas = ethutil.Big(obj[0].Gas) + args.GasPrice = ethutil.Big(obj[0].GasPrice) + args.Data = obj[0].Data + return nil } type GetStorageArgs struct { - Address string + Address string + BlockNumber uint64 } -func (obj *GetStorageArgs) UnmarshalJSON(b []byte) (err error) { - if err = json.Unmarshal(b, &obj.Address); err != nil { +func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) { + var obj []interface{} + r := bytes.NewReader(b) + if err := json.NewDecoder(r).Decode(&obj); err != nil { return errDecodeArgs } - return + + if len(obj) < 1 { + return errArguments + } + args.Address = obj[0].(string) + + if len(obj) > 1 { + args.BlockNumber = ethutil.BytesToNumber(fromHex(obj[1].(string))) + } + + return nil } -func (a *GetStorageArgs) requirements() error { - if len(a.Address) == 0 { - return NewErrorWithMessage(errArguments, "GetStorageAt requires an 'address' value as argument") +func (args *GetStorageArgs) requirements() error { + if len(args.Address) == 0 { + return NewErrorWithMessage(errArguments, "Address cannot be blank") } return nil } type GetStorageAtArgs struct { - Address string - Key string + Address string + Key string + BlockNumber uint64 } -func (obj *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) { - arg0 := "" - if err = json.Unmarshal(b, &arg0); err == nil { - obj.Address = arg0 - return +func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) { + var obj []interface{} + r := bytes.NewReader(b) + if err := json.NewDecoder(r).Decode(&obj); err != nil { + return errDecodeArgs + } + + if len(obj) < 2 { + return errArguments + } + args.Address = obj[0].(string) + args.Key = obj[1].(string) + + if len(obj) > 2 { + args.BlockNumber = ethutil.BytesToNumber(fromHex(obj[2].(string))) } - return errDecodeArgs + + return nil } -func (a *GetStorageAtArgs) requirements() error { - if a.Address == "" { - return NewErrorWithMessage(errArguments, "GetStorageAt requires an 'address' value as argument") +func (args *GetStorageAtArgs) requirements() error { + if len(args.Address) == 0 { + return NewErrorWithMessage(errArguments, "Address cannot be blank") } - if a.Key == "" { - return NewErrorWithMessage(errArguments, "GetStorageAt requires an 'key' value as argument") + + if len(args.Key) == 0 { + return NewErrorWithMessage(errArguments, "Key cannot be blank") } return nil } type GetTxCountArgs struct { - Address string `json:"address"` + Address string + BlockNumber uint64 } -func (obj *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) { - arg0 := "" - if err = json.Unmarshal(b, &arg0); err == nil { - obj.Address = arg0 - return +func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) { + var obj []interface{} + r := bytes.NewReader(b) + if err := json.NewDecoder(r).Decode(&obj); err != nil { + return errDecodeArgs + } + + if len(obj) < 1 { + return errArguments + } - return errDecodeArgs + args.Address = obj[0].(string) + + if len(obj) > 1 { + args.BlockNumber = ethutil.BytesToNumber(fromHex(obj[1].(string))) + } + + return nil } -func (a *GetTxCountArgs) requirements() error { - if a.Address == "" { - return NewErrorWithMessage(errArguments, "GetTxCountAt requires an 'address' value as argument") +func (args *GetTxCountArgs) requirements() error { + if len(args.Address) == 0 { + return NewErrorWithMessage(errArguments, "Address cannot be blank") } return nil } type GetBalanceArgs struct { - Address string + Address string + BlockNumber uint64 } -func (obj *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) { - arg0 := "" - if err = json.Unmarshal(b, &arg0); err == nil { - obj.Address = arg0 - return +func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) { + var obj []interface{} + r := bytes.NewReader(b) + if err := json.NewDecoder(r).Decode(&obj); err != nil { + return errDecodeArgs + } + + if len(obj) < 1 { + return errArguments + } + args.Address = obj[0].(string) + + if len(obj) > 1 { + args.BlockNumber = ethutil.BytesToNumber(fromHex(obj[1].(string))) } - return errDecodeArgs + + return nil } -func (a *GetBalanceArgs) requirements() error { - if a.Address == "" { - return NewErrorWithMessage(errArguments, "GetBalanceAt requires an 'address' value as argument") +func (args *GetBalanceArgs) requirements() error { + if len(args.Address) == 0 { + return NewErrorWithMessage(errArguments, "Address cannot be blank") } return nil } -type GetCodeAtArgs struct { - Address string +type GetDataArgs struct { + Address string + BlockNumber uint64 } -func (obj *GetCodeAtArgs) UnmarshalJSON(b []byte) (err error) { - arg0 := "" - if err = json.Unmarshal(b, &arg0); err == nil { - obj.Address = arg0 - return +func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) { + var obj []interface{} + r := bytes.NewReader(b) + if err := json.NewDecoder(r).Decode(&obj); err != nil { + return errDecodeArgs + } + + if len(obj) < 1 { + return errArguments + } + args.Address = obj[0].(string) + + if len(obj) > 1 { + args.BlockNumber = ethutil.BytesToNumber(fromHex(obj[1].(string))) } - return errDecodeArgs + + return nil } -func (a *GetCodeAtArgs) requirements() error { - if a.Address == "" { - return NewErrorWithMessage(errArguments, "GetCodeAt requires an 'address' value as argument") +func (args *GetDataArgs) requirements() error { + if len(args.Address) == 0 { + return NewErrorWithMessage(errArguments, "Address cannot be blank") } return nil } @@ -190,11 +259,55 @@ type Sha3Args struct { Data string } -func (obj *Sha3Args) UnmarshalJSON(b []byte) (err error) { - if err = json.Unmarshal(b, &obj.Data); err != nil { +func (args *Sha3Args) UnmarshalJSON(b []byte) (err error) { + var obj []interface{} + r := bytes.NewReader(b) + if err := json.NewDecoder(r).Decode(&obj); err != nil { + return NewErrorWithMessage(errDecodeArgs, err.Error()) + } + + if len(obj) < 1 { + return errArguments + } + args.Data = obj[0].(string) + + return nil +} + +type FilterArgs struct { + FromBlock uint64 + ToBlock uint64 + Limit uint64 + Offset uint64 + Address string + Topics []string +} + +func (args *FilterArgs) UnmarshalJSON(b []byte) (err error) { + var obj []struct { + FromBlock string `json:"fromBlock"` + ToBlock string `json:"toBlock"` + Limit string `json:"limit"` + Offset string `json:"offset"` + Address string `json:"address"` + Topics []string `json:"topics"` + } + + if err = json.Unmarshal(b, &obj); err != nil { return errDecodeArgs } - return + + if len(obj) < 1 { + return errArguments + } + args.FromBlock = ethutil.BytesToNumber(fromHex(obj[0].FromBlock)) + args.ToBlock = ethutil.BytesToNumber(fromHex(obj[0].ToBlock)) + args.Limit = ethutil.BytesToNumber(fromHex(obj[0].Limit)) + args.Offset = ethutil.BytesToNumber(fromHex(obj[0].Offset)) + args.Address = obj[0].Address + args.Topics = obj[0].Topics + + return nil } type FilterOptions struct { @@ -206,6 +319,33 @@ type FilterOptions struct { Max int } +func (args *FilterOptions) UnmarshalJSON(b []byte) (err error) { + var obj []struct { + FromBlock string `json:"fromBlock"` + ToBlock string `json:"toBlock"` + Limit string `json:"limit"` + Offset string `json:"offset"` + Address string `json:"address"` + Topics []string `json:"topics"` + } + + if err = json.Unmarshal(b, &obj); err != nil { + return errDecodeArgs + } + + if len(obj) < 1 { + return errArguments + } + args.Earliest = int64(ethutil.BytesToNumber(fromHex(obj[0].FromBlock))) + args.Latest = int64(ethutil.BytesToNumber(fromHex(obj[0].ToBlock))) + args.Max = int(ethutil.BytesToNumber(fromHex(obj[0].Limit))) + args.Skip = int(ethutil.BytesToNumber(fromHex(obj[0].Offset))) + args.Address = obj[0].Address + args.Topic = obj[0].Topics + + return nil +} + func toFilterOptions(options *FilterOptions) core.FilterOptions { var opts core.FilterOptions @@ -232,9 +372,9 @@ func toFilterOptions(options *FilterOptions) core.FilterOptions { return opts } -type FilterChangedArgs struct { - n int -} +// type FilterChangedArgs struct { +// n int +// } type DbArgs struct { Database string @@ -242,12 +382,32 @@ type DbArgs struct { Value string } +func (args *DbArgs) UnmarshalJSON(b []byte) (err error) { + var obj []interface{} + r := bytes.NewReader(b) + if err := json.NewDecoder(r).Decode(&obj); err != nil { + return errDecodeArgs + } + + if len(obj) < 2 { + return errArguments + } + args.Database = obj[0].(string) + args.Key = obj[1].(string) + + if len(obj) > 2 { + args.Value = obj[2].(string) + } + + return nil +} + func (a *DbArgs) requirements() error { if len(a.Database) == 0 { - return NewErrorWithMessage(errArguments, "DbPutArgs requires an 'Database' value as argument") + return NewErrorWithMessage(errArguments, "Database cannot be blank") } if len(a.Key) == 0 { - return NewErrorWithMessage(errArguments, "DbPutArgs requires an 'Key' value as argument") + return NewErrorWithMessage(errArguments, "Key cannot be blank") } return nil } @@ -260,3 +420,133 @@ type WhisperMessageArgs struct { Priority uint32 Ttl uint32 } + +func (args *WhisperMessageArgs) UnmarshalJSON(b []byte) (err error) { + var obj []struct { + Payload string + To string + From string + Topic []string + Priority string + Ttl string + } + + if err = json.Unmarshal(b, &obj); err != nil { + return errDecodeArgs + } + + if len(obj) < 1 { + return errArguments + } + args.Payload = obj[0].Payload + args.To = obj[0].To + args.From = obj[0].From + args.Topic = obj[0].Topic + args.Priority = uint32(ethutil.BytesToNumber(fromHex(obj[0].Priority))) + args.Ttl = uint32(ethutil.BytesToNumber(fromHex(obj[0].Ttl))) + + return nil +} + +type CompileArgs struct { + Source string +} + +func (args *CompileArgs) UnmarshalJSON(b []byte) (err error) { + var obj []interface{} + r := bytes.NewReader(b) + if err := json.NewDecoder(r).Decode(&obj); err != nil { + return errDecodeArgs + } + + if len(obj) > 0 { + args.Source = obj[0].(string) + } + + return nil +} + +type FilterStringArgs struct { + Word string +} + +func (args *FilterStringArgs) UnmarshalJSON(b []byte) (err error) { + var obj []string + r := bytes.NewReader(b) + if err := json.NewDecoder(r).Decode(&obj); err != nil { + return errDecodeArgs + } + + if len(obj) < 1 { + return errDecodeArgs + } + + args.Word = obj[0] + + return nil +} + +type FilterIdArgs struct { + Id int +} + +func (args *FilterIdArgs) UnmarshalJSON(b []byte) (err error) { + var obj []string + r := bytes.NewReader(b) + if err := json.NewDecoder(r).Decode(&obj); err != nil { + return errDecodeArgs + } + + if len(obj) < 1 { + return errDecodeArgs + } + + args.Id = int(ethutil.BytesToNumber(fromHex(obj[0]))) + + return nil +} + +type WhisperIdentityArgs struct { + Identity string +} + +func (args *WhisperIdentityArgs) UnmarshalJSON(b []byte) (err error) { + var obj []string + r := bytes.NewReader(b) + if err := json.NewDecoder(r).Decode(&obj); err != nil { + return errDecodeArgs + } + + if len(obj) < 1 { + return errDecodeArgs + } + + args.Identity = obj[0] + + return nil +} + +type WhisperFilterArgs struct { + To string + From string + Topics []string + Fn func() +} + +func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) { + var obj []WhisperFilterArgs + + if err = json.Unmarshal(b, &obj); err != nil { + return errDecodeArgs + } + + if len(obj) < 1 { + return errArguments + } + + args.To = obj[0].To + args.From = obj[0].From + args.Topics = obj[0].Topics + + return nil +} diff --git a/rpc/messages.go b/rpc/messages.go index 3ab99d2c51..4f5b009905 100644 --- a/rpc/messages.go +++ b/rpc/messages.go @@ -17,7 +17,6 @@ package rpc import ( - "bytes" "encoding/json" "errors" "fmt" @@ -33,10 +32,10 @@ var ( ) type RpcRequest struct { - ID interface{} `json:"id"` - JsonRpc string `json:"jsonrpc"` - Method string `json:"method"` - Params []json.RawMessage `json:"params"` + ID interface{} `json:"id"` + JsonRpc string `json:"jsonrpc"` + Method string `json:"method"` + Params json.RawMessage `json:"params"` } type RpcSuccessResponse struct { @@ -61,367 +60,30 @@ func NewErrorWithMessage(err error, msg string) error { return fmt.Errorf("%s: %s", err.Error(), msg) } -func (req *RpcRequest) ToSha3Args() (*Sha3Args, error) { - if len(req.Params) < 1 { - return nil, errArguments - } - - args := new(Sha3Args) - r := bytes.NewReader(req.Params[0]) - if err := json.NewDecoder(r).Decode(args); err != nil { - return nil, errDecodeArgs - } - - return args, nil -} - -func (req *RpcRequest) ToGetBlockArgs() (*GetBlockArgs, error) { - if len(req.Params) < 1 { - return nil, errArguments - } - - args := new(GetBlockArgs) - r := bytes.NewReader(req.Params[0]) - err := json.NewDecoder(r).Decode(args) - if err != nil { - return nil, errDecodeArgs - } - - return args, nil -} - -func (req *RpcRequest) ToNewTxArgs() (*NewTxArgs, error) { - if len(req.Params) < 1 { - return nil, errArguments - } - - args := new(NewTxArgs) - r := bytes.NewReader(req.Params[0]) - err := json.NewDecoder(r).Decode(args) - if err != nil { - return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) - } - - return args, nil -} - -func (req *RpcRequest) ToPushTxArgs() (*PushTxArgs, error) { - if len(req.Params) < 1 { - return nil, errArguments - } - - args := new(PushTxArgs) - r := bytes.NewReader(req.Params[0]) - err := json.NewDecoder(r).Decode(args) - if err != nil { - return nil, errDecodeArgs - } - - return args, nil -} - -func (req *RpcRequest) ToGetStorageAtArgs() (*GetStorageAtArgs, error) { - if len(req.Params) < 2 { - return nil, errArguments - } - - args := new(GetStorageAtArgs) - var arg0, arg1 string - - r0 := bytes.NewReader(req.Params[0]) - if err := json.NewDecoder(r0).Decode(arg0); err != nil { - return nil, errDecodeArgs - } - - r1 := bytes.NewReader(req.Params[1]) - if err := json.NewDecoder(r1).Decode(arg1); err != nil { - return nil, errDecodeArgs - } - - args.Address = arg0 - args.Key = arg1 - - return args, nil -} - -func (req *RpcRequest) ToStorageArgs() (*GetStorageArgs, error) { - if len(req.Params) < 1 { - return nil, errArguments - } - - args := new(GetStorageArgs) - r := bytes.NewReader(req.Params[0]) - err := json.NewDecoder(r).Decode(args) - if err != nil { - return nil, errDecodeArgs - } - - return args, nil -} - -func (req *RpcRequest) ToGetTxCountArgs() (*GetTxCountArgs, error) { - if len(req.Params) < 1 { - return nil, errArguments - } - - args := new(GetTxCountArgs) - r := bytes.NewReader(req.Params[0]) - err := json.NewDecoder(r).Decode(args) - if err != nil { - return nil, errDecodeArgs - } - - return args, nil -} - -func (req *RpcRequest) ToGetBalanceArgs() (*GetBalanceArgs, error) { - if len(req.Params) < 1 { - return nil, errArguments - } - - args := new(GetBalanceArgs) - r := bytes.NewReader(req.Params[0]) - err := json.NewDecoder(r).Decode(args) - if err != nil { - return nil, errDecodeArgs - } - - return args, nil -} - -func (req *RpcRequest) ToGetCodeAtArgs() (*GetCodeAtArgs, error) { - if len(req.Params) < 1 { - return nil, errArguments - } - - args := new(GetCodeAtArgs) - r := bytes.NewReader(req.Params[0]) - err := json.NewDecoder(r).Decode(args) - if err != nil { - return nil, errDecodeArgs - } - - return args, nil -} - -func (req *RpcRequest) ToBoolArgs() (bool, error) { - if len(req.Params) < 1 { - return false, errArguments - } - - var args bool - err := json.Unmarshal(req.Params[0], &args) - if err != nil { - return false, errDecodeArgs - } - - return args, nil -} - -func (req *RpcRequest) ToIntArgs() (int, error) { - if len(req.Params) < 1 { - return 0, errArguments - } - - var args int - if err := json.Unmarshal(req.Params[0], &args); err != nil { - return 0, errArguments - } - - return args, nil -} - -func (req *RpcRequest) ToCompileArgs() (string, error) { - if len(req.Params) < 1 { - return "", errArguments - } - - var args string - err := json.Unmarshal(req.Params[0], &args) - if err != nil { - return "", errDecodeArgs - } - - return args, nil -} - -func (req *RpcRequest) ToFilterArgs() (*FilterOptions, error) { - if len(req.Params) < 1 { - return nil, errArguments - } - - args := new(FilterOptions) - r := bytes.NewReader(req.Params[0]) - err := json.NewDecoder(r).Decode(args) - if err != nil { - return nil, errDecodeArgs - } - return args, nil -} - -func (req *RpcRequest) ToFilterStringArgs() (string, error) { - if len(req.Params) < 1 { - return "", errArguments - } - - var args string - err := json.Unmarshal(req.Params[0], &args) - if err != nil { - return "", errDecodeArgs - } - - return args, nil -} - -func (req *RpcRequest) ToUninstallFilterArgs() (int, error) { - if len(req.Params) < 1 { - return 0, errArguments - } - - var args int - err := json.Unmarshal(req.Params[0], &args) - if err != nil { - return 0, errDecodeArgs - } - - return args, nil -} - -func (req *RpcRequest) ToFilterChangedArgs() (int, error) { - if len(req.Params) < 1 { - return 0, errArguments - } - - var id int - r := bytes.NewReader(req.Params[0]) - err := json.NewDecoder(r).Decode(&id) - if err != nil { - return 0, errDecodeArgs - } - return id, nil -} - -func (req *RpcRequest) ToDbPutArgs() (*DbArgs, error) { - if len(req.Params) < 3 { - return nil, errArguments - } - - var args DbArgs - err := json.Unmarshal(req.Params[0], &args.Database) - if err != nil { - return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) - } - err = json.Unmarshal(req.Params[1], &args.Key) - if err != nil { - return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) - } - err = json.Unmarshal(req.Params[2], &args.Value) - if err != nil { - return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) - } +// func (req *RpcRequest) ToRegisterArgs() (string, error) { +// if len(req.Params) < 1 { +// return "", errArguments +// } - return &args, nil -} - -func (req *RpcRequest) ToDbGetArgs() (*DbArgs, error) { - if len(req.Params) < 2 { - return nil, errArguments - } +// var args string +// err := json.Unmarshal(req.Params, &args) +// if err != nil { +// return "", err +// } - var args DbArgs - err := json.Unmarshal(req.Params[0], &args.Database) - if err != nil { - return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) - } +// return args, nil +// } - err = json.Unmarshal(req.Params[1], &args.Key) - if err != nil { - return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) - } +// func (req *RpcRequest) ToWatchTxArgs() (string, error) { +// if len(req.Params) < 1 { +// return "", errArguments +// } - return &args, nil -} +// var args string +// err := json.Unmarshal(req.Params, &args) +// if err != nil { +// return "", err +// } -func (req *RpcRequest) ToWhisperFilterArgs() (*xeth.Options, error) { - if len(req.Params) < 1 { - return nil, errArguments - } - - var args xeth.Options - err := json.Unmarshal(req.Params[0], &args) - if err != nil { - return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) - } - - return &args, nil -} - -func (req *RpcRequest) ToIdArgs() (int, error) { - if len(req.Params) < 1 { - return 0, errArguments - } - - var id int - err := json.Unmarshal(req.Params[0], &id) - if err != nil { - return 0, errDecodeArgs - } - - return id, nil -} - -func (req *RpcRequest) ToWhisperPostArgs() (*WhisperMessageArgs, error) { - if len(req.Params) < 1 { - return nil, errArguments - } - - var args WhisperMessageArgs - err := json.Unmarshal(req.Params[0], &args) - if err != nil { - return nil, err - } - - return &args, nil -} - -func (req *RpcRequest) ToWhisperHasIdentityArgs() (string, error) { - if len(req.Params) < 1 { - return "", errArguments - } - - var args string - err := json.Unmarshal(req.Params[0], &args) - if err != nil { - return "", err - } - - return args, nil -} - -func (req *RpcRequest) ToRegisterArgs() (string, error) { - if len(req.Params) < 1 { - return "", errArguments - } - - var args string - err := json.Unmarshal(req.Params[0], &args) - if err != nil { - return "", err - } - - return args, nil -} - -func (req *RpcRequest) ToWatchTxArgs() (string, error) { - if len(req.Params) < 1 { - return "", errArguments - } - - var args string - err := json.Unmarshal(req.Params[0], &args) - if err != nil { - return "", err - } - - return args, nil -} +// return args, nil +// } diff --git a/xeth/xeth.go b/xeth/xeth.go index 8dd905b86b..451d3ceea7 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -86,21 +86,17 @@ func (self *XEth) BlockByHash(strHash string) *Block { return NewBlock(block) } -func (self *XEth) BlockByNumber(num int32) *Block { - if num == -1 { - return NewBlock(self.chainManager.CurrentBlock()) - } - - return NewBlock(self.chainManager.GetBlockByNumber(uint64(num))) +func (self *XEth) BlockByNumber(num uint64) *Block { + return NewBlock(self.chainManager.GetBlockByNumber(num)) } func (self *XEth) Block(v interface{}) *Block { if n, ok := v.(int32); ok { - return self.BlockByNumber(n) + return self.BlockByNumber(uint64(n)) } else if str, ok := v.(string); ok { return self.BlockByHash(str) } else if f, ok := v.(float64); ok { // Don't ask ... - return self.BlockByNumber(int32(f)) + return self.BlockByNumber(uint64(f)) } return nil