diff options
author | Bas van Kervel <bas@ethdev.com> | 2015-12-16 17:58:01 +0800 |
---|---|---|
committer | Jeffrey Wilcke <geffobscura@gmail.com> | 2016-01-26 20:51:50 +0800 |
commit | 19b2640e89465c1c57f1bbea0274d52d97151f60 (patch) | |
tree | 980e063693dae7fa6105646821ee6755b176b6e2 /rpc/api | |
parent | f2ab351e8d3b0a4e569ce56f6a4f17725ca5ba65 (diff) | |
download | go-tangerine-19b2640e89465c1c57f1bbea0274d52d97151f60.tar.gz go-tangerine-19b2640e89465c1c57f1bbea0274d52d97151f60.tar.zst go-tangerine-19b2640e89465c1c57f1bbea0274d52d97151f60.zip |
rpc: migrated the RPC insterface to a new reflection based RPC layer
Diffstat (limited to 'rpc/api')
34 files changed, 0 insertions, 8982 deletions
diff --git a/rpc/api/admin.go b/rpc/api/admin.go deleted file mode 100644 index daf2f31b4..000000000 --- a/rpc/api/admin.go +++ /dev/null @@ -1,465 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "fmt" - "io" - "math/big" - "os" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/compiler" - "github.com/ethereum/go-ethereum/common/natspec" - "github.com/ethereum/go-ethereum/common/registrar" - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/p2p/discover" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/rpc/codec" - "github.com/ethereum/go-ethereum/rpc/comms" - "github.com/ethereum/go-ethereum/rpc/shared" - "github.com/ethereum/go-ethereum/rpc/useragent" - "github.com/ethereum/go-ethereum/xeth" -) - -const ( - AdminApiversion = "1.0" - importBatchSize = 2500 -) - -var ( - // mapping between methods and handlers - AdminMapping = map[string]adminhandler{ - "admin_addPeer": (*adminApi).AddPeer, - "admin_peers": (*adminApi).Peers, - "admin_nodeInfo": (*adminApi).NodeInfo, - "admin_exportChain": (*adminApi).ExportChain, - "admin_importChain": (*adminApi).ImportChain, - "admin_setSolc": (*adminApi).SetSolc, - "admin_datadir": (*adminApi).DataDir, - "admin_startRPC": (*adminApi).StartRPC, - "admin_stopRPC": (*adminApi).StopRPC, - "admin_setGlobalRegistrar": (*adminApi).SetGlobalRegistrar, - "admin_setHashReg": (*adminApi).SetHashReg, - "admin_setUrlHint": (*adminApi).SetUrlHint, - "admin_saveInfo": (*adminApi).SaveInfo, - "admin_register": (*adminApi).Register, - "admin_registerUrl": (*adminApi).RegisterUrl, - "admin_startNatSpec": (*adminApi).StartNatSpec, - "admin_stopNatSpec": (*adminApi).StopNatSpec, - "admin_getContractInfo": (*adminApi).GetContractInfo, - "admin_httpGet": (*adminApi).HttpGet, - "admin_sleepBlocks": (*adminApi).SleepBlocks, - "admin_sleep": (*adminApi).Sleep, - "admin_enableUserAgent": (*adminApi).EnableUserAgent, - } -) - -// admin callback handler -type adminhandler func(*adminApi, *shared.Request) (interface{}, error) - -// admin api provider -type adminApi struct { - xeth *xeth.XEth - stack *node.Node - ethereum *eth.Ethereum - codec codec.Codec - coder codec.ApiCoder -} - -// create a new admin api instance -func NewAdminApi(xeth *xeth.XEth, stack *node.Node, codec codec.Codec) *adminApi { - api := &adminApi{ - xeth: xeth, - stack: stack, - codec: codec, - coder: codec.New(nil), - } - if stack != nil { - stack.Service(&api.ethereum) - } - return api -} - -// collection with supported methods -func (self *adminApi) Methods() []string { - methods := make([]string, len(AdminMapping)) - i := 0 - for k := range AdminMapping { - methods[i] = k - i++ - } - return methods -} - -// Execute given request -func (self *adminApi) Execute(req *shared.Request) (interface{}, error) { - if callback, ok := AdminMapping[req.Method]; ok { - return callback(self, req) - } - - return nil, &shared.NotImplementedError{req.Method} -} - -func (self *adminApi) Name() string { - return shared.AdminApiName -} - -func (self *adminApi) ApiVersion() string { - return AdminApiversion -} - -func (self *adminApi) AddPeer(req *shared.Request) (interface{}, error) { - args := new(AddPeerArgs) - if err := self.coder.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - node, err := discover.ParseNode(args.Url) - if err != nil { - return nil, fmt.Errorf("invalid node URL: %v", err) - } - self.stack.Server().AddPeer(node) - return true, nil -} - -func (self *adminApi) Peers(req *shared.Request) (interface{}, error) { - return self.stack.Server().PeersInfo(), nil -} - -func (self *adminApi) NodeInfo(req *shared.Request) (interface{}, error) { - return self.stack.Server().NodeInfo(), nil -} - -func (self *adminApi) DataDir(req *shared.Request) (interface{}, error) { - return self.stack.DataDir(), nil -} - -func hasAllBlocks(chain *core.BlockChain, bs []*types.Block) bool { - for _, b := range bs { - if !chain.HasBlock(b.Hash()) { - return false - } - } - return true -} - -func (self *adminApi) ImportChain(req *shared.Request) (interface{}, error) { - args := new(ImportExportChainArgs) - if err := self.coder.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - fh, err := os.Open(args.Filename) - if err != nil { - return false, err - } - defer fh.Close() - stream := rlp.NewStream(fh, 0) - - // Run actual the import. - blocks := make(types.Blocks, importBatchSize) - n := 0 - for batch := 0; ; batch++ { - - i := 0 - for ; i < importBatchSize; i++ { - var b types.Block - if err := stream.Decode(&b); err == io.EOF { - break - } else if err != nil { - return false, fmt.Errorf("at block %d: %v", n, err) - } - blocks[i] = &b - n++ - } - if i == 0 { - break - } - // Import the batch. - if hasAllBlocks(self.ethereum.BlockChain(), blocks[:i]) { - continue - } - if _, err := self.ethereum.BlockChain().InsertChain(blocks[:i]); err != nil { - return false, fmt.Errorf("invalid block %d: %v", n, err) - } - } - return true, nil -} - -func (self *adminApi) ExportChain(req *shared.Request) (interface{}, error) { - args := new(ImportExportChainArgs) - if err := self.coder.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - fh, err := os.OpenFile(args.Filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm) - if err != nil { - return false, err - } - defer fh.Close() - if err := self.ethereum.BlockChain().Export(fh); err != nil { - return false, err - } - - return true, nil -} - -func (self *adminApi) SetSolc(req *shared.Request) (interface{}, error) { - args := new(SetSolcArgs) - if err := self.coder.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - solc, err := self.xeth.SetSolc(args.Path) - if err != nil { - return nil, err - } - return solc.Info(), nil -} - -func (self *adminApi) StartRPC(req *shared.Request) (interface{}, error) { - args := new(StartRPCArgs) - if err := self.coder.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - cfg := comms.HttpConfig{ - ListenAddress: args.ListenAddress, - ListenPort: args.ListenPort, - CorsDomain: args.CorsDomain, - } - - apis, err := ParseApiString(args.Apis, self.codec, self.xeth, self.stack) - if err != nil { - return false, err - } - - err = comms.StartHttp(cfg, self.codec, Merge(apis...)) - if err == nil { - return true, nil - } - return false, err -} - -func (self *adminApi) StopRPC(req *shared.Request) (interface{}, error) { - comms.StopHttp() - return true, nil -} - -func (self *adminApi) SleepBlocks(req *shared.Request) (interface{}, error) { - args := new(SleepBlocksArgs) - if err := self.coder.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - var timer <-chan time.Time - var height *big.Int - var err error - if args.Timeout > 0 { - timer = time.NewTimer(time.Duration(args.Timeout) * time.Second).C - } - - height = new(big.Int).Add(self.xeth.CurrentBlock().Number(), big.NewInt(args.N)) - height, err = sleepBlocks(self.xeth.UpdateState(), height, timer) - if err != nil { - return nil, err - } - return height.Uint64(), nil -} - -func sleepBlocks(wait chan *big.Int, height *big.Int, timer <-chan time.Time) (newHeight *big.Int, err error) { - wait <- height - select { - case <-timer: - // if times out make sure the xeth loop does not block - go func() { - select { - case wait <- nil: - case <-wait: - } - }() - return nil, fmt.Errorf("timeout") - case newHeight = <-wait: - } - return -} - -func (self *adminApi) Sleep(req *shared.Request) (interface{}, error) { - args := new(SleepArgs) - if err := self.coder.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - time.Sleep(time.Duration(args.S) * time.Second) - return nil, nil -} - -func (self *adminApi) SetGlobalRegistrar(req *shared.Request) (interface{}, error) { - args := new(SetGlobalRegistrarArgs) - if err := self.coder.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - sender := common.HexToAddress(args.ContractAddress) - - reg := registrar.New(self.xeth) - txhash, err := reg.SetGlobalRegistrar(args.NameReg, sender) - if err != nil { - return false, err - } - - return txhash, nil -} - -func (self *adminApi) SetHashReg(req *shared.Request) (interface{}, error) { - args := new(SetHashRegArgs) - if err := self.coder.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - reg := registrar.New(self.xeth) - sender := common.HexToAddress(args.Sender) - txhash, err := reg.SetHashReg(args.HashReg, sender) - if err != nil { - return false, err - } - - return txhash, nil -} - -func (self *adminApi) SetUrlHint(req *shared.Request) (interface{}, error) { - args := new(SetUrlHintArgs) - if err := self.coder.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - urlHint := args.UrlHint - sender := common.HexToAddress(args.Sender) - - reg := registrar.New(self.xeth) - txhash, err := reg.SetUrlHint(urlHint, sender) - if err != nil { - return nil, err - } - - return txhash, nil -} - -func (self *adminApi) SaveInfo(req *shared.Request) (interface{}, error) { - args := new(SaveInfoArgs) - if err := self.coder.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - contenthash, err := compiler.SaveInfo(&args.ContractInfo, args.Filename) - if err != nil { - return nil, err - } - - return contenthash.Hex(), nil -} - -func (self *adminApi) Register(req *shared.Request) (interface{}, error) { - args := new(RegisterArgs) - if err := self.coder.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - sender := common.HexToAddress(args.Sender) - // sender and contract address are passed as hex strings - codeb := self.xeth.CodeAtBytes(args.Address) - codeHash := common.BytesToHash(crypto.Sha3(codeb)) - contentHash := common.HexToHash(args.ContentHashHex) - registry := registrar.New(self.xeth) - - _, err := registry.SetHashToHash(sender, codeHash, contentHash) - if err != nil { - return false, err - } - - return true, nil -} - -func (self *adminApi) RegisterUrl(req *shared.Request) (interface{}, error) { - args := new(RegisterUrlArgs) - if err := self.coder.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - sender := common.HexToAddress(args.Sender) - registry := registrar.New(self.xeth) - _, err := registry.SetUrlToHash(sender, common.HexToHash(args.ContentHash), args.Url) - if err != nil { - return false, err - } - - return true, nil -} - -func (self *adminApi) StartNatSpec(req *shared.Request) (interface{}, error) { - self.ethereum.NatSpec = true - return true, nil -} - -func (self *adminApi) StopNatSpec(req *shared.Request) (interface{}, error) { - self.ethereum.NatSpec = false - return true, nil -} - -func (self *adminApi) GetContractInfo(req *shared.Request) (interface{}, error) { - args := new(GetContractInfoArgs) - if err := self.coder.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - infoDoc, err := natspec.FetchDocsForContract(args.Contract, self.xeth, self.ethereum.HTTPClient()) - if err != nil { - return nil, err - } - - var info interface{} - err = self.coder.Decode(infoDoc, &info) - if err != nil { - return nil, err - } - - return info, nil -} - -func (self *adminApi) HttpGet(req *shared.Request) (interface{}, error) { - args := new(HttpGetArgs) - if err := self.coder.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - resp, err := self.ethereum.HTTPClient().Get(args.Uri, args.Path) - if err != nil { - return nil, err - } - - return string(resp), nil -} - -func (self *adminApi) EnableUserAgent(req *shared.Request) (interface{}, error) { - if fe, ok := self.xeth.Frontend().(*useragent.RemoteFrontend); ok { - fe.Enable() - } - return true, nil -} diff --git a/rpc/api/admin_args.go b/rpc/api/admin_args.go deleted file mode 100644 index e09597ad4..000000000 --- a/rpc/api/admin_args.go +++ /dev/null @@ -1,468 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "encoding/json" - - "github.com/ethereum/go-ethereum/common/compiler" - "github.com/ethereum/go-ethereum/rpc/shared" -) - -type AddPeerArgs struct { - Url string -} - -func (args *AddPeerArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) != 1 { - return shared.NewDecodeParamError("Expected enode as argument") - } - - urlstr, ok := obj[0].(string) - if !ok { - return shared.NewInvalidTypeError("url", "not a string") - } - args.Url = urlstr - - return nil -} - -type ImportExportChainArgs struct { - Filename string -} - -func (args *ImportExportChainArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) != 1 { - return shared.NewDecodeParamError("Expected filename as argument") - } - - filename, ok := obj[0].(string) - if !ok { - return shared.NewInvalidTypeError("filename", "not a string") - } - args.Filename = filename - - return nil -} - -type SetSolcArgs struct { - Path string -} - -func (args *SetSolcArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) != 1 { - return shared.NewDecodeParamError("Expected path as argument") - } - - if pathstr, ok := obj[0].(string); ok { - args.Path = pathstr - return nil - } - - return shared.NewInvalidTypeError("path", "not a string") -} - -type StartRPCArgs struct { - ListenAddress string - ListenPort uint - CorsDomain string - Apis string -} - -func (args *StartRPCArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - args.ListenAddress = "127.0.0.1" - args.ListenPort = 8545 - args.Apis = "net,eth,web3" - - if len(obj) >= 1 && obj[0] != nil { - if addr, ok := obj[0].(string); ok { - args.ListenAddress = addr - } else { - return shared.NewInvalidTypeError("listenAddress", "not a string") - } - } - - if len(obj) >= 2 && obj[1] != nil { - if port, ok := obj[1].(float64); ok && port >= 0 && port <= 64*1024 { - args.ListenPort = uint(port) - } else { - return shared.NewInvalidTypeError("listenPort", "not a valid port number") - } - } - - if len(obj) >= 3 && obj[2] != nil { - if corsDomain, ok := obj[2].(string); ok { - args.CorsDomain = corsDomain - } else { - return shared.NewInvalidTypeError("corsDomain", "not a string") - } - } - - if len(obj) >= 4 && obj[3] != nil { - if apis, ok := obj[3].(string); ok { - args.Apis = apis - } else { - return shared.NewInvalidTypeError("apis", "not a string") - } - } - - return nil -} - -type SleepArgs struct { - S int -} - -func (args *SleepArgs) UnmarshalJSON(b []byte) (err error) { - - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - if len(obj) >= 1 { - if obj[0] != nil { - if n, err := numString(obj[0]); err == nil { - args.S = int(n.Int64()) - } else { - return shared.NewInvalidTypeError("N", "not an integer: "+err.Error()) - } - } else { - return shared.NewInsufficientParamsError(0, 1) - } - } - return nil -} - -type SleepBlocksArgs struct { - N int64 - Timeout int64 -} - -func (args *SleepBlocksArgs) UnmarshalJSON(b []byte) (err error) { - - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - args.N = 1 - args.Timeout = 0 - if len(obj) >= 1 && obj[0] != nil { - if n, err := numString(obj[0]); err == nil { - args.N = n.Int64() - } else { - return shared.NewInvalidTypeError("N", "not an integer: "+err.Error()) - } - } - - if len(obj) >= 2 && obj[1] != nil { - if n, err := numString(obj[1]); err == nil { - args.Timeout = n.Int64() - } else { - return shared.NewInvalidTypeError("Timeout", "not an integer: "+err.Error()) - } - } - - return nil -} - -type SetGlobalRegistrarArgs struct { - NameReg string - ContractAddress string -} - -func (args *SetGlobalRegistrarArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) == 0 { - return shared.NewDecodeParamError("Expected namereg address") - } - - if len(obj) >= 1 { - if namereg, ok := obj[0].(string); ok { - args.NameReg = namereg - } else { - return shared.NewInvalidTypeError("NameReg", "not a string") - } - } - - if len(obj) >= 2 && obj[1] != nil { - if addr, ok := obj[1].(string); ok { - args.ContractAddress = addr - } else { - return shared.NewInvalidTypeError("ContractAddress", "not a string") - } - } - - return nil -} - -type SetHashRegArgs struct { - HashReg string - Sender string -} - -func (args *SetHashRegArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) >= 1 && obj[0] != nil { - if hashreg, ok := obj[0].(string); ok { - args.HashReg = hashreg - } else { - return shared.NewInvalidTypeError("HashReg", "not a string") - } - } - - if len(obj) >= 2 && obj[1] != nil { - if sender, ok := obj[1].(string); ok { - args.Sender = sender - } else { - return shared.NewInvalidTypeError("Sender", "not a string") - } - } - - return nil -} - -type SetUrlHintArgs struct { - UrlHint string - Sender string -} - -func (args *SetUrlHintArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) >= 1 && obj[0] != nil { - if urlhint, ok := obj[0].(string); ok { - args.UrlHint = urlhint - } else { - return shared.NewInvalidTypeError("UrlHint", "not a string") - } - } - - if len(obj) >= 2 && obj[1] != nil { - if sender, ok := obj[1].(string); ok { - args.Sender = sender - } else { - return shared.NewInvalidTypeError("Sender", "not a string") - } - } - - return nil -} - -type SaveInfoArgs struct { - ContractInfo compiler.ContractInfo - Filename string -} - -func (args *SaveInfoArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 2 { - return shared.NewInsufficientParamsError(len(obj), 2) - } - - if jsonraw, err := json.Marshal(obj[0]); err == nil { - if err = json.Unmarshal(jsonraw, &args.ContractInfo); err != nil { - return err - } - } else { - return err - } - - if filename, ok := obj[1].(string); ok { - args.Filename = filename - } else { - return shared.NewInvalidTypeError("Filename", "not a string") - } - - return nil -} - -type RegisterArgs struct { - Sender string - Address string - ContentHashHex string -} - -func (args *RegisterArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 3 { - return shared.NewInsufficientParamsError(len(obj), 3) - } - - if len(obj) >= 1 { - if sender, ok := obj[0].(string); ok { - args.Sender = sender - } else { - return shared.NewInvalidTypeError("Sender", "not a string") - } - } - - if len(obj) >= 2 { - if address, ok := obj[1].(string); ok { - args.Address = address - } else { - return shared.NewInvalidTypeError("Address", "not a string") - } - } - - if len(obj) >= 3 { - if hex, ok := obj[2].(string); ok { - args.ContentHashHex = hex - } else { - return shared.NewInvalidTypeError("ContentHashHex", "not a string") - } - } - - return nil -} - -type RegisterUrlArgs struct { - Sender string - ContentHash string - Url string -} - -func (args *RegisterUrlArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) >= 1 { - if sender, ok := obj[0].(string); ok { - args.Sender = sender - } else { - return shared.NewInvalidTypeError("Sender", "not a string") - } - } - - if len(obj) >= 2 { - if sender, ok := obj[1].(string); ok { - args.ContentHash = sender - } else { - return shared.NewInvalidTypeError("ContentHash", "not a string") - } - } - - if len(obj) >= 3 { - if sender, ok := obj[2].(string); ok { - args.Url = sender - } else { - return shared.NewInvalidTypeError("Url", "not a string") - } - } - - return nil -} - -type GetContractInfoArgs struct { - Contract string -} - -func (args *GetContractInfoArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - if len(obj) >= 1 { - if contract, ok := obj[0].(string); ok { - args.Contract = contract - } else { - return shared.NewInvalidTypeError("Contract", "not a string") - } - } - - return nil -} - -type HttpGetArgs struct { - Uri string - Path string -} - -func (args *HttpGetArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - if len(obj) >= 1 { - if uri, ok := obj[0].(string); ok { - args.Uri = uri - } else { - return shared.NewInvalidTypeError("Uri", "not a string") - } - } - - if len(obj) >= 2 && obj[1] != nil { - if path, ok := obj[1].(string); ok { - args.Path = path - } else { - return shared.NewInvalidTypeError("Path", "not a string") - } - } - - return nil -} diff --git a/rpc/api/admin_js.go b/rpc/api/admin_js.go deleted file mode 100644 index e6171cc74..000000000 --- a/rpc/api/admin_js.go +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -const Admin_JS = ` -web3._extend({ - property: 'admin', - methods: - [ - new web3._extend.Method({ - name: 'addPeer', - call: 'admin_addPeer', - params: 1, - inputFormatter: [null] - }), - new web3._extend.Method({ - name: 'exportChain', - call: 'admin_exportChain', - params: 1, - inputFormatter: [null] - }), - new web3._extend.Method({ - name: 'importChain', - call: 'admin_importChain', - params: 1, - inputFormatter: [null] - }), - new web3._extend.Method({ - name: 'sleepBlocks', - call: 'admin_sleepBlocks', - params: 2, - inputFormatter: [null, null] - }), - new web3._extend.Method({ - name: 'setSolc', - call: 'admin_setSolc', - params: 1, - inputFormatter: [null] - }), - new web3._extend.Method({ - name: 'startRPC', - call: 'admin_startRPC', - params: 4, - inputFormatter: [null, null, null, null] - }), - new web3._extend.Method({ - name: 'stopRPC', - call: 'admin_stopRPC', - params: 0, - inputFormatter: [] - }), - new web3._extend.Method({ - name: 'setGlobalRegistrar', - call: 'admin_setGlobalRegistrar', - params: 2, - inputFormatter: [null,null] - }), - new web3._extend.Method({ - name: 'setHashReg', - call: 'admin_setHashReg', - params: 2, - inputFormatter: [null,null] - }), - new web3._extend.Method({ - name: 'setUrlHint', - call: 'admin_setUrlHint', - params: 2, - inputFormatter: [null,null] - }), - new web3._extend.Method({ - name: 'saveInfo', - call: 'admin_saveInfo', - params: 2, - inputFormatter: [null,null] - }), - new web3._extend.Method({ - name: 'register', - call: 'admin_register', - params: 3, - inputFormatter: [null,null,null] - }), - new web3._extend.Method({ - name: 'registerUrl', - call: 'admin_registerUrl', - params: 3, - inputFormatter: [null,null,null] - }), - new web3._extend.Method({ - name: 'startNatSpec', - call: 'admin_startNatSpec', - params: 0, - inputFormatter: [] - }), - new web3._extend.Method({ - name: 'stopNatSpec', - call: 'admin_stopNatSpec', - params: 0, - inputFormatter: [] - }), - new web3._extend.Method({ - name: 'getContractInfo', - call: 'admin_getContractInfo', - params: 1, - inputFormatter: [null], - }), - new web3._extend.Method({ - name: 'httpGet', - call: 'admin_httpGet', - params: 2, - inputFormatter: [null, null] - }) - ], - properties: - [ - new web3._extend.Property({ - name: 'nodeInfo', - getter: 'admin_nodeInfo' - }), - new web3._extend.Property({ - name: 'peers', - getter: 'admin_peers' - }), - new web3._extend.Property({ - name: 'datadir', - getter: 'admin_datadir' - }) - ] -}); -` diff --git a/rpc/api/api.go b/rpc/api/api.go deleted file mode 100644 index e03250ec6..000000000 --- a/rpc/api/api.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "github.com/ethereum/go-ethereum/rpc/shared" -) - -// Merge multiple API's to a single API instance -func Merge(apis ...shared.EthereumApi) shared.EthereumApi { - return newMergedApi(apis...) -} diff --git a/rpc/api/api_test.go b/rpc/api/api_test.go deleted file mode 100644 index eb63e8151..000000000 --- a/rpc/api/api_test.go +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "testing" - - "encoding/json" - "strconv" - - "github.com/ethereum/go-ethereum/common/compiler" - "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/rpc/codec" - "github.com/ethereum/go-ethereum/rpc/shared" - "github.com/ethereum/go-ethereum/xeth" -) - -func TestParseApiString(t *testing.T) { - apis, err := ParseApiString("", codec.JSON, nil, nil) - if err == nil { - t.Errorf("Expected an err from parsing empty API string but got nil") - } - - if len(apis) != 0 { - t.Errorf("Expected 0 apis from empty API string") - } - - apis, err = ParseApiString("eth", codec.JSON, nil, nil) - if err != nil { - t.Errorf("Expected nil err from parsing empty API string but got %v", err) - } - - if len(apis) != 1 { - t.Errorf("Expected 1 apis but got %d - %v", apis, apis) - } - - apis, err = ParseApiString("eth,eth", codec.JSON, nil, nil) - if err != nil { - t.Errorf("Expected nil err from parsing empty API string but got \"%v\"", err) - } - - if len(apis) != 2 { - t.Errorf("Expected 2 apis but got %d - %v", apis, apis) - } - - apis, err = ParseApiString("eth,invalid", codec.JSON, nil, nil) - if err == nil { - t.Errorf("Expected an err but got no err") - } - -} - -const solcVersion = "0.9.23" - -func TestCompileSolidity(t *testing.T) { - - solc, err := compiler.New("") - if solc == nil { - t.Skip("no solc found: skip") - } else if solc.Version() != solcVersion { - t.Skip("WARNING: skipping test because of solc different version (%v, test written for %v, may need to update)", solc.Version(), solcVersion) - } - source := `contract test {\n` + - " /// @notice Will multiply `a` by 7." + `\n` + - ` function multiply(uint a) returns(uint d) {\n` + - ` return a * 7;\n` + - ` }\n` + - `}\n` - - jsonstr := `{"jsonrpc":"2.0","method":"eth_compileSolidity","params":["` + source + `"],"id":64}` - - expCode := "0x605880600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b603d6004803590602001506047565b8060005260206000f35b60006007820290506053565b91905056" - expAbiDefinition := `[{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"type":"function"}]` - expUserDoc := `{"methods":{"multiply(uint256)":{"notice":"Will multiply ` + "`a`" + ` by 7."}}}` - expDeveloperDoc := `{"methods":{}}` - expCompilerVersion := solc.Version() - expLanguage := "Solidity" - expLanguageVersion := "0" - expSource := source - - eth := ð.Ethereum{} - xeth := xeth.NewTest(nil, nil) - api := NewEthApi(xeth, eth, codec.JSON) - - var rpcRequest shared.Request - json.Unmarshal([]byte(jsonstr), &rpcRequest) - - response, err := api.CompileSolidity(&rpcRequest) - if err != nil { - t.Errorf("Execution failed, %v", err) - } - - respjson, err := json.Marshal(response) - if err != nil { - t.Errorf("expected no error, got %v", err) - } - - var contracts = make(map[string]*compiler.Contract) - err = json.Unmarshal(respjson, &contracts) - if err != nil { - t.Errorf("expected no error, got %v", err) - } - - if len(contracts) != 1 { - t.Errorf("expected one contract, got %v", len(contracts)) - } - - contract := contracts["test"] - - if contract.Code != expCode { - t.Errorf("Expected \n%s got \n%s", expCode, contract.Code) - } - - if strconv.Quote(contract.Info.Source) != `"`+expSource+`"` { - t.Errorf("Expected \n'%s' got \n'%s'", expSource, strconv.Quote(contract.Info.Source)) - } - - if contract.Info.Language != expLanguage { - t.Errorf("Expected %s got %s", expLanguage, contract.Info.Language) - } - - if contract.Info.LanguageVersion != expLanguageVersion { - t.Errorf("Expected %s got %s", expLanguageVersion, contract.Info.LanguageVersion) - } - - if contract.Info.CompilerVersion != expCompilerVersion { - t.Errorf("Expected %s got %s", expCompilerVersion, contract.Info.CompilerVersion) - } - - userdoc, err := json.Marshal(contract.Info.UserDoc) - if err != nil { - t.Errorf("expected no error, got %v", err) - } - - devdoc, err := json.Marshal(contract.Info.DeveloperDoc) - if err != nil { - t.Errorf("expected no error, got %v", err) - } - - abidef, err := json.Marshal(contract.Info.AbiDefinition) - if err != nil { - t.Errorf("expected no error, got %v", err) - } - - if string(abidef) != expAbiDefinition { - t.Errorf("Expected \n'%s' got \n'%s'", expAbiDefinition, string(abidef)) - } - - if string(userdoc) != expUserDoc { - t.Errorf("Expected \n'%s' got \n'%s'", expUserDoc, string(userdoc)) - } - - if string(devdoc) != expDeveloperDoc { - t.Errorf("Expected %s got %s", expDeveloperDoc, string(devdoc)) - } -} diff --git a/rpc/api/args.go b/rpc/api/args.go deleted file mode 100644 index 20f073b67..000000000 --- a/rpc/api/args.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "encoding/json" - - "github.com/ethereum/go-ethereum/rpc/shared" -) - -type CompileArgs struct { - Source string -} - -func (args *CompileArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - argstr, ok := obj[0].(string) - if !ok { - return shared.NewInvalidTypeError("arg0", "is not a string") - } - args.Source = argstr - - return nil -} - -type FilterStringArgs struct { - Word string -} - -func (args *FilterStringArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - var argstr string - argstr, ok := obj[0].(string) - if !ok { - return shared.NewInvalidTypeError("filter", "not a string") - } - switch argstr { - case "latest", "pending": - break - default: - return shared.NewValidationError("Word", "Must be `latest` or `pending`") - } - args.Word = argstr - return nil -} diff --git a/rpc/api/args_test.go b/rpc/api/args_test.go deleted file mode 100644 index 130315bd9..000000000 --- a/rpc/api/args_test.go +++ /dev/null @@ -1,2649 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "bytes" - "encoding/json" - "fmt" - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/rpc/shared" -) - -func TestBlockheightInvalidString(t *testing.T) { - v := "foo" - var num int64 - - str := ExpectInvalidTypeError(blockHeight(v, &num)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestBlockheightEarliest(t *testing.T) { - v := "earliest" - e := int64(0) - var num int64 - - err := blockHeight(v, &num) - if err != nil { - t.Error(err) - } - - if num != e { - t.Errorf("Expected %s but got %s", e, num) - } -} - -func TestBlockheightLatest(t *testing.T) { - v := "latest" - e := int64(-1) - var num int64 - - err := blockHeight(v, &num) - if err != nil { - t.Error(err) - } - - if num != e { - t.Errorf("Expected %s but got %s", e, num) - } -} - -func TestBlockheightPending(t *testing.T) { - v := "pending" - e := int64(-2) - var num int64 - - err := blockHeight(v, &num) - if err != nil { - t.Error(err) - } - - if num != e { - t.Errorf("Expected %s but got %s", e, num) - } -} - -func ExpectValidationError(err error) string { - var str string - switch err.(type) { - case nil: - str = "Expected error but didn't get one" - case *shared.ValidationError: - break - default: - str = fmt.Sprintf("Expected *rpc.ValidationError but got %T with message `%s`", err, err.Error()) - } - return str -} - -func ExpectInvalidTypeError(err error) string { - var str string - switch err.(type) { - case nil: - str = "Expected error but didn't get one" - case *shared.InvalidTypeError: - break - default: - str = fmt.Sprintf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) - } - return str -} - -func ExpectInsufficientParamsError(err error) string { - var str string - switch err.(type) { - case nil: - str = "Expected error but didn't get one" - case *shared.InsufficientParamsError: - break - default: - str = fmt.Sprintf("Expected *rpc.InsufficientParamsError but got %T with message %s", err, err.Error()) - } - return str -} - -func ExpectDecodeParamError(err error) string { - var str string - switch err.(type) { - case nil: - str = "Expected error but didn't get one" - case *shared.DecodeParamError: - break - default: - str = fmt.Sprintf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) - } - return str -} - -func TestSha3(t *testing.T) { - input := `["0x68656c6c6f20776f726c64"]` - expected := "0x68656c6c6f20776f726c64" - - args := new(Sha3Args) - json.Unmarshal([]byte(input), &args) - - if args.Data != expected { - t.Error("got %s expected %s", input, expected) - } -} - -func TestSha3ArgsInvalid(t *testing.T) { - input := `{}` - - args := new(Sha3Args) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestSha3ArgsEmpty(t *testing.T) { - input := `[]` - - args := new(Sha3Args) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} -func TestSha3ArgsDataInvalid(t *testing.T) { - input := `[4]` - - args := new(Sha3Args) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetBalanceArgs(t *testing.T) { - input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "0x1f"]` - expected := new(GetBalanceArgs) - expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1" - expected.BlockNumber = 31 - - args := new(GetBalanceArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if args.Address != expected.Address { - t.Errorf("Address should be %v but is %v", expected.Address, args.Address) - } - - if args.BlockNumber != expected.BlockNumber { - t.Errorf("BlockNumber should be %v but is %v", expected.BlockNumber, args.BlockNumber) - } -} - -func TestGetBalanceArgsBlocknumMissing(t *testing.T) { - input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1"]` - expected := new(GetBalanceArgs) - expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1" - expected.BlockNumber = -1 - - args := new(GetBalanceArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if args.Address != expected.Address { - t.Errorf("Address should be %v but is %v", expected.Address, args.Address) - } - - if args.BlockNumber != expected.BlockNumber { - t.Errorf("BlockNumber should be %v but is %v", expected.BlockNumber, args.BlockNumber) - } -} - -func TestGetBalanceArgsLatest(t *testing.T) { - input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "latest"]` - expected := new(GetBalanceArgs) - expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1" - expected.BlockNumber = -1 - - args := new(GetBalanceArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if args.Address != expected.Address { - t.Errorf("Address should be %v but is %v", expected.Address, args.Address) - } - - if args.BlockNumber != expected.BlockNumber { - t.Errorf("BlockNumber should be %v but is %v", expected.BlockNumber, args.BlockNumber) - } -} - -func TestGetBalanceArgsEmpty(t *testing.T) { - input := `[]` - - args := new(GetBalanceArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetBalanceArgsInvalid(t *testing.T) { - input := `6` - - args := new(GetBalanceArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetBalanceArgsBlockInvalid(t *testing.T) { - input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", false]` - - args := new(GetBalanceArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetBalanceArgsAddressInvalid(t *testing.T) { - input := `[-9, "latest"]` - - args := new(GetBalanceArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetBlockByHashArgs(t *testing.T) { - input := `["0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", true]` - expected := new(GetBlockByHashArgs) - expected.BlockHash = "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" - expected.IncludeTxs = true - - args := new(GetBlockByHashArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if args.BlockHash != expected.BlockHash { - t.Errorf("BlockHash should be %v but is %v", expected.BlockHash, args.BlockHash) - } - - if args.IncludeTxs != expected.IncludeTxs { - t.Errorf("IncludeTxs should be %v but is %v", expected.IncludeTxs, args.IncludeTxs) - } -} - -func TestGetBlockByHashArgsEmpty(t *testing.T) { - input := `[]` - - args := new(GetBlockByHashArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetBlockByHashArgsInvalid(t *testing.T) { - input := `{}` - - args := new(GetBlockByHashArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetBlockByHashArgsHashInt(t *testing.T) { - input := `[8]` - - args := new(GetBlockByHashArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetBlockByHashArgsHashBool(t *testing.T) { - input := `[false, true]` - - args := new(GetBlockByHashArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetBlockByNumberArgsBlockNum(t *testing.T) { - input := `[436, false]` - expected := new(GetBlockByNumberArgs) - expected.BlockNumber = 436 - expected.IncludeTxs = false - - args := new(GetBlockByNumberArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if args.BlockNumber != expected.BlockNumber { - t.Errorf("BlockNumber should be %v but is %v", expected.BlockNumber, args.BlockNumber) - } - - if args.IncludeTxs != expected.IncludeTxs { - t.Errorf("IncludeTxs should be %v but is %v", expected.IncludeTxs, args.IncludeTxs) - } -} - -func TestGetBlockByNumberArgsBlockHex(t *testing.T) { - input := `["0x1b4", false]` - expected := new(GetBlockByNumberArgs) - expected.BlockNumber = 436 - expected.IncludeTxs = false - - args := new(GetBlockByNumberArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if args.BlockNumber != expected.BlockNumber { - t.Errorf("BlockNumber should be %v but is %v", expected.BlockNumber, args.BlockNumber) - } - - if args.IncludeTxs != expected.IncludeTxs { - t.Errorf("IncludeTxs should be %v but is %v", expected.IncludeTxs, args.IncludeTxs) - } -} -func TestGetBlockByNumberArgsWords(t *testing.T) { - input := `["earliest", true]` - expected := new(GetBlockByNumberArgs) - expected.BlockNumber = 0 - expected.IncludeTxs = true - - args := new(GetBlockByNumberArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if args.BlockNumber != expected.BlockNumber { - t.Errorf("BlockNumber should be %v but is %v", expected.BlockNumber, args.BlockNumber) - } - - if args.IncludeTxs != expected.IncludeTxs { - t.Errorf("IncludeTxs should be %v but is %v", expected.IncludeTxs, args.IncludeTxs) - } -} - -func TestGetBlockByNumberEmpty(t *testing.T) { - input := `[]` - - args := new(GetBlockByNumberArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetBlockByNumberShort(t *testing.T) { - input := `["0xbbb"]` - - args := new(GetBlockByNumberArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetBlockByNumberBool(t *testing.T) { - input := `[true, true]` - - args := new(GetBlockByNumberArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} -func TestGetBlockByNumberBlockObject(t *testing.T) { - input := `{}` - - args := new(GetBlockByNumberArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestNewTxArgs(t *testing.T) { - input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", - "gas": "0x76c0", - "gasPrice": "0x9184e72a000", - "value": "0x9184e72a000", - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"}, - "0x10"]` - expected := new(NewTxArgs) - expected.From = "0xb60e8dd61c5d32be8058bb8eb970870f07233155" - expected.To = "0xd46e8dd67c5d32be8058bb8eb970870f072445675" - expected.Gas = big.NewInt(30400) - expected.GasPrice = big.NewInt(10000000000000) - expected.Value = big.NewInt(10000000000000) - expected.Data = "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" - expected.BlockNumber = big.NewInt(16).Int64() - - args := new(NewTxArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.From != args.From { - t.Errorf("From shoud be %#v but is %#v", expected.From, args.From) - } - - if expected.To != args.To { - t.Errorf("To shoud be %#v but is %#v", expected.To, args.To) - } - - if bytes.Compare(expected.Gas.Bytes(), args.Gas.Bytes()) != 0 { - t.Errorf("Gas shoud be %#v but is %#v", expected.Gas.Bytes(), args.Gas.Bytes()) - } - - if bytes.Compare(expected.GasPrice.Bytes(), args.GasPrice.Bytes()) != 0 { - t.Errorf("GasPrice shoud be %#v but is %#v", expected.GasPrice, args.GasPrice) - } - - if bytes.Compare(expected.Value.Bytes(), args.Value.Bytes()) != 0 { - t.Errorf("Value shoud be %#v but is %#v", expected.Value, args.Value) - } - - if expected.Data != args.Data { - t.Errorf("Data shoud be %#v but is %#v", expected.Data, args.Data) - } - - if expected.BlockNumber != args.BlockNumber { - t.Errorf("BlockNumber shoud be %#v but is %#v", expected.BlockNumber, args.BlockNumber) - } -} - -func TestNewTxArgsInt(t *testing.T) { - input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", - "gas": 100, - "gasPrice": 50, - "value": 8765456789, - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"}, - 5]` - expected := new(NewTxArgs) - expected.Gas = big.NewInt(100) - expected.GasPrice = big.NewInt(50) - expected.Value = big.NewInt(8765456789) - expected.BlockNumber = int64(5) - - args := new(NewTxArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if bytes.Compare(expected.Gas.Bytes(), args.Gas.Bytes()) != 0 { - t.Errorf("Gas shoud be %v but is %v", expected.Gas, args.Gas) - } - - if bytes.Compare(expected.GasPrice.Bytes(), args.GasPrice.Bytes()) != 0 { - t.Errorf("GasPrice shoud be %v but is %v", expected.GasPrice, args.GasPrice) - } - - if bytes.Compare(expected.Value.Bytes(), args.Value.Bytes()) != 0 { - t.Errorf("Value shoud be %v but is %v", expected.Value, args.Value) - } - - if expected.BlockNumber != args.BlockNumber { - t.Errorf("BlockNumber shoud be %v but is %v", expected.BlockNumber, args.BlockNumber) - } -} - -func TestNewTxArgsBlockBool(t *testing.T) { - input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", - "gas": "0x76c0", - "gasPrice": "0x9184e72a000", - "value": "0x9184e72a000", - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"}, - false]` - - args := new(NewTxArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestNewTxArgsGasInvalid(t *testing.T) { - input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", - "gas": false, - "gasPrice": "0x9184e72a000", - "value": "0x9184e72a000", - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" - }]` - - args := new(NewTxArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestNewTxArgsGaspriceInvalid(t *testing.T) { - input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", - "gas": "0x76c0", - "gasPrice": false, - "value": "0x9184e72a000", - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" - }]` - - args := new(NewTxArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestNewTxArgsValueInvalid(t *testing.T) { - input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", - "gas": "0x76c0", - "gasPrice": "0x9184e72a000", - "value": false, - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" - }]` - - args := new(NewTxArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestNewTxArgsGasMissing(t *testing.T) { - input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", - "gasPrice": "0x9184e72a000", - "value": "0x9184e72a000", - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" - }]` - expected := new(NewTxArgs) - expected.Gas = nil - - args := new(NewTxArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if args.Gas != expected.Gas { - // if bytes.Compare(expected.Gas.Bytes(), args.Gas.Bytes()) != 0 { - t.Errorf("Gas shoud be %v but is %v", expected.Gas, args.Gas) - } -} - -func TestNewTxArgsBlockGaspriceMissing(t *testing.T) { - input := `[{ - "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", - "gas": "0x76c0", - "value": "0x9184e72a000", - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" - }]` - expected := new(NewTxArgs) - expected.GasPrice = nil - - args := new(NewTxArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if args.GasPrice != expected.GasPrice { - // if bytes.Compare(expected.GasPrice.Bytes(), args.GasPrice.Bytes()) != 0 { - t.Errorf("GasPrice shoud be %v but is %v", expected.GasPrice, args.GasPrice) - } - -} - -func TestNewTxArgsValueMissing(t *testing.T) { - input := `[{ - "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", - "gas": "0x76c0", - "gasPrice": "0x9184e72a000", - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" - }]` - expected := new(NewTxArgs) - expected.Value = big.NewInt(0) - - args := new(NewTxArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if bytes.Compare(expected.Value.Bytes(), args.Value.Bytes()) != 0 { - t.Errorf("Value shoud be %v but is %v", expected.Value, args.Value) - } - -} - -func TestNewTxArgsEmpty(t *testing.T) { - input := `[]` - - args := new(NewTxArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestNewTxArgsInvalid(t *testing.T) { - input := `{}` - - args := new(NewTxArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} -func TestNewTxArgsNotStrings(t *testing.T) { - input := `[{"from":6}]` - - args := new(NewTxArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestNewTxArgsFromEmpty(t *testing.T) { - input := `[{"to": "0xb60e8dd61c5d32be8058bb8eb970870f07233155"}]` - - args := new(NewTxArgs) - str := ExpectValidationError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestCallArgs(t *testing.T) { - input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", - "gas": "0x76c0", - "gasPrice": "0x9184e72a000", - "value": "0x9184e72a000", - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"}, - "0x10"]` - expected := new(CallArgs) - expected.From = "0xb60e8dd61c5d32be8058bb8eb970870f07233155" - expected.To = "0xd46e8dd67c5d32be8058bb8eb970870f072445675" - expected.Gas = big.NewInt(30400) - expected.GasPrice = big.NewInt(10000000000000) - expected.Value = big.NewInt(10000000000000) - expected.Data = "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" - expected.BlockNumber = big.NewInt(16).Int64() - - args := new(CallArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.To != args.To { - t.Errorf("To shoud be %#v but is %#v", expected.To, args.To) - } - - if bytes.Compare(expected.Gas.Bytes(), args.Gas.Bytes()) != 0 { - t.Errorf("Gas shoud be %#v but is %#v", expected.Gas.Bytes(), args.Gas.Bytes()) - } - - if bytes.Compare(expected.GasPrice.Bytes(), args.GasPrice.Bytes()) != 0 { - t.Errorf("GasPrice shoud be %#v but is %#v", expected.GasPrice, args.GasPrice) - } - - if bytes.Compare(expected.Value.Bytes(), args.Value.Bytes()) != 0 { - t.Errorf("Value shoud be %#v but is %#v", expected.Value, args.Value) - } - - if expected.Data != args.Data { - t.Errorf("Data shoud be %#v but is %#v", expected.Data, args.Data) - } - - if expected.BlockNumber != args.BlockNumber { - t.Errorf("BlockNumber shoud be %#v but is %#v", expected.BlockNumber, args.BlockNumber) - } -} - -func TestCallArgsInt(t *testing.T) { - input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", - "gas": 100, - "gasPrice": 50, - "value": 8765456789, - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"}, - 5]` - expected := new(CallArgs) - expected.Gas = big.NewInt(100) - expected.GasPrice = big.NewInt(50) - expected.Value = big.NewInt(8765456789) - expected.BlockNumber = int64(5) - - args := new(CallArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if bytes.Compare(expected.Gas.Bytes(), args.Gas.Bytes()) != 0 { - t.Errorf("Gas shoud be %v but is %v", expected.Gas, args.Gas) - } - - if bytes.Compare(expected.GasPrice.Bytes(), args.GasPrice.Bytes()) != 0 { - t.Errorf("GasPrice shoud be %v but is %v", expected.GasPrice, args.GasPrice) - } - - if bytes.Compare(expected.Value.Bytes(), args.Value.Bytes()) != 0 { - t.Errorf("Value shoud be %v but is %v", expected.Value, args.Value) - } - - if expected.BlockNumber != args.BlockNumber { - t.Errorf("BlockNumber shoud be %v but is %v", expected.BlockNumber, args.BlockNumber) - } -} - -func TestCallArgsBlockBool(t *testing.T) { - input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", - "gas": "0x76c0", - "gasPrice": "0x9184e72a000", - "value": "0x9184e72a000", - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"}, - false]` - - args := new(CallArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestCallArgsGasInvalid(t *testing.T) { - input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", - "gas": false, - "gasPrice": "0x9184e72a000", - "value": "0x9184e72a000", - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" - }]` - - args := new(CallArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestCallArgsGaspriceInvalid(t *testing.T) { - input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", - "gas": "0x76c0", - "gasPrice": false, - "value": "0x9184e72a000", - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" - }]` - - args := new(CallArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestCallArgsValueInvalid(t *testing.T) { - input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", - "gas": "0x76c0", - "gasPrice": "0x9184e72a000", - "value": false, - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" - }]` - - args := new(CallArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestCallArgsGasMissing(t *testing.T) { - input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", - "gasPrice": "0x9184e72a000", - "value": "0x9184e72a000", - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" - }]` - - args := new(CallArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - expected := new(CallArgs) - expected.Gas = nil - - if args.Gas != expected.Gas { - // if bytes.Compare(expected.Gas.Bytes(), args.Gas.Bytes()) != 0 { - t.Errorf("Gas shoud be %v but is %v", expected.Gas, args.Gas) - } - -} - -func TestCallArgsBlockGaspriceMissing(t *testing.T) { - input := `[{ - "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", - "gas": "0x76c0", - "value": "0x9184e72a000", - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" - }]` - - args := new(CallArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - expected := new(CallArgs) - expected.GasPrice = nil - - if args.GasPrice != expected.GasPrice { - // if bytes.Compare(expected.GasPrice.Bytes(), args.GasPrice.Bytes()) != 0 { - t.Errorf("GasPrice shoud be %v but is %v", expected.GasPrice, args.GasPrice) - } -} - -func TestCallArgsValueMissing(t *testing.T) { - input := `[{ - "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", - "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", - "gas": "0x76c0", - "gasPrice": "0x9184e72a000", - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" - }]` - - args := new(CallArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - expected := new(CallArgs) - expected.Value = big.NewInt(int64(0)) - - if bytes.Compare(expected.Value.Bytes(), args.Value.Bytes()) != 0 { - t.Errorf("GasPrice shoud be %v but is %v", expected.Value, args.Value) - } -} - -func TestCallArgsEmpty(t *testing.T) { - input := `[]` - - args := new(CallArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestCallArgsInvalid(t *testing.T) { - input := `{}` - - args := new(CallArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} -func TestCallArgsNotStrings(t *testing.T) { - input := `[{"from":6}]` - - args := new(CallArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestCallArgsToEmpty(t *testing.T) { - input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155"}]` - args := new(CallArgs) - err := json.Unmarshal([]byte(input), &args) - if err != nil { - t.Error("Did not expect error. Got", err) - } -} - -func TestGetStorageArgs(t *testing.T) { - input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "latest"]` - expected := new(GetStorageArgs) - expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1" - expected.BlockNumber = -1 - - args := new(GetStorageArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.Address != args.Address { - t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address) - } - - if expected.BlockNumber != args.BlockNumber { - t.Errorf("BlockNumber shoud be %#v but is %#v", expected.BlockNumber, args.BlockNumber) - } -} - -func TestGetStorageArgsMissingBlocknum(t *testing.T) { - input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1"]` - expected := new(GetStorageArgs) - expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1" - expected.BlockNumber = -1 - - args := new(GetStorageArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.Address != args.Address { - t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address) - } - - if expected.BlockNumber != args.BlockNumber { - t.Errorf("BlockNumber shoud be %#v but is %#v", expected.BlockNumber, args.BlockNumber) - } -} - -func TestGetStorageInvalidArgs(t *testing.T) { - input := `{}` - - args := new(GetStorageArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetStorageInvalidBlockheight(t *testing.T) { - input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", {}]` - - args := new(GetStorageArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetStorageEmptyArgs(t *testing.T) { - input := `[]` - - args := new(GetStorageArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetStorageAddressInt(t *testing.T) { - input := `[32456785432456, "latest"]` - - args := new(GetStorageArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetStorageAtArgs(t *testing.T) { - input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "0x0", "0x2"]` - expected := new(GetStorageAtArgs) - expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1" - expected.Key = "0x0" - expected.BlockNumber = 2 - - args := new(GetStorageAtArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.Address != args.Address { - t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address) - } - - if expected.Key != args.Key { - t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address) - } - - if expected.BlockNumber != args.BlockNumber { - t.Errorf("BlockNumber shoud be %#v but is %#v", expected.BlockNumber, args.BlockNumber) - } -} - -func TestGetStorageAtArgsMissingBlocknum(t *testing.T) { - input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "0x0"]` - expected := new(GetStorageAtArgs) - expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1" - expected.Key = "0x0" - expected.BlockNumber = -1 - - args := new(GetStorageAtArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.Address != args.Address { - t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address) - } - - if expected.Key != args.Key { - t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address) - } - - if expected.BlockNumber != args.BlockNumber { - t.Errorf("BlockNumber shoud be %#v but is %#v", expected.BlockNumber, args.BlockNumber) - } -} - -func TestGetStorageAtEmptyArgs(t *testing.T) { - input := `[]` - - args := new(GetStorageAtArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetStorageAtArgsInvalid(t *testing.T) { - input := `{}` - - args := new(GetStorageAtArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetStorageAtArgsAddressNotString(t *testing.T) { - input := `[true, "0x0", "0x2"]` - - args := new(GetStorageAtArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetStorageAtArgsKeyNotString(t *testing.T) { - input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", true, "0x2"]` - - args := new(GetStorageAtArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetStorageAtArgsValueNotString(t *testing.T) { - input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "0x1", true]` - - args := new(GetStorageAtArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetTxCountArgs(t *testing.T) { - input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "pending"]` - expected := new(GetTxCountArgs) - expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1" - expected.BlockNumber = -2 - - args := new(GetTxCountArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.Address != args.Address { - t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address) - } - - if expected.BlockNumber != args.BlockNumber { - t.Errorf("BlockNumber shoud be %#v but is %#v", expected.BlockNumber, args.BlockNumber) - } -} - -func TestGetTxCountEmptyArgs(t *testing.T) { - input := `[]` - - args := new(GetTxCountArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetTxCountEmptyArgsInvalid(t *testing.T) { - input := `false` - - args := new(GetTxCountArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetTxCountAddressNotString(t *testing.T) { - input := `[false, "pending"]` - - args := new(GetTxCountArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetTxCountBlockheightMissing(t *testing.T) { - input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1"]` - expected := new(GetTxCountArgs) - expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1" - expected.BlockNumber = -1 - - args := new(GetTxCountArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.Address != args.Address { - t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address) - } - - if expected.BlockNumber != args.BlockNumber { - t.Errorf("BlockNumber shoud be %#v but is %#v", expected.BlockNumber, args.BlockNumber) - } -} - -func TestGetTxCountBlockheightInvalid(t *testing.T) { - input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", {}]` - - args := new(GetTxCountArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetDataArgs(t *testing.T) { - input := `["0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8", "latest"]` - expected := new(GetDataArgs) - expected.Address = "0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8" - expected.BlockNumber = -1 - - args := new(GetDataArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.Address != args.Address { - t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address) - } - - if expected.BlockNumber != args.BlockNumber { - t.Errorf("BlockNumber shoud be %#v but is %#v", expected.BlockNumber, args.BlockNumber) - } -} - -func TestGetDataArgsBlocknumMissing(t *testing.T) { - input := `["0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8"]` - expected := new(GetDataArgs) - expected.Address = "0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8" - expected.BlockNumber = -1 - - args := new(GetDataArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.Address != args.Address { - t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address) - } - - if expected.BlockNumber != args.BlockNumber { - t.Errorf("BlockNumber shoud be %#v but is %#v", expected.BlockNumber, args.BlockNumber) - } -} - -func TestGetDataArgsEmpty(t *testing.T) { - input := `[]` - - args := new(GetDataArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetDataArgsInvalid(t *testing.T) { - input := `{}` - - args := new(GetDataArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetDataArgsAddressNotString(t *testing.T) { - input := `[12, "latest"]` - - args := new(GetDataArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestGetDataArgsBlocknumberNotString(t *testing.T) { - input := `["0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8", false]` - - args := new(GetDataArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestBlockFilterArgs(t *testing.T) { - input := `[{ - "fromBlock": "0x1", - "toBlock": "0x2", - "limit": "0x3", - "offset": "0x0", - "address": "0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8", - "topics": - [ - ["0xAA", "0xBB"], - ["0xCC", "0xDD"] - ] - }]` - - expected := new(BlockFilterArgs) - expected.Earliest = 1 - expected.Latest = 2 - expected.Max = 3 - expected.Skip = 0 - expected.Address = []string{"0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8"} - expected.Topics = [][]string{ - []string{"0xAA", "0xBB"}, - []string{"0xCC", "0xDD"}, - } - - args := new(BlockFilterArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.Earliest != args.Earliest { - t.Errorf("Earliest shoud be %#v but is %#v", expected.Earliest, args.Earliest) - } - - if expected.Latest != args.Latest { - t.Errorf("Latest shoud be %#v but is %#v", expected.Latest, args.Latest) - } - - if expected.Max != args.Max { - t.Errorf("Max shoud be %#v but is %#v", expected.Max, args.Max) - } - - if expected.Skip != args.Skip { - t.Errorf("Skip shoud be %#v but is %#v", expected.Skip, args.Skip) - } - - if expected.Address[0] != args.Address[0] { - t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address) - } - - if expected.Topics[0][0] != args.Topics[0][0] { - t.Errorf("Topics shoud be %#v but is %#v", expected.Topics, args.Topics) - } - if expected.Topics[0][1] != args.Topics[0][1] { - t.Errorf("Topics shoud be %#v but is %#v", expected.Topics, args.Topics) - } - if expected.Topics[1][0] != args.Topics[1][0] { - t.Errorf("Topics shoud be %#v but is %#v", expected.Topics, args.Topics) - } - if expected.Topics[1][1] != args.Topics[1][1] { - t.Errorf("Topics shoud be %#v but is %#v", expected.Topics, args.Topics) - } - -} - -func TestBlockFilterArgsDefaults(t *testing.T) { - input := `[{ - "address": ["0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8"], - "topics": ["0xAA","0xBB"] - }]` - expected := new(BlockFilterArgs) - expected.Earliest = -1 - expected.Latest = -1 - expected.Max = 100 - expected.Skip = 0 - expected.Address = []string{"0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8"} - expected.Topics = [][]string{[]string{"0xAA"}, []string{"0xBB"}} - - args := new(BlockFilterArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.Earliest != args.Earliest { - t.Errorf("Earliest shoud be %#v but is %#v", expected.Earliest, args.Earliest) - } - - if expected.Latest != args.Latest { - t.Errorf("Latest shoud be %#v but is %#v", expected.Latest, args.Latest) - } - - if expected.Max != args.Max { - t.Errorf("Max shoud be %#v but is %#v", expected.Max, args.Max) - } - - if expected.Skip != args.Skip { - t.Errorf("Skip shoud be %#v but is %#v", expected.Skip, args.Skip) - } - - if expected.Address[0] != args.Address[0] { - t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address) - } - - if expected.Topics[0][0] != args.Topics[0][0] { - t.Errorf("Topics shoud be %#v but is %#v", expected.Topics, args.Topics) - } - - if expected.Topics[1][0] != args.Topics[1][0] { - t.Errorf("Topics shoud be %#v but is %#v", expected.Topics, args.Topics) - } -} - -func TestBlockFilterArgsWords(t *testing.T) { - input := `[{"fromBlock": "latest", "toBlock": "latest"}]` - expected := new(BlockFilterArgs) - expected.Earliest = -1 - expected.Latest = -1 - - args := new(BlockFilterArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.Earliest != args.Earliest { - t.Errorf("Earliest shoud be %#v but is %#v", expected.Earliest, args.Earliest) - } - - input = `[{"toBlock": "pending"}]` - if err := json.Unmarshal([]byte(input), &args); err == nil { - t.Errorf("Pending isn't currently supported and should raise an unsupported error") - } -} - -func TestBlockFilterArgsInvalid(t *testing.T) { - input := `{}` - - args := new(BlockFilterArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestBlockFilterArgsFromBool(t *testing.T) { - input := `[{ - "fromBlock": true, - "toBlock": "pending" - }]` - - args := new(BlockFilterArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestBlockFilterArgsToBool(t *testing.T) { - input := `[{ - "fromBlock": "pending", - "toBlock": true - }]` - - args := new(BlockFilterArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestBlockFilterArgsEmptyArgs(t *testing.T) { - input := `[]` - - args := new(BlockFilterArgs) - err := json.Unmarshal([]byte(input), &args) - if err == nil { - t.Error("Expected error but didn't get one") - } -} - -func TestBlockFilterArgsLimitInvalid(t *testing.T) { - input := `[{"limit": false}]` - - args := new(BlockFilterArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestBlockFilterArgsOffsetInvalid(t *testing.T) { - input := `[{"offset": true}]` - - args := new(BlockFilterArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestBlockFilterArgsAddressInt(t *testing.T) { - input := `[{ - "address": 1, - "topics": "0x12341234"}]` - - args := new(BlockFilterArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestBlockFilterArgsAddressSliceInt(t *testing.T) { - input := `[{ - "address": [1], - "topics": "0x12341234"}]` - - args := new(BlockFilterArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestBlockFilterArgsTopicInt(t *testing.T) { - input := `[{ - "address": ["0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8"], - "topics": 1}]` - - args := new(BlockFilterArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestBlockFilterArgsTopicSliceInt(t *testing.T) { - input := `[{ - "address": "0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8", - "topics": [1]}]` - - args := new(BlockFilterArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestBlockFilterArgsTopicSliceInt2(t *testing.T) { - input := `[{ - "address": "0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8", - "topics": ["0xAA", [1]]}]` - - args := new(BlockFilterArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestBlockFilterArgsTopicComplex(t *testing.T) { - input := `[{ - "address": "0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8", - "topics": ["0xAA", ["0xBB", "0xCC"]] - }]` - - args := new(BlockFilterArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - fmt.Printf("%v\n", args) - return - } - - if args.Topics[0][0] != "0xAA" { - t.Errorf("Topic should be %s but is %s", "0xAA", args.Topics[0][0]) - } - - if args.Topics[1][0] != "0xBB" { - t.Errorf("Topic should be %s but is %s", "0xBB", args.Topics[0][0]) - } - - if args.Topics[1][1] != "0xCC" { - t.Errorf("Topic should be %s but is %s", "0xCC", args.Topics[0][0]) - } -} - -func TestDbArgs(t *testing.T) { - input := `["testDB","myKey","0xbeef"]` - expected := new(DbArgs) - expected.Database = "testDB" - expected.Key = "myKey" - expected.Value = []byte("0xbeef") - - args := new(DbArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if err := args.requirements(); err != nil { - t.Error(err) - } - - if expected.Database != args.Database { - t.Errorf("Database shoud be %#v but is %#v", expected.Database, args.Database) - } - - if expected.Key != args.Key { - t.Errorf("Key shoud be %#v but is %#v", expected.Key, args.Key) - } - - if bytes.Compare(expected.Value, args.Value) != 0 { - t.Errorf("Value shoud be %#v but is %#v", expected.Value, args.Value) - } -} - -func TestDbArgsInvalid(t *testing.T) { - input := `{}` - - args := new(DbArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestDbArgsEmpty(t *testing.T) { - input := `[]` - - args := new(DbArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestDbArgsDatabaseType(t *testing.T) { - input := `[true, "keyval", "valval"]` - - args := new(DbArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestDbArgsKeyType(t *testing.T) { - input := `["dbval", 3, "valval"]` - - args := new(DbArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestDbArgsValType(t *testing.T) { - input := `["dbval", "keyval", {}]` - - args := new(DbArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestDbArgsDatabaseEmpty(t *testing.T) { - input := `["", "keyval", "valval"]` - - args := new(DbArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err.Error()) - } - - str := ExpectValidationError(args.requirements()) - if len(str) > 0 { - t.Error(str) - } -} - -func TestDbArgsKeyEmpty(t *testing.T) { - input := `["dbval", "", "valval"]` - - args := new(DbArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err.Error()) - } - - str := ExpectValidationError(args.requirements()) - if len(str) > 0 { - t.Error(str) - } -} - -func TestDbHexArgs(t *testing.T) { - input := `["testDB","myKey","0xbeef"]` - expected := new(DbHexArgs) - expected.Database = "testDB" - expected.Key = "myKey" - expected.Value = []byte{0xbe, 0xef} - - args := new(DbHexArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if err := args.requirements(); err != nil { - t.Error(err) - } - - if expected.Database != args.Database { - t.Errorf("Database shoud be %#v but is %#v", expected.Database, args.Database) - } - - if expected.Key != args.Key { - t.Errorf("Key shoud be %#v but is %#v", expected.Key, args.Key) - } - - if bytes.Compare(expected.Value, args.Value) != 0 { - t.Errorf("Value shoud be %#v but is %#v", expected.Value, args.Value) - } -} - -func TestDbHexArgsInvalid(t *testing.T) { - input := `{}` - - args := new(DbHexArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestDbHexArgsEmpty(t *testing.T) { - input := `[]` - - args := new(DbHexArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestDbHexArgsDatabaseType(t *testing.T) { - input := `[true, "keyval", "valval"]` - - args := new(DbHexArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestDbHexArgsKeyType(t *testing.T) { - input := `["dbval", 3, "valval"]` - - args := new(DbHexArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestDbHexArgsValType(t *testing.T) { - input := `["dbval", "keyval", {}]` - - args := new(DbHexArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestDbHexArgsDatabaseEmpty(t *testing.T) { - input := `["", "keyval", "valval"]` - - args := new(DbHexArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err.Error()) - } - - str := ExpectValidationError(args.requirements()) - if len(str) > 0 { - t.Error(str) - } -} - -func TestDbHexArgsKeyEmpty(t *testing.T) { - input := `["dbval", "", "valval"]` - - args := new(DbHexArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err.Error()) - } - - str := ExpectValidationError(args.requirements()) - if len(str) > 0 { - t.Error(str) - } -} - -func TestWhisperMessageArgs(t *testing.T) { - input := `[{"from":"0xc931d93e97ab07fe42d923478ba2465f2", - "topics": ["0x68656c6c6f20776f726c64"], - "payload":"0x68656c6c6f20776f726c64", - "ttl": "0x64", - "priority": "0x64"}]` - expected := new(WhisperMessageArgs) - expected.From = "0xc931d93e97ab07fe42d923478ba2465f2" - expected.To = "" - expected.Payload = "0x68656c6c6f20776f726c64" - expected.Priority = 100 - expected.Ttl = 100 - // expected.Topics = []string{"0x68656c6c6f20776f726c64"} - - args := new(WhisperMessageArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.From != args.From { - t.Errorf("From shoud be %#v but is %#v", expected.From, args.From) - } - - if expected.To != args.To { - t.Errorf("To shoud be %#v but is %#v", expected.To, args.To) - } - - if expected.Payload != args.Payload { - t.Errorf("Value shoud be %#v but is %#v", expected.Payload, args.Payload) - } - - if expected.Ttl != args.Ttl { - t.Errorf("Ttl shoud be %#v but is %#v", expected.Ttl, args.Ttl) - } - - if expected.Priority != args.Priority { - t.Errorf("Priority shoud be %#v but is %#v", expected.Priority, args.Priority) - } - - // if expected.Topics != args.Topics { - // t.Errorf("Topic shoud be %#v but is %#v", expected.Topic, args.Topic) - // } -} - -func TestWhisperMessageArgsInt(t *testing.T) { - input := `[{"from":"0xc931d93e97ab07fe42d923478ba2465f2", - "topics": ["0x68656c6c6f20776f726c64"], - "payload":"0x68656c6c6f20776f726c64", - "ttl": 12, - "priority": 16}]` - expected := new(WhisperMessageArgs) - expected.From = "0xc931d93e97ab07fe42d923478ba2465f2" - expected.To = "" - expected.Payload = "0x68656c6c6f20776f726c64" - expected.Priority = 16 - expected.Ttl = 12 - // expected.Topics = []string{"0x68656c6c6f20776f726c64"} - - args := new(WhisperMessageArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.From != args.From { - t.Errorf("From shoud be %#v but is %#v", expected.From, args.From) - } - - if expected.To != args.To { - t.Errorf("To shoud be %#v but is %#v", expected.To, args.To) - } - - if expected.Payload != args.Payload { - t.Errorf("Value shoud be %#v but is %#v", expected.Payload, args.Payload) - } - - if expected.Ttl != args.Ttl { - t.Errorf("Ttl shoud be %v but is %v", expected.Ttl, args.Ttl) - } - - if expected.Priority != args.Priority { - t.Errorf("Priority shoud be %v but is %v", expected.Priority, args.Priority) - } - - // if expected.Topics != args.Topics { - // t.Errorf("Topic shoud be %#v but is %#v", expected.Topic, args.Topic) - // } -} - -func TestWhisperMessageArgsInvalid(t *testing.T) { - input := `{}` - - args := new(WhisperMessageArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestWhisperMessageArgsEmpty(t *testing.T) { - input := `[]` - - args := new(WhisperMessageArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestWhisperMessageArgsTtlBool(t *testing.T) { - input := `[{"from":"0xc931d93e97ab07fe42d923478ba2465f2", - "topics": ["0x68656c6c6f20776f726c64"], - "payload":"0x68656c6c6f20776f726c64", - "ttl": true, - "priority": "0x64"}]` - args := new(WhisperMessageArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestWhisperMessageArgsPriorityBool(t *testing.T) { - input := `[{"from":"0xc931d93e97ab07fe42d923478ba2465f2", - "topics": ["0x68656c6c6f20776f726c64"], - "payload":"0x68656c6c6f20776f726c64", - "ttl": "0x12", - "priority": true}]` - args := new(WhisperMessageArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestFilterIdArgs(t *testing.T) { - input := `["0x7"]` - expected := new(FilterIdArgs) - expected.Id = 7 - - args := new(FilterIdArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.Id != args.Id { - t.Errorf("Id shoud be %#v but is %#v", expected.Id, args.Id) - } -} - -func TestFilterIdArgsInvalid(t *testing.T) { - input := `{}` - - args := new(FilterIdArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Errorf(str) - } -} - -func TestFilterIdArgsEmpty(t *testing.T) { - input := `[]` - - args := new(FilterIdArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Errorf(str) - } -} - -func TestFilterIdArgsBool(t *testing.T) { - input := `[true]` - - args := new(FilterIdArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Errorf(str) - } -} - -func TestWhisperFilterArgs(t *testing.T) { - input := `[{"topics": ["0x68656c6c6f20776f726c64"], "to": "0x34ag445g3455b34"}]` - expected := new(WhisperFilterArgs) - expected.To = "0x34ag445g3455b34" - expected.Topics = [][]string{[]string{"0x68656c6c6f20776f726c64"}} - - args := new(WhisperFilterArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.To != args.To { - t.Errorf("To shoud be %#v but is %#v", expected.To, args.To) - } - - // if expected.Topics != args.Topics { - // t.Errorf("Topics shoud be %#v but is %#v", expected.Topics, args.Topics) - // } -} - -func TestWhisperFilterArgsInvalid(t *testing.T) { - input := `{}` - - args := new(WhisperFilterArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestWhisperFilterArgsEmpty(t *testing.T) { - input := `[]` - - args := new(WhisperFilterArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestWhisperFilterArgsToInt(t *testing.T) { - input := `[{"to": 2}]` - - args := new(WhisperFilterArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestWhisperFilterArgsToBool(t *testing.T) { - input := `[{"topics": ["0x68656c6c6f20776f726c64"], "to": false}]` - - args := new(WhisperFilterArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestWhisperFilterArgsToMissing(t *testing.T) { - input := `[{"topics": ["0x68656c6c6f20776f726c64"]}]` - expected := new(WhisperFilterArgs) - expected.To = "" - - args := new(WhisperFilterArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if args.To != expected.To { - t.Errorf("To shoud be %v but is %v", expected.To, args.To) - } -} - -func TestWhisperFilterArgsTopicInt(t *testing.T) { - input := `[{"topics": [6], "to": "0x34ag445g3455b34"}]` - - args := new(WhisperFilterArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestCompileArgs(t *testing.T) { - input := `["contract test { function multiply(uint a) returns(uint d) { return a * 7; } }"]` - expected := new(CompileArgs) - expected.Source = `contract test { function multiply(uint a) returns(uint d) { return a * 7; } }` - - args := new(CompileArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.Source != args.Source { - t.Errorf("Source shoud be %#v but is %#v", expected.Source, args.Source) - } -} - -func TestCompileArgsInvalid(t *testing.T) { - input := `{}` - - args := new(CompileArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestCompileArgsEmpty(t *testing.T) { - input := `[]` - - args := new(CompileArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestCompileArgsBool(t *testing.T) { - input := `[false]` - - args := new(CompileArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestFilterStringArgs(t *testing.T) { - input := `["pending"]` - expected := new(FilterStringArgs) - expected.Word = "pending" - - args := new(FilterStringArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.Word != args.Word { - t.Errorf("Word shoud be %#v but is %#v", expected.Word, args.Word) - } -} - -func TestFilterStringEmptyArgs(t *testing.T) { - input := `[]` - - args := new(FilterStringArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Errorf(str) - } -} - -func TestFilterStringInvalidArgs(t *testing.T) { - input := `{}` - - args := new(FilterStringArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Errorf(str) - } -} - -func TestFilterStringWordInt(t *testing.T) { - input := `[7]` - - args := new(FilterStringArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Errorf(str) - } -} - -func TestFilterStringWordWrong(t *testing.T) { - input := `["foo"]` - - args := new(FilterStringArgs) - str := ExpectValidationError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Errorf(str) - } -} - -func TestWhisperIdentityArgs(t *testing.T) { - input := `["0xc931d93e97ab07fe42d923478ba2465f283"]` - expected := new(WhisperIdentityArgs) - expected.Identity = "0xc931d93e97ab07fe42d923478ba2465f283" - - args := new(WhisperIdentityArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.Identity != args.Identity { - t.Errorf("Identity shoud be %#v but is %#v", expected.Identity, args.Identity) - } -} - -func TestWhisperIdentityArgsInvalid(t *testing.T) { - input := `{}` - - args := new(WhisperIdentityArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Errorf(str) - } -} - -func TestWhisperIdentityArgsEmpty(t *testing.T) { - input := `[]` - - args := new(WhisperIdentityArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Errorf(str) - } -} - -func TestWhisperIdentityArgsInt(t *testing.T) { - input := `[4]` - - args := new(WhisperIdentityArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Errorf(str) - } -} - -func TestBlockNumArgs(t *testing.T) { - input := `["0x29a"]` - expected := new(BlockNumIndexArgs) - expected.BlockNumber = 666 - - args := new(BlockNumArg) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.BlockNumber != args.BlockNumber { - t.Errorf("BlockNumber shoud be %#v but is %#v", expected.BlockNumber, args.BlockNumber) - } -} - -func TestBlockNumArgsWord(t *testing.T) { - input := `["pending"]` - expected := new(BlockNumIndexArgs) - expected.BlockNumber = -2 - - args := new(BlockNumArg) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.BlockNumber != args.BlockNumber { - t.Errorf("BlockNumber shoud be %#v but is %#v", expected.BlockNumber, args.BlockNumber) - } -} - -func TestBlockNumArgsInvalid(t *testing.T) { - input := `{}` - - args := new(BlockNumArg) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestBlockNumArgsEmpty(t *testing.T) { - input := `[]` - - args := new(BlockNumArg) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} -func TestBlockNumArgsBool(t *testing.T) { - input := `[true]` - - args := new(BlockNumArg) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestBlockNumIndexArgs(t *testing.T) { - input := `["0x29a", "0x0"]` - expected := new(BlockNumIndexArgs) - expected.BlockNumber = 666 - expected.Index = 0 - - args := new(BlockNumIndexArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.BlockNumber != args.BlockNumber { - t.Errorf("BlockNumber shoud be %#v but is %#v", expected.BlockNumber, args.BlockNumber) - } - - if expected.Index != args.Index { - t.Errorf("Index shoud be %#v but is %#v", expected.Index, args.Index) - } -} - -func TestBlockNumIndexArgsWord(t *testing.T) { - input := `["latest", 67]` - expected := new(BlockNumIndexArgs) - expected.BlockNumber = -1 - expected.Index = 67 - - args := new(BlockNumIndexArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.BlockNumber != args.BlockNumber { - t.Errorf("BlockNumber shoud be %#v but is %#v", expected.BlockNumber, args.BlockNumber) - } - - if expected.Index != args.Index { - t.Errorf("Index shoud be %#v but is %#v", expected.Index, args.Index) - } -} - -func TestBlockNumIndexArgsEmpty(t *testing.T) { - input := `[]` - - args := new(BlockNumIndexArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestBlockNumIndexArgsInvalid(t *testing.T) { - input := `"foo"` - - args := new(BlockNumIndexArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestBlockNumIndexArgsBlocknumInvalid(t *testing.T) { - input := `[{}, "0x1"]` - - args := new(BlockNumIndexArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestBlockNumIndexArgsIndexInvalid(t *testing.T) { - input := `["0x29a", true]` - - args := new(BlockNumIndexArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestHashIndexArgs(t *testing.T) { - input := `["0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b", "0x1"]` - expected := new(HashIndexArgs) - expected.Hash = "0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b" - expected.Index = 1 - - args := new(HashIndexArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.Hash != args.Hash { - t.Errorf("Hash shoud be %#v but is %#v", expected.Hash, args.Hash) - } - - if expected.Index != args.Index { - t.Errorf("Index shoud be %#v but is %#v", expected.Index, args.Index) - } -} - -func TestHashIndexArgsEmpty(t *testing.T) { - input := `[]` - - args := new(HashIndexArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestHashIndexArgsInvalid(t *testing.T) { - input := `{}` - - args := new(HashIndexArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestHashIndexArgsInvalidHash(t *testing.T) { - input := `[7, "0x1"]` - - args := new(HashIndexArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestHashIndexArgsInvalidIndex(t *testing.T) { - input := `["0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b", false]` - - args := new(HashIndexArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestHashArgs(t *testing.T) { - input := `["0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b"]` - expected := new(HashIndexArgs) - expected.Hash = "0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b" - - args := new(HashArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.Hash != args.Hash { - t.Errorf("Hash shoud be %#v but is %#v", expected.Hash, args.Hash) - } -} - -func TestHashArgsEmpty(t *testing.T) { - input := `[]` - - args := new(HashArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestHashArgsInvalid(t *testing.T) { - input := `{}` - - args := new(HashArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestHashArgsInvalidHash(t *testing.T) { - input := `[7]` - - args := new(HashArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestSubmitWorkArgs(t *testing.T) { - input := `["0x0000000000000001", "0x1234567890abcdef1234567890abcdef", "0xD1GE5700000000000000000000000000"]` - expected := new(SubmitWorkArgs) - expected.Nonce = 1 - expected.Header = "0x1234567890abcdef1234567890abcdef" - expected.Digest = "0xD1GE5700000000000000000000000000" - - args := new(SubmitWorkArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.Nonce != args.Nonce { - t.Errorf("Nonce shoud be %d but is %d", expected.Nonce, args.Nonce) - } - - if expected.Header != args.Header { - t.Errorf("Header shoud be %#v but is %#v", expected.Header, args.Header) - } - - if expected.Digest != args.Digest { - t.Errorf("Digest shoud be %#v but is %#v", expected.Digest, args.Digest) - } -} - -func TestSubmitWorkArgsInvalid(t *testing.T) { - input := `{}` - - args := new(SubmitWorkArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestSubmitWorkArgsEmpty(t *testing.T) { - input := `[]` - - args := new(SubmitWorkArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestSubmitWorkArgsNonceInt(t *testing.T) { - input := `[1, "0x1234567890abcdef1234567890abcdef", "0xD1GE5700000000000000000000000000"]` - - args := new(SubmitWorkArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} -func TestSubmitWorkArgsHeaderInt(t *testing.T) { - input := `["0x0000000000000001", 1, "0xD1GE5700000000000000000000000000"]` - - args := new(SubmitWorkArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} -func TestSubmitWorkArgsDigestInt(t *testing.T) { - input := `["0x0000000000000001", "0x1234567890abcdef1234567890abcdef", 1]` - - args := new(SubmitWorkArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestBlockHeightFromJsonInvalid(t *testing.T) { - var num int64 - var msg json.RawMessage = []byte(`}{`) - str := ExpectDecodeParamError(blockHeightFromJson(msg, &num)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestSourceArgsEmpty(t *testing.T) { - input := `[]` - - args := new(SourceArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestSigArgs(t *testing.T) { - input := `["0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x0"]` - expected := new(NewSigArgs) - expected.From = "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" - expected.Data = "0x0" - - args := new(NewSigArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.From != args.From { - t.Errorf("From should be %v but is %v", expected.From, args.From) - } - - if expected.Data != args.Data { - t.Errorf("Data should be %v but is %v", expected.Data, args.Data) - } -} - -func TestSigArgsEmptyData(t *testing.T) { - input := `["0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", ""]` - - args := new(NewSigArgs) - str := ExpectValidationError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestSigArgsDataType(t *testing.T) { - input := `["0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", 13]` - - args := new(NewSigArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestSigArgsEmptyFrom(t *testing.T) { - input := `["", "0x0"]` - - args := new(NewSigArgs) - str := ExpectValidationError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestSigArgsFromType(t *testing.T) { - input := `[false, "0x0"]` - - args := new(NewSigArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestSigArgsEmpty(t *testing.T) { - input := `[]` - args := new(NewSigArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestDataArgs(t *testing.T) { - input := `["0x0123"]` - expected := new(NewDataArgs) - expected.Data = "0x0123" - - args := new(NewDataArgs) - if err := json.Unmarshal([]byte(input), &args); err != nil { - t.Error(err) - } - - if expected.Data != args.Data { - t.Errorf("Data should be %v but is %v", expected.Data, args.Data) - } -} - -func TestDataArgsEmptyData(t *testing.T) { - input := `[""]` - - args := new(NewDataArgs) - str := ExpectValidationError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestDataArgsDataType(t *testing.T) { - input := `[13]` - - args := new(NewDataArgs) - str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestDataArgsEmpty(t *testing.T) { - input := `[]` - args := new(NewDataArgs) - str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} - -func TestDataArgsInvalid(t *testing.T) { - input := `{}` - - args := new(NewDataArgs) - str := ExpectDecodeParamError(json.Unmarshal([]byte(input), args)) - if len(str) > 0 { - t.Error(str) - } -} diff --git a/rpc/api/db.go b/rpc/api/db.go deleted file mode 100644 index 0eddc410e..000000000 --- a/rpc/api/db.go +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/rpc/codec" - "github.com/ethereum/go-ethereum/rpc/shared" - "github.com/ethereum/go-ethereum/xeth" -) - -const ( - DbApiversion = "1.0" -) - -var ( - // mapping between methods and handlers - DbMapping = map[string]dbhandler{ - "db_getString": (*dbApi).GetString, - "db_putString": (*dbApi).PutString, - "db_getHex": (*dbApi).GetHex, - "db_putHex": (*dbApi).PutHex, - } -) - -// db callback handler -type dbhandler func(*dbApi, *shared.Request) (interface{}, error) - -// db api provider -type dbApi struct { - xeth *xeth.XEth - ethereum *eth.Ethereum - methods map[string]dbhandler - codec codec.ApiCoder -} - -// create a new db api instance -func NewDbApi(xeth *xeth.XEth, ethereum *eth.Ethereum, coder codec.Codec) *dbApi { - return &dbApi{ - xeth: xeth, - ethereum: ethereum, - methods: DbMapping, - codec: coder.New(nil), - } -} - -// collection with supported methods -func (self *dbApi) Methods() []string { - methods := make([]string, len(self.methods)) - i := 0 - for k := range self.methods { - methods[i] = k - i++ - } - return methods -} - -// Execute given request -func (self *dbApi) Execute(req *shared.Request) (interface{}, error) { - if callback, ok := self.methods[req.Method]; ok { - return callback(self, req) - } - - return nil, &shared.NotImplementedError{req.Method} -} - -func (self *dbApi) Name() string { - return shared.DbApiName -} - -func (self *dbApi) ApiVersion() string { - return DbApiversion -} - -func (self *dbApi) GetString(req *shared.Request) (interface{}, error) { - args := new(DbArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - if err := args.requirements(); err != nil { - return nil, err - } - - ret, err := self.xeth.DbGet([]byte(args.Database + args.Key)) - return string(ret), err -} - -func (self *dbApi) PutString(req *shared.Request) (interface{}, error) { - args := new(DbArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - if err := args.requirements(); err != nil { - return nil, err - } - - return self.xeth.DbPut([]byte(args.Database+args.Key), args.Value), nil -} - -func (self *dbApi) GetHex(req *shared.Request) (interface{}, error) { - args := new(DbHexArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - if err := args.requirements(); err != nil { - return nil, err - } - - if res, err := self.xeth.DbGet([]byte(args.Database + args.Key)); err == nil { - return newHexData(res), nil - } else { - return nil, err - } -} - -func (self *dbApi) PutHex(req *shared.Request) (interface{}, error) { - args := new(DbHexArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - if err := args.requirements(); err != nil { - return nil, err - } - - return self.xeth.DbPut([]byte(args.Database+args.Key), args.Value), nil -} diff --git a/rpc/api/db_args.go b/rpc/api/db_args.go deleted file mode 100644 index d61ea77ee..000000000 --- a/rpc/api/db_args.go +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "encoding/json" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rpc/shared" -) - -type DbArgs struct { - Database string - Key string - Value []byte -} - -func (args *DbArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 2 { - return shared.NewInsufficientParamsError(len(obj), 2) - } - - var objstr string - var ok bool - - if objstr, ok = obj[0].(string); !ok { - return shared.NewInvalidTypeError("database", "not a string") - } - args.Database = objstr - - if objstr, ok = obj[1].(string); !ok { - return shared.NewInvalidTypeError("key", "not a string") - } - args.Key = objstr - - if len(obj) > 2 { - objstr, ok = obj[2].(string) - if !ok { - return shared.NewInvalidTypeError("value", "not a string") - } - - args.Value = []byte(objstr) - } - - return nil -} - -func (a *DbArgs) requirements() error { - if len(a.Database) == 0 { - return shared.NewValidationError("Database", "cannot be blank") - } - if len(a.Key) == 0 { - return shared.NewValidationError("Key", "cannot be blank") - } - return nil -} - -type DbHexArgs struct { - Database string - Key string - Value []byte -} - -func (args *DbHexArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 2 { - return shared.NewInsufficientParamsError(len(obj), 2) - } - - var objstr string - var ok bool - - if objstr, ok = obj[0].(string); !ok { - return shared.NewInvalidTypeError("database", "not a string") - } - args.Database = objstr - - if objstr, ok = obj[1].(string); !ok { - return shared.NewInvalidTypeError("key", "not a string") - } - args.Key = objstr - - if len(obj) > 2 { - objstr, ok = obj[2].(string) - if !ok { - return shared.NewInvalidTypeError("value", "not a string") - } - - args.Value = common.FromHex(objstr) - } - - return nil -} - -func (a *DbHexArgs) requirements() error { - if len(a.Database) == 0 { - return shared.NewValidationError("Database", "cannot be blank") - } - if len(a.Key) == 0 { - return shared.NewValidationError("Key", "cannot be blank") - } - return nil -} diff --git a/rpc/api/db_js.go b/rpc/api/db_js.go deleted file mode 100644 index 899f8abd9..000000000 --- a/rpc/api/db_js.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -const Db_JS = ` -web3._extend({ - property: 'db', - methods: - [ - ], - properties: - [ - ] -}); -` diff --git a/rpc/api/debug.go b/rpc/api/debug.go deleted file mode 100644 index a6faa335e..000000000 --- a/rpc/api/debug.go +++ /dev/null @@ -1,303 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "fmt" - "strings" - "time" - - "github.com/ethereum/ethash" - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/rpc/codec" - "github.com/ethereum/go-ethereum/rpc/shared" - "github.com/ethereum/go-ethereum/xeth" - "github.com/rcrowley/go-metrics" -) - -const ( - DebugApiVersion = "1.0" -) - -var ( - // mapping between methods and handlers - DebugMapping = map[string]debughandler{ - "debug_dumpBlock": (*debugApi).DumpBlock, - "debug_getBlockRlp": (*debugApi).GetBlockRlp, - "debug_printBlock": (*debugApi).PrintBlock, - "debug_processBlock": (*debugApi).ProcessBlock, - "debug_seedHash": (*debugApi).SeedHash, - "debug_setHead": (*debugApi).SetHead, - "debug_metrics": (*debugApi).Metrics, - } -) - -// debug callback handler -type debughandler func(*debugApi, *shared.Request) (interface{}, error) - -// admin api provider -type debugApi struct { - xeth *xeth.XEth - ethereum *eth.Ethereum - methods map[string]debughandler - codec codec.ApiCoder -} - -// create a new debug api instance -func NewDebugApi(xeth *xeth.XEth, ethereum *eth.Ethereum, coder codec.Codec) *debugApi { - return &debugApi{ - xeth: xeth, - ethereum: ethereum, - methods: DebugMapping, - codec: coder.New(nil), - } -} - -// collection with supported methods -func (self *debugApi) Methods() []string { - methods := make([]string, len(self.methods)) - i := 0 - for k := range self.methods { - methods[i] = k - i++ - } - return methods -} - -// Execute given request -func (self *debugApi) Execute(req *shared.Request) (interface{}, error) { - if callback, ok := self.methods[req.Method]; ok { - return callback(self, req) - } - - return nil, &shared.NotImplementedError{req.Method} -} - -func (self *debugApi) Name() string { - return shared.DebugApiName -} - -func (self *debugApi) ApiVersion() string { - return DebugApiVersion -} - -func (self *debugApi) PrintBlock(req *shared.Request) (interface{}, error) { - args := new(BlockNumArg) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - block := self.xeth.EthBlockByNumber(args.BlockNumber) - return fmt.Sprintf("%s", block), nil -} - -func (self *debugApi) DumpBlock(req *shared.Request) (interface{}, error) { - args := new(BlockNumArg) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - block := self.xeth.EthBlockByNumber(args.BlockNumber) - if block == nil { - return nil, fmt.Errorf("block #%d not found", args.BlockNumber) - } - - stateDb, err := state.New(block.Root(), self.ethereum.ChainDb()) - if err != nil { - return nil, err - } - - return stateDb.RawDump(), nil -} - -func (self *debugApi) GetBlockRlp(req *shared.Request) (interface{}, error) { - args := new(BlockNumArg) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - block := self.xeth.EthBlockByNumber(args.BlockNumber) - if block == nil { - return nil, fmt.Errorf("block #%d not found", args.BlockNumber) - } - encoded, err := rlp.EncodeToBytes(block) - return fmt.Sprintf("%x", encoded), err -} - -func (self *debugApi) SetHead(req *shared.Request) (interface{}, error) { - args := new(BlockNumArg) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - self.ethereum.BlockChain().SetHead(uint64(args.BlockNumber)) - - return nil, nil -} - -func (self *debugApi) ProcessBlock(req *shared.Request) (interface{}, error) { - args := new(BlockNumArg) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - block := self.xeth.EthBlockByNumber(args.BlockNumber) - if block == nil { - return nil, fmt.Errorf("block #%d not found", args.BlockNumber) - } - - old := vm.Debug - defer func() { vm.Debug = old }() - vm.Debug = true - - var ( - blockchain = self.ethereum.BlockChain() - validator = blockchain.Validator() - processor = blockchain.Processor() - ) - - err := core.ValidateHeader(blockchain.AuxValidator(), block.Header(), blockchain.GetHeader(block.ParentHash()), true, false) - if err != nil { - return false, err - } - statedb, err := state.New(blockchain.GetBlock(block.ParentHash()).Root(), self.ethereum.ChainDb()) - if err != nil { - return false, err - } - receipts, _, usedGas, err := processor.Process(block, statedb) - if err != nil { - return false, err - } - err = validator.ValidateState(block, blockchain.GetBlock(block.ParentHash()), statedb, receipts, usedGas) - if err != nil { - return false, err - } - - return true, nil -} - -func (self *debugApi) SeedHash(req *shared.Request) (interface{}, error) { - args := new(BlockNumArg) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - if hash, err := ethash.GetSeedHash(uint64(args.BlockNumber)); err == nil { - return fmt.Sprintf("0x%x", hash), nil - } else { - return nil, err - } -} - -func (self *debugApi) Metrics(req *shared.Request) (interface{}, error) { - args := new(MetricsArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - // Create a rate formatter - units := []string{"", "K", "M", "G", "T", "E", "P"} - round := func(value float64, prec int) string { - unit := 0 - for value >= 1000 { - unit, value, prec = unit+1, value/1000, 2 - } - return fmt.Sprintf(fmt.Sprintf("%%.%df%s", prec, units[unit]), value) - } - format := func(total float64, rate float64) string { - return fmt.Sprintf("%s (%s/s)", round(total, 0), round(rate, 2)) - } - // Iterate over all the metrics, and just dump for now - counters := make(map[string]interface{}) - metrics.DefaultRegistry.Each(func(name string, metric interface{}) { - // Create or retrieve the counter hierarchy for this metric - root, parts := counters, strings.Split(name, "/") - for _, part := range parts[:len(parts)-1] { - if _, ok := root[part]; !ok { - root[part] = make(map[string]interface{}) - } - root = root[part].(map[string]interface{}) - } - name = parts[len(parts)-1] - - // Fill the counter with the metric details, formatting if requested - if args.Raw { - switch metric := metric.(type) { - case metrics.Meter: - root[name] = map[string]interface{}{ - "AvgRate01Min": metric.Rate1(), - "AvgRate05Min": metric.Rate5(), - "AvgRate15Min": metric.Rate15(), - "MeanRate": metric.RateMean(), - "Overall": float64(metric.Count()), - } - - case metrics.Timer: - root[name] = map[string]interface{}{ - "AvgRate01Min": metric.Rate1(), - "AvgRate05Min": metric.Rate5(), - "AvgRate15Min": metric.Rate15(), - "MeanRate": metric.RateMean(), - "Overall": float64(metric.Count()), - "Percentiles": map[string]interface{}{ - "5": metric.Percentile(0.05), - "20": metric.Percentile(0.2), - "50": metric.Percentile(0.5), - "80": metric.Percentile(0.8), - "95": metric.Percentile(0.95), - }, - } - - default: - root[name] = "Unknown metric type" - } - } else { - switch metric := metric.(type) { - case metrics.Meter: - root[name] = map[string]interface{}{ - "Avg01Min": format(metric.Rate1()*60, metric.Rate1()), - "Avg05Min": format(metric.Rate5()*300, metric.Rate5()), - "Avg15Min": format(metric.Rate15()*900, metric.Rate15()), - "Overall": format(float64(metric.Count()), metric.RateMean()), - } - - case metrics.Timer: - root[name] = map[string]interface{}{ - "Avg01Min": format(metric.Rate1()*60, metric.Rate1()), - "Avg05Min": format(metric.Rate5()*300, metric.Rate5()), - "Avg15Min": format(metric.Rate15()*900, metric.Rate15()), - "Overall": format(float64(metric.Count()), metric.RateMean()), - "Maximum": time.Duration(metric.Max()).String(), - "Minimum": time.Duration(metric.Min()).String(), - "Percentiles": map[string]interface{}{ - "5": time.Duration(metric.Percentile(0.05)).String(), - "20": time.Duration(metric.Percentile(0.2)).String(), - "50": time.Duration(metric.Percentile(0.5)).String(), - "80": time.Duration(metric.Percentile(0.8)).String(), - "95": time.Duration(metric.Percentile(0.95)).String(), - }, - } - - default: - root[name] = "Unknown metric type" - } - } - }) - return counters, nil -} diff --git a/rpc/api/debug_args.go b/rpc/api/debug_args.go deleted file mode 100644 index 041ad6b6a..000000000 --- a/rpc/api/debug_args.go +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "encoding/json" - "fmt" - "math/big" - "reflect" - - "github.com/ethereum/go-ethereum/rpc/shared" -) - -type WaitForBlockArgs struct { - MinHeight int - Timeout int // in seconds -} - -func (args *WaitForBlockArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) > 2 { - return fmt.Errorf("waitForArgs needs 0, 1, 2 arguments") - } - - // default values when not provided - args.MinHeight = -1 - args.Timeout = -1 - - if len(obj) >= 1 { - var minHeight *big.Int - if minHeight, err = numString(obj[0]); err != nil { - return err - } - args.MinHeight = int(minHeight.Int64()) - } - - if len(obj) >= 2 { - timeout, err := numString(obj[1]) - if err != nil { - return err - } - args.Timeout = int(timeout.Int64()) - } - - return nil -} - -type MetricsArgs struct { - Raw bool -} - -func (args *MetricsArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - if len(obj) > 1 { - return fmt.Errorf("metricsArgs needs 0, 1 arguments") - } - // default values when not provided - if len(obj) >= 1 && obj[0] != nil { - if value, ok := obj[0].(bool); !ok { - return fmt.Errorf("invalid argument %v", reflect.TypeOf(obj[0])) - } else { - args.Raw = value - } - } - return nil -} diff --git a/rpc/api/debug_js.go b/rpc/api/debug_js.go deleted file mode 100644 index 030511add..000000000 --- a/rpc/api/debug_js.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -const Debug_JS = ` -web3._extend({ - property: 'debug', - methods: - [ - new web3._extend.Method({ - name: 'printBlock', - call: 'debug_printBlock', - params: 1, - inputFormatter: [null] - }), - new web3._extend.Method({ - name: 'getBlockRlp', - call: 'debug_getBlockRlp', - params: 1, - inputFormatter: [null] - }), - new web3._extend.Method({ - name: 'setHead', - call: 'debug_setHead', - params: 1, - inputFormatter: [null] - }), - new web3._extend.Method({ - name: 'processBlock', - call: 'debug_processBlock', - params: 1, - inputFormatter: [null] - }), - new web3._extend.Method({ - name: 'seedHash', - call: 'debug_seedHash', - params: 1, - inputFormatter: [null] - }), - new web3._extend.Method({ - name: 'dumpBlock', - call: 'debug_dumpBlock', - params: 1, - inputFormatter: [null] - }), - new web3._extend.Method({ - name: 'metrics', - call: 'debug_metrics', - params: 1, - inputFormatter: [null] - }), - new web3._extend.Method({ - name: 'verbosity', - call: 'debug_verbosity', - params: 1, - inputFormatter: [web3._extend.utils.fromDecimal] - }), - new web3._extend.Method({ - name: 'vmodule', - call: 'debug_vmodule', - params: 1, - inputFormatter: [null] - }), - ], - properties: - [ - ] -}); -` diff --git a/rpc/api/eth.go b/rpc/api/eth.go deleted file mode 100644 index db7a643d8..000000000 --- a/rpc/api/eth.go +++ /dev/null @@ -1,721 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "bytes" - "encoding/json" - "math/big" - - "fmt" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/natspec" - "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/rpc/codec" - "github.com/ethereum/go-ethereum/rpc/shared" - "github.com/ethereum/go-ethereum/xeth" - "gopkg.in/fatih/set.v0" -) - -const ( - EthApiVersion = "1.0" -) - -// eth api provider -// See https://github.com/ethereum/wiki/wiki/JSON-RPC -type ethApi struct { - xeth *xeth.XEth - ethereum *eth.Ethereum - methods map[string]ethhandler - codec codec.ApiCoder -} - -// eth callback handler -type ethhandler func(*ethApi, *shared.Request) (interface{}, error) - -var ( - ethMapping = map[string]ethhandler{ - "eth_accounts": (*ethApi).Accounts, - "eth_blockNumber": (*ethApi).BlockNumber, - "eth_getBalance": (*ethApi).GetBalance, - "eth_protocolVersion": (*ethApi).ProtocolVersion, - "eth_coinbase": (*ethApi).Coinbase, - "eth_mining": (*ethApi).IsMining, - "eth_syncing": (*ethApi).IsSyncing, - "eth_gasPrice": (*ethApi).GasPrice, - "eth_getStorage": (*ethApi).GetStorage, - "eth_storageAt": (*ethApi).GetStorage, - "eth_getStorageAt": (*ethApi).GetStorageAt, - "eth_getTransactionCount": (*ethApi).GetTransactionCount, - "eth_getBlockTransactionCountByHash": (*ethApi).GetBlockTransactionCountByHash, - "eth_getBlockTransactionCountByNumber": (*ethApi).GetBlockTransactionCountByNumber, - "eth_getUncleCountByBlockHash": (*ethApi).GetUncleCountByBlockHash, - "eth_getUncleCountByBlockNumber": (*ethApi).GetUncleCountByBlockNumber, - "eth_getData": (*ethApi).GetData, - "eth_getCode": (*ethApi).GetData, - "eth_getNatSpec": (*ethApi).GetNatSpec, - "eth_sign": (*ethApi).Sign, - "eth_sendRawTransaction": (*ethApi).SubmitTransaction, - "eth_submitTransaction": (*ethApi).SubmitTransaction, - "eth_sendTransaction": (*ethApi).SendTransaction, - "eth_signTransaction": (*ethApi).SignTransaction, - "eth_transact": (*ethApi).SendTransaction, - "eth_estimateGas": (*ethApi).EstimateGas, - "eth_call": (*ethApi).Call, - "eth_flush": (*ethApi).Flush, - "eth_getBlockByHash": (*ethApi).GetBlockByHash, - "eth_getBlockByNumber": (*ethApi).GetBlockByNumber, - "eth_getTransactionByHash": (*ethApi).GetTransactionByHash, - "eth_getTransactionByBlockNumberAndIndex": (*ethApi).GetTransactionByBlockNumberAndIndex, - "eth_getTransactionByBlockHashAndIndex": (*ethApi).GetTransactionByBlockHashAndIndex, - "eth_getUncleByBlockHashAndIndex": (*ethApi).GetUncleByBlockHashAndIndex, - "eth_getUncleByBlockNumberAndIndex": (*ethApi).GetUncleByBlockNumberAndIndex, - "eth_getCompilers": (*ethApi).GetCompilers, - "eth_compileSolidity": (*ethApi).CompileSolidity, - "eth_newFilter": (*ethApi).NewFilter, - "eth_newBlockFilter": (*ethApi).NewBlockFilter, - "eth_newPendingTransactionFilter": (*ethApi).NewPendingTransactionFilter, - "eth_uninstallFilter": (*ethApi).UninstallFilter, - "eth_getFilterChanges": (*ethApi).GetFilterChanges, - "eth_getFilterLogs": (*ethApi).GetFilterLogs, - "eth_getLogs": (*ethApi).GetLogs, - "eth_hashrate": (*ethApi).Hashrate, - "eth_getWork": (*ethApi).GetWork, - "eth_submitWork": (*ethApi).SubmitWork, - "eth_submitHashrate": (*ethApi).SubmitHashrate, - "eth_resend": (*ethApi).Resend, - "eth_pendingTransactions": (*ethApi).PendingTransactions, - "eth_getTransactionReceipt": (*ethApi).GetTransactionReceipt, - } -) - -// create new ethApi instance -func NewEthApi(xeth *xeth.XEth, eth *eth.Ethereum, codec codec.Codec) *ethApi { - return ðApi{xeth, eth, ethMapping, codec.New(nil)} -} - -// collection with supported methods -func (self *ethApi) Methods() []string { - methods := make([]string, len(self.methods)) - i := 0 - for k := range self.methods { - methods[i] = k - i++ - } - return methods -} - -// Execute given request -func (self *ethApi) Execute(req *shared.Request) (interface{}, error) { - if callback, ok := self.methods[req.Method]; ok { - return callback(self, req) - } - - return nil, shared.NewNotImplementedError(req.Method) -} - -func (self *ethApi) Name() string { - return shared.EthApiName -} - -func (self *ethApi) ApiVersion() string { - return EthApiVersion -} - -func (self *ethApi) Accounts(req *shared.Request) (interface{}, error) { - return self.xeth.Accounts(), nil -} - -func (self *ethApi) Hashrate(req *shared.Request) (interface{}, error) { - return newHexNum(self.xeth.HashRate()), nil -} - -func (self *ethApi) BlockNumber(req *shared.Request) (interface{}, error) { - num := self.xeth.CurrentBlock().Number() - return newHexNum(num.Bytes()), nil -} - -func (self *ethApi) GetBalance(req *shared.Request) (interface{}, error) { - args := new(GetBalanceArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - return self.xeth.AtStateNum(args.BlockNumber).BalanceAt(args.Address), nil -} - -func (self *ethApi) ProtocolVersion(req *shared.Request) (interface{}, error) { - return self.xeth.EthVersion(), nil -} - -func (self *ethApi) Coinbase(req *shared.Request) (interface{}, error) { - return newHexData(self.xeth.Coinbase()), nil -} - -func (self *ethApi) IsMining(req *shared.Request) (interface{}, error) { - return self.xeth.IsMining(), nil -} - -func (self *ethApi) IsSyncing(req *shared.Request) (interface{}, error) { - origin, current, height := self.ethereum.Downloader().Progress() - if current < height { - return map[string]interface{}{ - "startingBlock": newHexNum(big.NewInt(int64(origin)).Bytes()), - "currentBlock": newHexNum(big.NewInt(int64(current)).Bytes()), - "highestBlock": newHexNum(big.NewInt(int64(height)).Bytes()), - }, nil - } - return false, nil -} - -func (self *ethApi) GasPrice(req *shared.Request) (interface{}, error) { - return newHexNum(self.xeth.DefaultGasPrice().Bytes()), nil -} - -func (self *ethApi) GetStorage(req *shared.Request) (interface{}, error) { - args := new(GetStorageArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - return self.xeth.AtStateNum(args.BlockNumber).State().SafeGet(args.Address).Storage(), nil -} - -func (self *ethApi) GetStorageAt(req *shared.Request) (interface{}, error) { - args := new(GetStorageAtArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - return self.xeth.AtStateNum(args.BlockNumber).StorageAt(args.Address, args.Key), nil -} - -func (self *ethApi) GetTransactionCount(req *shared.Request) (interface{}, error) { - args := new(GetTxCountArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - count := self.xeth.AtStateNum(args.BlockNumber).TxCountAt(args.Address) - return fmt.Sprintf("%#x", count), nil -} - -func (self *ethApi) GetBlockTransactionCountByHash(req *shared.Request) (interface{}, error) { - args := new(HashArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - block := self.xeth.EthBlockByHash(args.Hash) - if block == nil { - return nil, nil - } - return fmt.Sprintf("%#x", len(block.Transactions())), nil -} - -func (self *ethApi) GetBlockTransactionCountByNumber(req *shared.Request) (interface{}, error) { - args := new(BlockNumArg) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - block := self.xeth.EthBlockByNumber(args.BlockNumber) - if block == nil { - return nil, nil - } - return fmt.Sprintf("%#x", len(block.Transactions())), nil -} - -func (self *ethApi) GetUncleCountByBlockHash(req *shared.Request) (interface{}, error) { - args := new(HashArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - block := self.xeth.EthBlockByHash(args.Hash) - if block == nil { - return nil, nil - } - return fmt.Sprintf("%#x", len(block.Uncles())), nil -} - -func (self *ethApi) GetUncleCountByBlockNumber(req *shared.Request) (interface{}, error) { - args := new(BlockNumArg) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - block := self.xeth.EthBlockByNumber(args.BlockNumber) - if block == nil { - return nil, nil - } - return fmt.Sprintf("%#x", len(block.Uncles())), nil -} - -func (self *ethApi) GetData(req *shared.Request) (interface{}, error) { - args := new(GetDataArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - v := self.xeth.AtStateNum(args.BlockNumber).CodeAtBytes(args.Address) - return newHexData(v), nil -} - -func (self *ethApi) Sign(req *shared.Request) (interface{}, error) { - args := new(NewSigArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - v, err := self.xeth.Sign(args.From, args.Data, false) - if err != nil { - return nil, err - } - return v, nil -} - -func (self *ethApi) SubmitTransaction(req *shared.Request) (interface{}, error) { - args := new(NewDataArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - v, err := self.xeth.PushTx(args.Data) - if err != nil { - return nil, err - } - return v, nil -} - -// JsonTransaction is returned as response by the JSON RPC. It contains the -// signed RLP encoded transaction as Raw and the signed transaction object as Tx. -type JsonTransaction struct { - Raw string `json:"raw"` - Tx *tx `json:"tx"` -} - -func (self *ethApi) SignTransaction(req *shared.Request) (interface{}, error) { - args := new(NewTxArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - // nonce may be nil ("guess" mode) - var nonce string - if args.Nonce != nil { - nonce = args.Nonce.String() - } - - var gas, price string - if args.Gas != nil { - gas = args.Gas.String() - } - if args.GasPrice != nil { - price = args.GasPrice.String() - } - tx, err := self.xeth.SignTransaction(args.From, args.To, nonce, args.Value.String(), gas, price, args.Data) - if err != nil { - return nil, err - } - - data, err := rlp.EncodeToBytes(tx) - if err != nil { - return nil, err - } - - return JsonTransaction{"0x" + common.Bytes2Hex(data), newTx(tx)}, nil -} - -func (self *ethApi) SendTransaction(req *shared.Request) (interface{}, error) { - args := new(NewTxArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - // nonce may be nil ("guess" mode) - var nonce string - if args.Nonce != nil { - nonce = args.Nonce.String() - } - - var gas, price string - if args.Gas != nil { - gas = args.Gas.String() - } - if args.GasPrice != nil { - price = args.GasPrice.String() - } - v, err := self.xeth.Transact(args.From, args.To, nonce, args.Value.String(), gas, price, args.Data) - if err != nil { - return nil, err - } - return v, nil -} - -func (self *ethApi) GetNatSpec(req *shared.Request) (interface{}, error) { - args := new(NewTxArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - var jsontx = fmt.Sprintf(`{"params":[{"to":"%s","data": "%s"}]}`, args.To, args.Data) - notice := natspec.GetNotice(self.xeth, jsontx, self.ethereum.HTTPClient()) - - return notice, nil -} - -func (self *ethApi) EstimateGas(req *shared.Request) (interface{}, error) { - _, gas, err := self.doCall(req.Params) - if err != nil { - return nil, err - } - - // TODO unwrap the parent method's ToHex call - if len(gas) == 0 { - return newHexNum(0), nil - } else { - return newHexNum(common.String2Big(gas)), err - } -} - -func (self *ethApi) Call(req *shared.Request) (interface{}, error) { - v, _, err := self.doCall(req.Params) - if err != nil { - return nil, err - } - - // TODO unwrap the parent method's ToHex call - if v == "0x0" { - return newHexData([]byte{}), nil - } else { - return newHexData(common.FromHex(v)), nil - } -} - -func (self *ethApi) Flush(req *shared.Request) (interface{}, error) { - return nil, shared.NewNotImplementedError(req.Method) -} - -func (self *ethApi) doCall(params json.RawMessage) (string, string, error) { - args := new(CallArgs) - if err := self.codec.Decode(params, &args); err != nil { - return "", "", err - } - - return self.xeth.AtStateNum(args.BlockNumber).Call(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) -} - -func (self *ethApi) GetBlockByHash(req *shared.Request) (interface{}, error) { - args := new(GetBlockByHashArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - block := self.xeth.EthBlockByHash(args.BlockHash) - if block == nil { - return nil, nil - } - return NewBlockRes(block, self.xeth.Td(block.Hash()), args.IncludeTxs), nil -} - -func (self *ethApi) GetBlockByNumber(req *shared.Request) (interface{}, error) { - args := new(GetBlockByNumberArgs) - if err := json.Unmarshal(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - block := self.xeth.EthBlockByNumber(args.BlockNumber) - if block == nil { - return nil, nil - } - return NewBlockRes(block, self.xeth.Td(block.Hash()), args.IncludeTxs), nil -} - -func (self *ethApi) GetTransactionByHash(req *shared.Request) (interface{}, error) { - args := new(HashArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - tx, bhash, bnum, txi := self.xeth.EthTransactionByHash(args.Hash) - if tx != nil { - v := NewTransactionRes(tx) - // if the blockhash is 0, assume this is a pending transaction - if bytes.Compare(bhash.Bytes(), bytes.Repeat([]byte{0}, 32)) != 0 { - v.BlockHash = newHexData(bhash) - v.BlockNumber = newHexNum(bnum) - v.TxIndex = newHexNum(txi) - } - return v, nil - } - return nil, nil -} - -func (self *ethApi) GetTransactionByBlockHashAndIndex(req *shared.Request) (interface{}, error) { - args := new(HashIndexArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - raw := self.xeth.EthBlockByHash(args.Hash) - if raw == nil { - return nil, nil - } - block := NewBlockRes(raw, self.xeth.Td(raw.Hash()), true) - if args.Index >= int64(len(block.Transactions)) || args.Index < 0 { - return nil, nil - } else { - return block.Transactions[args.Index], nil - } -} - -func (self *ethApi) GetTransactionByBlockNumberAndIndex(req *shared.Request) (interface{}, error) { - args := new(BlockNumIndexArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - raw := self.xeth.EthBlockByNumber(args.BlockNumber) - if raw == nil { - return nil, nil - } - block := NewBlockRes(raw, self.xeth.Td(raw.Hash()), true) - if args.Index >= int64(len(block.Transactions)) || args.Index < 0 { - // return NewValidationError("Index", "does not exist") - return nil, nil - } - return block.Transactions[args.Index], nil -} - -func (self *ethApi) GetUncleByBlockHashAndIndex(req *shared.Request) (interface{}, error) { - args := new(HashIndexArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - raw := self.xeth.EthBlockByHash(args.Hash) - if raw == nil { - return nil, nil - } - block := NewBlockRes(raw, self.xeth.Td(raw.Hash()), false) - if args.Index >= int64(len(block.Uncles)) || args.Index < 0 { - // return NewValidationError("Index", "does not exist") - return nil, nil - } - return block.Uncles[args.Index], nil -} - -func (self *ethApi) GetUncleByBlockNumberAndIndex(req *shared.Request) (interface{}, error) { - args := new(BlockNumIndexArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - raw := self.xeth.EthBlockByNumber(args.BlockNumber) - if raw == nil { - return nil, nil - } - block := NewBlockRes(raw, self.xeth.Td(raw.Hash()), true) - if args.Index >= int64(len(block.Uncles)) || args.Index < 0 { - return nil, nil - } else { - return block.Uncles[args.Index], nil - } -} - -func (self *ethApi) GetCompilers(req *shared.Request) (interface{}, error) { - var lang string - if solc, _ := self.xeth.Solc(); solc != nil { - lang = "Solidity" - } - c := []string{lang} - return c, nil -} - -func (self *ethApi) CompileSolidity(req *shared.Request) (interface{}, error) { - solc, _ := self.xeth.Solc() - if solc == nil { - return nil, shared.NewNotAvailableError(req.Method, "solc (solidity compiler) not found") - } - - args := new(SourceArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - contracts, err := solc.Compile(args.Source) - if err != nil { - return nil, err - } - return contracts, nil -} - -func (self *ethApi) NewFilter(req *shared.Request) (interface{}, error) { - args := new(BlockFilterArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - id := self.xeth.NewLogFilter(args.Earliest, args.Latest, args.Skip, args.Max, args.Address, args.Topics) - return newHexNum(big.NewInt(int64(id)).Bytes()), nil -} - -func (self *ethApi) NewBlockFilter(req *shared.Request) (interface{}, error) { - return newHexNum(self.xeth.NewBlockFilter()), nil -} - -func (self *ethApi) NewPendingTransactionFilter(req *shared.Request) (interface{}, error) { - return newHexNum(self.xeth.NewTransactionFilter()), nil -} - -func (self *ethApi) UninstallFilter(req *shared.Request) (interface{}, error) { - args := new(FilterIdArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - return self.xeth.UninstallFilter(args.Id), nil -} - -func (self *ethApi) GetFilterChanges(req *shared.Request) (interface{}, error) { - args := new(FilterIdArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - switch self.xeth.GetFilterType(args.Id) { - case xeth.BlockFilterTy: - return NewHashesRes(self.xeth.BlockFilterChanged(args.Id)), nil - case xeth.TransactionFilterTy: - return NewHashesRes(self.xeth.TransactionFilterChanged(args.Id)), nil - case xeth.LogFilterTy: - return NewLogsRes(self.xeth.LogFilterChanged(args.Id)), nil - default: - return []string{}, nil // reply empty string slice - } -} - -func (self *ethApi) GetFilterLogs(req *shared.Request) (interface{}, error) { - args := new(FilterIdArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - return NewLogsRes(self.xeth.Logs(args.Id)), nil -} - -func (self *ethApi) GetLogs(req *shared.Request) (interface{}, error) { - args := new(BlockFilterArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - return NewLogsRes(self.xeth.AllLogs(args.Earliest, args.Latest, args.Skip, args.Max, args.Address, args.Topics)), nil -} - -func (self *ethApi) GetWork(req *shared.Request) (interface{}, error) { - self.xeth.SetMining(true, 0) - ret, err := self.xeth.RemoteMining().GetWork() - if err != nil { - return nil, shared.NewNotReadyError("mining work") - } else { - return ret, nil - } -} - -func (self *ethApi) SubmitWork(req *shared.Request) (interface{}, error) { - args := new(SubmitWorkArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - return self.xeth.RemoteMining().SubmitWork(args.Nonce, common.HexToHash(args.Digest), common.HexToHash(args.Header)), nil -} - -func (self *ethApi) SubmitHashrate(req *shared.Request) (interface{}, error) { - args := new(SubmitHashRateArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return false, shared.NewDecodeParamError(err.Error()) - } - self.xeth.RemoteMining().SubmitHashrate(common.HexToHash(args.Id), args.Rate) - return true, nil -} - -func (self *ethApi) Resend(req *shared.Request) (interface{}, error) { - args := new(ResendArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - from := common.HexToAddress(args.Tx.From) - - pending := self.ethereum.TxPool().GetTransactions() - for _, p := range pending { - if pFrom, err := p.From(); err == nil && pFrom == from && p.SigHash() == args.Tx.tx.SigHash() { - self.ethereum.TxPool().RemoveTx(common.HexToHash(args.Tx.Hash)) - return self.xeth.Transact(args.Tx.From, args.Tx.To, args.Tx.Nonce, args.Tx.Value, args.GasLimit, args.GasPrice, args.Tx.Data) - } - } - - return nil, fmt.Errorf("Transaction %s not found", args.Tx.Hash) -} - -func (self *ethApi) PendingTransactions(req *shared.Request) (interface{}, error) { - txs := self.ethereum.TxPool().GetTransactions() - - // grab the accounts from the account manager. This will help with determining which - // transactions should be returned. - accounts, err := self.ethereum.AccountManager().Accounts() - if err != nil { - return nil, err - } - - // Add the accouns to a new set - accountSet := set.New() - for _, account := range accounts { - accountSet.Add(account.Address) - } - - var ltxs []*tx - for _, tx := range txs { - if from, _ := tx.From(); accountSet.Has(from) { - ltxs = append(ltxs, newTx(tx)) - } - } - - return ltxs, nil -} - -func (self *ethApi) GetTransactionReceipt(req *shared.Request) (interface{}, error) { - args := new(HashArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - txhash := common.BytesToHash(common.FromHex(args.Hash)) - tx, bhash, bnum, txi := self.xeth.EthTransactionByHash(args.Hash) - rec := self.xeth.GetTxReceipt(txhash) - // We could have an error of "not found". Should disambiguate - // if err != nil { - // return err, nil - // } - if rec != nil && tx != nil { - v := NewReceiptRes(rec) - v.BlockHash = newHexData(bhash) - v.BlockNumber = newHexNum(bnum) - v.TransactionIndex = newHexNum(txi) - return v, nil - } - - return nil, nil -} diff --git a/rpc/api/eth_args.go b/rpc/api/eth_args.go deleted file mode 100644 index ed3d761f1..000000000 --- a/rpc/api/eth_args.go +++ /dev/null @@ -1,1104 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "encoding/json" - "fmt" - "math/big" - "strconv" - "strings" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/rpc/shared" -) - -const ( - defaultLogLimit = 100 - defaultLogOffset = 0 -) - -type GetBalanceArgs struct { - Address string - BlockNumber int64 -} - -func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - addstr, ok := obj[0].(string) - if !ok { - return shared.NewInvalidTypeError("address", "not a string") - } - args.Address = addstr - - if len(obj) > 1 { - if err := blockHeight(obj[1], &args.BlockNumber); err != nil { - return err - } - } else { - args.BlockNumber = -1 - } - - return nil -} - -type GetStorageArgs struct { - Address string - BlockNumber int64 -} - -func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - addstr, ok := obj[0].(string) - if !ok { - return shared.NewInvalidTypeError("address", "not a string") - } - args.Address = addstr - - if len(obj) > 1 { - if err := blockHeight(obj[1], &args.BlockNumber); err != nil { - return err - } - } else { - args.BlockNumber = -1 - } - - return nil -} - -type GetStorageAtArgs struct { - Address string - BlockNumber int64 - Key string -} - -func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 2 { - return shared.NewInsufficientParamsError(len(obj), 2) - } - - addstr, ok := obj[0].(string) - if !ok { - return shared.NewInvalidTypeError("address", "not a string") - } - args.Address = addstr - - keystr, ok := obj[1].(string) - if !ok { - return shared.NewInvalidTypeError("key", "not a string") - } - args.Key = keystr - - if len(obj) > 2 { - if err := blockHeight(obj[2], &args.BlockNumber); err != nil { - return err - } - } else { - args.BlockNumber = -1 - } - - return nil -} - -type GetTxCountArgs struct { - Address string - BlockNumber int64 -} - -func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - addstr, ok := obj[0].(string) - if !ok { - return shared.NewInvalidTypeError("address", "not a string") - } - args.Address = addstr - - if len(obj) > 1 { - if err := blockHeight(obj[1], &args.BlockNumber); err != nil { - return err - } - } else { - args.BlockNumber = -1 - } - - return nil -} - -type SubmitHashRateArgs struct { - Id string - Rate uint64 -} - -func (args *SubmitHashRateArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 2 { - return shared.NewInsufficientParamsError(len(obj), 2) - } - - arg0, ok := obj[0].(string) - if !ok { - return shared.NewInvalidTypeError("hash", "not a string") - } - args.Id = arg0 - - arg1, ok := obj[1].(string) - if !ok { - return shared.NewInvalidTypeError("rate", "not a string") - } - - args.Rate = common.String2Big(arg1).Uint64() - - return nil -} - -type HashArgs struct { - Hash string -} - -func (args *HashArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - arg0, ok := obj[0].(string) - if !ok { - return shared.NewInvalidTypeError("hash", "not a string") - } - args.Hash = arg0 - - return nil -} - -type BlockNumArg struct { - BlockNumber int64 -} - -func (args *BlockNumArg) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - if err := blockHeight(obj[0], &args.BlockNumber); err != nil { - return err - } - - return nil -} - -type GetDataArgs struct { - Address string - BlockNumber int64 -} - -func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - addstr, ok := obj[0].(string) - if !ok { - return shared.NewInvalidTypeError("address", "not a string") - } - args.Address = addstr - - if len(obj) > 1 { - if err := blockHeight(obj[1], &args.BlockNumber); err != nil { - return err - } - } else { - args.BlockNumber = -1 - } - - return nil -} - -type NewDataArgs struct { - Data string -} - -func (args *NewDataArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - // Check for sufficient params - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - data, ok := obj[0].(string) - if !ok { - return shared.NewInvalidTypeError("data", "not a string") - } - args.Data = data - - if len(args.Data) == 0 { - return shared.NewValidationError("data", "is required") - } - - return nil -} - -type NewSigArgs struct { - From string - Data string -} - -func (args *NewSigArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - // Check for sufficient params - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - from, ok := obj[0].(string) - if !ok { - return shared.NewInvalidTypeError("from", "not a string") - } - args.From = from - - if len(args.From) == 0 { - return shared.NewValidationError("from", "is required") - } - - data, ok := obj[1].(string) - if !ok { - return shared.NewInvalidTypeError("data", "not a string") - } - args.Data = data - - if len(args.Data) == 0 { - return shared.NewValidationError("data", "is required") - } - - return nil -} - -type NewTxArgs struct { - From string - To string - Nonce *big.Int - Value *big.Int - Gas *big.Int - GasPrice *big.Int - Data string - - BlockNumber int64 -} - -func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) { - var obj []json.RawMessage - var ext struct { - From string - To string - Nonce interface{} - Value interface{} - Gas interface{} - GasPrice interface{} - Data string - } - - // Decode byte slice to array of RawMessages - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - // Check for sufficient params - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - // Decode 0th RawMessage to temporary struct - if err := json.Unmarshal(obj[0], &ext); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(ext.From) == 0 { - return shared.NewValidationError("from", "is required") - } - - args.From = ext.From - args.To = ext.To - args.Data = ext.Data - - var num *big.Int - if ext.Nonce != nil { - num, err = numString(ext.Nonce) - if err != nil { - return err - } - } - args.Nonce = num - - if ext.Value == nil { - num = big.NewInt(0) - } else { - num, err = numString(ext.Value) - if err != nil { - return err - } - } - args.Value = num - - num = nil - if ext.Gas != nil { - if num, err = numString(ext.Gas); err != nil { - return err - } - } - args.Gas = num - - num = nil - if ext.GasPrice != nil { - if num, err = numString(ext.GasPrice); err != nil { - return err - } - } - args.GasPrice = num - - // Check for optional BlockNumber param - if len(obj) > 1 { - if err := blockHeightFromJson(obj[1], &args.BlockNumber); err != nil { - return err - } - } else { - args.BlockNumber = -1 - } - - return nil -} - -type SourceArgs struct { - Source string -} - -func (args *SourceArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - arg0, ok := obj[0].(string) - if !ok { - return shared.NewInvalidTypeError("source code", "not a string") - } - args.Source = arg0 - - return nil -} - -type CallArgs struct { - From string - To string - Value *big.Int - Gas *big.Int - GasPrice *big.Int - Data string - - BlockNumber int64 -} - -func (args *CallArgs) UnmarshalJSON(b []byte) (err error) { - var obj []json.RawMessage - 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 { - return shared.NewDecodeParamError(err.Error()) - } - - // Check for sufficient params - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - // Decode 0th RawMessage to temporary struct - if err := json.Unmarshal(obj[0], &ext); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - args.From = ext.From - args.To = ext.To - - var num *big.Int - if ext.Value == nil { - num = big.NewInt(0) - } else { - if num, err = numString(ext.Value); err != nil { - return err - } - } - args.Value = num - - if ext.Gas != nil { - if num, err = numString(ext.Gas); err != nil { - return err - } - } else { - num = nil - } - args.Gas = num - - if ext.GasPrice != nil { - if num, err = numString(ext.GasPrice); err != nil { - return err - } - } else { - num = nil - } - args.GasPrice = num - - args.Data = ext.Data - - // Check for optional BlockNumber param - if len(obj) > 1 { - if err := blockHeightFromJson(obj[1], &args.BlockNumber); err != nil { - return err - } - } else { - args.BlockNumber = -1 - } - - return nil -} - -type HashIndexArgs struct { - Hash string - Index int64 -} - -func (args *HashIndexArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 2 { - return shared.NewInsufficientParamsError(len(obj), 2) - } - - arg0, ok := obj[0].(string) - if !ok { - return shared.NewInvalidTypeError("hash", "not a string") - } - args.Hash = arg0 - - arg1, ok := obj[1].(string) - if !ok { - return shared.NewInvalidTypeError("index", "not a string") - } - args.Index = common.Big(arg1).Int64() - - return nil -} - -type BlockNumIndexArgs struct { - BlockNumber int64 - Index int64 -} - -func (args *BlockNumIndexArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 2 { - return shared.NewInsufficientParamsError(len(obj), 2) - } - - if err := blockHeight(obj[0], &args.BlockNumber); err != nil { - return err - } - - var arg1 *big.Int - if arg1, err = numString(obj[1]); err != nil { - return err - } - args.Index = arg1.Int64() - - return nil -} - -type GetBlockByHashArgs struct { - BlockHash string - IncludeTxs bool -} - -func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 2 { - return shared.NewInsufficientParamsError(len(obj), 2) - } - - argstr, ok := obj[0].(string) - if !ok { - return shared.NewInvalidTypeError("blockHash", "not a string") - } - args.BlockHash = argstr - - args.IncludeTxs = obj[1].(bool) - - if inclTx, ok := obj[1].(bool); ok { - args.IncludeTxs = inclTx - return nil - } - - return shared.NewInvalidTypeError("includeTxs", "not a bool") -} - -type GetBlockByNumberArgs struct { - BlockNumber int64 - IncludeTxs bool -} - -func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 2 { - return shared.NewInsufficientParamsError(len(obj), 2) - } - - if err := blockHeight(obj[0], &args.BlockNumber); err != nil { - return err - } - - if inclTx, ok := obj[1].(bool); ok { - args.IncludeTxs = inclTx - return nil - } - - return shared.NewInvalidTypeError("includeTxs", "not a bool") -} - -type BlockFilterArgs struct { - Earliest int64 - Latest int64 - 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 interface{} `json:"limit"` - Offset interface{} `json:"offset"` - Address interface{} `json:"address"` - Topics interface{} `json:"topics"` - } - - if err = json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - // args.Earliest, err = toNumber(obj[0].ToBlock) - // if err != nil { - // return shared.NewDecodeParamError(fmt.Sprintf("FromBlock %v", err)) - // } - // args.Latest, err = toNumber(obj[0].FromBlock) - // if err != nil { - // return shared.NewDecodeParamError(fmt.Sprintf("ToBlock %v", err)) - - var num int64 - var numBig *big.Int - - // if blank then latest - if obj[0].FromBlock == nil { - num = -1 - } else { - if err := blockHeight(obj[0].FromBlock, &num); err != nil { - return err - } - } - // if -2 or other "silly" number, use latest - if num < 0 { - args.Earliest = -1 //latest block - } else { - args.Earliest = num - } - - // if blank than latest - if obj[0].ToBlock == nil { - num = -1 - } else { - if err := blockHeight(obj[0].ToBlock, &num); err != nil { - return err - } - } - - if num == -2 { - return fmt.Errorf("\"pending\" is unsupported") - } else if num < -2 { - return fmt.Errorf("Invalid to block number") - } - - args.Latest = num - - if obj[0].Limit == nil { - numBig = big.NewInt(defaultLogLimit) - } else { - if numBig, err = numString(obj[0].Limit); err != nil { - return err - } - } - args.Max = int(numBig.Int64()) - - if obj[0].Offset == nil { - numBig = big.NewInt(defaultLogOffset) - } else { - if numBig, err = numString(obj[0].Offset); err != nil { - return err - } - } - args.Skip = int(numBig.Int64()) - - 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 shared.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 shared.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 if jv == nil { - topicdbl[i][j] = "" - } else { - return shared.NewInvalidTypeError(fmt.Sprintf("topic[%d][%d]", i, j), "is not a string") - } - } - } else if iv == nil { - topicdbl[i] = []string{""} - } else { - return shared.NewInvalidTypeError(fmt.Sprintf("topic[%d]", i), "not a string or array") - } - } - args.Topics = topicdbl - return nil - } else { - return shared.NewInvalidTypeError("topic", "is not a string or array") - } - } - - return nil -} - -type FilterIdArgs struct { - Id int -} - -func (args *FilterIdArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - var num *big.Int - if num, err = numString(obj[0]); err != nil { - return err - } - args.Id = int(num.Int64()) - - return nil -} - -type LogRes struct { - Address *hexdata `json:"address"` - Topics []*hexdata `json:"topics"` - Data *hexdata `json:"data"` - BlockNumber *hexnum `json:"blockNumber"` - LogIndex *hexnum `json:"logIndex"` - BlockHash *hexdata `json:"blockHash"` - TransactionHash *hexdata `json:"transactionHash"` - TransactionIndex *hexnum `json:"transactionIndex"` -} - -func NewLogRes(log *vm.Log) LogRes { - var l LogRes - l.Topics = make([]*hexdata, len(log.Topics)) - for j, topic := range log.Topics { - l.Topics[j] = newHexData(topic) - } - l.Address = newHexData(log.Address) - l.Data = newHexData(log.Data) - l.BlockNumber = newHexNum(log.BlockNumber) - l.LogIndex = newHexNum(log.Index) - l.TransactionHash = newHexData(log.TxHash) - l.TransactionIndex = newHexNum(log.TxIndex) - l.BlockHash = newHexData(log.BlockHash) - - return l -} - -func NewLogsRes(logs vm.Logs) (ls []LogRes) { - ls = make([]LogRes, len(logs)) - - for i, log := range logs { - ls[i] = NewLogRes(log) - } - - return -} - -func NewHashesRes(hs []common.Hash) []string { - hashes := make([]string, len(hs)) - - for i, hash := range hs { - hashes[i] = hash.Hex() - } - - return hashes -} - -type SubmitWorkArgs struct { - Nonce uint64 - Header string - Digest string -} - -func (args *SubmitWorkArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err = json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 3 { - return shared.NewInsufficientParamsError(len(obj), 3) - } - - var objstr string - var ok bool - if objstr, ok = obj[0].(string); !ok { - return shared.NewInvalidTypeError("nonce", "not a string") - } - - args.Nonce = common.String2Big(objstr).Uint64() - if objstr, ok = obj[1].(string); !ok { - return shared.NewInvalidTypeError("header", "not a string") - } - - args.Header = objstr - - if objstr, ok = obj[2].(string); !ok { - return shared.NewInvalidTypeError("digest", "not a string") - } - - args.Digest = objstr - - return nil -} - -type tx struct { - tx *types.Transaction - - To string `json:"to"` - From string `json:"from"` - Nonce string `json:"nonce"` - Value string `json:"value"` - Data string `json:"data"` - GasLimit string `json:"gas"` - GasPrice string `json:"gasPrice"` - Hash string `json:"hash"` -} - -func newTx(t *types.Transaction) *tx { - from, _ := t.From() - var to string - if t := t.To(); t != nil { - to = t.Hex() - } - - return &tx{ - tx: t, - To: to, - From: from.Hex(), - Value: t.Value().String(), - Nonce: strconv.Itoa(int(t.Nonce())), - Data: "0x" + common.Bytes2Hex(t.Data()), - GasLimit: t.Gas().String(), - GasPrice: t.GasPrice().String(), - Hash: t.Hash().Hex(), - } -} - -type ResendArgs struct { - Tx *tx - GasPrice string - GasLimit string -} - -func (tx *tx) UnmarshalJSON(b []byte) (err error) { - var fields map[string]interface{} - if err := json.Unmarshal(b, &fields); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - var ( - nonce uint64 - to common.Address - amount = new(big.Int).Set(common.Big0) - gasLimit = new(big.Int).Set(common.Big0) - gasPrice = new(big.Int).Set(common.Big0) - data []byte - contractCreation = true - ) - - if val, found := fields["Hash"]; found { - if hashVal, ok := val.(string); ok { - tx.Hash = hashVal - } - } - - if val, found := fields["To"]; found { - if strVal, ok := val.(string); ok && len(strVal) > 0 { - tx.To = strVal - to = common.HexToAddress(strVal) - contractCreation = false - } - } - - if val, found := fields["From"]; found { - if strVal, ok := val.(string); ok { - tx.From = strVal - } - } - - if val, found := fields["Nonce"]; found { - if strVal, ok := val.(string); ok { - tx.Nonce = strVal - if nonce, err = strconv.ParseUint(strVal, 10, 64); err != nil { - return shared.NewDecodeParamError(fmt.Sprintf("Unable to decode tx.Nonce - %v", err)) - } - } - } else { - return shared.NewDecodeParamError("tx.Nonce not found") - } - - var parseOk bool - if val, found := fields["Value"]; found { - if strVal, ok := val.(string); ok { - tx.Value = strVal - if _, parseOk = amount.SetString(strVal, 0); !parseOk { - return shared.NewDecodeParamError(fmt.Sprintf("Unable to decode tx.Amount - %v", err)) - } - } - } - - if val, found := fields["Data"]; found { - if strVal, ok := val.(string); ok { - tx.Data = strVal - if strings.HasPrefix(strVal, "0x") { - data = common.Hex2Bytes(strVal[2:]) - } else { - data = common.Hex2Bytes(strVal) - } - } - } - - if val, found := fields["GasLimit"]; found { - if strVal, ok := val.(string); ok { - tx.GasLimit = strVal - if _, parseOk = gasLimit.SetString(strVal, 0); !parseOk { - return shared.NewDecodeParamError(fmt.Sprintf("Unable to decode tx.GasLimit - %v", err)) - } - } - } - - if val, found := fields["GasPrice"]; found { - if strVal, ok := val.(string); ok { - tx.GasPrice = strVal - if _, parseOk = gasPrice.SetString(strVal, 0); !parseOk { - return shared.NewDecodeParamError(fmt.Sprintf("Unable to decode tx.GasPrice - %v", err)) - } - } - } - - if contractCreation { - tx.tx = types.NewContractCreation(nonce, amount, gasLimit, gasPrice, data) - } else { - tx.tx = types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, data) - } - - return nil -} - -func (args *ResendArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err = json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - data, err := json.Marshal(obj[0]) - if err != nil { - return shared.NewDecodeParamError("Unable to parse transaction object") - } - - trans := new(tx) - err = json.Unmarshal(data, trans) - if err != nil { - return shared.NewDecodeParamError("Unable to parse transaction object") - } - - if trans == nil || trans.tx == nil { - return shared.NewDecodeParamError("Unable to parse transaction object") - } - - gasLimit, gasPrice := trans.GasLimit, trans.GasPrice - - if len(obj) > 1 && obj[1] != nil { - if gp, ok := obj[1].(string); ok { - gasPrice = gp - } else { - return shared.NewInvalidTypeError("gasPrice", "not a string") - } - } - if len(obj) > 2 && obj[2] != nil { - if gl, ok := obj[2].(string); ok { - gasLimit = gl - } else { - return shared.NewInvalidTypeError("gasLimit", "not a string") - } - } - - args.Tx = trans - args.GasPrice = gasPrice - args.GasLimit = gasLimit - - return nil -} diff --git a/rpc/api/eth_js.go b/rpc/api/eth_js.go deleted file mode 100644 index dfc104ad8..000000000 --- a/rpc/api/eth_js.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -// JS api provided by web3.js -// eth_sign not standard - -const Eth_JS = ` -web3._extend({ - property: 'eth', - methods: - [ - new web3._extend.Method({ - name: 'sign', - call: 'eth_sign', - params: 2, - inputFormatter: [web3._extend.utils.toAddress, null] - }), - new web3._extend.Method({ - name: 'resend', - call: 'eth_resend', - params: 3, - inputFormatter: [web3._extend.formatters.inputTransactionFormatter, web3._extend.utils.fromDecimal, web3._extend.utils.fromDecimal] - }), - new web3._extend.Method({ - name: 'getNatSpec', - call: 'eth_getNatSpec', - params: 1, - inputFormatter: [web3._extend.formatters.inputTransactionFormatter] - }), - new web3._extend.Method({ - name: 'signTransaction', - call: 'eth_signTransaction', - params: 1, - inputFormatter: [web3._extend.formatters.inputTransactionFormatter] - }), - new web3._extend.Method({ - name: 'submitTransaction', - call: 'eth_submitTransaction', - params: 1, - inputFormatter: [web3._extend.formatters.inputTransactionFormatter] - }) - ], - properties: - [ - new web3._extend.Property({ - name: 'pendingTransactions', - getter: 'eth_pendingTransactions' - }) - ] -}); -` diff --git a/rpc/api/mergedapi.go b/rpc/api/mergedapi.go deleted file mode 100644 index 92e1e2bb7..000000000 --- a/rpc/api/mergedapi.go +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "github.com/ethereum/go-ethereum/logger" - "github.com/ethereum/go-ethereum/logger/glog" - "github.com/ethereum/go-ethereum/rpc/shared" -) - -const ( - MergedApiVersion = "1.0" -) - -// combines multiple API's -type MergedApi struct { - apis map[string]string - methods map[string]shared.EthereumApi -} - -// create new merged api instance -func newMergedApi(apis ...shared.EthereumApi) *MergedApi { - mergedApi := new(MergedApi) - mergedApi.apis = make(map[string]string, len(apis)) - mergedApi.methods = make(map[string]shared.EthereumApi) - - for _, api := range apis { - if api != nil { - mergedApi.apis[api.Name()] = api.ApiVersion() - for _, method := range api.Methods() { - mergedApi.methods[method] = api - } - } - } - return mergedApi -} - -// Supported RPC methods -func (self *MergedApi) Methods() []string { - all := make([]string, len(self.methods)) - for method, _ := range self.methods { - all = append(all, method) - } - return all -} - -// Call the correct API's Execute method for the given request -func (self *MergedApi) Execute(req *shared.Request) (interface{}, error) { - glog.V(logger.Detail).Infof("%s %s", req.Method, req.Params) - - if res, _ := self.handle(req); res != nil { - return res, nil - } - if api, found := self.methods[req.Method]; found { - return api.Execute(req) - } - return nil, shared.NewNotImplementedError(req.Method) -} - -func (self *MergedApi) Name() string { - return shared.MergedApiName -} - -func (self *MergedApi) ApiVersion() string { - return MergedApiVersion -} - -func (self *MergedApi) handle(req *shared.Request) (interface{}, error) { - if req.Method == "modules" { // provided API's - return self.apis, nil - } - - return nil, nil -} diff --git a/rpc/api/miner.go b/rpc/api/miner.go deleted file mode 100644 index e07855dd2..000000000 --- a/rpc/api/miner.go +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "github.com/ethereum/ethash" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/rpc/codec" - "github.com/ethereum/go-ethereum/rpc/shared" -) - -const ( - MinerApiVersion = "1.0" -) - -var ( - // mapping between methods and handlers - MinerMapping = map[string]minerhandler{ - "miner_hashrate": (*minerApi).Hashrate, - "miner_makeDAG": (*minerApi).MakeDAG, - "miner_setExtra": (*minerApi).SetExtra, - "miner_setGasPrice": (*minerApi).SetGasPrice, - "miner_setEtherbase": (*minerApi).SetEtherbase, - "miner_startAutoDAG": (*minerApi).StartAutoDAG, - "miner_start": (*minerApi).StartMiner, - "miner_stopAutoDAG": (*minerApi).StopAutoDAG, - "miner_stop": (*minerApi).StopMiner, - } -) - -// miner callback handler -type minerhandler func(*minerApi, *shared.Request) (interface{}, error) - -// miner api provider -type minerApi struct { - ethereum *eth.Ethereum - methods map[string]minerhandler - codec codec.ApiCoder -} - -// create a new miner api instance -func NewMinerApi(ethereum *eth.Ethereum, coder codec.Codec) *minerApi { - return &minerApi{ - ethereum: ethereum, - methods: MinerMapping, - codec: coder.New(nil), - } -} - -// Execute given request -func (self *minerApi) Execute(req *shared.Request) (interface{}, error) { - if callback, ok := self.methods[req.Method]; ok { - return callback(self, req) - } - - return nil, &shared.NotImplementedError{req.Method} -} - -// collection with supported methods -func (self *minerApi) Methods() []string { - methods := make([]string, len(self.methods)) - i := 0 - for k := range self.methods { - methods[i] = k - i++ - } - return methods -} - -func (self *minerApi) Name() string { - return shared.MinerApiName -} - -func (self *minerApi) ApiVersion() string { - return MinerApiVersion -} - -func (self *minerApi) StartMiner(req *shared.Request) (interface{}, error) { - args := new(StartMinerArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, err - } - if args.Threads == -1 { // (not specified by user, use default) - args.Threads = self.ethereum.MinerThreads - } - - self.ethereum.StartAutoDAG() - err := self.ethereum.StartMining(args.Threads, "") - if err == nil { - return true, nil - } - - return false, err -} - -func (self *minerApi) StopMiner(req *shared.Request) (interface{}, error) { - self.ethereum.StopMining() - return true, nil -} - -func (self *minerApi) Hashrate(req *shared.Request) (interface{}, error) { - return self.ethereum.Miner().HashRate(), nil -} - -func (self *minerApi) SetExtra(req *shared.Request) (interface{}, error) { - args := new(SetExtraArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, err - } - - if err := self.ethereum.Miner().SetExtra([]byte(args.Data)); err != nil { - return false, err - } - - return true, nil -} - -func (self *minerApi) SetGasPrice(req *shared.Request) (interface{}, error) { - args := new(GasPriceArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return false, err - } - - self.ethereum.Miner().SetGasPrice(common.String2Big(args.Price)) - return true, nil -} - -func (self *minerApi) SetEtherbase(req *shared.Request) (interface{}, error) { - args := new(SetEtherbaseArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return false, err - } - self.ethereum.SetEtherbase(args.Etherbase) - return nil, nil -} - -func (self *minerApi) StartAutoDAG(req *shared.Request) (interface{}, error) { - self.ethereum.StartAutoDAG() - return true, nil -} - -func (self *minerApi) StopAutoDAG(req *shared.Request) (interface{}, error) { - self.ethereum.StopAutoDAG() - return true, nil -} - -func (self *minerApi) MakeDAG(req *shared.Request) (interface{}, error) { - args := new(MakeDAGArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, err - } - - if args.BlockNumber < 0 { - return false, shared.NewValidationError("BlockNumber", "BlockNumber must be positive") - } - - err := ethash.MakeDAG(uint64(args.BlockNumber), "") - if err == nil { - return true, nil - } - return false, err -} diff --git a/rpc/api/miner_args.go b/rpc/api/miner_args.go deleted file mode 100644 index 5ceb244fe..000000000 --- a/rpc/api/miner_args.go +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "encoding/json" - - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rpc/shared" -) - -type StartMinerArgs struct { - Threads int -} - -func (args *StartMinerArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) == 0 || obj[0] == nil { - args.Threads = -1 - return nil - } - - var num *big.Int - if num, err = numString(obj[0]); err != nil { - return err - } - args.Threads = int(num.Int64()) - return nil -} - -type SetExtraArgs struct { - Data string -} - -func (args *SetExtraArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - extrastr, ok := obj[0].(string) - if !ok { - return shared.NewInvalidTypeError("Price", "not a string") - } - args.Data = extrastr - - return nil -} - -type GasPriceArgs struct { - Price string -} - -func (args *GasPriceArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - if pricestr, ok := obj[0].(string); ok { - args.Price = pricestr - return nil - } - - return shared.NewInvalidTypeError("Price", "not a string") -} - -type SetEtherbaseArgs struct { - Etherbase common.Address -} - -func (args *SetEtherbaseArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - if addr, ok := obj[0].(string); ok { - args.Etherbase = common.HexToAddress(addr) - if (args.Etherbase == common.Address{}) { - return shared.NewInvalidTypeError("Etherbase", "not a valid address") - } - return nil - } - - return shared.NewInvalidTypeError("Etherbase", "not a string") -} - -type MakeDAGArgs struct { - BlockNumber int64 -} - -func (args *MakeDAGArgs) UnmarshalJSON(b []byte) (err error) { - args.BlockNumber = -1 - var obj []interface{} - - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - if err := blockHeight(obj[0], &args.BlockNumber); err != nil { - return err - } - - return nil -} diff --git a/rpc/api/miner_js.go b/rpc/api/miner_js.go deleted file mode 100644 index 0998a9f41..000000000 --- a/rpc/api/miner_js.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -const Miner_JS = ` -web3._extend({ - property: 'miner', - methods: - [ - new web3._extend.Method({ - name: 'start', - call: 'miner_start', - params: 1, - inputFormatter: [null] - }), - new web3._extend.Method({ - name: 'stop', - call: 'miner_stop', - params: 1, - inputFormatter: [null] - }), - new web3._extend.Method({ - name: 'setEtherbase', - call: 'miner_setEtherbase', - params: 1, - inputFormatter: [web3._extend.formatters.formatInputInt], - outputFormatter: web3._extend.formatters.formatOutputBool - }), - new web3._extend.Method({ - name: 'setExtra', - call: 'miner_setExtra', - params: 1, - inputFormatter: [null] - }), - new web3._extend.Method({ - name: 'setGasPrice', - call: 'miner_setGasPrice', - params: 1, - inputFormatter: [web3._extend.utils.fromDecial] - }), - new web3._extend.Method({ - name: 'startAutoDAG', - call: 'miner_startAutoDAG', - params: 0, - inputFormatter: [] - }), - new web3._extend.Method({ - name: 'stopAutoDAG', - call: 'miner_stopAutoDAG', - params: 0, - inputFormatter: [] - }), - new web3._extend.Method({ - name: 'makeDAG', - call: 'miner_makeDAG', - params: 1, - inputFormatter: [web3._extend.formatters.inputDefaultBlockNumberFormatter] - }) - ], - properties: - [ - new web3._extend.Property({ - name: 'hashrate', - getter: 'miner_hashrate', - outputFormatter: web3._extend.utils.toDecimal - }) - ] -}); -` diff --git a/rpc/api/net.go b/rpc/api/net.go deleted file mode 100644 index 9c6369615..000000000 --- a/rpc/api/net.go +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/rpc/codec" - "github.com/ethereum/go-ethereum/rpc/shared" - "github.com/ethereum/go-ethereum/xeth" -) - -const ( - NetApiVersion = "1.0" -) - -var ( - // mapping between methods and handlers - netMapping = map[string]nethandler{ - "net_peerCount": (*netApi).PeerCount, - "net_listening": (*netApi).IsListening, - "net_version": (*netApi).Version, - } -) - -// net callback handler -type nethandler func(*netApi, *shared.Request) (interface{}, error) - -// net api provider -type netApi struct { - xeth *xeth.XEth - ethereum *eth.Ethereum - methods map[string]nethandler - codec codec.ApiCoder -} - -// create a new net api instance -func NewNetApi(xeth *xeth.XEth, eth *eth.Ethereum, coder codec.Codec) *netApi { - return &netApi{ - xeth: xeth, - ethereum: eth, - methods: netMapping, - codec: coder.New(nil), - } -} - -// collection with supported methods -func (self *netApi) Methods() []string { - methods := make([]string, len(self.methods)) - i := 0 - for k := range self.methods { - methods[i] = k - i++ - } - return methods -} - -// Execute given request -func (self *netApi) Execute(req *shared.Request) (interface{}, error) { - if callback, ok := self.methods[req.Method]; ok { - return callback(self, req) - } - - return nil, shared.NewNotImplementedError(req.Method) -} - -func (self *netApi) Name() string { - return shared.NetApiName -} - -func (self *netApi) ApiVersion() string { - return NetApiVersion -} - -// Number of connected peers -func (self *netApi) PeerCount(req *shared.Request) (interface{}, error) { - return newHexNum(self.xeth.PeerCount()), nil -} - -func (self *netApi) IsListening(req *shared.Request) (interface{}, error) { - return self.xeth.IsListening(), nil -} - -func (self *netApi) Version(req *shared.Request) (interface{}, error) { - return self.xeth.NetworkVersion(), nil -} diff --git a/rpc/api/net_js.go b/rpc/api/net_js.go deleted file mode 100644 index 2ee1f0041..000000000 --- a/rpc/api/net_js.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -const Net_JS = ` -web3._extend({ - property: 'net', - methods: - [ - new web3._extend.Method({ - name: 'addPeer', - call: 'net_addPeer', - params: 1, - inputFormatter: [null] - }) - ], - properties: - [ - new web3._extend.Property({ - name: 'version', - getter: 'net_version' - }) - ] -}); -` diff --git a/rpc/api/parsing.go b/rpc/api/parsing.go deleted file mode 100644 index 7667616ff..000000000 --- a/rpc/api/parsing.go +++ /dev/null @@ -1,522 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "bytes" - "encoding/binary" - "encoding/hex" - "encoding/json" - "math/big" - "strings" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/rpc/shared" -) - -type hexdata struct { - data []byte - isNil bool -} - -func (d *hexdata) String() string { - return "0x" + common.Bytes2Hex(d.data) -} - -func (d *hexdata) MarshalJSON() ([]byte, error) { - if d.isNil { - return json.Marshal(nil) - } - return json.Marshal(d.String()) -} - -func newHexData(input interface{}) *hexdata { - d := new(hexdata) - - if input == nil { - d.isNil = true - return d - } - switch input := input.(type) { - case []byte: - d.data = input - case common.Hash: - d.data = input.Bytes() - case *common.Hash: - if input == nil { - d.isNil = true - } else { - d.data = input.Bytes() - } - case common.Address: - d.data = input.Bytes() - case *common.Address: - if input == nil { - d.isNil = true - } else { - d.data = input.Bytes() - } - case types.Bloom: - d.data = input.Bytes() - case *types.Bloom: - if input == nil { - d.isNil = true - } else { - d.data = input.Bytes() - } - case *big.Int: - if input == nil { - d.isNil = true - } else { - d.data = input.Bytes() - } - case int64: - d.data = big.NewInt(input).Bytes() - case uint64: - buff := make([]byte, 8) - binary.BigEndian.PutUint64(buff, input) - d.data = buff - case int: - d.data = big.NewInt(int64(input)).Bytes() - case uint: - d.data = big.NewInt(int64(input)).Bytes() - case int8: - d.data = big.NewInt(int64(input)).Bytes() - case uint8: - d.data = big.NewInt(int64(input)).Bytes() - case int16: - d.data = big.NewInt(int64(input)).Bytes() - case uint16: - buff := make([]byte, 2) - binary.BigEndian.PutUint16(buff, input) - d.data = buff - case int32: - d.data = big.NewInt(int64(input)).Bytes() - case uint32: - buff := make([]byte, 4) - binary.BigEndian.PutUint32(buff, input) - d.data = buff - case string: // hexstring - // aaargh ffs TODO: avoid back-and-forth hex encodings where unneeded - bytes, err := hex.DecodeString(strings.TrimPrefix(input, "0x")) - if err != nil { - d.isNil = true - } else { - d.data = bytes - } - default: - d.isNil = true - } - - return d -} - -type hexnum struct { - data []byte - isNil bool -} - -func (d *hexnum) String() string { - // Get hex string from bytes - out := common.Bytes2Hex(d.data) - // Trim leading 0s - out = strings.TrimLeft(out, "0") - // Output "0x0" when value is 0 - if len(out) == 0 { - out = "0" - } - return "0x" + out -} - -func (d *hexnum) MarshalJSON() ([]byte, error) { - if d.isNil { - return json.Marshal(nil) - } - return json.Marshal(d.String()) -} - -func newHexNum(input interface{}) *hexnum { - d := new(hexnum) - - d.data = newHexData(input).data - - return d -} - -type BlockRes struct { - fullTx bool - - BlockNumber *hexnum `json:"number"` - BlockHash *hexdata `json:"hash"` - ParentHash *hexdata `json:"parentHash"` - Nonce *hexdata `json:"nonce"` - Sha3Uncles *hexdata `json:"sha3Uncles"` - LogsBloom *hexdata `json:"logsBloom"` - TransactionRoot *hexdata `json:"transactionsRoot"` - StateRoot *hexdata `json:"stateRoot"` - ReceiptRoot *hexdata `json:"receiptRoot"` - Miner *hexdata `json:"miner"` - Difficulty *hexnum `json:"difficulty"` - TotalDifficulty *hexnum `json:"totalDifficulty"` - Size *hexnum `json:"size"` - ExtraData *hexdata `json:"extraData"` - GasLimit *hexnum `json:"gasLimit"` - GasUsed *hexnum `json:"gasUsed"` - UnixTimestamp *hexnum `json:"timestamp"` - Transactions []*TransactionRes `json:"transactions"` - Uncles []*UncleRes `json:"uncles"` -} - -func (b *BlockRes) MarshalJSON() ([]byte, error) { - if b.fullTx { - var ext struct { - BlockNumber *hexnum `json:"number"` - BlockHash *hexdata `json:"hash"` - ParentHash *hexdata `json:"parentHash"` - Nonce *hexdata `json:"nonce"` - Sha3Uncles *hexdata `json:"sha3Uncles"` - LogsBloom *hexdata `json:"logsBloom"` - TransactionRoot *hexdata `json:"transactionsRoot"` - StateRoot *hexdata `json:"stateRoot"` - ReceiptRoot *hexdata `json:"receiptRoot"` - Miner *hexdata `json:"miner"` - Difficulty *hexnum `json:"difficulty"` - TotalDifficulty *hexnum `json:"totalDifficulty"` - Size *hexnum `json:"size"` - ExtraData *hexdata `json:"extraData"` - GasLimit *hexnum `json:"gasLimit"` - GasUsed *hexnum `json:"gasUsed"` - UnixTimestamp *hexnum `json:"timestamp"` - Transactions []*TransactionRes `json:"transactions"` - Uncles []*hexdata `json:"uncles"` - } - - ext.BlockNumber = b.BlockNumber - ext.BlockHash = b.BlockHash - ext.ParentHash = b.ParentHash - ext.Nonce = b.Nonce - ext.Sha3Uncles = b.Sha3Uncles - ext.LogsBloom = b.LogsBloom - ext.TransactionRoot = b.TransactionRoot - ext.StateRoot = b.StateRoot - ext.ReceiptRoot = b.ReceiptRoot - ext.Miner = b.Miner - ext.Difficulty = b.Difficulty - ext.TotalDifficulty = b.TotalDifficulty - ext.Size = b.Size - ext.ExtraData = b.ExtraData - ext.GasLimit = b.GasLimit - ext.GasUsed = b.GasUsed - ext.UnixTimestamp = b.UnixTimestamp - ext.Transactions = b.Transactions - ext.Uncles = make([]*hexdata, len(b.Uncles)) - for i, u := range b.Uncles { - ext.Uncles[i] = u.BlockHash - } - return json.Marshal(ext) - } else { - var ext struct { - BlockNumber *hexnum `json:"number"` - BlockHash *hexdata `json:"hash"` - ParentHash *hexdata `json:"parentHash"` - Nonce *hexdata `json:"nonce"` - Sha3Uncles *hexdata `json:"sha3Uncles"` - LogsBloom *hexdata `json:"logsBloom"` - TransactionRoot *hexdata `json:"transactionsRoot"` - StateRoot *hexdata `json:"stateRoot"` - ReceiptRoot *hexdata `json:"receiptRoot"` - Miner *hexdata `json:"miner"` - Difficulty *hexnum `json:"difficulty"` - TotalDifficulty *hexnum `json:"totalDifficulty"` - Size *hexnum `json:"size"` - ExtraData *hexdata `json:"extraData"` - GasLimit *hexnum `json:"gasLimit"` - GasUsed *hexnum `json:"gasUsed"` - UnixTimestamp *hexnum `json:"timestamp"` - Transactions []*hexdata `json:"transactions"` - Uncles []*hexdata `json:"uncles"` - } - - ext.BlockNumber = b.BlockNumber - ext.BlockHash = b.BlockHash - ext.ParentHash = b.ParentHash - ext.Nonce = b.Nonce - ext.Sha3Uncles = b.Sha3Uncles - ext.LogsBloom = b.LogsBloom - ext.TransactionRoot = b.TransactionRoot - ext.StateRoot = b.StateRoot - ext.ReceiptRoot = b.ReceiptRoot - ext.Miner = b.Miner - ext.Difficulty = b.Difficulty - ext.TotalDifficulty = b.TotalDifficulty - ext.Size = b.Size - ext.ExtraData = b.ExtraData - ext.GasLimit = b.GasLimit - ext.GasUsed = b.GasUsed - ext.UnixTimestamp = b.UnixTimestamp - ext.Transactions = make([]*hexdata, len(b.Transactions)) - for i, tx := range b.Transactions { - ext.Transactions[i] = tx.Hash - } - ext.Uncles = make([]*hexdata, len(b.Uncles)) - for i, u := range b.Uncles { - ext.Uncles[i] = u.BlockHash - } - return json.Marshal(ext) - } -} - -func NewBlockRes(block *types.Block, td *big.Int, fullTx bool) *BlockRes { - if block == nil { - return nil - } - - res := new(BlockRes) - res.fullTx = fullTx - res.BlockNumber = newHexNum(block.Number()) - res.BlockHash = newHexData(block.Hash()) - res.ParentHash = newHexData(block.ParentHash()) - res.Nonce = newHexData(block.Nonce()) - res.Sha3Uncles = newHexData(block.UncleHash()) - res.LogsBloom = newHexData(block.Bloom()) - res.TransactionRoot = newHexData(block.TxHash()) - res.StateRoot = newHexData(block.Root()) - res.ReceiptRoot = newHexData(block.ReceiptHash()) - res.Miner = newHexData(block.Coinbase()) - res.Difficulty = newHexNum(block.Difficulty()) - res.TotalDifficulty = newHexNum(td) - res.Size = newHexNum(block.Size().Int64()) - res.ExtraData = newHexData(block.Extra()) - res.GasLimit = newHexNum(block.GasLimit()) - res.GasUsed = newHexNum(block.GasUsed()) - res.UnixTimestamp = newHexNum(block.Time()) - - txs := block.Transactions() - res.Transactions = make([]*TransactionRes, len(txs)) - for i, tx := range txs { - res.Transactions[i] = NewTransactionRes(tx) - res.Transactions[i].BlockHash = res.BlockHash - res.Transactions[i].BlockNumber = res.BlockNumber - res.Transactions[i].TxIndex = newHexNum(i) - } - - uncles := block.Uncles() - res.Uncles = make([]*UncleRes, len(uncles)) - for i, uncle := range uncles { - res.Uncles[i] = NewUncleRes(uncle) - } - - return res -} - -type TransactionRes struct { - Hash *hexdata `json:"hash"` - Nonce *hexnum `json:"nonce"` - BlockHash *hexdata `json:"blockHash"` - BlockNumber *hexnum `json:"blockNumber"` - TxIndex *hexnum `json:"transactionIndex"` - From *hexdata `json:"from"` - To *hexdata `json:"to"` - Value *hexnum `json:"value"` - Gas *hexnum `json:"gas"` - GasPrice *hexnum `json:"gasPrice"` - Input *hexdata `json:"input"` -} - -func NewTransactionRes(tx *types.Transaction) *TransactionRes { - if tx == nil { - return nil - } - - var v = new(TransactionRes) - v.Hash = newHexData(tx.Hash()) - v.Nonce = newHexNum(tx.Nonce()) - // v.BlockHash = - // v.BlockNumber = - // v.TxIndex = - from, _ := tx.From() - v.From = newHexData(from) - v.To = newHexData(tx.To()) - v.Value = newHexNum(tx.Value()) - v.Gas = newHexNum(tx.Gas()) - v.GasPrice = newHexNum(tx.GasPrice()) - v.Input = newHexData(tx.Data()) - return v -} - -type UncleRes struct { - BlockNumber *hexnum `json:"number"` - BlockHash *hexdata `json:"hash"` - ParentHash *hexdata `json:"parentHash"` - Nonce *hexdata `json:"nonce"` - Sha3Uncles *hexdata `json:"sha3Uncles"` - ReceiptHash *hexdata `json:"receiptHash"` - LogsBloom *hexdata `json:"logsBloom"` - TransactionRoot *hexdata `json:"transactionsRoot"` - StateRoot *hexdata `json:"stateRoot"` - Miner *hexdata `json:"miner"` - Difficulty *hexnum `json:"difficulty"` - ExtraData *hexdata `json:"extraData"` - GasLimit *hexnum `json:"gasLimit"` - GasUsed *hexnum `json:"gasUsed"` - UnixTimestamp *hexnum `json:"timestamp"` -} - -func NewUncleRes(h *types.Header) *UncleRes { - if h == nil { - return nil - } - - var v = new(UncleRes) - v.BlockNumber = newHexNum(h.Number) - v.BlockHash = newHexData(h.Hash()) - v.ParentHash = newHexData(h.ParentHash) - v.Sha3Uncles = newHexData(h.UncleHash) - v.Nonce = newHexData(h.Nonce[:]) - v.LogsBloom = newHexData(h.Bloom) - v.TransactionRoot = newHexData(h.TxHash) - v.StateRoot = newHexData(h.Root) - v.Miner = newHexData(h.Coinbase) - v.Difficulty = newHexNum(h.Difficulty) - v.ExtraData = newHexData(h.Extra) - v.GasLimit = newHexNum(h.GasLimit) - v.GasUsed = newHexNum(h.GasUsed) - v.UnixTimestamp = newHexNum(h.Time) - v.ReceiptHash = newHexData(h.ReceiptHash) - - return v -} - -// type FilterLogRes struct { -// Hash string `json:"hash"` -// Address string `json:"address"` -// Data string `json:"data"` -// BlockNumber string `json:"blockNumber"` -// TransactionHash string `json:"transactionHash"` -// BlockHash string `json:"blockHash"` -// TransactionIndex string `json:"transactionIndex"` -// LogIndex string `json:"logIndex"` -// } - -// type FilterWhisperRes struct { -// Hash string `json:"hash"` -// From string `json:"from"` -// To string `json:"to"` -// Expiry string `json:"expiry"` -// Sent string `json:"sent"` -// Ttl string `json:"ttl"` -// Topics string `json:"topics"` -// Payload string `json:"payload"` -// WorkProved string `json:"workProved"` -// } - -type ReceiptRes struct { - TransactionHash *hexdata `json:"transactionHash"` - TransactionIndex *hexnum `json:"transactionIndex"` - BlockNumber *hexnum `json:"blockNumber"` - BlockHash *hexdata `json:"blockHash"` - CumulativeGasUsed *hexnum `json:"cumulativeGasUsed"` - GasUsed *hexnum `json:"gasUsed"` - ContractAddress *hexdata `json:"contractAddress"` - Logs *[]interface{} `json:"logs"` -} - -func NewReceiptRes(rec *types.Receipt) *ReceiptRes { - if rec == nil { - return nil - } - - var v = new(ReceiptRes) - v.TransactionHash = newHexData(rec.TxHash) - if rec.GasUsed != nil { - v.GasUsed = newHexNum(rec.GasUsed.Bytes()) - } - v.CumulativeGasUsed = newHexNum(rec.CumulativeGasUsed) - - // If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation - if bytes.Compare(rec.ContractAddress.Bytes(), bytes.Repeat([]byte{0}, 20)) != 0 { - v.ContractAddress = newHexData(rec.ContractAddress) - } - - logs := make([]interface{}, len(rec.Logs)) - for i, log := range rec.Logs { - logs[i] = NewLogRes(log) - } - v.Logs = &logs - - return v -} - -func numString(raw interface{}) (*big.Int, error) { - var number *big.Int - // Parse as integer - num, ok := raw.(float64) - if ok { - number = big.NewInt(int64(num)) - return number, nil - } - - // Parse as string/hexstring - str, ok := raw.(string) - if ok { - number = common.String2Big(str) - return number, nil - } - - return nil, shared.NewInvalidTypeError("", "not a number or string") -} - -func blockHeight(raw interface{}, number *int64) error { - // Parse as integer - num, ok := raw.(float64) - if ok { - *number = int64(num) - return nil - } - - // Parse as string/hexstring - str, ok := raw.(string) - if !ok { - return shared.NewInvalidTypeError("", "not a number or string") - } - - switch str { - case "earliest": - *number = 0 - case "latest": - *number = -1 - case "pending": - *number = -2 - default: - if common.HasHexPrefix(str) { - *number = common.String2Big(str).Int64() - } else { - return shared.NewInvalidTypeError("blockNumber", "is not a valid string") - } - } - - return nil -} - -func blockHeightFromJson(msg json.RawMessage, number *int64) error { - var raw interface{} - if err := json.Unmarshal(msg, &raw); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - return blockHeight(raw, number) -} diff --git a/rpc/api/personal.go b/rpc/api/personal.go deleted file mode 100644 index 4f347c610..000000000 --- a/rpc/api/personal.go +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "fmt" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/rpc/codec" - "github.com/ethereum/go-ethereum/rpc/shared" - "github.com/ethereum/go-ethereum/xeth" -) - -const ( - PersonalApiVersion = "1.0" -) - -var ( - // mapping between methods and handlers - personalMapping = map[string]personalhandler{ - "personal_listAccounts": (*personalApi).ListAccounts, - "personal_newAccount": (*personalApi).NewAccount, - "personal_unlockAccount": (*personalApi).UnlockAccount, - } -) - -// net callback handler -type personalhandler func(*personalApi, *shared.Request) (interface{}, error) - -// net api provider -type personalApi struct { - xeth *xeth.XEth - ethereum *eth.Ethereum - methods map[string]personalhandler - codec codec.ApiCoder -} - -// create a new net api instance -func NewPersonalApi(xeth *xeth.XEth, eth *eth.Ethereum, coder codec.Codec) *personalApi { - return &personalApi{ - xeth: xeth, - ethereum: eth, - methods: personalMapping, - codec: coder.New(nil), - } -} - -// collection with supported methods -func (self *personalApi) Methods() []string { - methods := make([]string, len(self.methods)) - i := 0 - for k := range self.methods { - methods[i] = k - i++ - } - return methods -} - -// Execute given request -func (self *personalApi) Execute(req *shared.Request) (interface{}, error) { - if callback, ok := self.methods[req.Method]; ok { - return callback(self, req) - } - - return nil, shared.NewNotImplementedError(req.Method) -} - -func (self *personalApi) Name() string { - return shared.PersonalApiName -} - -func (self *personalApi) ApiVersion() string { - return PersonalApiVersion -} - -func (self *personalApi) ListAccounts(req *shared.Request) (interface{}, error) { - return self.xeth.Accounts(), nil -} - -func (self *personalApi) NewAccount(req *shared.Request) (interface{}, error) { - args := new(NewAccountArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - var passwd string - if args.Passphrase == nil { - fe := self.xeth.Frontend() - if fe == nil { - return false, fmt.Errorf("unable to create account: unable to interact with user") - } - var ok bool - passwd, ok = fe.AskPassword() - if !ok { - return false, fmt.Errorf("unable to create account: no password given") - } - } else { - passwd = *args.Passphrase - } - am := self.ethereum.AccountManager() - acc, err := am.NewAccount(passwd) - return acc.Address.Hex(), err -} - -func (self *personalApi) UnlockAccount(req *shared.Request) (interface{}, error) { - args := new(UnlockAccountArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, shared.NewDecodeParamError(err.Error()) - } - - if args.Passphrase == nil { - fe := self.xeth.Frontend() - if fe == nil { - return false, fmt.Errorf("No password provided") - } - return fe.UnlockAccount(common.HexToAddress(args.Address).Bytes()), nil - } - - am := self.ethereum.AccountManager() - addr := common.HexToAddress(args.Address) - - err := am.TimedUnlock(addr, *args.Passphrase, time.Duration(args.Duration)*time.Second) - return err == nil, err -} diff --git a/rpc/api/personal_args.go b/rpc/api/personal_args.go deleted file mode 100644 index 5d215c71d..000000000 --- a/rpc/api/personal_args.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "encoding/json" - - "github.com/ethereum/go-ethereum/rpc/shared" -) - -type NewAccountArgs struct { - Passphrase *string -} - -func (args *NewAccountArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) >= 1 && obj[0] != nil { - if passphrasestr, ok := obj[0].(string); ok { - args.Passphrase = &passphrasestr - } else { - return shared.NewInvalidTypeError("passphrase", "not a string") - } - } - - return nil -} - -type UnlockAccountArgs struct { - Address string - Passphrase *string - Duration int -} - -func (args *UnlockAccountArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - args.Duration = 0 - - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - if addrstr, ok := obj[0].(string); ok { - args.Address = addrstr - } else { - return shared.NewInvalidTypeError("address", "not a string") - } - - if len(obj) >= 2 && obj[1] != nil { - if passphrasestr, ok := obj[1].(string); ok { - args.Passphrase = &passphrasestr - } else { - return shared.NewInvalidTypeError("passphrase", "not a string") - } - } - - if len(obj) >= 3 && obj[2] != nil { - if duration, ok := obj[2].(float64); ok { - args.Duration = int(duration) - } - } - - return nil -} diff --git a/rpc/api/personal_js.go b/rpc/api/personal_js.go deleted file mode 100644 index 84c669af7..000000000 --- a/rpc/api/personal_js.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -const Personal_JS = ` -web3._extend({ - property: 'personal', - methods: - [ - new web3._extend.Method({ - name: 'newAccount', - call: 'personal_newAccount', - params: 1, - inputFormatter: [null], - outputFormatter: web3._extend.utils.toAddress - }), - new web3._extend.Method({ - name: 'unlockAccount', - call: 'personal_unlockAccount', - params: 3, - inputFormatter: [null, null, null] - }), - new web3._extend.Method({ - name: 'lockAccount', - call: 'personal_lockAccount', - params: 1 - }) - ], - properties: - [ - new web3._extend.Property({ - name: 'listAccounts', - getter: 'personal_listAccounts' - }) - ] -}); -` diff --git a/rpc/api/shh.go b/rpc/api/shh.go deleted file mode 100644 index 60e805605..000000000 --- a/rpc/api/shh.go +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/rpc/codec" - "github.com/ethereum/go-ethereum/rpc/shared" - "github.com/ethereum/go-ethereum/xeth" -) - -const ( - ShhApiVersion = "1.0" -) - -var ( - // mapping between methods and handlers - shhMapping = map[string]shhhandler{ - "shh_version": (*shhApi).Version, - "shh_post": (*shhApi).Post, - "shh_hasIdentity": (*shhApi).HasIdentity, - "shh_newIdentity": (*shhApi).NewIdentity, - "shh_newFilter": (*shhApi).NewFilter, - "shh_uninstallFilter": (*shhApi).UninstallFilter, - "shh_getMessages": (*shhApi).GetMessages, - "shh_getFilterChanges": (*shhApi).GetFilterChanges, - } -) - -func newWhisperOfflineError(method string) error { - return shared.NewNotAvailableError(method, "whisper offline") -} - -// net callback handler -type shhhandler func(*shhApi, *shared.Request) (interface{}, error) - -// shh api provider -type shhApi struct { - xeth *xeth.XEth - ethereum *eth.Ethereum - methods map[string]shhhandler - codec codec.ApiCoder -} - -// create a new whisper api instance -func NewShhApi(xeth *xeth.XEth, eth *eth.Ethereum, coder codec.Codec) *shhApi { - return &shhApi{ - xeth: xeth, - ethereum: eth, - methods: shhMapping, - codec: coder.New(nil), - } -} - -// collection with supported methods -func (self *shhApi) Methods() []string { - methods := make([]string, len(self.methods)) - i := 0 - for k := range self.methods { - methods[i] = k - i++ - } - return methods -} - -// Execute given request -func (self *shhApi) Execute(req *shared.Request) (interface{}, error) { - if callback, ok := self.methods[req.Method]; ok { - return callback(self, req) - } - - return nil, shared.NewNotImplementedError(req.Method) -} - -func (self *shhApi) Name() string { - return shared.ShhApiName -} - -func (self *shhApi) ApiVersion() string { - return ShhApiVersion -} - -func (self *shhApi) Version(req *shared.Request) (interface{}, error) { - w := self.xeth.Whisper() - if w == nil { - return nil, newWhisperOfflineError(req.Method) - } - - return w.Version(), nil -} - -func (self *shhApi) Post(req *shared.Request) (interface{}, error) { - w := self.xeth.Whisper() - if w == nil { - return nil, newWhisperOfflineError(req.Method) - } - - args := new(WhisperMessageArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, err - } - - err := w.Post(args.Payload, args.To, args.From, args.Topics, args.Priority, args.Ttl) - if err != nil { - return false, err - } - - return true, nil -} - -func (self *shhApi) HasIdentity(req *shared.Request) (interface{}, error) { - w := self.xeth.Whisper() - if w == nil { - return nil, newWhisperOfflineError(req.Method) - } - - args := new(WhisperIdentityArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, err - } - - return w.HasIdentity(args.Identity), nil -} - -func (self *shhApi) NewIdentity(req *shared.Request) (interface{}, error) { - w := self.xeth.Whisper() - if w == nil { - return nil, newWhisperOfflineError(req.Method) - } - - return w.NewIdentity(), nil -} - -func (self *shhApi) NewFilter(req *shared.Request) (interface{}, error) { - args := new(WhisperFilterArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, err - } - - id := self.xeth.NewWhisperFilter(args.To, args.From, args.Topics) - return newHexNum(big.NewInt(int64(id)).Bytes()), nil -} - -func (self *shhApi) UninstallFilter(req *shared.Request) (interface{}, error) { - args := new(FilterIdArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, err - } - return self.xeth.UninstallWhisperFilter(args.Id), nil -} - -func (self *shhApi) GetFilterChanges(req *shared.Request) (interface{}, error) { - w := self.xeth.Whisper() - if w == nil { - return nil, newWhisperOfflineError(req.Method) - } - - // Retrieve all the new messages arrived since the last request - args := new(FilterIdArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, err - } - - return self.xeth.WhisperMessagesChanged(args.Id), nil -} - -func (self *shhApi) GetMessages(req *shared.Request) (interface{}, error) { - w := self.xeth.Whisper() - if w == nil { - return nil, newWhisperOfflineError(req.Method) - } - - // Retrieve all the cached messages matching a specific, existing filter - args := new(FilterIdArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, err - } - - return self.xeth.WhisperMessages(args.Id), nil -} diff --git a/rpc/api/shh_args.go b/rpc/api/shh_args.go deleted file mode 100644 index 468a0b98f..000000000 --- a/rpc/api/shh_args.go +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "encoding/json" - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/rpc/shared" -) - -type WhisperMessageArgs struct { - Payload string - To string - From string - Topics []string - Priority uint32 - Ttl uint32 -} - -func (args *WhisperMessageArgs) UnmarshalJSON(b []byte) (err error) { - var obj []struct { - Payload string - To string - From string - Topics []string - Priority interface{} - Ttl interface{} - } - - if err = json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - args.Payload = obj[0].Payload - args.To = obj[0].To - args.From = obj[0].From - args.Topics = obj[0].Topics - - var num *big.Int - if num, err = numString(obj[0].Priority); err != nil { - return err - } - args.Priority = uint32(num.Int64()) - - if num, err = numString(obj[0].Ttl); err != nil { - return err - } - args.Ttl = uint32(num.Int64()) - - return nil -} - -type WhisperIdentityArgs struct { - Identity string -} - -func (args *WhisperIdentityArgs) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - argstr, ok := obj[0].(string) - if !ok { - return shared.NewInvalidTypeError("arg0", "not a string") - } - - args.Identity = argstr - - return nil -} - -type WhisperFilterArgs struct { - To string - From string - Topics [][]string -} - -// UnmarshalJSON implements the json.Unmarshaler interface, invoked to convert a -// JSON message blob into a WhisperFilterArgs structure. -func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) { - // Unmarshal the JSON message and sanity check - var obj []struct { - To interface{} `json:"to"` - From interface{} `json:"from"` - Topics interface{} `json:"topics"` - } - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - // Retrieve the simple data contents of the filter arguments - if obj[0].To == nil { - args.To = "" - } else { - argstr, ok := obj[0].To.(string) - if !ok { - return shared.NewInvalidTypeError("to", "is not a string") - } - args.To = argstr - } - if obj[0].From == nil { - args.From = "" - } else { - argstr, ok := obj[0].From.(string) - if !ok { - return shared.NewInvalidTypeError("from", "is not a string") - } - args.From = argstr - } - // Construct the nested topic array - if obj[0].Topics != nil { - // Make sure we have an actual topic array - list, ok := obj[0].Topics.([]interface{}) - if !ok { - return shared.NewInvalidTypeError("topics", "is not an array") - } - // Iterate over each topic and handle nil, string or array - topics := make([][]string, len(list)) - for idx, field := range list { - switch value := field.(type) { - case nil: - topics[idx] = []string{} - - case string: - topics[idx] = []string{value} - - case []interface{}: - topics[idx] = make([]string, len(value)) - for i, nested := range value { - switch value := nested.(type) { - case nil: - topics[idx][i] = "" - - case string: - topics[idx][i] = value - - default: - return shared.NewInvalidTypeError(fmt.Sprintf("topic[%d][%d]", idx, i), "is not a string") - } - } - default: - return shared.NewInvalidTypeError(fmt.Sprintf("topic[%d]", idx), "not a string or array") - } - } - args.Topics = topics - } - return nil -} diff --git a/rpc/api/shh_js.go b/rpc/api/shh_js.go deleted file mode 100644 index a92ad1644..000000000 --- a/rpc/api/shh_js.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -const Shh_JS = ` -web3._extend({ - property: 'shh', - methods: - [ - - ], - properties: - [ - new web3._extend.Property({ - name: 'version', - getter: 'shh_version' - }) - ] -}); -` diff --git a/rpc/api/txpool.go b/rpc/api/txpool.go deleted file mode 100644 index 27e40cae5..000000000 --- a/rpc/api/txpool.go +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/rpc/codec" - "github.com/ethereum/go-ethereum/rpc/shared" - "github.com/ethereum/go-ethereum/xeth" -) - -const ( - TxPoolApiVersion = "1.0" -) - -var ( - // mapping between methods and handlers - txpoolMapping = map[string]txpoolhandler{ - "txpool_status": (*txPoolApi).Status, - } -) - -// net callback handler -type txpoolhandler func(*txPoolApi, *shared.Request) (interface{}, error) - -// txpool api provider -type txPoolApi struct { - xeth *xeth.XEth - ethereum *eth.Ethereum - methods map[string]txpoolhandler - codec codec.ApiCoder -} - -// create a new txpool api instance -func NewTxPoolApi(xeth *xeth.XEth, eth *eth.Ethereum, coder codec.Codec) *txPoolApi { - return &txPoolApi{ - xeth: xeth, - ethereum: eth, - methods: txpoolMapping, - codec: coder.New(nil), - } -} - -// collection with supported methods -func (self *txPoolApi) Methods() []string { - methods := make([]string, len(self.methods)) - i := 0 - for k := range self.methods { - methods[i] = k - i++ - } - return methods -} - -// Execute given request -func (self *txPoolApi) Execute(req *shared.Request) (interface{}, error) { - if callback, ok := self.methods[req.Method]; ok { - return callback(self, req) - } - - return nil, shared.NewNotImplementedError(req.Method) -} - -func (self *txPoolApi) Name() string { - return shared.TxPoolApiName -} - -func (self *txPoolApi) ApiVersion() string { - return TxPoolApiVersion -} - -func (self *txPoolApi) Status(req *shared.Request) (interface{}, error) { - pending, queue := self.ethereum.TxPool().Stats() - return map[string]int{ - "pending": pending, - "queued": queue, - }, nil -} diff --git a/rpc/api/txpool_js.go b/rpc/api/txpool_js.go deleted file mode 100644 index b6c29871a..000000000 --- a/rpc/api/txpool_js.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -const TxPool_JS = ` -web3._extend({ - property: 'txpool', - methods: - [ - ], - properties: - [ - new web3._extend.Property({ - name: 'status', - getter: 'txpool_status' - }) - ] -}); -` diff --git a/rpc/api/utils.go b/rpc/api/utils.go deleted file mode 100644 index 794b6abee..000000000 --- a/rpc/api/utils.go +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "strings" - - "fmt" - - "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/rpc/codec" - "github.com/ethereum/go-ethereum/rpc/shared" - "github.com/ethereum/go-ethereum/xeth" -) - -var ( - // Mapping between the different methods each api supports - AutoCompletion = map[string][]string{ - "admin": []string{ - "addPeer", - "datadir", - "enableUserAgent", - "exportChain", - "getContractInfo", - "httpGet", - "importChain", - "nodeInfo", - "peers", - "register", - "registerUrl", - "saveInfo", - "setGlobalRegistrar", - "setHashReg", - "setUrlHint", - "setSolc", - "sleep", - "sleepBlocks", - "startNatSpec", - "startRPC", - "stopNatSpec", - "stopRPC", - "verbosity", - }, - "db": []string{ - "getString", - "putString", - "getHex", - "putHex", - }, - "debug": []string{ - "dumpBlock", - "getBlockRlp", - "metrics", - "printBlock", - "processBlock", - "seedHash", - "setHead", - }, - "eth": []string{ - "accounts", - "blockNumber", - "call", - "contract", - "coinbase", - "compile.lll", - "compile.serpent", - "compile.solidity", - "contract", - "defaultAccount", - "defaultBlock", - "estimateGas", - "filter", - "getBalance", - "getBlock", - "getBlockTransactionCount", - "getBlockUncleCount", - "getCode", - "getNatSpec", - "getCompilers", - "gasPrice", - "getStorageAt", - "getTransaction", - "getTransactionCount", - "getTransactionFromBlock", - "getTransactionReceipt", - "getUncle", - "hashrate", - "mining", - "namereg", - "pendingTransactions", - "resend", - "sendRawTransaction", - "sendTransaction", - "sign", - "syncing", - }, - "miner": []string{ - "hashrate", - "makeDAG", - "setEtherbase", - "setExtra", - "setGasPrice", - "startAutoDAG", - "start", - "stopAutoDAG", - "stop", - }, - "net": []string{ - "peerCount", - "listening", - }, - "personal": []string{ - "listAccounts", - "newAccount", - "unlockAccount", - }, - "shh": []string{ - "post", - "newIdentity", - "hasIdentity", - "newGroup", - "addToGroup", - "filter", - }, - "txpool": []string{ - "status", - }, - "web3": []string{ - "sha3", - "version", - "fromWei", - "toWei", - "toHex", - "toAscii", - "fromAscii", - "toBigNumber", - "isAddress", - }, - } -) - -// Parse a comma separated API string to individual api's -func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, stack *node.Node) ([]shared.EthereumApi, error) { - if len(strings.TrimSpace(apistr)) == 0 { - return nil, fmt.Errorf("Empty apistr provided") - } - - names := strings.Split(apistr, ",") - apis := make([]shared.EthereumApi, len(names)) - - var eth *eth.Ethereum - if stack != nil { - if err := stack.Service(ð); err != nil { - return nil, err - } - } - for i, name := range names { - switch strings.ToLower(strings.TrimSpace(name)) { - case shared.AdminApiName: - apis[i] = NewAdminApi(xeth, stack, codec) - case shared.DebugApiName: - apis[i] = NewDebugApi(xeth, eth, codec) - case shared.DbApiName: - apis[i] = NewDbApi(xeth, eth, codec) - case shared.EthApiName: - apis[i] = NewEthApi(xeth, eth, codec) - case shared.MinerApiName: - apis[i] = NewMinerApi(eth, codec) - case shared.NetApiName: - apis[i] = NewNetApi(xeth, eth, codec) - case shared.ShhApiName: - apis[i] = NewShhApi(xeth, eth, codec) - case shared.TxPoolApiName: - apis[i] = NewTxPoolApi(xeth, eth, codec) - case shared.PersonalApiName: - apis[i] = NewPersonalApi(xeth, eth, codec) - case shared.Web3ApiName: - apis[i] = NewWeb3Api(xeth, codec) - case "rpc": // gives information about the RPC interface - continue - default: - return nil, fmt.Errorf("Unknown API '%s'", name) - } - } - return apis, nil -} - -func Javascript(name string) string { - switch strings.ToLower(strings.TrimSpace(name)) { - case shared.AdminApiName: - return Admin_JS - case shared.DebugApiName: - return Debug_JS - case shared.DbApiName: - return Db_JS - case shared.EthApiName: - return Eth_JS - case shared.MinerApiName: - return Miner_JS - case shared.NetApiName: - return Net_JS - case shared.ShhApiName: - return Shh_JS - case shared.TxPoolApiName: - return TxPool_JS - case shared.PersonalApiName: - return Personal_JS - } - - return "" -} diff --git a/rpc/api/web3.go b/rpc/api/web3.go deleted file mode 100644 index e2d8543d3..000000000 --- a/rpc/api/web3.go +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rpc/codec" - "github.com/ethereum/go-ethereum/rpc/shared" - "github.com/ethereum/go-ethereum/xeth" -) - -const ( - Web3ApiVersion = "1.0" -) - -var ( - // mapping between methods and handlers - Web3Mapping = map[string]web3handler{ - "web3_sha3": (*web3Api).Sha3, - "web3_clientVersion": (*web3Api).ClientVersion, - } -) - -// web3 callback handler -type web3handler func(*web3Api, *shared.Request) (interface{}, error) - -// web3 api provider -type web3Api struct { - xeth *xeth.XEth - methods map[string]web3handler - codec codec.ApiCoder -} - -// create a new web3 api instance -func NewWeb3Api(xeth *xeth.XEth, coder codec.Codec) *web3Api { - return &web3Api{ - xeth: xeth, - methods: Web3Mapping, - codec: coder.New(nil), - } -} - -// collection with supported methods -func (self *web3Api) Methods() []string { - methods := make([]string, len(self.methods)) - i := 0 - for k := range self.methods { - methods[i] = k - i++ - } - return methods -} - -// Execute given request -func (self *web3Api) Execute(req *shared.Request) (interface{}, error) { - if callback, ok := self.methods[req.Method]; ok { - return callback(self, req) - } - - return nil, &shared.NotImplementedError{req.Method} -} - -func (self *web3Api) Name() string { - return shared.Web3ApiName -} - -func (self *web3Api) ApiVersion() string { - return Web3ApiVersion -} - -// Calculates the sha3 over req.Params.Data -func (self *web3Api) Sha3(req *shared.Request) (interface{}, error) { - args := new(Sha3Args) - if err := self.codec.Decode(req.Params, &args); err != nil { - return nil, err - } - - return common.ToHex(crypto.Sha3(common.FromHex(args.Data))), nil -} - -// returns the xeth client vrsion -func (self *web3Api) ClientVersion(req *shared.Request) (interface{}, error) { - return self.xeth.ClientVersion(), nil -} diff --git a/rpc/api/web3_args.go b/rpc/api/web3_args.go deleted file mode 100644 index 9e39f7130..000000000 --- a/rpc/api/web3_args.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package api - -import ( - "encoding/json" - - "github.com/ethereum/go-ethereum/rpc/shared" -) - -type Sha3Args struct { - Data string -} - -func (args *Sha3Args) UnmarshalJSON(b []byte) (err error) { - var obj []interface{} - if err := json.Unmarshal(b, &obj); err != nil { - return shared.NewDecodeParamError(err.Error()) - } - - if len(obj) < 1 { - return shared.NewInsufficientParamsError(len(obj), 1) - } - - argstr, ok := obj[0].(string) - if !ok { - return shared.NewInvalidTypeError("data", "is not a string") - } - args.Data = argstr - return nil -} |