mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 14:16:44 +00:00
rpc: start supporting return type resolution
This commit is contained in:
parent
553d501df7
commit
6c775aed29
5 changed files with 470 additions and 193 deletions
|
|
@ -97,7 +97,10 @@ func (self *dbApi) GetString(req *shared.Request) (interface{}, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ret, err := self.xeth.DbGet([]byte(args.Database + args.Key))
|
ret, err := self.xeth.DbGet([]byte(args.Database + args.Key))
|
||||||
return string(ret), err
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return string(ret), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *dbApi) PutString(req *shared.Request) (interface{}, error) {
|
func (self *dbApi) PutString(req *shared.Request) (interface{}, error) {
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,10 @@ func (self *debugApi) GetBlockRlp(req *shared.Request) (interface{}, error) {
|
||||||
return nil, fmt.Errorf("block #%d not found", args.BlockNumber)
|
return nil, fmt.Errorf("block #%d not found", args.BlockNumber)
|
||||||
}
|
}
|
||||||
encoded, err := rlp.EncodeToBytes(block)
|
encoded, err := rlp.EncodeToBytes(block)
|
||||||
return fmt.Sprintf("%x", encoded), err
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%x", encoded), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *debugApi) SetHead(req *shared.Request) (interface{}, error) {
|
func (self *debugApi) SetHead(req *shared.Request) (interface{}, error) {
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,10 @@ func (self *personalApi) NewAccount(req *shared.Request) (interface{}, error) {
|
||||||
|
|
||||||
am := self.ethereum.AccountManager()
|
am := self.ethereum.AccountManager()
|
||||||
acc, err := am.NewAccount(args.Passphrase)
|
acc, err := am.NewAccount(args.Passphrase)
|
||||||
return acc.Address.Hex(), err
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return acc.Address.Hex(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *personalApi) UnlockAccount(req *shared.Request) (interface{}, error) {
|
func (self *personalApi) UnlockAccount(req *shared.Request) (interface{}, error) {
|
||||||
|
|
|
||||||
315
rpc/genapi.go
315
rpc/genapi.go
|
|
@ -42,8 +42,13 @@ type Admin struct {
|
||||||
xeth *Xeth
|
xeth *Xeth
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Admin) AddPeer(url string) (interface{}, error) {
|
func (self *Admin) AddPeer(url string) (result bool, failure error) {
|
||||||
return self.xeth.Call("admin_addPeer", []interface{}{url})
|
res, err := self.xeth.Call("admin_addPeer", []interface{}{url})
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(bool), nil
|
||||||
}
|
}
|
||||||
func (self *Admin) ChainSyncStatus() (interface{}, error) {
|
func (self *Admin) ChainSyncStatus() (interface{}, error) {
|
||||||
return self.xeth.Call("admin_chainSyncStatus", nil)
|
return self.xeth.Call("admin_chainSyncStatus", nil)
|
||||||
|
|
@ -51,20 +56,40 @@ func (self *Admin) ChainSyncStatus() (interface{}, error) {
|
||||||
func (self *Admin) Datadir() (interface{}, error) {
|
func (self *Admin) Datadir() (interface{}, error) {
|
||||||
return self.xeth.Call("admin_datadir", nil)
|
return self.xeth.Call("admin_datadir", nil)
|
||||||
}
|
}
|
||||||
func (self *Admin) EnableUserAgent() (interface{}, error) {
|
func (self *Admin) EnableUserAgent() (result bool, failure error) {
|
||||||
return self.xeth.Call("admin_enableUserAgent", nil)
|
res, err := self.xeth.Call("admin_enableUserAgent", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(bool), nil
|
||||||
}
|
}
|
||||||
func (self *Admin) ExportChain() (interface{}, error) {
|
func (self *Admin) ExportChain() (result bool, failure error) {
|
||||||
return self.xeth.Call("admin_exportChain", nil)
|
res, err := self.xeth.Call("admin_exportChain", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(bool), nil
|
||||||
}
|
}
|
||||||
func (self *Admin) GetContractInfo(contract string) (interface{}, error) {
|
func (self *Admin) GetContractInfo(contract string) (interface{}, error) {
|
||||||
return self.xeth.Call("admin_getContractInfo", []interface{}{contract})
|
return self.xeth.Call("admin_getContractInfo", []interface{}{contract})
|
||||||
}
|
}
|
||||||
func (self *Admin) HttpGet(uri string, path string) (interface{}, error) {
|
func (self *Admin) HttpGet(uri string, path string) (result string, failure error) {
|
||||||
return self.xeth.Call("admin_httpGet", []interface{}{uri, path})
|
res, err := self.xeth.Call("admin_httpGet", []interface{}{uri, path})
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(string), nil
|
||||||
}
|
}
|
||||||
func (self *Admin) ImportChain() (interface{}, error) {
|
func (self *Admin) ImportChain() (result bool, failure error) {
|
||||||
return self.xeth.Call("admin_importChain", nil)
|
res, err := self.xeth.Call("admin_importChain", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(bool), nil
|
||||||
}
|
}
|
||||||
func (self *Admin) NodeInfo() (interface{}, error) {
|
func (self *Admin) NodeInfo() (interface{}, error) {
|
||||||
return self.xeth.Call("admin_nodeInfo", nil)
|
return self.xeth.Call("admin_nodeInfo", nil)
|
||||||
|
|
@ -72,11 +97,21 @@ func (self *Admin) NodeInfo() (interface{}, error) {
|
||||||
func (self *Admin) Peers() (interface{}, error) {
|
func (self *Admin) Peers() (interface{}, error) {
|
||||||
return self.xeth.Call("admin_peers", nil)
|
return self.xeth.Call("admin_peers", nil)
|
||||||
}
|
}
|
||||||
func (self *Admin) Register(sender string, address string, contentHashHex string) (interface{}, error) {
|
func (self *Admin) Register(sender string, address string, contentHashHex string) (result bool, failure error) {
|
||||||
return self.xeth.Call("admin_register", []interface{}{sender, address, contentHashHex})
|
res, err := self.xeth.Call("admin_register", []interface{}{sender, address, contentHashHex})
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(bool), nil
|
||||||
}
|
}
|
||||||
func (self *Admin) RegisterUrl(sender string, contentHash string, url string) (interface{}, error) {
|
func (self *Admin) RegisterUrl(sender string, contentHash string, url string) (result bool, failure error) {
|
||||||
return self.xeth.Call("admin_registerUrl", []interface{}{sender, contentHash, url})
|
res, err := self.xeth.Call("admin_registerUrl", []interface{}{sender, contentHash, url})
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(bool), nil
|
||||||
}
|
}
|
||||||
func (self *Admin) SaveInfo(contractInfo compiler.ContractInfo, filename string) (interface{}, error) {
|
func (self *Admin) SaveInfo(contractInfo compiler.ContractInfo, filename string) (interface{}, error) {
|
||||||
return self.xeth.Call("admin_saveInfo", []interface{}{contractInfo, filename})
|
return self.xeth.Call("admin_saveInfo", []interface{}{contractInfo, filename})
|
||||||
|
|
@ -99,20 +134,45 @@ func (self *Admin) Sleep(s int) (interface{}, error) {
|
||||||
func (self *Admin) SleepBlocks(n int64, timeout int64) (interface{}, error) {
|
func (self *Admin) SleepBlocks(n int64, timeout int64) (interface{}, error) {
|
||||||
return self.xeth.Call("admin_sleepBlocks", []interface{}{n, timeout})
|
return self.xeth.Call("admin_sleepBlocks", []interface{}{n, timeout})
|
||||||
}
|
}
|
||||||
func (self *Admin) StartNatSpec() (interface{}, error) {
|
func (self *Admin) StartNatSpec() (result bool, failure error) {
|
||||||
return self.xeth.Call("admin_startNatSpec", nil)
|
res, err := self.xeth.Call("admin_startNatSpec", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(bool), nil
|
||||||
}
|
}
|
||||||
func (self *Admin) StartRPC(listenAddress string, listenPort uint, corsDomain string, apis string) (interface{}, error) {
|
func (self *Admin) StartRPC(listenAddress string, listenPort uint, corsDomain string, apis string) (result bool, failure error) {
|
||||||
return self.xeth.Call("admin_startRPC", []interface{}{listenAddress, listenPort, corsDomain, apis})
|
res, err := self.xeth.Call("admin_startRPC", []interface{}{listenAddress, listenPort, corsDomain, apis})
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(bool), nil
|
||||||
}
|
}
|
||||||
func (self *Admin) StopNatSpec() (interface{}, error) {
|
func (self *Admin) StopNatSpec() (result bool, failure error) {
|
||||||
return self.xeth.Call("admin_stopNatSpec", nil)
|
res, err := self.xeth.Call("admin_stopNatSpec", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(bool), nil
|
||||||
}
|
}
|
||||||
func (self *Admin) StopRPC() (interface{}, error) {
|
func (self *Admin) StopRPC() (result bool, failure error) {
|
||||||
return self.xeth.Call("admin_stopRPC", nil)
|
res, err := self.xeth.Call("admin_stopRPC", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(bool), nil
|
||||||
}
|
}
|
||||||
func (self *Admin) Verbosity(level int) (interface{}, error) {
|
func (self *Admin) Verbosity(level int) (result bool, failure error) {
|
||||||
return self.xeth.Call("admin_verbosity", []interface{}{level})
|
res, err := self.xeth.Call("admin_verbosity", []interface{}{level})
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(bool), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Db struct {
|
type Db struct {
|
||||||
|
|
@ -122,8 +182,13 @@ type Db struct {
|
||||||
func (self *Db) GetHex() (interface{}, error) {
|
func (self *Db) GetHex() (interface{}, error) {
|
||||||
return self.xeth.Call("db_getHex", nil)
|
return self.xeth.Call("db_getHex", nil)
|
||||||
}
|
}
|
||||||
func (self *Db) GetString() (interface{}, error) {
|
func (self *Db) GetString() (result string, failure error) {
|
||||||
return self.xeth.Call("db_getString", nil)
|
res, err := self.xeth.Call("db_getString", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(string), nil
|
||||||
}
|
}
|
||||||
func (self *Db) PutHex() (interface{}, error) {
|
func (self *Db) PutHex() (interface{}, error) {
|
||||||
return self.xeth.Call("db_putHex", nil)
|
return self.xeth.Call("db_putHex", nil)
|
||||||
|
|
@ -148,8 +213,13 @@ func (self *Debug) Metrics(raw bool) (interface{}, error) {
|
||||||
func (self *Debug) PrintBlock() (interface{}, error) {
|
func (self *Debug) PrintBlock() (interface{}, error) {
|
||||||
return self.xeth.Call("debug_printBlock", nil)
|
return self.xeth.Call("debug_printBlock", nil)
|
||||||
}
|
}
|
||||||
func (self *Debug) ProcessBlock() (interface{}, error) {
|
func (self *Debug) ProcessBlock() (result bool, failure error) {
|
||||||
return self.xeth.Call("debug_processBlock", nil)
|
res, err := self.xeth.Call("debug_processBlock", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(bool), nil
|
||||||
}
|
}
|
||||||
func (self *Debug) SeedHash() (interface{}, error) {
|
func (self *Debug) SeedHash() (interface{}, error) {
|
||||||
return self.xeth.Call("debug_seedHash", nil)
|
return self.xeth.Call("debug_seedHash", nil)
|
||||||
|
|
@ -165,8 +235,13 @@ type Eth struct {
|
||||||
func (self *Eth) Accounts() (interface{}, error) {
|
func (self *Eth) Accounts() (interface{}, error) {
|
||||||
return self.xeth.Call("eth_accounts", nil)
|
return self.xeth.Call("eth_accounts", nil)
|
||||||
}
|
}
|
||||||
func (self *Eth) BlockNumber() (interface{}, error) {
|
func (self *Eth) BlockNumber() (result int64, failure error) {
|
||||||
return self.xeth.Call("eth_blockNumber", nil)
|
res, err := self.xeth.Call("eth_blockNumber", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return new(big.Int).SetBytes(common.FromHex(res.(string))).Int64(), nil
|
||||||
}
|
}
|
||||||
func (self *Eth) Call(from string, to string, value *big.Int, gas *big.Int, gasPrice *big.Int, data string, blockNumber int64) (interface{}, error) {
|
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})
|
return self.xeth.Call("eth_call", []interface{}{from, to, value, gas, gasPrice, data, blockNumber})
|
||||||
|
|
@ -177,14 +252,24 @@ func (self *Eth) Coinbase() (interface{}, error) {
|
||||||
func (self *Eth) CompileSolidity() (interface{}, error) {
|
func (self *Eth) CompileSolidity() (interface{}, error) {
|
||||||
return self.xeth.Call("eth_compileSolidity", nil)
|
return self.xeth.Call("eth_compileSolidity", nil)
|
||||||
}
|
}
|
||||||
func (self *Eth) EstimateGas() (interface{}, error) {
|
func (self *Eth) EstimateGas() (result int64, failure error) {
|
||||||
return self.xeth.Call("eth_estimateGas", nil)
|
res, err := self.xeth.Call("eth_estimateGas", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return new(big.Int).SetBytes(common.FromHex(res.(string))).Int64(), nil
|
||||||
}
|
}
|
||||||
func (self *Eth) Flush() (interface{}, error) {
|
func (self *Eth) Flush() (interface{}, error) {
|
||||||
return self.xeth.Call("eth_flush", nil)
|
return self.xeth.Call("eth_flush", nil)
|
||||||
}
|
}
|
||||||
func (self *Eth) GasPrice(price string) (interface{}, error) {
|
func (self *Eth) GasPrice(price string) (result int64, failure error) {
|
||||||
return self.xeth.Call("eth_gasPrice", []interface{}{price})
|
res, err := self.xeth.Call("eth_gasPrice", []interface{}{price})
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return new(big.Int).SetBytes(common.FromHex(res.(string))).Int64(), nil
|
||||||
}
|
}
|
||||||
func (self *Eth) GetBalance(address string, blockNumber int64) (interface{}, error) {
|
func (self *Eth) GetBalance(address string, blockNumber int64) (interface{}, error) {
|
||||||
return self.xeth.Call("eth_getBalance", []interface{}{address, blockNumber})
|
return self.xeth.Call("eth_getBalance", []interface{}{address, blockNumber})
|
||||||
|
|
@ -234,8 +319,13 @@ func (self *Eth) GetTransactionByBlockNumberAndIndex() (interface{}, error) {
|
||||||
func (self *Eth) GetTransactionByHash() (interface{}, error) {
|
func (self *Eth) GetTransactionByHash() (interface{}, error) {
|
||||||
return self.xeth.Call("eth_getTransactionByHash", nil)
|
return self.xeth.Call("eth_getTransactionByHash", nil)
|
||||||
}
|
}
|
||||||
func (self *Eth) GetTransactionCount() (interface{}, error) {
|
func (self *Eth) GetTransactionCount() (result int64, failure error) {
|
||||||
return self.xeth.Call("eth_getTransactionCount", nil)
|
res, err := self.xeth.Call("eth_getTransactionCount", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return new(big.Int).SetBytes(common.FromHex(res.(string))).Int64(), nil
|
||||||
}
|
}
|
||||||
func (self *Eth) GetTransactionReceipt() (interface{}, error) {
|
func (self *Eth) GetTransactionReceipt() (interface{}, error) {
|
||||||
return self.xeth.Call("eth_getTransactionReceipt", nil)
|
return self.xeth.Call("eth_getTransactionReceipt", nil)
|
||||||
|
|
@ -246,29 +336,59 @@ func (self *Eth) GetUncleByBlockHashAndIndex() (interface{}, error) {
|
||||||
func (self *Eth) GetUncleByBlockNumberAndIndex() (interface{}, error) {
|
func (self *Eth) GetUncleByBlockNumberAndIndex() (interface{}, error) {
|
||||||
return self.xeth.Call("eth_getUncleByBlockNumberAndIndex", nil)
|
return self.xeth.Call("eth_getUncleByBlockNumberAndIndex", nil)
|
||||||
}
|
}
|
||||||
func (self *Eth) GetUncleCountByBlockHash() (interface{}, error) {
|
func (self *Eth) GetUncleCountByBlockHash() (result int64, failure error) {
|
||||||
return self.xeth.Call("eth_getUncleCountByBlockHash", nil)
|
res, err := self.xeth.Call("eth_getUncleCountByBlockHash", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return new(big.Int).SetBytes(common.FromHex(res.(string))).Int64(), nil
|
||||||
}
|
}
|
||||||
func (self *Eth) GetUncleCountByBlockNumber() (interface{}, error) {
|
func (self *Eth) GetUncleCountByBlockNumber() (result int64, failure error) {
|
||||||
return self.xeth.Call("eth_getUncleCountByBlockNumber", nil)
|
res, err := self.xeth.Call("eth_getUncleCountByBlockNumber", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return new(big.Int).SetBytes(common.FromHex(res.(string))).Int64(), nil
|
||||||
}
|
}
|
||||||
func (self *Eth) GetWork() (interface{}, error) {
|
func (self *Eth) GetWork() (interface{}, error) {
|
||||||
return self.xeth.Call("eth_getWork", nil)
|
return self.xeth.Call("eth_getWork", nil)
|
||||||
}
|
}
|
||||||
func (self *Eth) Hashrate() (interface{}, error) {
|
func (self *Eth) Hashrate() (result int64, failure error) {
|
||||||
return self.xeth.Call("eth_hashrate", nil)
|
res, err := self.xeth.Call("eth_hashrate", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return new(big.Int).SetBytes(common.FromHex(res.(string))).Int64(), nil
|
||||||
}
|
}
|
||||||
func (self *Eth) Mining() (interface{}, error) {
|
func (self *Eth) Mining() (interface{}, error) {
|
||||||
return self.xeth.Call("eth_mining", nil)
|
return self.xeth.Call("eth_mining", nil)
|
||||||
}
|
}
|
||||||
func (self *Eth) NewBlockFilter() (interface{}, error) {
|
func (self *Eth) NewBlockFilter() (result int64, failure error) {
|
||||||
return self.xeth.Call("eth_newBlockFilter", nil)
|
res, err := self.xeth.Call("eth_newBlockFilter", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return new(big.Int).SetBytes(common.FromHex(res.(string))).Int64(), nil
|
||||||
}
|
}
|
||||||
func (self *Eth) NewFilter() (interface{}, error) {
|
func (self *Eth) NewFilter() (result int64, failure error) {
|
||||||
return self.xeth.Call("eth_newFilter", nil)
|
res, err := self.xeth.Call("eth_newFilter", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return new(big.Int).SetBytes(common.FromHex(res.(string))).Int64(), nil
|
||||||
}
|
}
|
||||||
func (self *Eth) NewPendingTransactionFilter() (interface{}, error) {
|
func (self *Eth) NewPendingTransactionFilter() (result int64, failure error) {
|
||||||
return self.xeth.Call("eth_newPendingTransactionFilter", nil)
|
res, err := self.xeth.Call("eth_newPendingTransactionFilter", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return new(big.Int).SetBytes(common.FromHex(res.(string))).Int64(), nil
|
||||||
}
|
}
|
||||||
func (self *Eth) PendingTransactions() (interface{}, error) {
|
func (self *Eth) PendingTransactions() (interface{}, error) {
|
||||||
return self.xeth.Call("eth_pendingTransactions", nil)
|
return self.xeth.Call("eth_pendingTransactions", nil)
|
||||||
|
|
@ -288,8 +408,13 @@ func (self *Eth) Sign() (interface{}, error) {
|
||||||
func (self *Eth) StorageAt(address string, blockNumber int64) (interface{}, error) {
|
func (self *Eth) StorageAt(address string, blockNumber int64) (interface{}, error) {
|
||||||
return self.xeth.Call("eth_storageAt", []interface{}{address, blockNumber})
|
return self.xeth.Call("eth_storageAt", []interface{}{address, blockNumber})
|
||||||
}
|
}
|
||||||
func (self *Eth) SubmitHashrate() (interface{}, error) {
|
func (self *Eth) SubmitHashrate() (result bool, failure error) {
|
||||||
return self.xeth.Call("eth_submitHashrate", nil)
|
res, err := self.xeth.Call("eth_submitHashrate", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(bool), nil
|
||||||
}
|
}
|
||||||
func (self *Eth) SubmitWork(nonce uint64, header string, digest string) (interface{}, error) {
|
func (self *Eth) SubmitWork(nonce uint64, header string, digest string) (interface{}, error) {
|
||||||
return self.xeth.Call("eth_submitWork", []interface{}{nonce, header, digest})
|
return self.xeth.Call("eth_submitWork", []interface{}{nonce, header, digest})
|
||||||
|
|
@ -308,29 +433,64 @@ type Miner struct {
|
||||||
func (self *Miner) Hashrate() (interface{}, error) {
|
func (self *Miner) Hashrate() (interface{}, error) {
|
||||||
return self.xeth.Call("miner_hashrate", nil)
|
return self.xeth.Call("miner_hashrate", nil)
|
||||||
}
|
}
|
||||||
func (self *Miner) MakeDAG(blockNumber int64) (interface{}, error) {
|
func (self *Miner) MakeDAG(blockNumber int64) (result bool, failure error) {
|
||||||
return self.xeth.Call("miner_makeDAG", []interface{}{blockNumber})
|
res, err := self.xeth.Call("miner_makeDAG", []interface{}{blockNumber})
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(bool), nil
|
||||||
}
|
}
|
||||||
func (self *Miner) SetEtherbase(etherbase common.Address) (interface{}, error) {
|
func (self *Miner) SetEtherbase(etherbase common.Address) (interface{}, error) {
|
||||||
return self.xeth.Call("miner_setEtherbase", []interface{}{etherbase})
|
return self.xeth.Call("miner_setEtherbase", []interface{}{etherbase})
|
||||||
}
|
}
|
||||||
func (self *Miner) SetExtra(data string) (interface{}, error) {
|
func (self *Miner) SetExtra(data string) (result bool, failure error) {
|
||||||
return self.xeth.Call("miner_setExtra", []interface{}{data})
|
res, err := self.xeth.Call("miner_setExtra", []interface{}{data})
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(bool), nil
|
||||||
}
|
}
|
||||||
func (self *Miner) SetGasPrice() (interface{}, error) {
|
func (self *Miner) SetGasPrice() (result bool, failure error) {
|
||||||
return self.xeth.Call("miner_setGasPrice", nil)
|
res, err := self.xeth.Call("miner_setGasPrice", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(bool), nil
|
||||||
}
|
}
|
||||||
func (self *Miner) Start(threads int) (interface{}, error) {
|
func (self *Miner) Start(threads int) (result bool, failure error) {
|
||||||
return self.xeth.Call("miner_start", []interface{}{threads})
|
res, err := self.xeth.Call("miner_start", []interface{}{threads})
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(bool), nil
|
||||||
}
|
}
|
||||||
func (self *Miner) StartAutoDAG() (interface{}, error) {
|
func (self *Miner) StartAutoDAG() (result bool, failure error) {
|
||||||
return self.xeth.Call("miner_startAutoDAG", nil)
|
res, err := self.xeth.Call("miner_startAutoDAG", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(bool), nil
|
||||||
}
|
}
|
||||||
func (self *Miner) Stop() (interface{}, error) {
|
func (self *Miner) Stop() (result bool, failure error) {
|
||||||
return self.xeth.Call("miner_stop", nil)
|
res, err := self.xeth.Call("miner_stop", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(bool), nil
|
||||||
}
|
}
|
||||||
func (self *Miner) StopAutoDAG() (interface{}, error) {
|
func (self *Miner) StopAutoDAG() (result bool, failure error) {
|
||||||
return self.xeth.Call("miner_stopAutoDAG", nil)
|
res, err := self.xeth.Call("miner_stopAutoDAG", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(bool), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Net struct {
|
type Net struct {
|
||||||
|
|
@ -340,8 +500,13 @@ type Net struct {
|
||||||
func (self *Net) Listening() (interface{}, error) {
|
func (self *Net) Listening() (interface{}, error) {
|
||||||
return self.xeth.Call("net_listening", nil)
|
return self.xeth.Call("net_listening", nil)
|
||||||
}
|
}
|
||||||
func (self *Net) PeerCount() (interface{}, error) {
|
func (self *Net) PeerCount() (result int64, failure error) {
|
||||||
return self.xeth.Call("net_peerCount", nil)
|
res, err := self.xeth.Call("net_peerCount", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return new(big.Int).SetBytes(common.FromHex(res.(string))).Int64(), nil
|
||||||
}
|
}
|
||||||
func (self *Net) Version() (interface{}, error) {
|
func (self *Net) Version() (interface{}, error) {
|
||||||
return self.xeth.Call("net_version", nil)
|
return self.xeth.Call("net_version", nil)
|
||||||
|
|
@ -374,14 +539,24 @@ func (self *Shh) GetMessages() (interface{}, error) {
|
||||||
func (self *Shh) HasIdentity() (interface{}, error) {
|
func (self *Shh) HasIdentity() (interface{}, error) {
|
||||||
return self.xeth.Call("shh_hasIdentity", nil)
|
return self.xeth.Call("shh_hasIdentity", nil)
|
||||||
}
|
}
|
||||||
func (self *Shh) NewFilter() (interface{}, error) {
|
func (self *Shh) NewFilter() (result int64, failure error) {
|
||||||
return self.xeth.Call("shh_newFilter", nil)
|
res, err := self.xeth.Call("shh_newFilter", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return new(big.Int).SetBytes(common.FromHex(res.(string))).Int64(), nil
|
||||||
}
|
}
|
||||||
func (self *Shh) NewIdentity() (interface{}, error) {
|
func (self *Shh) NewIdentity() (interface{}, error) {
|
||||||
return self.xeth.Call("shh_newIdentity", nil)
|
return self.xeth.Call("shh_newIdentity", nil)
|
||||||
}
|
}
|
||||||
func (self *Shh) Post() (interface{}, error) {
|
func (self *Shh) Post() (result bool, failure error) {
|
||||||
return self.xeth.Call("shh_post", nil)
|
res, err := self.xeth.Call("shh_post", nil)
|
||||||
|
if err != nil {
|
||||||
|
failure = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.(bool), nil
|
||||||
}
|
}
|
||||||
func (self *Shh) UninstallFilter() (interface{}, error) {
|
func (self *Shh) UninstallFilter() (interface{}, error) {
|
||||||
return self.xeth.Call("shh_uninstallFilter", nil)
|
return self.xeth.Call("shh_uninstallFilter", nil)
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
@ -47,8 +48,8 @@ type Package struct {
|
||||||
type Endpoint struct {
|
type Endpoint struct {
|
||||||
Method string
|
Method string
|
||||||
Function string
|
Function string
|
||||||
Argument string
|
|
||||||
Params []string
|
Params []string
|
||||||
|
Return string
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
@ -57,130 +58,24 @@ func main() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to retrieve API package details: %v", err)
|
log.Fatalf("Failed to retrieve API package details: %v", err)
|
||||||
}
|
}
|
||||||
types, values, err := declarations(api)
|
funs, types, values, err := declarations(api)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to collect API declarations: %v", err)
|
log.Fatalf("Failed to collect API declarations: %v", err)
|
||||||
}
|
}
|
||||||
// Create the collectors for the submodules
|
// Gather all the deteced API endpoints
|
||||||
modules := []string{}
|
methods, err := endpoints(funs, types, values)
|
||||||
methods := make(map[string][]*Endpoint)
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to gather API endpoints: %v", err)
|
||||||
// Iterate over all the API mappings, and locate the RPC function associations
|
|
||||||
for variable, val := range values {
|
|
||||||
if strings.HasSuffix(variable, "Mapping") {
|
|
||||||
// Iterate over all the exposed functionality and extract them
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Insert the function to the submodule collection (alphabetically)
|
|
||||||
endpoint := &Endpoint{
|
|
||||||
Method: call,
|
|
||||||
Function: fmt.Sprintf("%s(%s)", function, strings.Join(params, ",")),
|
|
||||||
Argument: args,
|
|
||||||
Params: paramList,
|
|
||||||
}
|
|
||||||
for i := 0; i < len(methods[module]); i++ {
|
|
||||||
if methods[module][i].Function > endpoint.Function {
|
|
||||||
methods[module] = append(methods[module], nil)
|
|
||||||
copy(methods[module][i+1:], methods[module][i:])
|
|
||||||
methods[module][i] = endpoint
|
|
||||||
|
|
||||||
endpoint = nil
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if endpoint != nil {
|
|
||||||
methods[module] = append(methods[module], endpoint)
|
|
||||||
}
|
|
||||||
// Register the module if first occurance
|
|
||||||
if len(methods[module]) == 1 {
|
|
||||||
modules = append(modules, module)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
sort.Strings(modules)
|
// Generate the client API and output if successfull
|
||||||
|
if code, err := generate(methods); err != nil {
|
||||||
// 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(client comms.EthereumClient) *GenApi {\n")
|
|
||||||
client += fmt.Sprint("xeth := NewXeth(client)\n\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 := range modules {
|
|
||||||
endpoints := methods[module]
|
|
||||||
|
|
||||||
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)
|
log.Fatalf("Failed to format output code: %v", err)
|
||||||
} else if err := ioutil.WriteFile("../genapi.go", blob, 0600); err != nil {
|
} else if err := ioutil.WriteFile("../genapi.go", code, 0600); err != nil {
|
||||||
log.Fatalf("Failed to write output code: %v", err)
|
log.Fatalf("Failed to write output code: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loads the details of the Go package.
|
// details loads the metadata of the Go package.
|
||||||
func details(name string) (*Package, error) {
|
func details(name string) (*Package, error) {
|
||||||
// Create the command to retrieve the package infos
|
// Create the command to retrieve the package infos
|
||||||
cmd := exec.Command("go", "list", "-e", "-json", name)
|
cmd := exec.Command("go", "list", "-e", "-json", name)
|
||||||
|
|
@ -209,8 +104,9 @@ func details(name string) (*Package, error) {
|
||||||
return info, nil
|
return info, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterates over a package contents and collects interesting declarations.
|
// declarations iterates over a package contents and collects type and value declarations.
|
||||||
func declarations(pack *Package) (map[string]*ast.TypeSpec, map[string]ast.Expr, error) {
|
func declarations(pack *Package) (map[string]*ast.BlockStmt, map[string]*ast.TypeSpec, map[string]ast.Expr, error) {
|
||||||
|
funs := make(map[string]*ast.BlockStmt)
|
||||||
types := make(map[string]*ast.TypeSpec)
|
types := make(map[string]*ast.TypeSpec)
|
||||||
values := make(map[string]ast.Expr)
|
values := make(map[string]ast.Expr)
|
||||||
|
|
||||||
|
|
@ -219,11 +115,17 @@ func declarations(pack *Package) (map[string]*ast.TypeSpec, map[string]ast.Expr,
|
||||||
fileSet := token.NewFileSet()
|
fileSet := token.NewFileSet()
|
||||||
tree, err := parser.ParseFile(fileSet, filepath.Join(pack.Dir, path), nil, parser.ParseComments)
|
tree, err := parser.ParseFile(fileSet, filepath.Join(pack.Dir, path), nil, parser.ParseComments)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
// Collect all top level declarations
|
// Collect all top level declarations
|
||||||
for _, decl := range tree.Decls {
|
for _, decl := range tree.Decls {
|
||||||
switch decl := decl.(type) {
|
switch decl := decl.(type) {
|
||||||
|
case *ast.FuncDecl:
|
||||||
|
if decl.Recv != nil {
|
||||||
|
recv := decl.Recv.List[0].Type.(*ast.StarExpr).X.(*ast.Ident).String()
|
||||||
|
call := decl.Name.String()
|
||||||
|
funs[recv+"."+call] = decl.Body
|
||||||
|
}
|
||||||
case *ast.GenDecl:
|
case *ast.GenDecl:
|
||||||
for _, spec := range decl.Specs {
|
for _, spec := range decl.Specs {
|
||||||
switch spec := spec.(type) {
|
switch spec := spec.(type) {
|
||||||
|
|
@ -238,5 +140,196 @@ func declarations(pack *Package) (map[string]*ast.TypeSpec, map[string]ast.Expr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return types, values, nil
|
return funs, types, values, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns recursively iterates over a block statement and extracts all the
|
||||||
|
// return statements that contain nil errors.
|
||||||
|
func returns(block *ast.BlockStmt) []*ast.ReturnStmt {
|
||||||
|
results := []*ast.ReturnStmt{}
|
||||||
|
|
||||||
|
for _, stmt := range block.List {
|
||||||
|
switch stmt := stmt.(type) {
|
||||||
|
case *ast.ReturnStmt:
|
||||||
|
if ident, ok := stmt.Results[1].(*ast.Ident); ok {
|
||||||
|
if ident.String() == "nil" {
|
||||||
|
results = append(results, stmt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case *ast.IfStmt:
|
||||||
|
results = append(results, returns(stmt.Body)...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
// endpoints collects the detected RPC API method endpoints.
|
||||||
|
func endpoints(funs map[string]*ast.BlockStmt, types map[string]*ast.TypeSpec, values map[string]ast.Expr) (map[string][]*Endpoint, error) {
|
||||||
|
methods := 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") {
|
||||||
|
// Iterate over all the exposed functionality and extract them
|
||||||
|
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, "\"")
|
||||||
|
impl := mapping.(*ast.KeyValueExpr).Value.(*ast.SelectorExpr)
|
||||||
|
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:
|
||||||
|
return nil, fmt.Errorf("Unknown pointer subtype: %v", sub)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Unknown type: %v", t)
|
||||||
|
}
|
||||||
|
params = append(params, fmt.Sprintf("%s %s", variable, kind))
|
||||||
|
paramList = append(paramList, variable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Try to detect and generate the return type
|
||||||
|
owner := impl.X.(*ast.ParenExpr).X.(*ast.StarExpr).X.(*ast.Ident).String()
|
||||||
|
method := mapping.(*ast.KeyValueExpr).Value.(*ast.SelectorExpr).Sel.String()
|
||||||
|
rets := returns(funs[owner+"."+method])
|
||||||
|
|
||||||
|
result := "interface{}"
|
||||||
|
for _, ret := range rets {
|
||||||
|
res := ret.Results[0]
|
||||||
|
switch res := res.(type) {
|
||||||
|
case *ast.Ident:
|
||||||
|
if res.String() == "nil" {
|
||||||
|
break
|
||||||
|
} else if res.String() == "true" || res.String() == "false" {
|
||||||
|
result = "bool"
|
||||||
|
} else {
|
||||||
|
fmt.Println(owner, method, res, "unknown ident")
|
||||||
|
}
|
||||||
|
case *ast.CallExpr:
|
||||||
|
if ident, ok := res.Fun.(*ast.Ident); ok {
|
||||||
|
if ident.String() == "string" {
|
||||||
|
result = "string"
|
||||||
|
} else if ident.String() == "newHexNum" {
|
||||||
|
result = "int64"
|
||||||
|
} else {
|
||||||
|
fmt.Println(owner, method, res, "unknown ident funcion")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Println(owner, method, res, "call", res.Fun, reflect.TypeOf(res.Fun))
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
fmt.Println(owner, method, res, reflect.TypeOf(res))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Insert the function to the submodule collection (alphabetically)
|
||||||
|
methods[module] = append(methods[module], &Endpoint{
|
||||||
|
Method: call,
|
||||||
|
Function: fmt.Sprintf("%s(%s)", function, strings.Join(params, ",")),
|
||||||
|
Params: paramList,
|
||||||
|
Return: result,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return methods, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate creates the client code belonging to a set of API method endpoints.
|
||||||
|
func generate(methods map[string][]*Endpoint) ([]byte, error) {
|
||||||
|
// Create a sorted list of API modules and endpoints to generate
|
||||||
|
modules := make([]string, 0, len(methods))
|
||||||
|
for module, _ := range methods {
|
||||||
|
modules = append(modules, module)
|
||||||
|
}
|
||||||
|
sort.Strings(modules)
|
||||||
|
|
||||||
|
for _, module := range modules {
|
||||||
|
for i := 0; i < len(methods[module]); i++ {
|
||||||
|
for j := i + 1; j < len(methods[module]); j++ {
|
||||||
|
if methods[module][i].Function > methods[module][j].Function {
|
||||||
|
methods[module][i], methods[module][j] = methods[module][j], methods[module][i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 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(client comms.EthereumClient) *GenApi {\n")
|
||||||
|
client += fmt.Sprint("xeth := NewXeth(client)\n\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 := range modules {
|
||||||
|
endpoints := methods[module]
|
||||||
|
|
||||||
|
client += fmt.Sprintf("\ntype %s struct {\n xeth *Xeth\n}\n", module)
|
||||||
|
for _, endpoint := range endpoints {
|
||||||
|
// Generate the header (only add variables if conversions are required)
|
||||||
|
if endpoint.Return == "interface{}" {
|
||||||
|
client += fmt.Sprintf("func (self *%s) %s (interface{}, error) {\n", module, endpoint.Function)
|
||||||
|
} else {
|
||||||
|
client += fmt.Sprintf("func (self *%s) %s (result %s, failure error) {\n", module, endpoint.Function, endpoint.Return)
|
||||||
|
}
|
||||||
|
// Generate the actual function invocation (straight return if no return type is known)
|
||||||
|
invocation := fmt.Sprintf("self.xeth.Call(\"%s\", nil)", endpoint.Method)
|
||||||
|
if len(endpoint.Params) > 0 {
|
||||||
|
invocation = fmt.Sprintf("self.xeth.Call(\"%s\", []interface{}{%s})", endpoint.Method, strings.Join(endpoint.Params, ","))
|
||||||
|
}
|
||||||
|
if endpoint.Return == "interface{}" {
|
||||||
|
client += fmt.Sprintf("return %s\n", invocation)
|
||||||
|
} else {
|
||||||
|
client += fmt.Sprintf("res, err := %s\n", invocation)
|
||||||
|
}
|
||||||
|
// If conversions are needed, check for errors and post process
|
||||||
|
if endpoint.Return != "interface{}" {
|
||||||
|
client += fmt.Sprintf("if err != nil { failure = err; return; }\n")
|
||||||
|
|
||||||
|
if endpoint.Return == "int64" {
|
||||||
|
client += fmt.Sprintf("return new(big.Int).SetBytes(common.FromHex(res.(string))).Int64(), nil\n")
|
||||||
|
} else {
|
||||||
|
client += fmt.Sprintf("return res.(%s), nil\n", endpoint.Return)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
client += fmt.Sprintf("}\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Format the final code and return
|
||||||
|
return imports.Process("", []byte(client), nil)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue