Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get transaction with status api route #1969

Merged
merged 11 commits into from
Jun 24, 2020
6 changes: 0 additions & 6 deletions api/mock/facade.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,10 @@ type Facade struct {
ComputeTransactionGasLimitHandler func(tx *transaction.Transaction) (uint64, error)
NodeConfigCalled func() map[string]interface{}
GetQueryHandlerCalled func(name string) (debug.QueryHandler, error)
GetTransactionStatusCalled func(hash string) (string, error)
GetValueForKeyCalled func(address string, key string) (string, error)
GetPeerInfoCalled func(pid string) ([]core.QueryP2PPeerInfo, error)
}

// GetTransactionStatus -
func (f *Facade) GetTransactionStatus(hash string) (string, error) {
return f.GetTransactionStatusCalled(hash)
}

// RestApiInterface -
func (f *Facade) RestApiInterface() string {
return "localhost:8080"
Expand Down
35 changes: 6 additions & 29 deletions api/transaction/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ type TxService interface {
ValidateTransaction(tx *transaction.Transaction) error
SendBulkTransactions([]*transaction.Transaction) (uint64, error)
GetTransaction(hash string) (*transaction.ApiTransactionResult, error)
GetTransactionStatus(hash string) (string, error)
ComputeTransactionGasLimit(tx *transaction.Transaction) (uint64, error)
EncodeAddressPubkey(pk []byte) (string, error)
IsInterfaceNil() bool
Expand Down Expand Up @@ -68,7 +67,6 @@ func Routes(router *wrapper.RouterWrapper) {
router.RegisterHandler(http.MethodPost, "/cost", ComputeTransactionGasLimit)
router.RegisterHandler(http.MethodPost, "/send-multiple", SendMultipleTransactions)
router.RegisterHandler(http.MethodGet, "/:txhash", GetTransaction)
router.RegisterHandler(http.MethodGet, "/:txhash/status", GetTransactionStatus)
iulianpascalau marked this conversation as resolved.
Show resolved Hide resolved
}

// SendTransaction will receive a transaction from the client and propagate it for processing
Expand Down Expand Up @@ -132,11 +130,13 @@ func SendMultipleTransactions(c *gin.Context) {
return
}

var txs []*transaction.Transaction
var tx *transaction.Transaction
var txHash []byte
var (
txs []*transaction.Transaction
tx *transaction.Transaction
txHash []byte
)

txsHashes := make(map[int]string, 0)
txsHashes := make(map[int]string)
iulianpascalau marked this conversation as resolved.
Show resolved Hide resolved
for idx, receivedTx := range gtx {
tx, txHash, err = ef.CreateTransaction(
receivedTx.Nonce,
Expand Down Expand Up @@ -199,29 +199,6 @@ func GetTransaction(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"transaction": tx})
}

// GetTransactionStatus returns the status of a transaction identified by the given hash
func GetTransactionStatus(c *gin.Context) {
ef, ok := c.MustGet("elrondFacade").(TxService)
if !ok {
c.JSON(http.StatusInternalServerError, gin.H{"error": errors.ErrInvalidAppContext.Error()})
return
}

txhash := c.Param("txhash")
if txhash == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("%s: %s", errors.ErrValidation.Error(), errors.ErrValidationEmptyTxHash.Error())})
return
}

status, err := ef.GetTransactionStatus(txhash)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": errors.ErrGetTransaction.Error()})
return
}

c.JSON(http.StatusOK, gin.H{"status": status})
}

