Skip to content
Snippets Groups Projects
client.go 4.42 KiB
Newer Older
package client

import (
	"errors"
Silas Davis's avatar
Silas Davis committed
	core_types "github.com/eris-ltd/eris-db/core/types"
	rpc_types "github.com/eris-ltd/eris-db/rpc/tendermint/core/types"
Silas Davis's avatar
Silas Davis committed
	"github.com/eris-ltd/eris-db/txs"
Silas Davis's avatar
Silas Davis committed
	rpcclient "github.com/tendermint/go-rpc/client"
	"github.com/tendermint/go-wire"
Silas Davis's avatar
Silas Davis committed
func Status(client rpcclient.Client) (*rpc_types.ResultStatus, error) {
	res, err := performCall(client, "status")
	if err != nil {
		return nil, err
	}
Silas Davis's avatar
Silas Davis committed
	return res.(*rpc_types.ResultStatus), nil
}

func GenPrivAccount(client rpcclient.Client) (*acm.PrivAccount, error) {
	res, err := performCall(client, "unsafe/gen_priv_account")
	if err != nil {
		return nil, err
	}
Silas Davis's avatar
Silas Davis committed
	return res.(*rpc_types.ResultGenPrivAccount).PrivAccount, nil
func GetAccount(client rpcclient.Client, address []byte) (*acm.Account, error) {
	res, err := performCall(client, "get_account",
		"address", address)
	if err != nil {
		return nil, err
	}
Silas Davis's avatar
Silas Davis committed
	return res.(*rpc_types.ResultGetAccount).Account, nil
Silas Davis's avatar
Silas Davis committed
func SignTx(client rpcclient.Client, tx txs.Tx,
	privAccounts []*acm.PrivAccount) (txs.Tx, error) {
	res, err := performCall(client, "unsafe/sign_tx",
		"tx", wrappedTx{tx},
		"privAccounts", privAccounts)
	if err != nil {
		return nil, err
	}
Silas Davis's avatar
Silas Davis committed
	return res.(*rpc_types.ResultSignTx).Tx, nil
Silas Davis's avatar
Silas Davis committed
func BroadcastTx(client rpcclient.Client,
	tx txs.Tx) (txs.Receipt, error) {
	res, err := performCall(client, "broadcast_tx",
		"tx", wrappedTx{tx})
	if err != nil {
Silas Davis's avatar
Silas Davis committed
		return txs.Receipt{}, err
Silas Davis's avatar
Silas Davis committed
	receiptBytes := res.(*rpc_types.ResultBroadcastTx).Data
	receipt := txs.Receipt{}
	err = wire.ReadBinaryBytes(receiptBytes, &receipt)
	return receipt, err
Silas Davis's avatar
Silas Davis committed
func DumpStorage(client rpcclient.Client,
	address []byte) (*rpc_types.ResultDumpStorage, error) {
	res, err := performCall(client, "dump_storage",
		"address", address)
	if err != nil {
		return nil, err
	}
Silas Davis's avatar
Silas Davis committed
	return res.(*rpc_types.ResultDumpStorage), err
func GetStorage(client rpcclient.Client, address, key []byte) ([]byte, error) {
	res, err := performCall(client, "get_storage",
		"address", address,
		"key", key)
	if err != nil {
		return nil, err
	}
Silas Davis's avatar
Silas Davis committed
	return res.(*rpc_types.ResultGetStorage).Value, nil
func CallCode(client rpcclient.Client, fromAddress, code,
	data []byte) (*rpc_types.ResultCall, error) {
	res, err := performCall(client, "call_code",
		"fromAddress", fromAddress,
		"code", code,
		"data", data)
	if err != nil {
		return nil, err
	}
Silas Davis's avatar
Silas Davis committed
	return res.(*rpc_types.ResultCall), err
Silas Davis's avatar
Silas Davis committed
func Call(client rpcclient.Client, fromAddress, toAddress,
	data []byte) (*rpc_types.ResultCall, error) {
	res, err := performCall(client, "call",
		"fromAddress", fromAddress,
		"toAddress", toAddress,
		"data", data)
	if err != nil {
		return nil, err
	}
Silas Davis's avatar
Silas Davis committed
	return res.(*rpc_types.ResultCall), err
Silas Davis's avatar
Silas Davis committed
func GetName(client rpcclient.Client, name string) (*core_types.NameRegEntry, error) {
	res, err := performCall(client, "get_name",
		"name", name)
	if err != nil {
		return nil, err
	}
Silas Davis's avatar
Silas Davis committed
	return res.(*rpc_types.ResultGetName).Entry, nil

func BlockchainInfo(client rpcclient.Client, minHeight,
	maxHeight int) (*rpc_types.ResultBlockchainInfo, error) {
	res, err := performCall(client, "blockchain",
		"minHeight", minHeight,
		"maxHeight", maxHeight)
	if err != nil {
		return nil, err
	}
	return res.(*rpc_types.ResultBlockchainInfo), err
}

func performCall(client rpcclient.Client, method string,
	paramKeyVals ...interface{}) (res rpc_types.ErisDBResult, err error) {
	paramsMap, paramsSlice, err := mapAndValues(paramKeyVals...)
	if err != nil {
		return
	}
	switch cli := client.(type) {
	case *rpcclient.ClientJSONRPC:
		_, err = cli.Call(method, paramsSlice, &res)
	case *rpcclient.ClientURI:
		_, err = cli.Call(method, paramsMap, &res)
	}
	return
func mapAndValues(orderedKeyVals ...interface{}) (map[string]interface{},
	[]interface{}, error) {
	if len(orderedKeyVals)%2 != 0 {
		return nil, nil, fmt.Errorf("mapAndValues requires a even length list of"+
			" keys and values but got: %v (length %v)",
			orderedKeyVals, len(orderedKeyVals))
	}
	paramsMap := make(map[string]interface{})
	paramsSlice := make([]interface{}, len(orderedKeyVals)/2)
	for i := 0; i < len(orderedKeyVals); i += 2 {
		key, ok := orderedKeyVals[i].(string)
		if !ok {
			return nil, nil, errors.New("mapAndValues requires every even element" +
				" of orderedKeyVals to be a string key")
		}
		val := orderedKeyVals[i+1]
		paramsMap[key] = val
		paramsSlice[i/2] = val
	return paramsMap, paramsSlice, nil
}

type wrappedTx struct {
	txs.Tx `json:"unwrap"`
}