arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
hermez-node/db/l2db/apiqueries.go
db/l2db/apiqueries.goRaw
  1package l2db
  2
  3import (
  4	"fmt"
  5
  6	ethCommon "github.com/ethereum/go-ethereum/common"
  7	"github.com/hermeznetwork/hermez-node/common"
  8	"github.com/hermeznetwork/tracerr"
  9	"github.com/russross/meddler"
 10)
 11
 12var (
 13	errPoolFull = fmt.Errorf("the pool is at full capacity. More transactions are not accepted currently")
 14)
 15
 16// AddAccountCreationAuthAPI inserts an account creation authorization into the DB
 17func (l2db *L2DB) AddAccountCreationAuthAPI(auth *common.AccountCreationAuth) error {
 18	cancel, err := l2db.apiConnCon.Acquire()
 19	defer cancel()
 20	if err != nil {
 21		return tracerr.Wrap(err)
 22	}
 23	defer l2db.apiConnCon.Release()
 24	return l2db.AddAccountCreationAuth(auth)
 25}
 26
 27// GetAccountCreationAuthAPI returns an account creation authorization from the DB
 28func (l2db *L2DB) GetAccountCreationAuthAPI(addr ethCommon.Address) (*AccountCreationAuthAPI, error) {
 29	cancel, err := l2db.apiConnCon.Acquire()
 30	defer cancel()
 31	if err != nil {
 32		return nil, tracerr.Wrap(err)
 33	}
 34	defer l2db.apiConnCon.Release()
 35	auth := new(AccountCreationAuthAPI)
 36	return auth, tracerr.Wrap(meddler.QueryRow(
 37		l2db.dbRead, auth,
 38		"SELECT * FROM account_creation_auth WHERE eth_addr = $1;",
 39		addr,
 40	))
 41}
 42
 43// AddTxAPI inserts a tx to the pool
 44func (l2db *L2DB) AddTxAPI(tx *PoolL2TxWrite) error {
 45	cancel, err := l2db.apiConnCon.Acquire()
 46	defer cancel()
 47	if err != nil {
 48		return tracerr.Wrap(err)
 49	}
 50	defer l2db.apiConnCon.Release()
 51
 52	row := l2db.dbRead.QueryRow(`SELECT
 53		($1::NUMERIC * COALESCE(token.usd, 0) * fee_percentage($2::NUMERIC)) /
 54			(10.0 ^ token.decimals::NUMERIC)
 55		FROM token WHERE token.token_id = $3;`,
 56		tx.AmountFloat, tx.Fee, tx.TokenID)
 57	var feeUSD float64
 58	if err := row.Scan(&feeUSD); err != nil {
 59		return tracerr.Wrap(err)
 60	}
 61	if feeUSD < l2db.minFeeUSD {
 62		return tracerr.Wrap(fmt.Errorf("tx.feeUSD (%v) < minFeeUSD (%v)",
 63			feeUSD, l2db.minFeeUSD))
 64	}
 65
 66	// Prepare insert SQL query argument parameters
 67	namesPart, err := meddler.Default.ColumnsQuoted(tx, false)
 68	if err != nil {
 69		return err
 70	}
 71	valuesPart, err := meddler.Default.PlaceholdersString(tx, false)
 72	if err != nil {
 73		return err
 74	}
 75	values, err := meddler.Default.Values(tx, false)
 76	if err != nil {
 77		return err
 78	}
 79
 80	q := fmt.Sprintf(
 81		`INSERT INTO tx_pool (%s)
 82		SELECT %s
 83		WHERE (SELECT COUNT(*) FROM tx_pool WHERE state = $%v AND NOT external_delete) < $%v;`,
 84		namesPart, valuesPart,
 85		len(values)+1, len(values)+2) //nolint:gomnd
 86	values = append(values, common.PoolL2TxStatePending, l2db.maxTxs)
 87	res, err := l2db.dbWrite.Exec(q, values...)
 88	if err != nil {
 89		return tracerr.Wrap(err)
 90	}
 91	rowsAffected, err := res.RowsAffected()
 92	if err != nil {
 93		return tracerr.Wrap(err)
 94	}
 95	if rowsAffected == 0 {
 96		return tracerr.Wrap(errPoolFull)
 97	}
 98	return nil
 99}
100
101// selectPoolTxAPI select part of queries to get PoolL2TxRead
102const selectPoolTxAPI = `SELECT  tx_pool.tx_id, hez_idx(tx_pool.from_idx, token.symbol) AS from_idx, tx_pool.effective_from_eth_addr, 
103tx_pool.effective_from_bjj, hez_idx(tx_pool.to_idx, token.symbol) AS to_idx, tx_pool.effective_to_eth_addr, 
104tx_pool.effective_to_bjj, tx_pool.token_id, tx_pool.amount, tx_pool.fee, tx_pool.nonce, 
105tx_pool.state, tx_pool.info, tx_pool.signature, tx_pool.timestamp, tx_pool.batch_num, hez_idx(tx_pool.rq_from_idx, token.symbol) AS rq_from_idx, 
106hez_idx(tx_pool.rq_to_idx, token.symbol) AS rq_to_idx, tx_pool.rq_to_eth_addr, tx_pool.rq_to_bjj, tx_pool.rq_token_id, tx_pool.rq_amount, 
107tx_pool.rq_fee, tx_pool.rq_nonce, tx_pool.tx_type, 
108token.item_id AS token_item_id, token.eth_block_num, token.eth_addr, token.name, token.symbol, token.decimals, token.usd, token.usd_update 
109FROM tx_pool INNER JOIN token ON tx_pool.token_id = token.token_id `
110
111// GetTxAPI return the specified Tx in PoolTxAPI format
112func (l2db *L2DB) GetTxAPI(txID common.TxID) (*PoolTxAPI, error) {
113	cancel, err := l2db.apiConnCon.Acquire()
114	defer cancel()
115	if err != nil {
116		return nil, tracerr.Wrap(err)
117	}
118	defer l2db.apiConnCon.Release()
119	tx := new(PoolTxAPI)
120	return tx, tracerr.Wrap(meddler.QueryRow(
121		l2db.dbRead, tx,
122		selectPoolTxAPI+"WHERE tx_id = $1;",
123		txID,
124	))
125}