mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 11:26:44 +01:00
Refactor api txs
This commit is contained in:
272
api/txspool_test.go
Normal file
272
api/txspool_test.go
Normal file
@@ -0,0 +1,272 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hermeznetwork/hermez-node/common"
|
||||
"github.com/hermeznetwork/hermez-node/db/historydb"
|
||||
"github.com/iden3/go-iden3-crypto/babyjub"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// testPoolTxReceive is a struct to be used to assert the response
|
||||
// of GET /transactions-pool/:id
|
||||
type testPoolTxReceive struct {
|
||||
TxID common.TxID `json:"id"`
|
||||
Type common.TxType `json:"type"`
|
||||
FromIdx string `json:"fromAccountIndex"`
|
||||
FromEthAddr *string `json:"fromHezEthereumAddress"`
|
||||
FromBJJ *string `json:"fromBJJ"`
|
||||
ToIdx *string `json:"toAccountIndex"`
|
||||
ToEthAddr *string `json:"toHezEthereumAddress"`
|
||||
ToBJJ *string `json:"toBjj"`
|
||||
Amount string `json:"amount"`
|
||||
Fee common.FeeSelector `json:"fee"`
|
||||
Nonce common.Nonce `json:"nonce"`
|
||||
State common.PoolL2TxState `json:"state"`
|
||||
Signature babyjub.SignatureComp `json:"signature"`
|
||||
RqFromIdx *string `json:"requestFromAccountIndex"`
|
||||
RqToIdx *string `json:"requestToAccountIndex"`
|
||||
RqToEthAddr *string `json:"requestToHezEthereumAddress"`
|
||||
RqToBJJ *string `json:"requestToBJJ"`
|
||||
RqTokenID *common.TokenID `json:"requestTokenId"`
|
||||
RqAmount *string `json:"requestAmount"`
|
||||
RqFee *common.FeeSelector `json:"requestFee"`
|
||||
RqNonce *common.Nonce `json:"requestNonce"`
|
||||
BatchNum *common.BatchNum `json:"batchNum"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
Token historydb.TokenWithUSD `json:"token"`
|
||||
}
|
||||
|
||||
// testPoolTxSend is a struct to be used as a JSON body
|
||||
// when testing POST /transactions-pool
|
||||
type testPoolTxSend struct {
|
||||
TxID common.TxID `json:"id" binding:"required"`
|
||||
Type common.TxType `json:"type" binding:"required"`
|
||||
TokenID common.TokenID `json:"tokenId"`
|
||||
FromIdx string `json:"fromAccountIndex" binding:"required"`
|
||||
ToIdx *string `json:"toAccountIndex"`
|
||||
ToEthAddr *string `json:"toHezEthereumAddress"`
|
||||
ToBJJ *string `json:"toBjj"`
|
||||
Amount string `json:"amount" binding:"required"`
|
||||
Fee common.FeeSelector `json:"fee"`
|
||||
Nonce common.Nonce `json:"nonce"`
|
||||
Signature babyjub.SignatureComp `json:"signature" binding:"required"`
|
||||
RqFromIdx *string `json:"requestFromAccountIndex"`
|
||||
RqToIdx *string `json:"requestToAccountIndex"`
|
||||
RqToEthAddr *string `json:"requestToHezEthereumAddress"`
|
||||
RqToBJJ *string `json:"requestToBjj"`
|
||||
RqTokenID *common.TokenID `json:"requestTokenId"`
|
||||
RqAmount *string `json:"requestAmount"`
|
||||
RqFee *common.FeeSelector `json:"requestFee"`
|
||||
RqNonce *common.Nonce `json:"requestNonce"`
|
||||
}
|
||||
|
||||
func genTestPoolTx(accs []common.Account, privKs []babyjub.PrivateKey, tokens []historydb.TokenWithUSD) (poolTxsToSend []testPoolTxSend, poolTxsToReceive []testPoolTxReceive) {
|
||||
// Generate common.PoolL2Tx
|
||||
// WARNING: this should be replaced once til is ready
|
||||
poolTxs := []common.PoolL2Tx{}
|
||||
amount := new(big.Int)
|
||||
amount, ok := amount.SetString("100000000000000", 10)
|
||||
if !ok {
|
||||
panic("bad amount")
|
||||
}
|
||||
poolTx := common.PoolL2Tx{
|
||||
FromIdx: accs[0].Idx,
|
||||
ToIdx: accs[1].Idx,
|
||||
Amount: amount,
|
||||
TokenID: accs[0].TokenID,
|
||||
Nonce: 6,
|
||||
}
|
||||
if _, err := common.NewPoolL2Tx(&poolTx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
h, err := poolTx.HashToSign()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
poolTx.Signature = privKs[0].SignPoseidon(h).Compress()
|
||||
poolTxs = append(poolTxs, poolTx)
|
||||
// Transform to API formats
|
||||
poolTxsToSend = []testPoolTxSend{}
|
||||
poolTxsToReceive = []testPoolTxReceive{}
|
||||
for _, poolTx := range poolTxs {
|
||||
fmt.Println(poolTx)
|
||||
// common.PoolL2Tx ==> testPoolTxSend
|
||||
token := getTokenByID(poolTx.TokenID, tokens)
|
||||
genSendTx := testPoolTxSend{
|
||||
TxID: poolTx.TxID,
|
||||
Type: poolTx.Type,
|
||||
TokenID: poolTx.TokenID,
|
||||
FromIdx: idxToHez(poolTx.FromIdx, token.Symbol),
|
||||
Amount: poolTx.Amount.String(),
|
||||
Fee: poolTx.Fee,
|
||||
Nonce: poolTx.Nonce,
|
||||
Signature: poolTx.Signature,
|
||||
RqFee: &poolTx.RqFee,
|
||||
RqNonce: &poolTx.RqNonce,
|
||||
}
|
||||
// common.PoolL2Tx ==> testPoolTxReceive
|
||||
genReceiveTx := testPoolTxReceive{
|
||||
TxID: poolTx.TxID,
|
||||
Type: poolTx.Type,
|
||||
FromIdx: idxToHez(poolTx.FromIdx, token.Symbol),
|
||||
Amount: poolTx.Amount.String(),
|
||||
Fee: poolTx.Fee,
|
||||
Nonce: poolTx.Nonce,
|
||||
State: poolTx.State,
|
||||
Signature: poolTx.Signature,
|
||||
Timestamp: poolTx.Timestamp,
|
||||
// BatchNum: poolTx.BatchNum,
|
||||
RqFee: &poolTx.RqFee,
|
||||
RqNonce: &poolTx.RqNonce,
|
||||
Token: token,
|
||||
}
|
||||
fromAcc := getAccountByIdx(poolTx.ToIdx, accs)
|
||||
fromAddr := ethAddrToHez(fromAcc.EthAddr)
|
||||
genReceiveTx.FromEthAddr = &fromAddr
|
||||
fromBjj := bjjToString(fromAcc.PublicKey)
|
||||
genReceiveTx.FromBJJ = &fromBjj
|
||||
if poolTx.ToIdx != 0 {
|
||||
toIdx := idxToHez(poolTx.ToIdx, token.Symbol)
|
||||
genSendTx.ToIdx = &toIdx
|
||||
genReceiveTx.ToIdx = &toIdx
|
||||
}
|
||||
if poolTx.ToEthAddr != common.EmptyAddr {
|
||||
toEth := ethAddrToHez(poolTx.ToEthAddr)
|
||||
genSendTx.ToEthAddr = &toEth
|
||||
genReceiveTx.ToEthAddr = &toEth
|
||||
} else if poolTx.ToIdx > 255 {
|
||||
acc := getAccountByIdx(poolTx.ToIdx, accs)
|
||||
addr := ethAddrToHez(acc.EthAddr)
|
||||
genReceiveTx.ToEthAddr = &addr
|
||||
}
|
||||
if poolTx.ToBJJ != nil {
|
||||
toBJJ := bjjToString(poolTx.ToBJJ)
|
||||
genSendTx.ToBJJ = &toBJJ
|
||||
genReceiveTx.ToBJJ = &toBJJ
|
||||
} else if poolTx.ToIdx > 255 {
|
||||
acc := getAccountByIdx(poolTx.ToIdx, accs)
|
||||
bjj := bjjToString(acc.PublicKey)
|
||||
genReceiveTx.ToBJJ = &bjj
|
||||
}
|
||||
if poolTx.RqFromIdx != 0 {
|
||||
rqFromIdx := idxToHez(poolTx.RqFromIdx, token.Symbol)
|
||||
genSendTx.RqFromIdx = &rqFromIdx
|
||||
genReceiveTx.RqFromIdx = &rqFromIdx
|
||||
genSendTx.RqTokenID = &token.TokenID
|
||||
genReceiveTx.RqTokenID = &token.TokenID
|
||||
rqAmount := poolTx.RqAmount.String()
|
||||
genSendTx.RqAmount = &rqAmount
|
||||
genReceiveTx.RqAmount = &rqAmount
|
||||
|
||||
if poolTx.RqToIdx != 0 {
|
||||
rqToIdx := idxToHez(poolTx.RqToIdx, token.Symbol)
|
||||
genSendTx.RqToIdx = &rqToIdx
|
||||
genReceiveTx.RqToIdx = &rqToIdx
|
||||
}
|
||||
if poolTx.RqToEthAddr != common.EmptyAddr {
|
||||
rqToEth := ethAddrToHez(poolTx.RqToEthAddr)
|
||||
genSendTx.RqToEthAddr = &rqToEth
|
||||
genReceiveTx.RqToEthAddr = &rqToEth
|
||||
}
|
||||
if poolTx.RqToBJJ != nil {
|
||||
rqToBJJ := bjjToString(poolTx.RqToBJJ)
|
||||
genSendTx.RqToBJJ = &rqToBJJ
|
||||
genReceiveTx.RqToBJJ = &rqToBJJ
|
||||
}
|
||||
}
|
||||
poolTxsToSend = append(poolTxsToSend, genSendTx)
|
||||
poolTxsToReceive = append(poolTxsToReceive, genReceiveTx)
|
||||
}
|
||||
return poolTxsToSend, poolTxsToReceive
|
||||
}
|
||||
|
||||
func TestPoolTxs(t *testing.T) {
|
||||
// POST
|
||||
endpoint := apiURL + "transactions-pool"
|
||||
fetchedTxID := common.TxID{}
|
||||
for _, tx := range tc.poolTxsToSend {
|
||||
jsonTxBytes, err := json.Marshal(tx)
|
||||
assert.NoError(t, err)
|
||||
jsonTxReader := bytes.NewReader(jsonTxBytes)
|
||||
assert.NoError(
|
||||
t, doGoodReq(
|
||||
"POST",
|
||||
endpoint,
|
||||
jsonTxReader, &fetchedTxID,
|
||||
),
|
||||
)
|
||||
assert.Equal(t, tx.TxID, fetchedTxID)
|
||||
}
|
||||
// 400
|
||||
// Wrong signature
|
||||
badTx := tc.poolTxsToSend[0]
|
||||
badTx.FromIdx = "hez:foo:1000"
|
||||
jsonTxBytes, err := json.Marshal(badTx)
|
||||
assert.NoError(t, err)
|
||||
jsonTxReader := bytes.NewReader(jsonTxBytes)
|
||||
err = doBadReq("POST", endpoint, jsonTxReader, 400)
|
||||
assert.NoError(t, err)
|
||||
// Wrong to
|
||||
badTx = tc.poolTxsToSend[0]
|
||||
ethAddr := "hez:0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
badTx.ToEthAddr = ðAddr
|
||||
badTx.ToIdx = nil
|
||||
jsonTxBytes, err = json.Marshal(badTx)
|
||||
assert.NoError(t, err)
|
||||
jsonTxReader = bytes.NewReader(jsonTxBytes)
|
||||
err = doBadReq("POST", endpoint, jsonTxReader, 400)
|
||||
assert.NoError(t, err)
|
||||
// Wrong rq
|
||||
badTx = tc.poolTxsToSend[0]
|
||||
rqFromIdx := "hez:foo:30"
|
||||
badTx.RqFromIdx = &rqFromIdx
|
||||
jsonTxBytes, err = json.Marshal(badTx)
|
||||
assert.NoError(t, err)
|
||||
jsonTxReader = bytes.NewReader(jsonTxBytes)
|
||||
err = doBadReq("POST", endpoint, jsonTxReader, 400)
|
||||
assert.NoError(t, err)
|
||||
// GET
|
||||
endpoint += "/"
|
||||
for _, tx := range tc.poolTxsToReceive {
|
||||
fetchedTx := testPoolTxReceive{}
|
||||
assert.NoError(
|
||||
t, doGoodReq(
|
||||
"GET",
|
||||
endpoint+tx.TxID.String(),
|
||||
nil, &fetchedTx,
|
||||
),
|
||||
)
|
||||
assertPoolTx(t, tx, fetchedTx)
|
||||
}
|
||||
// 400
|
||||
err = doBadReq("GET", endpoint+"0xG20000000156660000000090", nil, 400)
|
||||
assert.NoError(t, err)
|
||||
// 404
|
||||
err = doBadReq("GET", endpoint+"0x020000000156660000000090", nil, 404)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func assertPoolTx(t *testing.T, expected, actual testPoolTxReceive) {
|
||||
// state should be pending
|
||||
assert.Equal(t, common.PoolL2TxStatePending, actual.State)
|
||||
expected.State = actual.State
|
||||
actual.Token.ItemID = 0
|
||||
// timestamp should be very close to now
|
||||
assert.Less(t, time.Now().UTC().Unix()-3, actual.Timestamp.Unix())
|
||||
expected.Timestamp = actual.Timestamp
|
||||
// token timestamp
|
||||
if expected.Token.USDUpdate == nil {
|
||||
assert.Equal(t, expected.Token.USDUpdate, actual.Token.USDUpdate)
|
||||
} else {
|
||||
assert.Equal(t, expected.Token.USDUpdate.Unix(), actual.Token.USDUpdate.Unix())
|
||||
expected.Token.USDUpdate = actual.Token.USDUpdate
|
||||
}
|
||||
assert.Equal(t, expected, actual)
|
||||
}
|
||||
Reference in New Issue
Block a user