mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-12-04 19:19:44 +00:00
rpc: adjust getrawtransaction
and gettransactionheight
RPC call
We should not return transaction metadata from `getrawtransaction` in case transaction is not in the mempool. Height shouldn't be returned from `gettransactionheight` in case transaction is in the mempool.
This commit is contained in:
parent
124c674b17
commit
4a8259caea
4 changed files with 41 additions and 45 deletions
|
@ -1237,10 +1237,10 @@ func (bc *Blockchain) headerListLen() (n int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,29 +28,27 @@ type TransactionMetadata struct {
|
||||||
|
|
||||||
// NewTransactionOutputRaw returns a new ransactionOutputRaw object.
|
// NewTransactionOutputRaw returns a new ransactionOutputRaw object.
|
||||||
func NewTransactionOutputRaw(tx *transaction.Transaction, header *block.Header, chain core.Blockchainer) TransactionOutputRaw {
|
func NewTransactionOutputRaw(tx *transaction.Transaction, header *block.Header, chain core.Blockchainer) TransactionOutputRaw {
|
||||||
// confirmations formula
|
result := TransactionOutputRaw{
|
||||||
confirmations := int(chain.BlockHeight() - header.Base.Index + 1)
|
|
||||||
return TransactionOutputRaw{
|
|
||||||
Transaction: tx,
|
Transaction: tx,
|
||||||
TransactionMetadata: TransactionMetadata{
|
TransactionMetadata: TransactionMetadata{
|
||||||
SysFee: chain.SystemFee(tx),
|
SysFee: chain.SystemFee(tx),
|
||||||
NetFee: chain.NetworkFee(tx),
|
NetFee: chain.NetworkFee(tx),
|
||||||
Blockhash: header.Hash(),
|
|
||||||
Confirmations: confirmations,
|
|
||||||
Timestamp: header.Timestamp,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
if header == nil {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
// confirmations formula
|
||||||
|
confirmations := int(chain.BlockHeight() - header.Base.Index + 1)
|
||||||
|
result.TransactionMetadata.Blockhash = header.Hash()
|
||||||
|
result.TransactionMetadata.Confirmations = confirmations
|
||||||
|
result.TransactionMetadata.Timestamp = header.Timestamp
|
||||||
|
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)
|
||||||
SysFee: t.SysFee,
|
|
||||||
NetFee: t.NetFee,
|
|
||||||
Blockhash: t.Blockhash,
|
|
||||||
Confirmations: t.Confirmations,
|
|
||||||
Timestamp: t.Timestamp,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -78,17 +76,6 @@ func (t *TransactionOutputRaw) UnmarshalJSON(data []byte) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
t.SysFee = output.SysFee
|
t.TransactionMetadata = *output
|
||||||
t.NetFee = output.NetFee
|
return json.Unmarshal(data, &t.Transaction)
|
||||||
t.Blockhash = output.Blockhash
|
|
||||||
t.Confirmations = output.Confirmations
|
|
||||||
t.Timestamp = output.Timestamp
|
|
||||||
|
|
||||||
transaction := new(transaction.Transaction)
|
|
||||||
err = json.Unmarshal(data, transaction)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
t.Transaction = transaction
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package result
|
package result
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"math"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
@ -38,6 +41,9 @@ func NewUnclaimed(a *state.Account, chain core.Blockchainer) (*Unclaimed, error)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if txHeight == math.MaxUint32 {
|
||||||
|
return nil, errors.New("wrong transaction stored in account data")
|
||||||
|
}
|
||||||
gen, sys, err := chain.CalculateClaimable(usb.Value, txHeight, blockHeight)
|
gen, sys, err := chain.CalculateClaimable(usb.Value, txHeight, blockHeight)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -1159,27 +1160,29 @@ 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 = errors.Wrapf(err, "Invalid transaction hash: %s", txHash)
|
err = errors.Wrapf(err, "Invalid transaction hash: %s", txHash)
|
||||||
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, 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 {
|
||||||
resultsErr = response.NewInvalidParamsError(err.Error(), err)
|
return nil, response.NewInvalidParamsError(err.Error(), err)
|
||||||
} else {
|
|
||||||
results = result.NewTransactionOutputRaw(tx, header, s.chain)
|
|
||||||
}
|
}
|
||||||
} else {
|
return result.NewTransactionOutputRaw(tx, header, s.chain), nil
|
||||||
results = hex.EncodeToString(tx.Bytes())
|
|
||||||
}
|
}
|
||||||
|
return hex.EncodeToString(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) {
|
||||||
|
@ -1189,7 +1192,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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue