diff options
Diffstat (limited to 'rpc/api')
-rw-r--r-- | rpc/api/admin.go | 95 | ||||
-rw-r--r-- | rpc/api/admin_args.go | 52 | ||||
-rw-r--r-- | rpc/api/admin_js.go | 14 | ||||
-rw-r--r-- | rpc/api/api.go | 40 | ||||
-rw-r--r-- | rpc/api/api_test.go | 111 | ||||
-rw-r--r-- | rpc/api/args.go | 58 | ||||
-rw-r--r-- | rpc/api/args_test.go | 2635 | ||||
-rw-r--r-- | rpc/api/db.go | 128 | ||||
-rw-r--r-- | rpc/api/db_args.go | 110 | ||||
-rw-r--r-- | rpc/api/db_js.go | 41 | ||||
-rw-r--r-- | rpc/api/debug.go | 2 | ||||
-rw-r--r-- | rpc/api/eth.go | 102 | ||||
-rw-r--r-- | rpc/api/eth_args.go | 41 | ||||
-rw-r--r-- | rpc/api/eth_js.go | 17 | ||||
-rw-r--r-- | rpc/api/mergedapi.go | 12 | ||||
-rw-r--r-- | rpc/api/mergedapi_js.go | 1 | ||||
-rw-r--r-- | rpc/api/miner.go | 2 | ||||
-rw-r--r-- | rpc/api/net.go | 4 | ||||
-rw-r--r-- | rpc/api/personal.go | 2 | ||||
-rw-r--r-- | rpc/api/shh.go | 2 | ||||
-rw-r--r-- | rpc/api/txpool.go | 2 | ||||
-rw-r--r-- | rpc/api/utils.go | 52 | ||||
-rw-r--r-- | rpc/api/web3.go | 2 | ||||
-rw-r--r-- | rpc/api/web3_args.go | 24 |
24 files changed, 3384 insertions, 165 deletions
diff --git a/rpc/api/admin.go b/rpc/api/admin.go index a6b9cf050..b27482cfe 100644 --- a/rpc/api/admin.go +++ b/rpc/api/admin.go @@ -11,6 +11,7 @@ import ( "github.com/ethereum/go-ethereum/logger/glog" "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/xeth" ) @@ -23,8 +24,6 @@ const ( var ( // mapping between methods and handlers AdminMapping = map[string]adminhandler{ - // "admin_startRPC": (*adminApi).StartRPC, - // "admin_stopRPC": (*adminApi).StopRPC, "admin_addPeer": (*adminApi).AddPeer, "admin_peers": (*adminApi).Peers, "admin_nodeInfo": (*adminApi).NodeInfo, @@ -34,6 +33,8 @@ var ( "admin_chainSyncStatus": (*adminApi).ChainSyncStatus, "admin_setSolc": (*adminApi).SetSolc, "admin_datadir": (*adminApi).DataDir, + "admin_startRPC": (*adminApi).StartRPC, + "admin_stopRPC": (*adminApi).StopRPC, } ) @@ -44,25 +45,25 @@ type adminhandler func(*adminApi, *shared.Request) (interface{}, error) type adminApi struct { xeth *xeth.XEth ethereum *eth.Ethereum - methods map[string]adminhandler - codec codec.ApiCoder + codec codec.Codec + coder codec.ApiCoder } // create a new admin api instance -func NewAdminApi(xeth *xeth.XEth, ethereum *eth.Ethereum, coder codec.Codec) *adminApi { +func NewAdminApi(xeth *xeth.XEth, ethereum *eth.Ethereum, codec codec.Codec) *adminApi { return &adminApi{ xeth: xeth, ethereum: ethereum, - methods: AdminMapping, - codec: coder.New(nil), + codec: codec, + coder: codec.New(nil), } } // collection with supported methods func (self *adminApi) Methods() []string { - methods := make([]string, len(self.methods)) + methods := make([]string, len(AdminMapping)) i := 0 - for k := range self.methods { + for k := range AdminMapping { methods[i] = k i++ } @@ -71,7 +72,7 @@ func (self *adminApi) Methods() []string { // Execute given request func (self *adminApi) Execute(req *shared.Request) (interface{}, error) { - if callback, ok := self.methods[req.Method]; ok { + if callback, ok := AdminMapping[req.Method]; ok { return callback(self, req) } @@ -79,7 +80,7 @@ func (self *adminApi) Execute(req *shared.Request) (interface{}, error) { } func (self *adminApi) Name() string { - return AdminApiName + return shared.AdminApiName } func (self *adminApi) ApiVersion() string { @@ -88,7 +89,7 @@ func (self *adminApi) ApiVersion() string { func (self *adminApi) AddPeer(req *shared.Request) (interface{}, error) { args := new(AddPeerArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { + if err := self.coder.Decode(req.Params, &args); err != nil { return nil, shared.NewDecodeParamError(err.Error()) } @@ -103,33 +104,6 @@ func (self *adminApi) Peers(req *shared.Request) (interface{}, error) { return self.ethereum.PeersInfo(), nil } -func (self *adminApi) StartRPC(req *shared.Request) (interface{}, error) { - return false, nil - // Enable when http rpc interface is refactored to prevent import cycles - // args := new(StartRpcArgs) - // if err := self.codec.Decode(req.Params, &args); err != nil { - // return nil, shared.NewDecodeParamError(err.Error()) - // } - // - // cfg := rpc.RpcConfig{ - // ListenAddress: args.Address, - // ListenPort: args.Port, - // } - // - // err := rpc.Start(self.xeth, cfg) - // if err == nil { - // return true, nil - // } - // return false, err -} - -func (self *adminApi) StopRPC(req *shared.Request) (interface{}, error) { - return false, nil - // Enable when http rpc interface is refactored to prevent import cycles - // rpc.Stop() - // return true, nil -} - func (self *adminApi) NodeInfo(req *shared.Request) (interface{}, error) { return self.ethereum.NodeInfo(), nil } @@ -149,7 +123,7 @@ func hasAllBlocks(chain *core.ChainManager, bs []*types.Block) bool { func (self *adminApi) ImportChain(req *shared.Request) (interface{}, error) { args := new(ImportExportChainArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { + if err := self.coder.Decode(req.Params, &args); err != nil { return nil, shared.NewDecodeParamError(err.Error()) } @@ -192,7 +166,7 @@ func (self *adminApi) ImportChain(req *shared.Request) (interface{}, error) { func (self *adminApi) ExportChain(req *shared.Request) (interface{}, error) { args := new(ImportExportChainArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { + if err := self.coder.Decode(req.Params, &args); err != nil { return nil, shared.NewDecodeParamError(err.Error()) } @@ -210,7 +184,7 @@ func (self *adminApi) ExportChain(req *shared.Request) (interface{}, error) { func (self *adminApi) Verbosity(req *shared.Request) (interface{}, error) { args := new(VerbosityArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { + if err := self.coder.Decode(req.Params, &args); err != nil { return nil, shared.NewDecodeParamError(err.Error()) } @@ -222,16 +196,16 @@ func (self *adminApi) ChainSyncStatus(req *shared.Request) (interface{}, error) pending, cached, importing, estimate := self.ethereum.Downloader().Stats() return map[string]interface{}{ - "blocksAvailable": pending, + "blocksAvailable": pending, "blocksWaitingForImport": cached, - "importing": importing, - "estimate": estimate.String(), + "importing": importing, + "estimate": estimate.String(), }, nil } func (self *adminApi) SetSolc(req *shared.Request) (interface{}, error) { args := new(SetSolcArgs) - if err := self.codec.Decode(req.Params, &args); err != nil { + if err := self.coder.Decode(req.Params, &args); err != nil { return nil, shared.NewDecodeParamError(err.Error()) } @@ -241,3 +215,32 @@ func (self *adminApi) SetSolc(req *shared.Request) (interface{}, error) { } 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.ethereum) + 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 +} diff --git a/rpc/api/admin_args.go b/rpc/api/admin_args.go index 56bb57e20..5437971ca 100644 --- a/rpc/api/admin_args.go +++ b/rpc/api/admin_args.go @@ -95,3 +95,55 @@ func (args *SetSolcArgs) UnmarshalJSON(b []byte) (err error) { 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 { + if addr, ok := obj[0].(string); ok { + args.ListenAddress = addr + } else { + return shared.NewInvalidTypeError("listenAddress", "not a string") + } + } + + if len(obj) >= 2 { + 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 { + if corsDomain, ok := obj[2].(string); ok { + args.CorsDomain = corsDomain + } else { + return shared.NewInvalidTypeError("corsDomain", "not a string") + } + } + + if len(obj) >= 4 { + if apis, ok := obj[3].(string); ok { + args.Apis = apis + } else { + return shared.NewInvalidTypeError("apis", "not a string") + } + } + + return nil +} diff --git a/rpc/api/admin_js.go b/rpc/api/admin_js.go index c3e713c67..97642ade7 100644 --- a/rpc/api/admin_js.go +++ b/rpc/api/admin_js.go @@ -39,6 +39,20 @@ web3._extend({ params: 1, inputFormatter: [web3._extend.utils.formatInputString], outputFormatter: web3._extend.formatters.formatOutputString + }), + new web3._extend.Method({ + name: 'startRPC', + call: 'admin_startRPC', + params: 4, + inputFormatter: [web3._extend.utils.formatInputString,web3._extend.utils.formatInputInteger,web3._extend.utils.formatInputString,web3._extend.utils.formatInputString], + outputFormatter: web3._extend.formatters.formatOutputBool + }), + new web3._extend.Method({ + name: 'stopRPC', + call: 'admin_stopRPC', + params: 0, + inputFormatter: [], + outputFormatter: web3._extend.formatters.formatOutputBool }) ], properties: diff --git a/rpc/api/api.go b/rpc/api/api.go index e431e5c1e..ca1ccb9a5 100644 --- a/rpc/api/api.go +++ b/rpc/api/api.go @@ -1,48 +1,10 @@ package api import ( - "strings" - "github.com/ethereum/go-ethereum/rpc/shared" ) -const ( - AdminApiName = "admin" - EthApiName = "eth" - DebugApiName = "debug" - MergedApiName = "merged" - MinerApiName = "miner" - NetApiName = "net" - ShhApiName = "shh" - TxPoolApiName = "txpool" - PersonalApiName = "personal" - Web3ApiName = "web3" -) - -var ( - // List with all API's which are offered over the IPC interface by default - DefaultIpcApis = strings.Join([]string{ - AdminApiName, EthApiName, DebugApiName, MinerApiName, NetApiName, - ShhApiName, TxPoolApiName, PersonalApiName, Web3ApiName, - }, ",") -) - -// Ethereum RPC API interface -type EthereumApi interface { - // API identifier - Name() string - - // API version - ApiVersion() string - - // Execute the given request and returns the response or an error - Execute(*shared.Request) (interface{}, error) - - // List of supported RCP methods this API provides - Methods() []string -} - // Merge multiple API's to a single API instance -func Merge(apis ...EthereumApi) EthereumApi { +func Merge(apis ...shared.EthereumApi) shared.EthereumApi { return newMergedApi(apis...) } diff --git a/rpc/api/api_test.go b/rpc/api/api_test.go index f1a47944d..7e273ef28 100644 --- a/rpc/api/api_test.go +++ b/rpc/api/api_test.go @@ -3,7 +3,14 @@ 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) { @@ -40,3 +47,107 @@ func TestParseApiString(t *testing.T) { } } + +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 + + xeth := xeth.NewTest(ð.Ethereum{}, nil) + api := NewEthApi(xeth, 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 new file mode 100644 index 000000000..fc85448e6 --- /dev/null +++ b/rpc/api/args.go @@ -0,0 +1,58 @@ +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 new file mode 100644 index 000000000..a30f247bc --- /dev/null +++ b/rpc/api/args_test.go @@ -0,0 +1,2635 @@ +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) + str := ExpectValidationError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +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": "pending" + }]` + expected := new(BlockFilterArgs) + expected.Earliest = -1 + expected.Latest = -2 + + 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) + } +} + +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 new file mode 100644 index 000000000..6f10d6447 --- /dev/null +++ b/rpc/api/db.go @@ -0,0 +1,128 @@ +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 new file mode 100644 index 000000000..459616d87 --- /dev/null +++ b/rpc/api/db_args.go @@ -0,0 +1,110 @@ +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 new file mode 100644 index 000000000..62cdcd20e --- /dev/null +++ b/rpc/api/db_js.go @@ -0,0 +1,41 @@ +package api + +const Db_JS = ` +web3._extend({ + property: 'db', + methods: + [ + new web3._extend.Method({ + name: 'getString', + call: 'db_getString', + params: 2, + inputFormatter: [web3._extend.formatters.formatInputString, web3._extend.formatters.formatInputString], + outputFormatter: web3._extend.formatters.formatOutputString + }), + new web3._extend.Method({ + name: 'putString', + call: 'db_putString', + params: 3, + inputFormatter: [web3._extend.formatters.formatInputString, web3._extend.formatters.formatInputString, web3._extend.formatters.formatInputString], + outputFormatter: web3._extend.formatters.formatOutputBool + }), + new web3._extend.Method({ + name: 'getHex', + call: 'db_getHex', + params: 2, + inputFormatter: [web3._extend.formatters.formatInputString, web3._extend.formatters.formatInputString], + outputFormatter: web3._extend.formatters.formatOutputString + }), + new web3._extend.Method({ + name: 'putHex', + call: 'db_putHex', + params: 3, + inputFormatter: [web3._extend.formatters.formatInputString, web3._extend.formatters.formatInputString, web3._extend.formatters.formatInputString], + outputFormatter: web3._extend.formatters.formatOutputBool + }), + ], + properties: + [ + ] +}); +` diff --git a/rpc/api/debug.go b/rpc/api/debug.go index 5b6a449dc..b451d8662 100644 --- a/rpc/api/debug.go +++ b/rpc/api/debug.go @@ -71,7 +71,7 @@ func (self *debugApi) Execute(req *shared.Request) (interface{}, error) { } func (self *debugApi) Name() string { - return DebugApiName + return shared.DebugApiName } func (self *debugApi) ApiVersion() string { diff --git a/rpc/api/eth.go b/rpc/api/eth.go index 66ee69930..0dff138c6 100644 --- a/rpc/api/eth.go +++ b/rpc/api/eth.go @@ -28,47 +28,49 @@ 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_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_sign": (*ethApi).Sign, - "eth_sendTransaction": (*ethApi).SendTransaction, - "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_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_accounts": (*ethApi).Accounts, + "eth_blockNumber": (*ethApi).BlockNumber, + "eth_getBalance": (*ethApi).GetBalance, + "eth_protocolVersion": (*ethApi).ProtocolVersion, + "eth_coinbase": (*ethApi).Coinbase, + "eth_mining": (*ethApi).IsMining, + "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_sign": (*ethApi).Sign, + "eth_sendRawTransaction": (*ethApi).SendRawTransaction, + "eth_sendTransaction": (*ethApi).SendTransaction, + "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, } ) @@ -98,7 +100,7 @@ func (self *ethApi) Execute(req *shared.Request) (interface{}, error) { } func (self *ethApi) Name() string { - return EthApiName + return shared.EthApiName } func (self *ethApi) ApiVersion() string { @@ -114,7 +116,8 @@ func (self *ethApi) Hashrate(req *shared.Request) (interface{}, error) { } func (self *ethApi) BlockNumber(req *shared.Request) (interface{}, error) { - return self.xeth.CurrentBlock().Number(), nil + num := self.xeth.CurrentBlock().Number() + return newHexNum(num.Bytes()), nil } func (self *ethApi) GetBalance(req *shared.Request) (interface{}, error) { @@ -247,6 +250,19 @@ func (self *ethApi) Sign(req *shared.Request) (interface{}, error) { return v, nil } +func (self *ethApi) SendRawTransaction(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 +} + func (self *ethApi) SendTransaction(req *shared.Request) (interface{}, error) { args := new(NewTxArgs) if err := self.codec.Decode(req.Params, &args); err != nil { diff --git a/rpc/api/eth_args.go b/rpc/api/eth_args.go index 1c86bee51..bf8ffead6 100644 --- a/rpc/api/eth_args.go +++ b/rpc/api/eth_args.go @@ -226,6 +226,35 @@ func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) { 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 @@ -437,21 +466,21 @@ func (args *CallArgs) UnmarshalJSON(b []byte) (err error) { } args.Value = num - if ext.Gas == nil { - num = big.NewInt(0) - } else { + if ext.Gas != nil { if num, err = numString(ext.Gas); err != nil { return err } + } else { + num = nil } args.Gas = num - if ext.GasPrice == nil { - num = big.NewInt(0) - } else { + if ext.GasPrice != nil { if num, err = numString(ext.GasPrice); err != nil { return err } + } else { + num = nil } args.GasPrice = num diff --git a/rpc/api/eth_js.go b/rpc/api/eth_js.go index f7630bdd5..e1268eb76 100644 --- a/rpc/api/eth_js.go +++ b/rpc/api/eth_js.go @@ -1,3 +1,20 @@ 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.formatters.formatInputString,web3._extend.formatters.formatInputString], + outputFormatter: web3._extend.formatters.formatOutputString + }) + ] +}); +` diff --git a/rpc/api/mergedapi.go b/rpc/api/mergedapi.go index b62477a14..bc4fa32e8 100644 --- a/rpc/api/mergedapi.go +++ b/rpc/api/mergedapi.go @@ -1,6 +1,8 @@ package api import ( + "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/rpc/shared" ) @@ -11,14 +13,14 @@ const ( // combines multiple API's type MergedApi struct { apis map[string]string - methods map[string]EthereumApi + methods map[string]shared.EthereumApi } // create new merged api instance -func newMergedApi(apis ...EthereumApi) *MergedApi { +func newMergedApi(apis ...shared.EthereumApi) *MergedApi { mergedApi := new(MergedApi) mergedApi.apis = make(map[string]string, len(apis)) - mergedApi.methods = make(map[string]EthereumApi) + mergedApi.methods = make(map[string]shared.EthereumApi) for _, api := range apis { mergedApi.apis[api.Name()] = api.ApiVersion() @@ -40,6 +42,8 @@ func (self *MergedApi) Methods() []string { // 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("rpc method: %s", req.Method) + if res, _ := self.handle(req); res != nil { return res, nil } @@ -50,7 +54,7 @@ func (self *MergedApi) Execute(req *shared.Request) (interface{}, error) { } func (self *MergedApi) Name() string { - return MergedApiName + return shared.MergedApiName } func (self *MergedApi) ApiVersion() string { diff --git a/rpc/api/mergedapi_js.go b/rpc/api/mergedapi_js.go deleted file mode 100644 index 778f64ec1..000000000 --- a/rpc/api/mergedapi_js.go +++ /dev/null @@ -1 +0,0 @@ -package api diff --git a/rpc/api/miner.go b/rpc/api/miner.go index 0b5e74f52..7a84cb9ae 100644 --- a/rpc/api/miner.go +++ b/rpc/api/miner.go @@ -66,7 +66,7 @@ func (self *minerApi) Methods() []string { } func (self *minerApi) Name() string { - return MinerApiName + return shared.MinerApiName } func (self *minerApi) ApiVersion() string { diff --git a/rpc/api/net.go b/rpc/api/net.go index d6888ee4a..761654661 100644 --- a/rpc/api/net.go +++ b/rpc/api/net.go @@ -63,7 +63,7 @@ func (self *netApi) Execute(req *shared.Request) (interface{}, error) { } func (self *netApi) Name() string { - return NetApiName + return shared.NetApiName } func (self *netApi) ApiVersion() string { @@ -77,7 +77,7 @@ func (self *netApi) Version(req *shared.Request) (interface{}, error) { // Number of connected peers func (self *netApi) PeerCount(req *shared.Request) (interface{}, error) { - return self.xeth.PeerCount(), nil + return newHexNum(self.xeth.PeerCount()), nil } func (self *netApi) IsListening(req *shared.Request) (interface{}, error) { diff --git a/rpc/api/personal.go b/rpc/api/personal.go index 7a6c91c82..b4a63ea7a 100644 --- a/rpc/api/personal.go +++ b/rpc/api/personal.go @@ -66,7 +66,7 @@ func (self *personalApi) Execute(req *shared.Request) (interface{}, error) { } func (self *personalApi) Name() string { - return PersonalApiName + return shared.PersonalApiName } func (self *personalApi) ApiVersion() string { diff --git a/rpc/api/shh.go b/rpc/api/shh.go index e83a7b22e..18a8fd15d 100644 --- a/rpc/api/shh.go +++ b/rpc/api/shh.go @@ -72,7 +72,7 @@ func (self *shhApi) Execute(req *shared.Request) (interface{}, error) { } func (self *shhApi) Name() string { - return ShhApiName + return shared.ShhApiName } func (self *shhApi) ApiVersion() string { diff --git a/rpc/api/txpool.go b/rpc/api/txpool.go index 64550bdaf..25ad6e9b2 100644 --- a/rpc/api/txpool.go +++ b/rpc/api/txpool.go @@ -60,7 +60,7 @@ func (self *txPoolApi) Execute(req *shared.Request) (interface{}, error) { } func (self *txPoolApi) Name() string { - return TxPoolApiName + return shared.TxPoolApiName } func (self *txPoolApi) ApiVersion() string { diff --git a/rpc/api/utils.go b/rpc/api/utils.go index 318d7c39b..6e4835de6 100644 --- a/rpc/api/utils.go +++ b/rpc/api/utils.go @@ -7,6 +7,7 @@ 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" ) @@ -23,6 +24,14 @@ var ( "chainSyncStatus", "setSolc", "datadir", + "startRPC", + "stopRPC", + }, + "db": []string{ + "getString", + "putString", + "getHex", + "putHex", }, "debug": []string{ "dumpBlock", @@ -51,6 +60,7 @@ var ( "getData", "getCode", "sign", + "sendRawTransaction", "sendTransaction", "transact", "estimateGas", @@ -122,33 +132,35 @@ var ( ) // Parse a comma separated API string to individual api's -func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth.Ethereum) ([]EthereumApi, error) { +func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth.Ethereum) ([]shared.EthereumApi, error) { if len(strings.TrimSpace(apistr)) == 0 { return nil, fmt.Errorf("Empty apistr provided") } names := strings.Split(apistr, ",") - apis := make([]EthereumApi, len(names)) + apis := make([]shared.EthereumApi, len(names)) for i, name := range names { switch strings.ToLower(strings.TrimSpace(name)) { - case AdminApiName: + case shared.AdminApiName: apis[i] = NewAdminApi(xeth, eth, codec) - case DebugApiName: + case shared.DebugApiName: apis[i] = NewDebugApi(xeth, eth, codec) - case EthApiName: + case shared.DbApiName: + apis[i] = NewDbApi(xeth, eth, codec) + case shared.EthApiName: apis[i] = NewEthApi(xeth, codec) - case MinerApiName: + case shared.MinerApiName: apis[i] = NewMinerApi(eth, codec) - case NetApiName: + case shared.NetApiName: apis[i] = NewNetApi(xeth, eth, codec) - case ShhApiName: + case shared.ShhApiName: apis[i] = NewShhApi(xeth, eth, codec) - case TxPoolApiName: + case shared.TxPoolApiName: apis[i] = NewTxPoolApi(xeth, eth, codec) - case PersonalApiName: + case shared.PersonalApiName: apis[i] = NewPersonalApi(xeth, eth, codec) - case Web3ApiName: + case shared.Web3ApiName: apis[i] = NewWeb3Api(xeth, codec) default: return nil, fmt.Errorf("Unknown API '%s'", name) @@ -160,19 +172,23 @@ func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth. func Javascript(name string) string { switch strings.ToLower(strings.TrimSpace(name)) { - case AdminApiName: + case shared.AdminApiName: return Admin_JS - case DebugApiName: + case shared.DebugApiName: return Debug_JS - case MinerApiName: + case shared.DbApiName: + return Db_JS + case shared.EthApiName: + return Eth_JS + case shared.MinerApiName: return Miner_JS - case NetApiName: + case shared.NetApiName: return Net_JS - case ShhApiName: + case shared.ShhApiName: return Shh_JS - case TxPoolApiName: + case shared.TxPoolApiName: return TxPool_JS - case PersonalApiName: + case shared.PersonalApiName: return Personal_JS } diff --git a/rpc/api/web3.go b/rpc/api/web3.go index ed5008446..4c20baa25 100644 --- a/rpc/api/web3.go +++ b/rpc/api/web3.go @@ -60,7 +60,7 @@ func (self *web3Api) Execute(req *shared.Request) (interface{}, error) { } func (self *web3Api) Name() string { - return Web3ApiName + return shared.Web3ApiName } func (self *web3Api) ApiVersion() string { diff --git a/rpc/api/web3_args.go b/rpc/api/web3_args.go index 5455a6c8e..38af7191e 100644 --- a/rpc/api/web3_args.go +++ b/rpc/api/web3_args.go @@ -1,5 +1,29 @@ 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 +} |