Impl api get batch(es)

This commit is contained in:
Arnau B
2020-10-26 10:43:34 +01:00
parent 7c8f380637
commit 28c0164525
15 changed files with 599 additions and 136 deletions

View File

@@ -150,15 +150,113 @@ func (hdb *HistoryDB) addBatches(d meddler.DB, batches []common.Batch) error {
return nil
}
// GetBatch return the batch with the given batchNum
func (hdb *HistoryDB) GetBatch(batchNum common.BatchNum) (HistoryBatch, error) {
var batch *common.Batch
// GetBatchAPI return the batch with the given batchNum
func (hdb *HistoryDB) GetBatchAPI(batchNum common.BatchNum) (*BatchAPI, error) {
batch := &BatchAPI{}
return batch, meddler.QueryRow(
hdb.db, &batch,
"SELECT * FROM batch WHERE batch_num == $1;", batchNum,
hdb.db, batch,
`SELECT batch.*, block.timestamp, block.hash
FROM batch INNER JOIN block ON batch.eth_block_num = block.eth_block_num
WHERE batch_num = $1;`, batchNum,
)
}
// GetBatchesAPI return the batches applying the given filters
func (hdb *HistoryDB) GetBatchesAPI(
minBatchNum, maxBatchNum, slotNum *uint,
forgerAddr *ethCommon.Address,
fromItem, limit *uint, order string,
) ([]BatchAPI, *db.Pagination, error) {
var query string
var args []interface{}
queryStr := `SELECT batch.*, block.timestamp, block.hash,
count(*) OVER() AS total_items, MIN(batch.item_id) OVER() AS first_item,
MAX(batch.item_id) OVER() AS last_item
FROM batch INNER JOIN block ON batch.eth_block_num = block.eth_block_num `
// Apply filters
nextIsAnd := false
// minBatchNum filter
if minBatchNum != nil {
if nextIsAnd {
queryStr += "AND "
} else {
queryStr += "WHERE "
}
queryStr += "batch.batch_num > ? "
args = append(args, minBatchNum)
nextIsAnd = true
}
// maxBatchNum filter
if maxBatchNum != nil {
if nextIsAnd {
queryStr += "AND "
} else {
queryStr += "WHERE "
}
queryStr += "batch.batch_num < ? "
args = append(args, maxBatchNum)
nextIsAnd = true
}
// slotNum filter
if slotNum != nil {
if nextIsAnd {
queryStr += "AND "
} else {
queryStr += "WHERE "
}
queryStr += "batch.slot_num = ? "
args = append(args, slotNum)
nextIsAnd = true
}
// forgerAddr filter
if forgerAddr != nil {
if nextIsAnd {
queryStr += "AND "
} else {
queryStr += "WHERE "
}
queryStr += "batch.forger_addr = ? "
args = append(args, forgerAddr)
nextIsAnd = true
}
// pagination
if fromItem != nil {
if nextIsAnd {
queryStr += "AND "
} else {
queryStr += "WHERE "
}
if order == OrderAsc {
queryStr += "batch.item_id >= ? "
} else {
queryStr += "batch.item_id <= ? "
}
args = append(args, fromItem)
}
queryStr += "ORDER BY batch.item_id "
if order == OrderAsc {
queryStr += " ASC "
} else {
queryStr += " DESC "
}
queryStr += fmt.Sprintf("LIMIT %d;", *limit)
query = hdb.db.Rebind(queryStr)
log.Debug(query)
batchPtrs := []*BatchAPI{}
if err := meddler.QueryAll(hdb.db, &batchPtrs, query, args...); err != nil {
return nil, nil, err
}
batches := db.SlicePtrsToSlice(batchPtrs).([]BatchAPI)
if len(batches) == 0 {
return nil, nil, sql.ErrNoRows
}
return batches, &db.Pagination{
TotalItems: batches[0].TotalItems,
FirstItem: batches[0].FirstItem,
LastItem: batches[0].LastItem,
}, nil
}
// GetBatches retrieve batches from the DB, given a range of batch numbers defined by from and to
func (hdb *HistoryDB) GetBatches(from, to common.BatchNum) ([]common.Batch, error) {
var batches []*common.Batch

View File

@@ -5,8 +5,8 @@ import (
"time"
ethCommon "github.com/ethereum/go-ethereum/common"
"github.com/hermeznetwork/hermez-node/apitypes"
"github.com/hermeznetwork/hermez-node/common"
"github.com/hermeznetwork/hermez-node/db"
"github.com/iden3/go-iden3-crypto/babyjub"
"github.com/iden3/go-merkletree"
)
@@ -133,23 +133,24 @@ type HistoryCoordinator struct {
LastItem int `meddler:"last_item"`
}
// HistoryBatch is a representation of a batch with additional information
// BatchAPI is a representation of a batch with additional information
// required by the API, and extracted by joining block table
type HistoryBatch struct {
ItemID int `json:"itemId" meddler:"item_id"`
BatchNum common.BatchNum `json:"batchNum" meddler:"batch_num"`
EthBlockNum int64 `json:"ethereumBlockNum" meddler:"eth_block_num"`
EthBlockHash ethCommon.Hash `json:"ethereumBlockHash" meddler:"hash"`
Timestamp time.Time `json:"timestamp" meddler:"timestamp,utctime"`
ForgerAddr ethCommon.Address `json:"forgerAddr" meddler:"forger_addr"`
CollectedFees map[common.TokenID]db.BigIntStr `json:"collectedFees" meddler:"fees_collected,json"`
TotalFeesUSD float64 `json:"historicTotalCollectedFeesUSD" meddler:"total_fees_usd"`
StateRoot db.BigIntStr `json:"stateRoot" meddler:"state_root"`
NumAccounts int `json:"numAccounts" meddler:"num_accounts"`
ExitRoot db.BigIntStr `json:"exitRoot" meddler:"exit_root"`
ForgeL1TxsNum *int64 `json:"forgeL1TransactionsNum" meddler:"forge_l1_txs_num"`
SlotNum int64 `json:"slotNum" meddler:"slot_num"`
TotalItems int `json:"-" meddler:"total_items"`
FirstItem int `json:"-" meddler:"first_item"`
LastItem int `json:"-" meddler:"last_item"`
type BatchAPI struct {
ItemID int `json:"itemId" meddler:"item_id"`
BatchNum common.BatchNum `json:"batchNum" meddler:"batch_num"`
EthBlockNum int64 `json:"ethereumBlockNum" meddler:"eth_block_num"`
EthBlockHash ethCommon.Hash `json:"ethereumBlockHash" meddler:"hash"`
Timestamp time.Time `json:"timestamp" meddler:"timestamp,utctime"`
ForgerAddr ethCommon.Address `json:"forgerAddr" meddler:"forger_addr"`
CollectedFees apitypes.CollectedFees `json:"collectedFees" meddler:"fees_collected,json"`
// CollectedFees map[common.TokenID]*big.Int `json:"collectedFees" meddler:"fees_collected,json"`
TotalFeesUSD *float64 `json:"historicTotalCollectedFeesUSD" meddler:"total_fees_usd"`
StateRoot apitypes.BigIntStr `json:"stateRoot" meddler:"state_root"`
NumAccounts int `json:"numAccounts" meddler:"num_accounts"`
ExitRoot apitypes.BigIntStr `json:"exitRoot" meddler:"exit_root"`
ForgeL1TxsNum *int64 `json:"forgeL1TransactionsNum" meddler:"forge_l1_txs_num"`
SlotNum int64 `json:"slotNum" meddler:"slot_num"`
TotalItems int `json:"-" meddler:"total_items"`
FirstItem int `json:"-" meddler:"first_item"`
LastItem int `json:"-" meddler:"last_item"`
}

View File

@@ -17,7 +17,7 @@ CREATE TABLE coordinator (
CREATE TABLE batch (
item_id SERIAL PRIMARY KEY,
batch_num BIGINT NOT NULL,
batch_num BIGINT UNIQUE NOT NULL,
eth_block_num BIGINT NOT NULL REFERENCES block (eth_block_num) ON DELETE CASCADE,
forger_addr BYTEA NOT NULL, -- fake foreign key for coordinator
fees_collected BYTEA NOT NULL,

View File

@@ -192,11 +192,3 @@ type Paginationer interface {
GetPagination() *Pagination
Len() int
}
// BigIntStr is used to Marshal *big.Int directly into strings
type BigIntStr big.Int
func (b BigIntStr) MarshalText() ([]byte, error) {
bigInt := big.Int(b)
return []byte((&bigInt).String()), nil
}