forked from TrueCloudLab/neoneo-go
rpc/client: only return the Result from calls, handle Error internally
Adjust structures accordingly and throw away most of them, they're useless.
This commit is contained in:
parent
28a26d2cae
commit
3fa9de764b
5 changed files with 52 additions and 72 deletions
|
@ -364,7 +364,7 @@ func invokeInternal(ctx *cli.Context, withMethod bool, signAndPush bool) error {
|
||||||
operation string
|
operation string
|
||||||
params = make([]smartcontract.Parameter, 0)
|
params = make([]smartcontract.Parameter, 0)
|
||||||
paramsStart = 1
|
paramsStart = 1
|
||||||
resp *response.InvokeScript
|
resp *response.InvokeResult
|
||||||
wif *keys.WIF
|
wif *keys.WIF
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -414,10 +414,10 @@ func invokeInternal(ctx *cli.Context, withMethod bool, signAndPush bool) error {
|
||||||
return cli.NewExitError(err, 1)
|
return cli.NewExitError(err, 1)
|
||||||
}
|
}
|
||||||
if signAndPush {
|
if signAndPush {
|
||||||
if len(resp.Result.Script) == 0 {
|
if len(resp.Script) == 0 {
|
||||||
return cli.NewExitError(errors.New("no script returned from the RPC node"), 1)
|
return cli.NewExitError(errors.New("no script returned from the RPC node"), 1)
|
||||||
}
|
}
|
||||||
script, err := hex.DecodeString(resp.Result.Script)
|
script, err := hex.DecodeString(resp.Script)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("bad script returned from the RPC node: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("bad script returned from the RPC node: %v", err), 1)
|
||||||
}
|
}
|
||||||
|
@ -427,7 +427,7 @@ func invokeInternal(ctx *cli.Context, withMethod bool, signAndPush bool) error {
|
||||||
}
|
}
|
||||||
fmt.Printf("Sent invocation transaction %s\n", txHash.StringLE())
|
fmt.Printf("Sent invocation transaction %s\n", txHash.StringLE())
|
||||||
} else {
|
} else {
|
||||||
b, err := json.MarshalIndent(resp.Result, "", " ")
|
b, err := json.MarshalIndent(resp, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
return cli.NewExitError(err, 1)
|
||||||
}
|
}
|
||||||
|
@ -464,7 +464,7 @@ func testInvokeScript(ctx *cli.Context) error {
|
||||||
return cli.NewExitError(err, 1)
|
return cli.NewExitError(err, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err = json.MarshalIndent(resp.Result, "", " ")
|
b, err = json.MarshalIndent(resp, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
return cli.NewExitError(err, 1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/core/transaction"
|
"github.com/CityOfZion/neo-go/pkg/core/transaction"
|
||||||
"github.com/CityOfZion/neo-go/pkg/crypto/keys"
|
"github.com/CityOfZion/neo-go/pkg/crypto/keys"
|
||||||
"github.com/CityOfZion/neo-go/pkg/rpc/request"
|
"github.com/CityOfZion/neo-go/pkg/rpc/request"
|
||||||
|
"github.com/CityOfZion/neo-go/pkg/rpc/response"
|
||||||
"github.com/CityOfZion/neo-go/pkg/util"
|
"github.com/CityOfZion/neo-go/pkg/util"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
@ -162,13 +163,10 @@ func (c *Client) CalculateInputs(address string, asset util.Uint256, cost util.F
|
||||||
var utxos state.UnspentBalances
|
var utxos state.UnspentBalances
|
||||||
|
|
||||||
resp, err := c.GetUnspents(address)
|
resp, err := c.GetUnspents(address)
|
||||||
if err != nil || resp.Error != nil {
|
if err != nil {
|
||||||
if err == nil {
|
|
||||||
err = fmt.Errorf("remote returned %d: %s", resp.Error.Code, resp.Error.Message)
|
|
||||||
}
|
|
||||||
return nil, util.Fixed8(0), errors.Wrapf(err, "cannot get balance for address %v", address)
|
return nil, util.Fixed8(0), errors.Wrapf(err, "cannot get balance for address %v", address)
|
||||||
}
|
}
|
||||||
for _, ubi := range resp.Result.Balance {
|
for _, ubi := range resp.Balance {
|
||||||
if asset.Equals(ubi.AssetHash) {
|
if asset.Equals(ubi.AssetHash) {
|
||||||
utxos = ubi.Unspents
|
utxos = ubi.Unspents
|
||||||
break
|
break
|
||||||
|
@ -187,6 +185,7 @@ func (c *Client) performRequest(method string, p request.RawParams, v interface{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
}
|
}
|
||||||
buf = new(bytes.Buffer)
|
buf = new(bytes.Buffer)
|
||||||
|
raw = &response.Raw{}
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := json.NewEncoder(buf).Encode(r); err != nil {
|
if err := json.NewEncoder(buf).Encode(r); err != nil {
|
||||||
|
@ -205,9 +204,17 @@ func (c *Client) performRequest(method string, p request.RawParams, v interface{
|
||||||
|
|
||||||
// The node might send us proper JSON anyway, so look there first and if
|
// The node might send us proper JSON anyway, so look there first and if
|
||||||
// it parses, then it has more relevant data than HTTP error code.
|
// it parses, then it has more relevant data than HTTP error code.
|
||||||
err = json.NewDecoder(resp.Body).Decode(v)
|
err = json.NewDecoder(resp.Body).Decode(raw)
|
||||||
if resp.StatusCode != http.StatusOK && err != nil {
|
if err == nil {
|
||||||
|
if raw.Error != nil {
|
||||||
|
err = raw.Error
|
||||||
|
} else {
|
||||||
|
err = json.Unmarshal(raw.Result, v)
|
||||||
|
}
|
||||||
|
} else if resp.StatusCode != http.StatusOK {
|
||||||
err = fmt.Errorf("HTTP %d/%s", resp.StatusCode, http.StatusText(resp.StatusCode))
|
err = fmt.Errorf("HTTP %d/%s", resp.StatusCode, http.StatusText(resp.StatusCode))
|
||||||
|
} else {
|
||||||
|
err = errors.Wrap(err, "JSON decoding")
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -2,13 +2,13 @@ package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/core"
|
"github.com/CityOfZion/neo-go/pkg/core"
|
||||||
"github.com/CityOfZion/neo-go/pkg/core/transaction"
|
"github.com/CityOfZion/neo-go/pkg/core/transaction"
|
||||||
"github.com/CityOfZion/neo-go/pkg/crypto/keys"
|
"github.com/CityOfZion/neo-go/pkg/crypto/keys"
|
||||||
"github.com/CityOfZion/neo-go/pkg/rpc/request"
|
"github.com/CityOfZion/neo-go/pkg/rpc/request"
|
||||||
"github.com/CityOfZion/neo-go/pkg/rpc/response"
|
"github.com/CityOfZion/neo-go/pkg/rpc/response"
|
||||||
|
"github.com/CityOfZion/neo-go/pkg/rpc/response/result"
|
||||||
"github.com/CityOfZion/neo-go/pkg/smartcontract"
|
"github.com/CityOfZion/neo-go/pkg/smartcontract"
|
||||||
"github.com/CityOfZion/neo-go/pkg/util"
|
"github.com/CityOfZion/neo-go/pkg/util"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
@ -32,10 +32,10 @@ import (
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// GetAccountState returns detailed information about a NEO account.
|
// GetAccountState returns detailed information about a NEO account.
|
||||||
func (c *Client) GetAccountState(address string) (*response.AccountState, error) {
|
func (c *Client) GetAccountState(address string) (*result.AccountState, error) {
|
||||||
var (
|
var (
|
||||||
params = request.NewRawParams(address)
|
params = request.NewRawParams(address)
|
||||||
resp = &response.AccountState{}
|
resp = &result.AccountState{}
|
||||||
)
|
)
|
||||||
if err := c.performRequest("getaccountstate", params, resp); err != nil {
|
if err := c.performRequest("getaccountstate", params, resp); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -44,10 +44,10 @@ func (c *Client) GetAccountState(address string) (*response.AccountState, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUnspents returns UTXOs for the given NEO account.
|
// GetUnspents returns UTXOs for the given NEO account.
|
||||||
func (c *Client) GetUnspents(address string) (*response.Unspent, error) {
|
func (c *Client) GetUnspents(address string) (*result.Unspents, error) {
|
||||||
var (
|
var (
|
||||||
params = request.NewRawParams(address)
|
params = request.NewRawParams(address)
|
||||||
resp = &response.Unspent{}
|
resp = &result.Unspents{}
|
||||||
)
|
)
|
||||||
if err := c.performRequest("getunspents", params, resp); err != nil {
|
if err := c.performRequest("getunspents", params, resp); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -57,10 +57,10 @@ func (c *Client) GetUnspents(address string) (*response.Unspent, error) {
|
||||||
|
|
||||||
// InvokeScript returns the result of the given script after running it true the VM.
|
// InvokeScript returns the result of the given script after running it true the VM.
|
||||||
// NOTE: This is a test invoke and will not affect the blockchain.
|
// NOTE: This is a test invoke and will not affect the blockchain.
|
||||||
func (c *Client) InvokeScript(script string) (*response.InvokeScript, error) {
|
func (c *Client) InvokeScript(script string) (*response.InvokeResult, error) {
|
||||||
var (
|
var (
|
||||||
params = request.NewRawParams(script)
|
params = request.NewRawParams(script)
|
||||||
resp = &response.InvokeScript{}
|
resp = &response.InvokeResult{}
|
||||||
)
|
)
|
||||||
if err := c.performRequest("invokescript", params, resp); err != nil {
|
if err := c.performRequest("invokescript", params, resp); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -71,10 +71,10 @@ func (c *Client) InvokeScript(script string) (*response.InvokeScript, error) {
|
||||||
// InvokeFunction returns the results after calling the smart contract scripthash
|
// InvokeFunction returns the results after calling the smart contract scripthash
|
||||||
// with the given operation and parameters.
|
// with the given operation and parameters.
|
||||||
// NOTE: this is test invoke and will not affect the blockchain.
|
// NOTE: this is test invoke and will not affect the blockchain.
|
||||||
func (c *Client) InvokeFunction(script, operation string, params []smartcontract.Parameter) (*response.InvokeScript, error) {
|
func (c *Client) InvokeFunction(script, operation string, params []smartcontract.Parameter) (*response.InvokeResult, error) {
|
||||||
var (
|
var (
|
||||||
p = request.NewRawParams(script, operation, params)
|
p = request.NewRawParams(script, operation, params)
|
||||||
resp = &response.InvokeScript{}
|
resp = &response.InvokeResult{}
|
||||||
)
|
)
|
||||||
if err := c.performRequest("invokefunction", p, resp); err != nil {
|
if err := c.performRequest("invokefunction", p, resp); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -84,10 +84,10 @@ func (c *Client) InvokeFunction(script, operation string, params []smartcontract
|
||||||
|
|
||||||
// Invoke returns the results after calling the smart contract scripthash
|
// Invoke returns the results after calling the smart contract scripthash
|
||||||
// with the given parameters.
|
// with the given parameters.
|
||||||
func (c *Client) Invoke(script string, params []smartcontract.Parameter) (*response.InvokeScript, error) {
|
func (c *Client) Invoke(script string, params []smartcontract.Parameter) (*response.InvokeResult, error) {
|
||||||
var (
|
var (
|
||||||
p = request.NewRawParams(script, params)
|
p = request.NewRawParams(script, params)
|
||||||
resp = &response.InvokeScript{}
|
resp = &response.InvokeResult{}
|
||||||
)
|
)
|
||||||
if err := c.performRequest("invoke", p, resp); err != nil {
|
if err := c.performRequest("invoke", p, resp); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -112,15 +112,18 @@ func (c *Client) Invoke(script string, params []smartcontract.Parameter) (*respo
|
||||||
// The given hex string needs to be signed with a keypair.
|
// The given hex string needs to be signed with a keypair.
|
||||||
// When the result of the response object is true, the TX has successfully
|
// When the result of the response object is true, the TX has successfully
|
||||||
// been broadcasted to the network.
|
// been broadcasted to the network.
|
||||||
func (c *Client) sendRawTransaction(rawTX *transaction.Transaction) (*response.SendRawTx, error) {
|
func (c *Client) sendRawTransaction(rawTX *transaction.Transaction) error {
|
||||||
var (
|
var (
|
||||||
params = request.NewRawParams(hex.EncodeToString(rawTX.Bytes()))
|
params = request.NewRawParams(hex.EncodeToString(rawTX.Bytes()))
|
||||||
resp = &response.SendRawTx{}
|
resp bool
|
||||||
)
|
)
|
||||||
if err := c.performRequest("sendrawtransaction", params, resp); err != nil {
|
if err := c.performRequest("sendrawtransaction", params, &resp); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
return resp, nil
|
if !resp {
|
||||||
|
return errors.New("sendrawtransaction returned false")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendToAddress sends an amount of specific asset to a given address.
|
// SendToAddress sends an amount of specific asset to a given address.
|
||||||
|
@ -137,21 +140,16 @@ func (c *Client) SendToAddress(asset util.Uint256, address string, amount util.F
|
||||||
WIF: c.WIF(),
|
WIF: c.WIF(),
|
||||||
Balancer: c.Balancer(),
|
Balancer: c.Balancer(),
|
||||||
}
|
}
|
||||||
respRaw *response.SendRawTx
|
resp util.Uint256
|
||||||
resp = util.Uint256{}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if rawTx, err = request.CreateRawContractTransaction(txParams); err != nil {
|
if rawTx, err = request.CreateRawContractTransaction(txParams); err != nil {
|
||||||
return resp, errors.Wrap(err, "failed to create raw transaction for `sendtoaddress`")
|
return resp, errors.Wrap(err, "failed to create raw transaction for `sendtoaddress`")
|
||||||
}
|
}
|
||||||
if respRaw, err = c.sendRawTransaction(rawTx); err != nil {
|
if err = c.sendRawTransaction(rawTx); err != nil {
|
||||||
return resp, errors.Wrap(err, "failed to send raw transaction")
|
return resp, errors.Wrap(err, "failed to send raw transaction")
|
||||||
}
|
}
|
||||||
if respRaw.Result {
|
|
||||||
return rawTx.Hash(), nil
|
return rawTx.Hash(), nil
|
||||||
} else {
|
|
||||||
return resp, errors.New("failed to send raw transaction")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignAndPushInvocationTx signs and pushes given script as an invocation
|
// SignAndPushInvocationTx signs and pushes given script as an invocation
|
||||||
|
@ -175,13 +173,10 @@ func (c *Client) SignAndPushInvocationTx(script []byte, wif *keys.WIF, gas util.
|
||||||
return txHash, errors.Wrap(err, "failed to sign tx")
|
return txHash, errors.Wrap(err, "failed to sign tx")
|
||||||
}
|
}
|
||||||
txHash = tx.Hash()
|
txHash = tx.Hash()
|
||||||
resp, err := c.sendRawTransaction(tx)
|
err = c.sendRawTransaction(tx)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return txHash, errors.Wrap(err, "failed sendning tx")
|
return txHash, errors.Wrap(err, "failed sendning tx")
|
||||||
}
|
}
|
||||||
if resp.Error != nil {
|
|
||||||
return txHash, fmt.Errorf("remote returned %d: %s", resp.Error.Code, resp.Error.Message)
|
|
||||||
}
|
|
||||||
return txHash, nil
|
return txHash, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,6 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/vm"
|
"github.com/CityOfZion/neo-go/pkg/vm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// InvokeScript stores response for the invoke script call.
|
|
||||||
type InvokeScript struct {
|
|
||||||
HeaderAndError
|
|
||||||
Result *InvokeResult `json:"result,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InvokeResult represents the outcome of a script that is
|
// InvokeResult represents the outcome of a script that is
|
||||||
// executed by the NEO VM.
|
// executed by the NEO VM.
|
||||||
type InvokeResult struct {
|
type InvokeResult struct {
|
||||||
|
@ -23,18 +17,6 @@ type InvokeResult struct {
|
||||||
Stack []request.StackParam
|
Stack []request.StackParam
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccountState holds the getaccountstate response.
|
|
||||||
type AccountState struct {
|
|
||||||
Header
|
|
||||||
Result *result.AccountState `json:"result"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unspent represents server response to the `getunspents` command.
|
|
||||||
type Unspent struct {
|
|
||||||
HeaderAndError
|
|
||||||
Result *result.Unspents `json:"result,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Header is a generic JSON-RPC 2.0 response header (ID and JSON-RPC version).
|
// Header is a generic JSON-RPC 2.0 response header (ID and JSON-RPC version).
|
||||||
type Header struct {
|
type Header struct {
|
||||||
ID json.RawMessage `json:"id"`
|
ID json.RawMessage `json:"id"`
|
||||||
|
@ -52,13 +34,7 @@ type HeaderAndError struct {
|
||||||
// response: http://www.jsonrpc.org/specification#response_object.
|
// response: http://www.jsonrpc.org/specification#response_object.
|
||||||
type Raw struct {
|
type Raw struct {
|
||||||
HeaderAndError
|
HeaderAndError
|
||||||
Result interface{} `json:"result,omitempty"`
|
Result json.RawMessage `json:"result,omitempty"`
|
||||||
}
|
|
||||||
|
|
||||||
// SendToAddress stores response for the sendtoaddress call.
|
|
||||||
type SendToAddress struct {
|
|
||||||
HeaderAndError
|
|
||||||
Result *result.TransactionOutputRaw
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTxOut represents result of `gettxout` RPC call.
|
// GetTxOut represents result of `gettxout` RPC call.
|
||||||
|
@ -72,9 +48,3 @@ type GetRawTx struct {
|
||||||
HeaderAndError
|
HeaderAndError
|
||||||
Result *result.TransactionOutputRaw `json:"result"`
|
Result *result.TransactionOutputRaw `json:"result"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendRawTx represents a `sendrawtransaction` RPC call response.
|
|
||||||
type SendRawTx struct {
|
|
||||||
HeaderAndError
|
|
||||||
Result bool `json:"result"`
|
|
||||||
}
|
|
||||||
|
|
|
@ -590,6 +590,14 @@ func (s *Server) WriteErrorResponse(r *request.In, w http.ResponseWriter, err er
|
||||||
|
|
||||||
// WriteResponse encodes the response and writes it to the ResponseWriter.
|
// WriteResponse encodes the response and writes it to the ResponseWriter.
|
||||||
func (s *Server) WriteResponse(r *request.In, w http.ResponseWriter, result interface{}) {
|
func (s *Server) WriteResponse(r *request.In, w http.ResponseWriter, result interface{}) {
|
||||||
|
resJSON, err := json.Marshal(result)
|
||||||
|
if err != nil {
|
||||||
|
s.log.Error("Error encountered while encoding response",
|
||||||
|
zap.String("err", err.Error()),
|
||||||
|
zap.String("method", r.Method))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
resp := response.Raw{
|
resp := response.Raw{
|
||||||
HeaderAndError: response.HeaderAndError{
|
HeaderAndError: response.HeaderAndError{
|
||||||
Header: response.Header{
|
Header: response.Header{
|
||||||
|
@ -597,7 +605,7 @@ func (s *Server) WriteResponse(r *request.In, w http.ResponseWriter, result inte
|
||||||
ID: r.RawID,
|
ID: r.RawID,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Result: result,
|
Result: resJSON,
|
||||||
}
|
}
|
||||||
|
|
||||||
s.writeServerResponse(r, w, resp)
|
s.writeServerResponse(r, w, resp)
|
||||||
|
|
Loading…
Reference in a new issue