aboutsummaryrefslogtreecommitdiffstats
path: root/rpc/api
diff options
context:
space:
mode:
Diffstat (limited to 'rpc/api')
-rw-r--r--rpc/api/admin.go95
-rw-r--r--rpc/api/admin_args.go52
-rw-r--r--rpc/api/admin_js.go14
-rw-r--r--rpc/api/api.go40
-rw-r--r--rpc/api/api_test.go111
-rw-r--r--rpc/api/args.go58
-rw-r--r--rpc/api/args_test.go2635
-rw-r--r--rpc/api/db.go128
-rw-r--r--rpc/api/db_args.go110
-rw-r--r--rpc/api/db_js.go41
-rw-r--r--rpc/api/debug.go2
-rw-r--r--rpc/api/eth.go102
-rw-r--r--rpc/api/eth_args.go41
-rw-r--r--rpc/api/eth_js.go17
-rw-r--r--rpc/api/mergedapi.go12
-rw-r--r--rpc/api/mergedapi_js.go1
-rw-r--r--rpc/api/miner.go2
-rw-r--r--rpc/api/net.go4
-rw-r--r--rpc/api/personal.go2
-rw-r--r--rpc/api/shh.go2
-rw-r--r--rpc/api/txpool.go2
-rw-r--r--rpc/api/utils.go52
-rw-r--r--rpc/api/web3.go2
-rw-r--r--rpc/api/web3_args.go24
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(&eth.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
+}