Merge pull request #1543 from nspcc-dev/compatibility-fixes

rpc, cli: tiny compatibility fixes
This commit is contained in:
Roman Khimov 2020-11-16 15:53:42 +03:00 committed by GitHub
commit 88cee80a58
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 38 additions and 75 deletions

View file

@ -6,6 +6,7 @@ import (
"errors" "errors"
"io" "io"
"io/ioutil" "io/ioutil"
"math"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -123,7 +124,7 @@ func (e *executor) GetTransaction(t *testing.T, h util.Uint256) (*transaction.Tr
require.Eventually(t, func() bool { require.Eventually(t, func() bool {
var err error var err error
tx, height, err = e.Chain.GetTransaction(h) tx, height, err = e.Chain.GetTransaction(h)
return err == nil && height != 0 return err == nil && height != math.MaxUint32
}, time.Second*2, time.Millisecond*100, "too long time waiting for block") }, time.Second*2, time.Millisecond*100, "too long time waiting for block")
return tx, height return tx, height
} }

View file

@ -445,7 +445,7 @@ func transferNEP5(ctx *cli.Context) error {
fmt.Fprintln(ctx.App.ErrWriter, "Can't find matching token in the wallet. Querying RPC-node for balances.") fmt.Fprintln(ctx.App.ErrWriter, "Can't find matching token in the wallet. Querying RPC-node for balances.")
token, err = getMatchingTokenRPC(ctx, c, from, ctx.String("token")) token, err = getMatchingTokenRPC(ctx, c, from, ctx.String("token"))
if err != nil { if err != nil {
return cli.NewExitError(err, 1) return cli.NewExitError(fmt.Errorf("failed to get matching token: %w", err), 1)
} }
} }

View file

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"errors" "errors"
"fmt" "fmt"
"math"
"math/big" "math/big"
"sort" "sort"
"sync" "sync"
@ -942,10 +943,10 @@ func (bc *Blockchain) persist() error {
return nil return nil
} }
// GetTransaction returns a TX and its height by the given hash. // GetTransaction returns a TX and its height by the given hash. The height is MaxUint32 if tx is in the mempool.
func (bc *Blockchain) GetTransaction(hash util.Uint256) (*transaction.Transaction, uint32, error) { func (bc *Blockchain) GetTransaction(hash util.Uint256) (*transaction.Transaction, uint32, error) {
if tx, ok := bc.memPool.TryGetValue(hash); ok { if tx, ok := bc.memPool.TryGetValue(hash); ok {
return tx, 0, nil // the height is not actually defined for memPool transaction. Not sure if zero is a good number in this case. return tx, math.MaxUint32, nil // the height is not actually defined for memPool transaction.
} }
return bc.dao.GetTransaction(hash) return bc.dao.GetTransaction(hash)
} }

View file

