mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 19:36:44 +01:00
Refactor api txs
This commit is contained in:
171
api/txspool.go
Normal file
171
api/txspool.go
Normal file
@@ -0,0 +1,171 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math/big"
|
||||
"net/http"
|
||||
|
||||
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/hermeznetwork/hermez-node/apitypes"
|
||||
"github.com/hermeznetwork/hermez-node/common"
|
||||
"github.com/hermeznetwork/hermez-node/db/l2db"
|
||||
"github.com/iden3/go-iden3-crypto/babyjub"
|
||||
)
|
||||
|
||||
func postPoolTx(c *gin.Context) {
|
||||
// Parse body
|
||||
var receivedTx receivedPoolTx
|
||||
if err := c.ShouldBindJSON(&receivedTx); err != nil {
|
||||
retBadReq(err, c)
|
||||
return
|
||||
}
|
||||
// Transform from received to insert format and validate
|
||||
writeTx := receivedTx.toPoolL2TxWrite()
|
||||
if err := verifyPoolL2TxWrite(writeTx); err != nil {
|
||||
retBadReq(err, c)
|
||||
return
|
||||
}
|
||||
// Insert to DB
|
||||
if err := l2.AddTx(writeTx); err != nil {
|
||||
retSQLErr(err, c)
|
||||
return
|
||||
}
|
||||
// Return TxID
|
||||
c.JSON(http.StatusOK, writeTx.TxID.String())
|
||||
}
|
||||
|
||||
func getPoolTx(c *gin.Context) {
|
||||
// Get TxID
|
||||
txID, err := parseParamTxID(c)
|
||||
if err != nil {
|
||||
retBadReq(err, c)
|
||||
return
|
||||
}
|
||||
// Fetch tx from l2DB
|
||||
tx, err := l2.GetTxAPI(txID)
|
||||
if err != nil {
|
||||
retSQLErr(err, c)
|
||||
return
|
||||
}
|
||||
// Build succesfull response
|
||||
c.JSON(http.StatusOK, tx)
|
||||
}
|
||||
|
||||
type receivedPoolTx struct {
|
||||
TxID common.TxID `json:"id" binding:"required"`
|
||||
Type common.TxType `json:"type" binding:"required"`
|
||||
TokenID common.TokenID `json:"tokenId"`
|
||||
FromIdx apitypes.StrHezIdx `json:"fromAccountIndex" binding:"required"`
|
||||
ToIdx *apitypes.StrHezIdx `json:"toAccountIndex"`
|
||||
ToEthAddr *apitypes.StrHezEthAddr `json:"toHezEthereumAddress"`
|
||||
ToBJJ *apitypes.StrHezBJJ `json:"toBjj"`
|
||||
Amount apitypes.StrBigInt `json:"amount" binding:"required"`
|
||||
Fee common.FeeSelector `json:"fee"`
|
||||
Nonce common.Nonce `json:"nonce"`
|
||||
Signature babyjub.SignatureComp `json:"signature" binding:"required"`
|
||||
RqFromIdx *apitypes.StrHezIdx `json:"requestFromAccountIndex"`
|
||||
RqToIdx *apitypes.StrHezIdx `json:"requestToAccountIndex"`
|
||||
RqToEthAddr *apitypes.StrHezEthAddr `json:"requestToHezEthereumAddress"`
|
||||
RqToBJJ *apitypes.StrHezBJJ `json:"requestToBjj"`
|
||||
RqTokenID *common.TokenID `json:"requestTokenId"`
|
||||
RqAmount *apitypes.StrBigInt `json:"requestAmount"`
|
||||
RqFee *common.FeeSelector `json:"requestFee"`
|
||||
RqNonce *common.Nonce `json:"requestNonce"`
|
||||
}
|
||||
|
||||
func (tx *receivedPoolTx) toPoolL2TxWrite() *l2db.PoolL2TxWrite {
|
||||
f := new(big.Float).SetInt((*big.Int)(&tx.Amount))
|
||||
amountF, _ := f.Float64()
|
||||
return &l2db.PoolL2TxWrite{
|
||||
TxID: tx.TxID,
|
||||
FromIdx: common.Idx(tx.FromIdx),
|
||||
ToIdx: (*common.Idx)(tx.ToIdx),
|
||||
ToEthAddr: (*ethCommon.Address)(tx.ToEthAddr),
|
||||
ToBJJ: (*babyjub.PublicKey)(tx.ToBJJ),
|
||||
TokenID: tx.TokenID,
|
||||
Amount: (*big.Int)(&tx.Amount),
|
||||
AmountFloat: amountF,
|
||||
Fee: tx.Fee,
|
||||
Nonce: tx.Nonce,
|
||||
State: common.PoolL2TxStatePending,
|
||||
Signature: tx.Signature,
|
||||
RqFromIdx: (*common.Idx)(tx.RqFromIdx),
|
||||
RqToIdx: (*common.Idx)(tx.RqToIdx),
|
||||
RqToEthAddr: (*ethCommon.Address)(tx.RqToEthAddr),
|
||||
RqToBJJ: (*babyjub.PublicKey)(tx.RqToBJJ),
|
||||
RqTokenID: tx.RqTokenID,
|
||||
RqAmount: (*big.Int)(tx.RqAmount),
|
||||
RqFee: tx.RqFee,
|
||||
RqNonce: tx.RqNonce,
|
||||
Type: tx.Type,
|
||||
}
|
||||
}
|
||||
|
||||
func verifyPoolL2TxWrite(txw *l2db.PoolL2TxWrite) error {
|
||||
poolTx := common.PoolL2Tx{
|
||||
TxID: txw.TxID,
|
||||
FromIdx: txw.FromIdx,
|
||||
ToBJJ: txw.ToBJJ,
|
||||
TokenID: txw.TokenID,
|
||||
Amount: txw.Amount,
|
||||
Fee: txw.Fee,
|
||||
Nonce: txw.Nonce,
|
||||
// State: txw.State,
|
||||
Signature: txw.Signature,
|
||||
RqToBJJ: txw.RqToBJJ,
|
||||
RqAmount: txw.RqAmount,
|
||||
Type: txw.Type,
|
||||
}
|
||||
// ToIdx
|
||||
if txw.ToIdx != nil {
|
||||
poolTx.ToIdx = *txw.ToIdx
|
||||
}
|
||||
// ToEthAddr
|
||||
if txw.ToEthAddr == nil {
|
||||
poolTx.ToEthAddr = common.EmptyAddr
|
||||
} else {
|
||||
poolTx.ToEthAddr = *txw.ToEthAddr
|
||||
}
|
||||
// RqFromIdx
|
||||
if txw.RqFromIdx != nil {
|
||||
poolTx.RqFromIdx = *txw.RqFromIdx
|
||||
}
|
||||
// RqToIdx
|
||||
if txw.RqToIdx != nil {
|
||||
poolTx.RqToIdx = *txw.RqToIdx
|
||||
}
|
||||
// RqToEthAddr
|
||||
if txw.RqToEthAddr == nil {
|
||||
poolTx.RqToEthAddr = common.EmptyAddr
|
||||
} else {
|
||||
poolTx.RqToEthAddr = *txw.RqToEthAddr
|
||||
}
|
||||
// RqTokenID
|
||||
if txw.RqTokenID != nil {
|
||||
poolTx.RqTokenID = *txw.RqTokenID
|
||||
}
|
||||
// RqFee
|
||||
if txw.RqFee != nil {
|
||||
poolTx.RqFee = *txw.RqFee
|
||||
}
|
||||
// RqNonce
|
||||
if txw.RqNonce != nil {
|
||||
poolTx.RqNonce = *txw.RqNonce
|
||||
}
|
||||
// Check type and id
|
||||
_, err := common.NewPoolL2Tx(&poolTx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Get public key
|
||||
account, err := s.GetAccount(poolTx.FromIdx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Check signature
|
||||
if !poolTx.VerifySignature(account.PublicKey) {
|
||||
return errors.New("wrong signature")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user