diff options
Diffstat (limited to 'rpc/packages.go')
-rw-r--r-- | rpc/packages.go | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/rpc/packages.go b/rpc/packages.go new file mode 100644 index 000000000..5d17a0f90 --- /dev/null +++ b/rpc/packages.go @@ -0,0 +1,212 @@ +/* + This file is part of go-ethereum + + go-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + go-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. +*/ +/* + +For each request type, define the following: + +1. RpcRequest "To" method [message.go], which does basic validation and conversion to "Args" type via json.Decoder() +2. json.Decoder() calls "UnmarshalON" defined on each "Args" struct +3. EthereumApi method, taking the "Args" type and replying with an interface to be marshalled to ON + +*/ +package rpc + +import ( + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/ethutil" + "github.com/ethereum/go-ethereum/xeth" +) + +type RpcServer interface { + Start() + Stop() +} + +func NewEthereumApi(xeth *xeth.XEth) *EthereumApi { + return &EthereumApi{xeth: xeth} +} + +type EthereumApi struct { + xeth *xeth.XEth +} + +func (p *EthereumApi) GetBlock(args *GetBlockArgs, reply *interface{}) error { + err := args.requirements() + if err != nil { + return err + } + + if args.BlockNumber > 0 { + *reply = p.xeth.BlockByNumber(args.BlockNumber) + } else { + *reply = p.xeth.BlockByHash(args.Hash) + } + return nil +} + +func (p *EthereumApi) Transact(args *NewTxArgs, reply *interface{}) error { + err := args.requirements() + if err != nil { + return err + } + result, _ := p.xeth.Transact( /* TODO specify account */ args.Recipient, args.Value, args.Gas, args.GasPrice, args.Body) + *reply = result + return nil +} + +func (p *EthereumApi) Create(args *NewTxArgs, reply *interface{}) error { + err := args.requirementsContract() + if err != nil { + return err + } + + result, _ := p.xeth.Transact( /* TODO specify account */ "", args.Value, args.Gas, args.GasPrice, args.Body) + *reply = result + return nil +} + +func (p *EthereumApi) PushTx(args *PushTxArgs, reply *interface{}) error { + err := args.requirementsPushTx() + if err != nil { + return err + } + result, _ := p.xeth.PushTx(args.Tx) + *reply = result + return nil +} + +func (p *EthereumApi) GetStorageAt(args *GetStorageArgs, reply *interface{}) error { + err := args.requirements() + if err != nil { + return err + } + + state := p.xeth.State().SafeGet(args.Address) + + var hx string + if strings.Index(args.Key, "0x") == 0 { + hx = string([]byte(args.Key)[2:]) + } else { + // Convert the incoming string (which is a bigint) into hex + i, _ := new(big.Int).SetString(args.Key, 10) + hx = ethutil.Bytes2Hex(i.Bytes()) + } + rpclogger.Debugf("GetStorageAt(%s, %s)\n", args.Address, hx) + value := state.Storage(ethutil.Hex2Bytes(hx)) + *reply = GetStorageAtRes{Address: args.Address, Key: args.Key, Value: value.Str()} + return nil +} + +func (p *EthereumApi) GetPeerCount(reply *interface{}) error { + *reply = p.xeth.PeerCount() + return nil +} + +func (p *EthereumApi) GetIsListening(reply *interface{}) error { + *reply = p.xeth.IsListening() + return nil +} + +func (p *EthereumApi) GetCoinbase(reply *interface{}) error { + *reply = p.xeth.Coinbase() + return nil +} + +func (p *EthereumApi) GetIsMining(reply *interface{}) error { + *reply = p.xeth.IsMining() + return nil +} + +func (p *EthereumApi) GetTxCountAt(args *GetTxCountArgs, reply *interface{}) error { + err := args.requirements() + if err != nil { + return err + } + *reply = p.xeth.TxCountAt(args.Address) + return nil +} + +func (p *EthereumApi) GetBalanceAt(args *GetBalanceArgs, reply *interface{}) error { + err := args.requirements() + if err != nil { + return err + } + state := p.xeth.State().SafeGet(args.Address) + *reply = BalanceRes{Balance: state.Balance().String(), Address: args.Address} + return nil +} + +func (p *EthereumApi) GetCodeAt(args *GetCodeAtArgs, reply *interface{}) error { + err := args.requirements() + if err != nil { + return err + } + *reply = p.xeth.CodeAt(args.Address) + return nil +} + +func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error { + // Spec at https://github.com/ethereum/wiki/wiki/Generic-ON-RPC + rpclogger.DebugDetailf("%T %s", req.Params, req.Params) + switch req.Method { + case "eth_coinbase": + return p.GetCoinbase(reply) + case "eth_listening": + return p.GetIsListening(reply) + case "eth_mining": + return p.GetIsMining(reply) + case "eth_peerCount": + return p.GetPeerCount(reply) + case "eth_countAt": + args, err := req.ToGetTxCountArgs() + if err != nil { + return err + } + return p.GetTxCountAt(args, reply) + case "eth_codeAt": + args, err := req.ToGetCodeAtArgs() + if err != nil { + return err + } + return p.GetCodeAt(args, reply) + case "eth_balanceAt": + args, err := req.ToGetBalanceArgs() + if err != nil { + return err + } + return p.GetBalanceAt(args, reply) + case "eth_stateAt": + args, err := req.ToGetStorageArgs() + if err != nil { + return err + } + return p.GetStorageAt(args, reply) + case "eth_blockByNumber", "eth_blockByHash": + args, err := req.ToGetBlockArgs() + if err != nil { + return err + } + return p.GetBlock(args, reply) + default: + return NewErrorResponse(ErrorNotImplemented) + } + + rpclogger.DebugDetailf("Reply: %T %s", reply, reply) + return nil +} |