@ -1,8 +1,6 @@
package result package result
import ( import (
"encoding/json"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
) )
@ -19,13 +17,6 @@ type NEP5Balance struct {
LastUpdated uint32 `json:"lastupdatedblock"` LastUpdated uint32 `json:"lastupdatedblock"`
} }
// nep5Balance is an auxiliary struct for proper Asset marshaling.
type nep5Balance struct {
Asset string `json:"assethash"`
Amount string `json:"amount"`
LastUpdated uint32 `json:"lastupdatedblock"`
}
// NEP5Transfers is a result for the getnep5transfers RPC. // NEP5Transfers is a result for the getnep5transfers RPC.
type NEP5Transfers struct { type NEP5Transfers struct {
Sent []NEP5Transfer `json:"sent"` Sent []NEP5Transfer `json:"sent"`
@ -43,29 +34,3 @@ type NEP5Transfer struct {
NotifyIndex uint32 `json:"transfernotifyindex"` NotifyIndex uint32 `json:"transfernotifyindex"`
TxHash util.Uint256 `json:"txhash"` TxHash util.Uint256 `json:"txhash"`
} }
// MarshalJSON implements json.Marshaler interface.
func (b *NEP5Balance) MarshalJSON() ([]byte, error) {
s := &nep5Balance{
Asset: b.Asset.StringLE(),
Amount: b.Amount,
LastUpdated: b.LastUpdated,
}
return json.Marshal(s)
}
// UnmarshalJSON implements json.Unmarshaler interface.
func (b *NEP5Balance) UnmarshalJSON(data []byte) error {
s := new(nep5Balance)
if err := json.Unmarshal(data, s); err != nil {
return err
}
asset, err := util.Uint160DecodeStringLE(s.Asset)
if err != nil {
return err
}
b.Amount = s.Amount
b.Asset = asset
b.LastUpdated = s.LastUpdated
return nil
}

View file

@ -23,32 +23,31 @@ type TransactionMetadata struct {
Blockhash util.Uint256 `json:"blockhash,omitempty"` Blockhash util.Uint256 `json:"blockhash,omitempty"`
Confirmations int `json:"confirmations,omitempty"` Confirmations int `json:"confirmations,omitempty"`
Timestamp uint64 `json:"blocktime,omitempty"` Timestamp uint64 `json:"blocktime,omitempty"`
VMState string `json:"vmstate"` VMState string `json:"vmstate,omitempty"`
} }
// NewTransactionOutputRaw returns a new ransactionOutputRaw object. // NewTransactionOutputRaw returns a new ransactionOutputRaw object.
func NewTransactionOutputRaw(tx *transaction.Transaction, header *block.Header, appExecResult *state.AppExecResult, chain blockchainer.Blockchainer) TransactionOutputRaw { func NewTransactionOutputRaw(tx *transaction.Transaction, header *block.Header, appExecResult *state.AppExecResult, chain blockchainer.Blockchainer) TransactionOutputRaw {
result := TransactionOutputRaw{
Transaction: *tx,
}
if header == nil {
return result
}
// confirmations formula // confirmations formula
confirmations := int(chain.BlockHeight() - header.Base.Index + 1) confirmations := int(chain.BlockHeight() - header.Base.Index + 1)
return TransactionOutputRaw{ result.TransactionMetadata = TransactionMetadata{
Transaction: *tx, Blockhash: header.Hash(),
TransactionMetadata: TransactionMetadata{ Confirmations: confirmations,
Blockhash: header.Hash(), Timestamp: header.Timestamp,
Confirmations: confirmations, VMState: appExecResult.VMState.String(),
Timestamp: header.Timestamp,
VMState: appExecResult.VMState.String(),
},
} }
return result
} }
// MarshalJSON implements json.Marshaler interface. // MarshalJSON implements json.Marshaler interface.
func (t TransactionOutputRaw) MarshalJSON() ([]byte, error) { func (t TransactionOutputRaw) MarshalJSON() ([]byte, error) {
output, err := json.Marshal(TransactionMetadata{ output, err := json.Marshal(t.TransactionMetadata)
Blockhash: t.Blockhash,
Confirmations: t.Confirmations,
Timestamp: t.Timestamp,
VMState: t.VMState,
})
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -76,10 +75,6 @@ func (t *TransactionOutputRaw) UnmarshalJSON(data []byte) error {
if err != nil { if err != nil {
return err return err
} }
t.Blockhash = output.Blockhash t.TransactionMetadata = *output
t.Confirmations = output.Confirmations
t.Timestamp = output.Timestamp
t.VMState = output.VMState
return json.Unmarshal(data, &t.Transaction) return json.Unmarshal(data, &t.Transaction)
} }

View file

@ -846,33 +846,34 @@ func (s *Server) getStorage(ps request.Params) (interface{}, *response.Error) {
} }
func (s *Server) getrawtransaction(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) getrawtransaction(reqParams request.Params) (interface{}, *response.Error) {
var resultsErr *response.Error txHash, err := reqParams.Value(0).GetUint256()
var results interface{} if err != nil {
return nil, response.ErrInvalidParams
if txHash, err := reqParams.Value(0).GetUint256(); err != nil { }
resultsErr = response.ErrInvalidParams tx, height, err := s.chain.GetTransaction(txHash)
} else if tx, height, err := s.chain.GetTransaction(txHash); err != nil { if err != nil {
err = fmt.Errorf("invalid transaction %s: %w", txHash, err) err = fmt.Errorf("invalid transaction %s: %w", txHash, err)
return nil, response.NewRPCError("Unknown transaction", err.Error(), err) return nil, response.NewRPCError("Unknown transaction", err.Error(), err)
} else if reqParams.Value(1).GetBoolean() { }
if reqParams.Value(1).GetBoolean() {
if height == math.MaxUint32 {
return result.NewTransactionOutputRaw(tx, nil, nil, s.chain), nil
}
_header := s.chain.GetHeaderHash(int(height)) _header := s.chain.GetHeaderHash(int(height))
header, err := s.chain.GetHeader(_header) header, err := s.chain.GetHeader(_header)
if err != nil { if err != nil {
return nil, response.NewInvalidParamsError(err.Error(), err) return nil, response.NewRPCError("Failed to get header for the transaction", err.Error(), err)
} }
aers, err := s.chain.GetAppExecResults(txHash, trigger.Application) aers, err := s.chain.GetAppExecResults(txHash, trigger.Application)
if err != nil { if err != nil {
return nil, response.NewRPCError("Unknown transaction", err.Error(), err) return nil, response.NewRPCError("Failed to get application log for the transaction", err.Error(), err)
} }
if len(aers) == 0 { if len(aers) == 0 {
return nil, response.NewRPCError("Unknown transaction", "", nil) return nil, response.NewRPCError("Application log for the transaction is empty", "", nil)
} }
results = result.NewTransactionOutputRaw(tx, header, &aers[0], s.chain) return result.NewTransactionOutputRaw(tx, header, &aers[0], s.chain), nil
} else {
results = tx.Bytes()
} }
return tx.Bytes(), nil
return results, resultsErr
} }
func (s *Server) getTransactionHeight(ps request.Params) (interface{}, *response.Error) { func (s *Server) getTransactionHeight(ps request.Params) (interface{}, *response.Error) {
@ -882,7 +883,7 @@ func (s *Server) getTransactionHeight(ps request.Params) (interface{}, *response
} }
_, height, err := s.chain.GetTransaction(h) _, height, err := s.chain.GetTransaction(h)
if err != nil { if err != nil || height == math.MaxUint32 {
return nil, response.NewRPCError("unknown transaction", "", nil) return nil, response.NewRPCError("unknown transaction", "", nil)
} }