// ComputeTransactionGasLimit returns how many gas units a transaction wil consume
func ComputeTransactionGasLimit(c *gin.Context) {
ef, ok := c.MustGet("elrondFacade").(TxService)
Expand Down
39 changes: 0 additions & 39 deletions api/transaction/routes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,6 @@ type TransactionHashResponse struct {
TxHash string `json:"txHash,omitempty"`
}

type TransactionStatusResponse struct {
GeneralResponse
Status string `json:"status"`
}

type TransactionCostResponse struct {
GeneralResponse
Cost uint64 `json:"txGasUnits"`
Expand All @@ -53,40 +48,6 @@ func init() {
gin.SetMode(gin.TestMode)
}

func TestGetTransactionStatus(t *testing.T) {
rightHash := "hash"
wrongHash := "wronghash"
facade := mock.Facade{
GetTransactionStatusCalled: func(hash string) (string, error) {
if hash == rightHash {
return "pending", nil
}
return "unknown", nil
},
}

req, _ := http.NewRequest("GET", "/transaction/"+wrongHash+"/status", nil)
ws := startNodeServer(&facade)
resp := httptest.NewRecorder()
ws.ServeHTTP(resp, req)

response := TransactionStatusResponse{}
loadResponse(resp.Body, &response)

assert.Equal(t, http.StatusOK, resp.Code)
assert.Equal(t, "unknown", response.Status)

req, _ = http.NewRequest("GET", "/transaction/"+rightHash+"/status", nil)
resp = httptest.NewRecorder()
ws.ServeHTTP(resp, req)

response = TransactionStatusResponse{}
loadResponse(resp.Body, &response)

assert.Equal(t, http.StatusOK, resp.Code)
assert.Equal(t, "pending", response.Status)
}

func TestGetTransaction_WithCorrectHashShouldReturnTransaction(t *testing.T) {
sender := "sender"
receiver := "receiver"
Expand Down
3 changes: 0 additions & 3 deletions cmd/node/config/api.toml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,4 @@

# /transaction/:txhash will return the transaction in JSON format based on its hash
{ Name = "/:txhash", Open = true },

# /transaction/:txhash/status will return the status of a transaction based on its hash
{ Name = "/:txhash/status", Open = true }
]
4 changes: 2 additions & 2 deletions core/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,10 +335,10 @@ type TransactionStatus string
const (
// TxStatusReceived represents the status of a transaction which was received but not yet executed
TxStatusReceived TransactionStatus = "received"
// TxStatusPartiallyExecuted represent the status of a transaction which was received and executed on source shard
TxStatusPartiallyExecuted TransactionStatus = "partially-executed"
// TxStatusExecuted represents the status of a transaction which was received and executed
TxStatusExecuted TransactionStatus = "executed"
// TxStatusUnknown represents the status returned for a missing transaction
TxStatusUnknown TransactionStatus = "unknown"
)

const (
Expand Down
27 changes: 15 additions & 12 deletions data/transaction/apiTransactionResult.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package transaction

import "github.com/ElrondNetwork/elrond-go/core"

// ApiTransactionResult is the data transfer object which will be returned on the get transaction by hash endpoint
type ApiTransactionResult struct {
Type string `json:"type"`
Nonce uint64 `json:"nonce,omitempty"`
Round uint64 `json:"round,omitempty"`
Epoch uint32 `json:"epoch,omitempty"`
Value string `json:"value,omitempty"`
Receiver string `json:"receiver,omitempty"`
Sender string `json:"sender,omitempty"`
GasPrice uint64 `json:"gasPrice,omitempty"`
GasLimit uint64 `json:"gasLimit,omitempty"`
Data string `json:"data,omitempty"`
Code string `json:"code,omitempty"`
Signature string `json:"signature,omitempty"`
Type string `json:"type"`
Nonce uint64 `json:"nonce,omitempty"`
Round uint64 `json:"round,omitempty"`
Epoch uint32 `json:"epoch,omitempty"`
Value string `json:"value,omitempty"`
Receiver string `json:"receiver,omitempty"`
Sender string `json:"sender,omitempty"`
GasPrice uint64 `json:"gasPrice,omitempty"`
GasLimit uint64 `json:"gasLimit,omitempty"`
Data string `json:"data,omitempty"`
Code string `json:"code,omitempty"`
Signature string `json:"signature,omitempty"`
Status core.TransactionStatus `json:"status,omitempty"`
}
3 changes: 0 additions & 3 deletions facade/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ type NodeHandler interface {
//GetTransaction will return a transaction based on the hash
GetTransaction(hash string) (*transaction.ApiTransactionResult, error)

//GetTransactionStatus gets the transaction status
GetTransactionStatus(hash string) (string, error)

// GetAccount returns an accountResponse containing information
// about the account corelated with provided address
GetAccount(address string) (state.UserAccountHandler, error)
Expand Down
10 changes: 0 additions & 10 deletions facade/mock/nodeStub.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ type NodeStub struct {
DirectTriggerCalled func(epoch uint32) error
IsSelfTriggerCalled func() bool
GetQueryHandlerCalled func(name string) (debug.QueryHandler, error)
GetTransactionStatusCalled func(hash string) (string, error)
GetValueForKeyCalled func(address string, key string) (string, error)
GetPeerInfoCalled func(pid string) ([]core.QueryP2PPeerInfo, error)
}
Expand All @@ -46,15 +45,6 @@ func (ns *NodeStub) GetValueForKey(address string, key string) (string, error) {
return "", nil
}

// GetTransactionStatus -
func (ns *NodeStub) GetTransactionStatus(hash string) (string, error) {
if ns.GetTransactionStatusCalled != nil {
return ns.GetTransactionStatusCalled(hash)
}

return "unknown", nil
}

// EncodeAddressPubkey -
func (ns *NodeStub) EncodeAddressPubkey(pk []byte) (string, error) {
return hex.EncodeToString(pk), nil
Expand Down
5 changes: 0 additions & 5 deletions facade/nodeFacade.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,11 +244,6 @@ func (nf *nodeFacade) GetTransaction(hash string) (*transaction.ApiTransactionRe
return nf.node.GetTransaction(hash)
}

// GetTransactionStatus gets the current transaction status, given a specific tx hash
func (nf *nodeFacade) GetTransactionStatus(hash string) (string, error) {
return nf.node.GetTransactionStatus(hash)
}

// ComputeTransactionGasLimit will estimate how many gas a transaction will consume
func (nf *nodeFacade) ComputeTransactionGasLimit(tx *transaction.Transaction) (uint64, error) {
return nf.apiResolver.ComputeTransactionGasLimit(tx)
Expand Down
6 changes: 6 additions & 0 deletions node/export_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package node

import (
"github.com/ElrondNetwork/elrond-go/core"
"github.com/ElrondNetwork/elrond-go/data"
"github.com/ElrondNetwork/elrond-go/p2p"
)

func (n *Node) CreateConsensusTopic(messageProcessor p2p.MessageProcessor) error {
return n.createConsensusTopic(messageProcessor)
}

func (n *Node) ComputeTransactionStatus(tx data.TransactionHandler, isInPool bool) core.TransactionStatus {
return n.computeTransactionStatus(tx, isInPool)
}
8 changes: 6 additions & 2 deletions node/mock/shardCoordinatorMock.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import (

// ShardCoordinatorMock -
type ShardCoordinatorMock struct {
SelfShardId uint32
SelfShardId uint32
ComputeIdCalled func([]byte) uint32
}

// NumberOfShards -
Expand All @@ -15,7 +16,10 @@ func (scm ShardCoordinatorMock) NumberOfShards() uint32 {
}

// ComputeId -
func (scm ShardCoordinatorMock) ComputeId(_ []byte) uint32 {
func (scm ShardCoordinatorMock) ComputeId(addr []byte) uint32 {
if scm.ComputeIdCalled != nil {
return scm.ComputeIdCalled(addr)
}
return 0
}

Expand Down