Add PoolL2Tx.Info about the status of the tx

PoolL2Tx.Info contains information about the status & State of the
transaction. As for example, if the Tx has not been selected in the last
batch due not enough Balance at the Sender account, this reason would
appear at this parameter.
This will help the client (wallet, batchexplorer, etc) to reason why a
L2Tx is not selected in the forged batches.
This commit is contained in:
arnaucube
2021-02-02 19:21:25 +01:00
parent 510d5c548c
commit a8f6891aea
12 changed files with 188 additions and 50 deletions

View File

@@ -94,6 +94,37 @@ func (l2db *L2DB) AddTx(tx *PoolL2TxWrite) error {
return tracerr.Wrap(meddler.Insert(l2db.db, "tx_pool", tx))
}
// UpdateTxsInfo updates the parameter Info of the pool transactions
func (l2db *L2DB) UpdateTxsInfo(txs []common.PoolL2Tx) error {
if len(txs) == 0 {
return nil
}
type txUpdate struct {
ID common.TxID `db:"id"`
Info string `db:"info"`
}
txUpdates := make([]txUpdate, len(txs))
for i := range txs {
txUpdates[i] = txUpdate{ID: txs[i].TxID, Info: txs[i].Info}
}
const query string = `
UPDATE tx_pool SET
info = tx_update.info
FROM (VALUES
(NULL::::BYTEA, NULL::::VARCHAR),
(:id, :info)
) as tx_update (id, info)
WHERE tx_pool.tx_id = tx_update.id;
`
if len(txUpdates) > 0 {
if _, err := sqlx.NamedExec(l2db.db, query, txUpdates); err != nil {
return tracerr.Wrap(err)
}
}
return nil
}
// AddTxTest inserts a tx into the L2DB. This is useful for test purposes,
// but in production txs will only be inserted through the API
func (l2db *L2DB) AddTxTest(tx *common.PoolL2Tx) error {
@@ -146,7 +177,7 @@ func (l2db *L2DB) AddTxTest(tx *common.PoolL2Tx) error {
const selectPoolTxAPI = `SELECT tx_pool.tx_id, hez_idx(tx_pool.from_idx, token.symbol) AS from_idx, tx_pool.effective_from_eth_addr,
tx_pool.effective_from_bjj, hez_idx(tx_pool.to_idx, token.symbol) AS to_idx, tx_pool.effective_to_eth_addr,
tx_pool.effective_to_bjj, tx_pool.token_id, tx_pool.amount, tx_pool.fee, tx_pool.nonce,
tx_pool.state, tx_pool.signature, tx_pool.timestamp, tx_pool.batch_num, hez_idx(tx_pool.rq_from_idx, token.symbol) AS rq_from_idx,
tx_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,
hez_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,
tx_pool.rq_fee, tx_pool.rq_nonce, tx_pool.tx_type,
token.item_id AS token_item_id, token.eth_block_num, token.eth_addr, token.name, token.symbol, token.decimals, token.usd, token.usd_update
@@ -155,7 +186,7 @@ FROM tx_pool INNER JOIN token ON tx_pool.token_id = token.token_id `
// selectPoolTxCommon select part of queries to get common.PoolL2Tx
const selectPoolTxCommon = `SELECT tx_pool.tx_id, from_idx, to_idx, tx_pool.to_eth_addr,
tx_pool.to_bjj, tx_pool.token_id, tx_pool.amount, tx_pool.fee, tx_pool.nonce,
tx_pool.state, tx_pool.signature, tx_pool.timestamp, rq_from_idx,
tx_pool.state, tx_pool.info, tx_pool.signature, tx_pool.timestamp, rq_from_idx,
rq_to_idx, tx_pool.rq_to_eth_addr, tx_pool.rq_to_bjj, tx_pool.rq_token_id, tx_pool.rq_amount,
tx_pool.rq_fee, tx_pool.rq_nonce, tx_pool.tx_type,
fee_percentage(tx_pool.fee::NUMERIC) * token.usd * tx_pool.amount_f AS fee_usd, token.usd_update

View File

@@ -162,6 +162,30 @@ func TestAddTxTest(t *testing.T) {
assert.Equal(t, 0, offset)
}
}
func TestUpdateTxsInfo(t *testing.T) {
err := prepareHistoryDB(historyDB)
if err != nil {
log.Error("Error prepare historyDB", err)
}
poolL2Txs, err := generatePoolL2Txs()
assert.NoError(t, err)
for i := range poolL2Txs {
err := l2DB.AddTxTest(&poolL2Txs[i])
require.NoError(t, err)
// once added, change the Info parameter
poolL2Txs[i].Info = "test"
}
// update the txs
err = l2DB.UpdateTxsInfo(poolL2Txs)
require.NoError(t, err)
for i := range poolL2Txs {
fetchedTx, err := l2DB.GetTx(poolL2Txs[i].TxID)
assert.NoError(t, err)
assert.Equal(t, "test", fetchedTx.Info)
}
}
func assertTx(t *testing.T, expected, actual *common.PoolL2Tx) {
// Check that timestamp has been set within the last 3 seconds

View File

@@ -49,6 +49,7 @@ type PoolTxAPI struct {
Fee common.FeeSelector `meddler:"fee"`
Nonce common.Nonce `meddler:"nonce"`
State common.PoolL2TxState `meddler:"state"`
Info *string `meddler:"info"`
Signature babyjub.SignatureComp `meddler:"signature"`
RqFromIdx *apitypes.HezIdx `meddler:"rq_from_idx"`
RqToIdx *apitypes.HezIdx `meddler:"rq_to_idx"`
@@ -90,6 +91,7 @@ func (tx PoolTxAPI) MarshalJSON() ([]byte, error) {
"fee": tx.Fee,
"nonce": tx.Nonce,
"state": tx.State,
"info": tx.Info,
"signature": tx.Signature,
"timestamp": tx.Timestamp,
"batchNum": tx.BatchNum,

View File

@@ -606,6 +606,7 @@ CREATE TABLE tx_pool (
fee SMALLINT NOT NULL,
nonce BIGINT NOT NULL,
state CHAR(4) NOT NULL,
info VARCHAR,
signature BYTEA NOT NULL,
timestamp TIMESTAMP WITHOUT TIME ZONE DEFAULT timezone('utc', now()),
batch_num BIGINT,