mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 22:26:42 +00:00
rpc: first version of an RPC over IPC API generator and API
This commit is contained in:
parent
6ec13e7e2b
commit
959bd21e75
4 changed files with 630 additions and 3 deletions
|
|
@ -165,7 +165,11 @@ func monitor(ctx *cli.Context) {
|
|||
// retrieveMetrics contacts the attached geth node and retrieves the entire set
|
||||
// of collected system metrics.
|
||||
func retrieveMetrics(xeth *rpc.Xeth) (map[string]interface{}, error) {
|
||||
return xeth.Call("debug_metrics", []interface{}{true})
|
||||
reply, err := xeth.Call("debug_metrics", []interface{}{true})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return reply.(map[string]interface{}), nil
|
||||
}
|
||||
|
||||
// resolveMetrics takes a list of input metric patterns, and resolves each to one
|
||||
|
|
|
|||
407
rpc/genapi.go
Normal file
407
rpc/genapi.go
Normal file
|
|
@ -0,0 +1,407 @@
|
|||
package rpc
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/compiler"
|
||||
)
|
||||
|
||||
type GenApi struct {
|
||||
Db *Db
|
||||
Miner *Miner
|
||||
Web3 *Web3
|
||||
Net *Net
|
||||
Personal *Personal
|
||||
Shh *Shh
|
||||
Admin *Admin
|
||||
Debug *Debug
|
||||
Txpool *Txpool
|
||||
Eth *Eth
|
||||
}
|
||||
|
||||
func NewGenApi(xeth *Xeth) *GenApi {
|
||||
return &GenApi{
|
||||
Net: &Net{xeth},
|
||||
Personal: &Personal{xeth},
|
||||
Shh: &Shh{xeth},
|
||||
Db: &Db{xeth},
|
||||
Miner: &Miner{xeth},
|
||||
Web3: &Web3{xeth},
|
||||
Debug: &Debug{xeth},
|
||||
Txpool: &Txpool{xeth},
|
||||
Eth: &Eth{xeth},
|
||||
Admin: &Admin{xeth},
|
||||
}
|
||||
}
|
||||
|
||||
type Net struct {
|
||||
xeth *Xeth
|
||||
}
|
||||
|
||||
func (self *Net) PeerCount() (interface{}, error) {
|
||||
return self.xeth.Call("net_peerCount", nil)
|
||||
}
|
||||
func (self *Net) Listening() (interface{}, error) {
|
||||
return self.xeth.Call("net_listening", nil)
|
||||
}
|
||||
func (self *Net) Version() (interface{}, error) {
|
||||
return self.xeth.Call("net_version", nil)
|
||||
}
|
||||
|
||||
type Personal struct {
|
||||
xeth *Xeth
|
||||
}
|
||||
|
||||
func (self *Personal) ListAccounts() (interface{}, error) {
|
||||
return self.xeth.Call("personal_listAccounts", nil)
|
||||
}
|
||||
func (self *Personal) NewAccount(passphrase string) (interface{}, error) {
|
||||
return self.xeth.Call("personal_newAccount", []interface{}{passphrase})
|
||||
}
|
||||
func (self *Personal) DeleteAccount(address string, passphrase string) (interface{}, error) {
|
||||
return self.xeth.Call("personal_deleteAccount", []interface{}{address, passphrase})
|
||||
}
|
||||
func (self *Personal) UnlockAccount(address string, passphrase string, duration int) (interface{}, error) {
|
||||
return self.xeth.Call("personal_unlockAccount", []interface{}{address, passphrase, duration})
|
||||
}
|
||||
|
||||
type Shh struct {
|
||||
xeth *Xeth
|
||||
}
|
||||
|
||||
func (self *Shh) Version() (interface{}, error) {
|
||||
return self.xeth.Call("shh_version", nil)
|
||||
}
|
||||
func (self *Shh) Post() (interface{}, error) {
|
||||
return self.xeth.Call("shh_post", nil)
|
||||
}
|
||||
func (self *Shh) HasIdentity() (interface{}, error) {
|
||||
return self.xeth.Call("shh_hasIdentity", nil)
|
||||
}
|
||||
func (self *Shh) NewIdentity() (interface{}, error) {
|
||||
return self.xeth.Call("shh_newIdentity", nil)
|
||||
}
|
||||
func (self *Shh) NewFilter() (interface{}, error) {
|
||||
return self.xeth.Call("shh_newFilter", nil)
|
||||
}
|
||||
func (self *Shh) UninstallFilter() (interface{}, error) {
|
||||
return self.xeth.Call("shh_uninstallFilter", nil)
|
||||
}
|
||||
func (self *Shh) GetFilterChanges() (interface{}, error) {
|
||||
return self.xeth.Call("shh_getFilterChanges", nil)
|
||||
}
|
||||
|
||||
type Db struct {
|
||||
xeth *Xeth
|
||||
}
|
||||
|
||||
func (self *Db) GetString() (interface{}, error) {
|
||||
return self.xeth.Call("db_getString", nil)
|
||||
}
|
||||
func (self *Db) PutString() (interface{}, error) {
|
||||
return self.xeth.Call("db_putString", nil)
|
||||
}
|
||||
func (self *Db) GetHex() (interface{}, error) {
|
||||
return self.xeth.Call("db_getHex", nil)
|
||||
}
|
||||
func (self *Db) PutHex() (interface{}, error) {
|
||||
return self.xeth.Call("db_putHex", nil)
|
||||
}
|
||||
|
||||
type Miner struct {
|
||||
xeth *Xeth
|
||||
}
|
||||
|
||||
func (self *Miner) Hashrate() (interface{}, error) {
|
||||
return self.xeth.Call("miner_hashrate", nil)
|
||||
}
|
||||
func (self *Miner) MakeDAG(blockNumber int64) (interface{}, error) {
|
||||
return self.xeth.Call("miner_makeDAG", []interface{}{blockNumber})
|
||||
}
|
||||
func (self *Miner) SetExtra(data string) (interface{}, error) {
|
||||
return self.xeth.Call("miner_setExtra", []interface{}{data})
|
||||
}
|
||||
func (self *Miner) SetGasPrice() (interface{}, error) {
|
||||
return self.xeth.Call("miner_setGasPrice", nil)
|
||||
}
|
||||
func (self *Miner) SetEtherbase(etherbase common.Address) (interface{}, error) {
|
||||
return self.xeth.Call("miner_setEtherbase", []interface{}{etherbase})
|
||||
}
|
||||
func (self *Miner) StartAutoDAG() (interface{}, error) {
|
||||
return self.xeth.Call("miner_startAutoDAG", nil)
|
||||
}
|
||||
func (self *Miner) Start(threads int) (interface{}, error) {
|
||||
return self.xeth.Call("miner_start", []interface{}{threads})
|
||||
}
|
||||
func (self *Miner) StopAutoDAG() (interface{}, error) {
|
||||
return self.xeth.Call("miner_stopAutoDAG", nil)
|
||||
}
|
||||
func (self *Miner) Stop() (interface{}, error) {
|
||||
return self.xeth.Call("miner_stop", nil)
|
||||
}
|
||||
|
||||
type Web3 struct {
|
||||
xeth *Xeth
|
||||
}
|
||||
|
||||
func (self *Web3) Sha3(data string) (interface{}, error) {
|
||||
return self.xeth.Call("web3_sha3", []interface{}{data})
|
||||
}
|
||||
func (self *Web3) ClientVersion() (interface{}, error) {
|
||||
return self.xeth.Call("web3_clientVersion", nil)
|
||||
}
|
||||
|
||||
type Debug struct {
|
||||
xeth *Xeth
|
||||
}
|
||||
|
||||
func (self *Debug) DumpBlock() (interface{}, error) {
|
||||
return self.xeth.Call("debug_dumpBlock", nil)
|
||||
}
|
||||
func (self *Debug) GetBlockRlp() (interface{}, error) {
|
||||
return self.xeth.Call("debug_getBlockRlp", nil)
|
||||
}
|
||||
func (self *Debug) PrintBlock() (interface{}, error) {
|
||||
return self.xeth.Call("debug_printBlock", nil)
|
||||
}
|
||||
func (self *Debug) ProcessBlock() (interface{}, error) {
|
||||
return self.xeth.Call("debug_processBlock", nil)
|
||||
}
|
||||
func (self *Debug) SeedHash() (interface{}, error) {
|
||||
return self.xeth.Call("debug_seedHash", nil)
|
||||
}
|
||||
func (self *Debug) SetHead() (interface{}, error) {
|
||||
return self.xeth.Call("debug_setHead", nil)
|
||||
}
|
||||
func (self *Debug) Metrics(raw bool) (interface{}, error) {
|
||||
return self.xeth.Call("debug_metrics", []interface{}{raw})
|
||||
}
|
||||
|
||||
type Txpool struct {
|
||||
xeth *Xeth
|
||||
}
|
||||
|
||||
func (self *Txpool) Status() (interface{}, error) {
|
||||
return self.xeth.Call("txpool_status", nil)
|
||||
}
|
||||
|
||||
type Eth struct {
|
||||
xeth *Xeth
|
||||
}
|
||||
|
||||
func (self *Eth) Accounts() (interface{}, error) {
|
||||
return self.xeth.Call("eth_accounts", nil)
|
||||
}
|
||||
func (self *Eth) BlockNumber() (interface{}, error) {
|
||||
return self.xeth.Call("eth_blockNumber", nil)
|
||||
}
|
||||
func (self *Eth) GetBalance(address string, blockNumber int64) (interface{}, error) {
|
||||
return self.xeth.Call("eth_getBalance", []interface{}{address, blockNumber})
|
||||
}
|
||||
func (self *Eth) ProtocolVersion() (interface{}, error) {
|
||||
return self.xeth.Call("eth_protocolVersion", nil)
|
||||
}
|
||||
func (self *Eth) Coinbase() (interface{}, error) {
|
||||
return self.xeth.Call("eth_coinbase", nil)
|
||||
}
|
||||
func (self *Eth) Mining() (interface{}, error) {
|
||||
return self.xeth.Call("eth_mining", nil)
|
||||
}
|
||||
func (self *Eth) GasPrice(price string) (interface{}, error) {
|
||||
return self.xeth.Call("eth_gasPrice", []interface{}{price})
|
||||
}
|
||||
func (self *Eth) GetStorage(address string, blockNumber int64) (interface{}, error) {
|
||||
return self.xeth.Call("eth_getStorage", []interface{}{address, blockNumber})
|
||||
}
|
||||
func (self *Eth) StorageAt(address string, blockNumber int64) (interface{}, error) {
|
||||
return self.xeth.Call("eth_storageAt", []interface{}{address, blockNumber})
|
||||
}
|
||||
func (self *Eth) GetStorageAt(address string, blockNumber int64, key string) (interface{}, error) {
|
||||
return self.xeth.Call("eth_getStorageAt", []interface{}{address, blockNumber, key})
|
||||
}
|
||||
func (self *Eth) GetTransactionCount() (interface{}, error) {
|
||||
return self.xeth.Call("eth_getTransactionCount", nil)
|
||||
}
|
||||
func (self *Eth) GetBlockTransactionCountByHash() (interface{}, error) {
|
||||
return self.xeth.Call("eth_getBlockTransactionCountByHash", nil)
|
||||
}
|
||||
func (self *Eth) GetBlockTransactionCountByNumber() (interface{}, error) {
|
||||
return self.xeth.Call("eth_getBlockTransactionCountByNumber", nil)
|
||||
}
|
||||
func (self *Eth) GetUncleCountByBlockHash() (interface{}, error) {
|
||||
return self.xeth.Call("eth_getUncleCountByBlockHash", nil)
|
||||
}
|
||||
func (self *Eth) GetUncleCountByBlockNumber() (interface{}, error) {
|
||||
return self.xeth.Call("eth_getUncleCountByBlockNumber", nil)
|
||||
}
|
||||
func (self *Eth) GetData(address string, blockNumber int64) (interface{}, error) {
|
||||
return self.xeth.Call("eth_getData", []interface{}{address, blockNumber})
|
||||
}
|
||||
func (self *Eth) GetCode(address string, blockNumber int64) (interface{}, error) {
|
||||
return self.xeth.Call("eth_getCode", []interface{}{address, blockNumber})
|
||||
}
|
||||
func (self *Eth) Sign() (interface{}, error) {
|
||||
return self.xeth.Call("eth_sign", nil)
|
||||
}
|
||||
func (self *Eth) SendRawTransaction() (interface{}, error) {
|
||||
return self.xeth.Call("eth_sendRawTransaction", nil)
|
||||
}
|
||||
func (self *Eth) SendTransaction() (interface{}, error) {
|
||||
return self.xeth.Call("eth_sendTransaction", nil)
|
||||
}
|
||||
func (self *Eth) Transact() (interface{}, error) {
|
||||
return self.xeth.Call("eth_transact", nil)
|
||||
}
|
||||
func (self *Eth) EstimateGas() (interface{}, error) {
|
||||
return self.xeth.Call("eth_estimateGas", nil)
|
||||
}
|
||||
func (self *Eth) Call(from string, to string, value *big.Int, gas *big.Int, gasPrice *big.Int, data string, blockNumber int64) (interface{}, error) {
|
||||
return self.xeth.Call("eth_call", []interface{}{from, to, value, gas, gasPrice, data, blockNumber})
|
||||
}
|
||||
func (self *Eth) Flush() (interface{}, error) {
|
||||
return self.xeth.Call("eth_flush", nil)
|
||||
}
|
||||
func (self *Eth) GetBlockByHash(blockHash string, includeTxs bool) (interface{}, error) {
|
||||
return self.xeth.Call("eth_getBlockByHash", []interface{}{blockHash, includeTxs})
|
||||
}
|
||||
func (self *Eth) GetBlockByNumber(blockNumber int64, includeTxs bool) (interface{}, error) {
|
||||
return self.xeth.Call("eth_getBlockByNumber", []interface{}{blockNumber, includeTxs})
|
||||
}
|
||||
func (self *Eth) GetTransactionByHash() (interface{}, error) {
|
||||
return self.xeth.Call("eth_getTransactionByHash", nil)
|
||||
}
|
||||
func (self *Eth) GetTransactionByBlockNumberAndIndex() (interface{}, error) {
|
||||
return self.xeth.Call("eth_getTransactionByBlockNumberAndIndex", nil)
|
||||
}
|
||||
func (self *Eth) GetTransactionByBlockHashAndIndex() (interface{}, error) {
|
||||
return self.xeth.Call("eth_getTransactionByBlockHashAndIndex", nil)
|
||||
}
|
||||
func (self *Eth) GetUncleByBlockHashAndIndex() (interface{}, error) {
|
||||
return self.xeth.Call("eth_getUncleByBlockHashAndIndex", nil)
|
||||
}
|
||||
func (self *Eth) GetUncleByBlockNumberAndIndex() (interface{}, error) {
|
||||
return self.xeth.Call("eth_getUncleByBlockNumberAndIndex", nil)
|
||||
}
|
||||
func (self *Eth) GetCompilers() (interface{}, error) {
|
||||
return self.xeth.Call("eth_getCompilers", nil)
|
||||
}
|
||||
func (self *Eth) CompileSolidity() (interface{}, error) {
|
||||
return self.xeth.Call("eth_compileSolidity", nil)
|
||||
}
|
||||
func (self *Eth) NewFilter() (interface{}, error) {
|
||||
return self.xeth.Call("eth_newFilter", nil)
|
||||
}
|
||||
func (self *Eth) NewBlockFilter() (interface{}, error) {
|
||||
return self.xeth.Call("eth_newBlockFilter", nil)
|
||||
}
|
||||
func (self *Eth) NewPendingTransactionFilter() (interface{}, error) {
|
||||
return self.xeth.Call("eth_newPendingTransactionFilter", nil)
|
||||
}
|
||||
func (self *Eth) UninstallFilter() (interface{}, error) {
|
||||
return self.xeth.Call("eth_uninstallFilter", nil)
|
||||
}
|
||||
func (self *Eth) GetFilterChanges() (interface{}, error) {
|
||||
return self.xeth.Call("eth_getFilterChanges", nil)
|
||||
}
|
||||
func (self *Eth) GetFilterLogs() (interface{}, error) {
|
||||
return self.xeth.Call("eth_getFilterLogs", nil)
|
||||
}
|
||||
func (self *Eth) GetLogs() (interface{}, error) {
|
||||
return self.xeth.Call("eth_getLogs", nil)
|
||||
}
|
||||
func (self *Eth) Hashrate() (interface{}, error) {
|
||||
return self.xeth.Call("eth_hashrate", nil)
|
||||
}
|
||||
func (self *Eth) GetWork() (interface{}, error) {
|
||||
return self.xeth.Call("eth_getWork", nil)
|
||||
}
|
||||
func (self *Eth) SubmitWork(nonce uint64, header string, digest string) (interface{}, error) {
|
||||
return self.xeth.Call("eth_submitWork", []interface{}{nonce, header, digest})
|
||||
}
|
||||
func (self *Eth) SubmitHashrate() (interface{}, error) {
|
||||
return self.xeth.Call("eth_submitHashrate", nil)
|
||||
}
|
||||
func (self *Eth) PendingTransactions() (interface{}, error) {
|
||||
return self.xeth.Call("eth_pendingTransactions", nil)
|
||||
}
|
||||
func (self *Eth) GetTransactionReceipt() (interface{}, error) {
|
||||
return self.xeth.Call("eth_getTransactionReceipt", nil)
|
||||
}
|
||||
|
||||
type Admin struct {
|
||||
xeth *Xeth
|
||||
}
|
||||
|
||||
func (self *Admin) AddPeer(url string) (interface{}, error) {
|
||||
return self.xeth.Call("admin_addPeer", []interface{}{url})
|
||||
}
|
||||
func (self *Admin) Peers() (interface{}, error) {
|
||||
return self.xeth.Call("admin_peers", nil)
|
||||
}
|
||||
func (self *Admin) NodeInfo() (interface{}, error) {
|
||||
return self.xeth.Call("admin_nodeInfo", nil)
|
||||
}
|
||||
func (self *Admin) ExportChain() (interface{}, error) {
|
||||
return self.xeth.Call("admin_exportChain", nil)
|
||||
}
|
||||
func (self *Admin) ImportChain() (interface{}, error) {
|
||||
return self.xeth.Call("admin_importChain", nil)
|
||||
}
|
||||
func (self *Admin) Verbosity(level int) (interface{}, error) {
|
||||
return self.xeth.Call("admin_verbosity", []interface{}{level})
|
||||
}
|
||||
func (self *Admin) ChainSyncStatus() (interface{}, error) {
|
||||
return self.xeth.Call("admin_chainSyncStatus", nil)
|
||||
}
|
||||
func (self *Admin) SetSolc(path string) (interface{}, error) {
|
||||
return self.xeth.Call("admin_setSolc", []interface{}{path})
|
||||
}
|
||||
func (self *Admin) Datadir() (interface{}, error) {
|
||||
return self.xeth.Call("admin_datadir", nil)
|
||||
}
|
||||
func (self *Admin) StartRPC(listenAddress string, listenPort uint, corsDomain string, apis string) (interface{}, error) {
|
||||
return self.xeth.Call("admin_startRPC", []interface{}{listenAddress, listenPort, corsDomain, apis})
|
||||
}
|
||||
func (self *Admin) StopRPC() (interface{}, error) {
|
||||
return self.xeth.Call("admin_stopRPC", nil)
|
||||
}
|
||||
func (self *Admin) SetGlobalRegistrar(nameReg string, contractAddress string) (interface{}, error) {
|
||||
return self.xeth.Call("admin_setGlobalRegistrar", []interface{}{nameReg, contractAddress})
|
||||
}
|
||||
func (self *Admin) SetHashReg(hashReg string, sender string) (interface{}, error) {
|
||||
return self.xeth.Call("admin_setHashReg", []interface{}{hashReg, sender})
|
||||
}
|
||||
func (self *Admin) SetUrlHint(urlHint string, sender string) (interface{}, error) {
|
||||
return self.xeth.Call("admin_setUrlHint", []interface{}{urlHint, sender})
|
||||
}
|
||||
func (self *Admin) SaveInfo(contractInfo compiler.ContractInfo, filename string) (interface{}, error) {
|
||||
return self.xeth.Call("admin_saveInfo", []interface{}{contractInfo, filename})
|
||||
}
|
||||
func (self *Admin) Register(sender string, address string, contentHashHex string) (interface{}, error) {
|
||||
return self.xeth.Call("admin_register", []interface{}{sender, address, contentHashHex})
|
||||
}
|
||||
func (self *Admin) RegisterUrl(sender string, contentHash string, url string) (interface{}, error) {
|
||||
return self.xeth.Call("admin_registerUrl", []interface{}{sender, contentHash, url})
|
||||
}
|
||||
func (self *Admin) StartNatSpec() (interface{}, error) {
|
||||
return self.xeth.Call("admin_startNatSpec", nil)
|
||||
}
|
||||
func (self *Admin) StopNatSpec() (interface{}, error) {
|
||||
return self.xeth.Call("admin_stopNatSpec", nil)
|
||||
}
|
||||
func (self *Admin) GetContractInfo(contract string) (interface{}, error) {
|
||||
return self.xeth.Call("admin_getContractInfo", []interface{}{contract})
|
||||
}
|
||||
func (self *Admin) HttpGet(uri string, path string) (interface{}, error) {
|
||||
return self.xeth.Call("admin_httpGet", []interface{}{uri, path})
|
||||
}
|
||||
func (self *Admin) SleepBlocks(n int64, timeout int64) (interface{}, error) {
|
||||
return self.xeth.Call("admin_sleepBlocks", []interface{}{n, timeout})
|
||||
}
|
||||
func (self *Admin) Sleep(s int) (interface{}, error) {
|
||||
return self.xeth.Call("admin_sleep", []interface{}{s})
|
||||
}
|
||||
func (self *Admin) EnableUserAgent() (interface{}, error) {
|
||||
return self.xeth.Call("admin_enableUserAgent", nil)
|
||||
}
|
||||
216
rpc/generator/generator.go
Normal file
216
rpc/generator/generator.go
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// This is the Go API auto-generator for the RPC APIs.
|
||||
package main //build !none
|
||||
|
||||
//go:generate go run generator.go
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"golang.org/x/tools/imports"
|
||||
)
|
||||
|
||||
// Package description from the go list command
|
||||
type Package struct {
|
||||
Name string
|
||||
Dir string
|
||||
GoFiles []string
|
||||
}
|
||||
|
||||
type Endpoint struct {
|
||||
Method string
|
||||
Function string
|
||||
Argument string
|
||||
Params []string
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Iterate over all the API files and collect the top level declarations
|
||||
api, err := details("github.com/ethereum/go-ethereum/rpc/api")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to retrieve API package details: %v", err)
|
||||
}
|
||||
types, values, err := declarations(api)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to collect API declarations: %v", err)
|
||||
}
|
||||
// Create the collectors for the sobmodules
|
||||
modules := make(map[string][]*Endpoint)
|
||||
|
||||
// Iterate over all the API mappings, and locate the RPC function associations
|
||||
for variable, val := range values {
|
||||
if strings.HasSuffix(variable, "Mapping") {
|
||||
for _, mapping := range val.(*ast.CompositeLit).Elts {
|
||||
// Fetch the name of the RPC function, and the associated argument definition
|
||||
call := strings.Trim(mapping.(*ast.KeyValueExpr).Key.(*ast.BasicLit).Value, "\"")
|
||||
args := mapping.(*ast.KeyValueExpr).Value.(*ast.SelectorExpr).Sel.Name + "Args"
|
||||
|
||||
// Generate the submodule and function names
|
||||
module := strings.Split(call, "_")[0]
|
||||
module = string(unicode.ToUpper(rune(module[0]))) + module[1:]
|
||||
function := strings.Split(call, "_")[1]
|
||||
function = string(unicode.ToUpper(rune(function[0]))) + function[1:]
|
||||
|
||||
// Generate the parameter list
|
||||
params, paramList := []string{}, []string{}
|
||||
if arg := types[args]; arg != nil {
|
||||
for _, field := range arg.Type.(*ast.StructType).Fields.List {
|
||||
variable := field.Names[0].String()
|
||||
variable = string(unicode.ToLower(rune(variable[0]))) + variable[1:]
|
||||
|
||||
kind := ""
|
||||
switch t := field.Type.(type) {
|
||||
case *ast.Ident:
|
||||
kind = t.String()
|
||||
case *ast.SelectorExpr:
|
||||
kind = t.X.(*ast.Ident).String() + "." + t.Sel.String()
|
||||
case *ast.StarExpr:
|
||||
switch sub := t.X.(type) {
|
||||
case *ast.Ident:
|
||||
kind = "*" + sub.String()
|
||||
case *ast.SelectorExpr:
|
||||
kind = "*" + sub.X.(*ast.Ident).String() + "." + sub.Sel.String()
|
||||
default:
|
||||
log.Fatalf("Unknown pointer subtype: %v", sub)
|
||||
}
|
||||
default:
|
||||
log.Fatalf("Unknown type: %v", t)
|
||||
}
|
||||
params = append(params, fmt.Sprintf("%s %s", variable, kind))
|
||||
paramList = append(paramList, variable)
|
||||
}
|
||||
}
|
||||
// Append the function to the sobmodule collection
|
||||
modules[module] = append(modules[module], &Endpoint{
|
||||
Method: call,
|
||||
Function: fmt.Sprintf("%s(%s)", function, strings.Join(params, ",")),
|
||||
Argument: args,
|
||||
Params: paramList,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
// Start generating the client API
|
||||
client := "package rpc\n"
|
||||
|
||||
// Generate the client struct with all its submodules
|
||||
client += fmt.Sprintf("type GenApi struct {\n")
|
||||
for module, _ := range modules {
|
||||
client += fmt.Sprintf("%s *%s\n", module, module)
|
||||
}
|
||||
client += fmt.Sprintf("}\n")
|
||||
|
||||
// Generate the API constructor to create the individual submodules
|
||||
client += fmt.Sprint("func NewGenApi(xeth *Xeth) *GenApi {\n")
|
||||
client += fmt.Sprint("return &GenApi{\n")
|
||||
for module, _ := range modules {
|
||||
client += fmt.Sprintf("%s: &%s{xeth},\n", module, module)
|
||||
}
|
||||
client += fmt.Sprintf("}}\n")
|
||||
|
||||
// Generate each of the client API calls
|
||||
for module, endpoints := range modules {
|
||||
client += fmt.Sprintf("\ntype %s struct {\n xeth *Xeth\n}\n", module)
|
||||
for _, endpoint := range endpoints {
|
||||
client += fmt.Sprintf("func (self *%s) %s (interface{}, error) {\n", module, endpoint.Function)
|
||||
if len(endpoint.Params) == 0 {
|
||||
client += fmt.Sprintf("return self.xeth.Call(\"%s\", nil)\n", endpoint.Method)
|
||||
} else {
|
||||
client += fmt.Sprintf("return self.xeth.Call(\"%s\", []interface{}{%s})\n", endpoint.Method, strings.Join(endpoint.Params, ","))
|
||||
}
|
||||
client += fmt.Sprintf("}\n")
|
||||
}
|
||||
}
|
||||
// Format the final code and output
|
||||
if blob, err := imports.Process("", []byte(client), nil); err != nil {
|
||||
log.Fatalf("Failed to format output code: %v", err)
|
||||
} else {
|
||||
fmt.Println(string(blob))
|
||||
}
|
||||
}
|
||||
|
||||
// Loads the details of the Go package.
|
||||
func details(name string) (*Package, error) {
|
||||
// Create the command to retrieve the package infos
|
||||
cmd := exec.Command("go", "list", "-e", "-json", name)
|
||||
|
||||
// Retrieve the output, redirect the errors
|
||||
out, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
// Start executing and parse the results
|
||||
if err := cmd.Start(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer cmd.Process.Kill()
|
||||
|
||||
info := new(Package)
|
||||
if err := json.NewDecoder(out).Decode(&info); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Clean up and return
|
||||
if err := cmd.Wait(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
|
||||
// Iterates over a package contents and collects interesting declarations.
|
||||
func declarations(pack *Package) (map[string]*ast.TypeSpec, map[string]ast.Expr, error) {
|
||||
types := make(map[string]*ast.TypeSpec)
|
||||
values := make(map[string]ast.Expr)
|
||||
|
||||
for _, path := range pack.GoFiles {
|
||||
// Parse the specified source file
|
||||
fileSet := token.NewFileSet()
|
||||
tree, err := parser.ParseFile(fileSet, filepath.Join(pack.Dir, path), nil, parser.ParseComments)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// Collect all top level declarations
|
||||
for _, decl := range tree.Decls {
|
||||
switch decl := decl.(type) {
|
||||
case *ast.GenDecl:
|
||||
for _, spec := range decl.Specs {
|
||||
switch spec := spec.(type) {
|
||||
case *ast.ValueSpec:
|
||||
for i, name := range spec.Names {
|
||||
values[name.String()] = spec.Values[i]
|
||||
}
|
||||
case *ast.TypeSpec:
|
||||
types[spec.Name.String()] = spec
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return types, values, nil
|
||||
}
|
||||
|
|
@ -41,7 +41,7 @@ func NewXeth(client comms.EthereumClient) *Xeth {
|
|||
}
|
||||
|
||||
// Call invokes a method with the given parameters are the remote node.
|
||||
func (self *Xeth) Call(method string, params []interface{}) (map[string]interface{}, error) {
|
||||
func (self *Xeth) Call(method string, params []interface{}) (interface{}, error) {
|
||||
// Assemble the json RPC request
|
||||
data, err := json.Marshal(params)
|
||||
if err != nil {
|
||||
|
|
@ -69,7 +69,7 @@ func (self *Xeth) Call(method string, params []interface{}) (map[string]interfac
|
|||
return nil, fmt.Errorf("Method invocation failed: %v", failure.Error)
|
||||
|
||||
case isSuccessResponse:
|
||||
return success.Result.(map[string]interface{}), nil
|
||||
return success.Result, nil
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("Invalid response type: %v", reflect.TypeOf(res))
|
||||
|
|
|
|||
Loading…
Reference in a new issue