Skip to content

Commit

Permalink
indexer: drop concept of transaction id, hash is now the primary key
Browse files Browse the repository at this point in the history
 * api: remove endpoint /chain/transactions/reference/index/{index}

indexer migration:
 * 0013_recreate_table_transactions.sql
  • Loading branch information
altergui committed Aug 30, 2024
1 parent 50c3f98 commit 194de89
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 112 deletions.
38 changes: 0 additions & 38 deletions api/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,6 @@ func (a *API) enableChainHandlers() error {
); err != nil {
return err
}
if err := a.Endpoint.RegisterMethod(
"/chain/transactions/reference/index/{index}",
"GET",
apirest.MethodAccessTypePublic,
a.chainTxRefByIndexHandler,
); err != nil {
return err
}
if err := a.Endpoint.RegisterMethod(
"/chain/blocks/{height}/transactions/page/{page}",
"GET",
Expand Down Expand Up @@ -717,36 +709,6 @@ func (a *API) chainTxHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) er
return ctx.Send(data, apirest.HTTPstatusOK)
}

// chainTxRefByIndexHandler
//
// @Summary Transaction by index
// @Description Get transaction by its index. This is not transaction reference (hash), and neither the block height and block index. The transaction index is an incremental counter for each transaction. You could use the transaction `block` and `index` to retrieve full info using [transaction by block and index](transaction-by-block-index).
// @Tags Chain
// @Accept json
// @Produce json
// @Param index path int true "Index of the transaction"
// @Success 200 {object} indexertypes.Transaction
// @Success 204 "See [errors](vocdoni-api#errors) section"
// @Router /chain/transactions/reference/index/{index} [get]
func (a *API) chainTxRefByIndexHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) error {
index, err := strconv.ParseUint(ctx.URLParam("index"), 10, 64)
if err != nil {
return err
}
ref, err := a.indexer.GetTransaction(index)
if err != nil {
if errors.Is(err, indexer.ErrTransactionNotFound) {
return ErrTransactionNotFound
}
return ErrVochainGetTxFailed.WithErr(err)
}
data, err := json.Marshal(ref)
if err != nil {
return err
}
return ctx.Send(data, apirest.HTTPstatusOK)
}

// chainTxListHandler
//
// @Summary List transactions
Expand Down
4 changes: 2 additions & 2 deletions vochain/indexer/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,10 @@ func BenchmarkFetchTx(b *testing.B) {

startTime := time.Now()
for j := 0; j < numTxs; j++ {
_, err = idx.GetTransaction(uint64((i * numTxs) + j + 1))
_, err = idx.GetTxReferenceByBlockHeightAndBlockIndex(int64(i), int64(j))
qt.Assert(b, err, qt.IsNil)
}
log.Infof("fetched %d transactions (out of %d total) by index, took %s",
log.Infof("fetched %d transactions (out of %d total) by height+index, took %s",
numTxs, (i+1)*numTxs, time.Since(startTime))
startTime = time.Now()
for j := 0; j < numTxs; j++ {
Expand Down
10 changes: 0 additions & 10 deletions vochain/indexer/db/db.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion vochain/indexer/db/models.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 5 additions & 28 deletions vochain/indexer/db/transactions.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions vochain/indexer/indexer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1404,7 +1404,7 @@ func TestTxIndexer(t *testing.T) {

for i := 0; i < totalBlocks; i++ {
for j := 0; j < txsPerBlock; j++ {
ref, err := idx.GetTransaction(uint64(i*txsPerBlock + j + 1))
ref, err := idx.GetTxReferenceByBlockHeightAndBlockIndex(int64(i), int64(j))
qt.Assert(t, err, qt.IsNil)
qt.Assert(t, ref.BlockHeight, qt.Equals, uint32(i))
qt.Assert(t, ref.TxBlockIndex, qt.Equals, int32(j))
Expand All @@ -1422,8 +1422,6 @@ func TestTxIndexer(t *testing.T) {
txs, _, err := idx.SearchTransactions(15, 0, 0, "")
qt.Assert(t, err, qt.IsNil)
for i, tx := range txs {
// Index is between 1 and totalCount.
qt.Assert(t, tx.Index, qt.Equals, uint64(totalTxs-i))
// BlockIndex and TxBlockIndex start at 0, so subtract 1.
qt.Assert(t, tx.BlockHeight, qt.Equals, uint32(totalTxs-i-1)/txsPerBlock)
qt.Assert(t, tx.TxBlockIndex, qt.Equals, int32(totalTxs-i-1)%txsPerBlock)
Expand All @@ -1433,7 +1431,6 @@ func TestTxIndexer(t *testing.T) {
txs, _, err = idx.SearchTransactions(1, 5, 0, "")
qt.Assert(t, err, qt.IsNil)
qt.Assert(t, txs, qt.HasLen, 1)
qt.Assert(t, txs[0].Index, qt.Equals, uint64(95))
}

func TestCensusUpdate(t *testing.T) {
Expand Down
10 changes: 0 additions & 10 deletions vochain/indexer/indexertypes/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,17 +176,8 @@ type TxPackage struct {
Signature types.HexBytes `json:"signature"`
}

// TxMetadata contains tx information for the TransactionList api
type TxMetadata struct {
Type string `json:"type"`
BlockHeight uint32 `json:"blockHeight,omitempty"`
Index int32 `json:"index"`
Hash types.HexBytes `json:"hash"`
}

// Transaction holds the db reference for a single transaction
type Transaction struct {
Index uint64 `json:"transactionNumber" format:"int64" example:"944"`
Hash types.HexBytes `json:"transactionHash" swaggertype:"string" example:"75e8f822f5dd13973ac5158d600f0a2a5fea4bfefce9712ab5195bf17884cfad"`
BlockHeight uint32 `json:"blockHeight" format:"int32" example:"64924"`
TxBlockIndex int32 `json:"transactionIndex" format:"int32" example:"0"`
Expand All @@ -195,7 +186,6 @@ type Transaction struct {

func TransactionFromDB(dbtx *indexerdb.Transaction) *Transaction {
return &Transaction{
Index: uint64(dbtx.ID),
Hash: dbtx.Hash,
BlockHeight: uint32(dbtx.BlockHeight),
TxBlockIndex: int32(dbtx.BlockIndex),
Expand Down
56 changes: 56 additions & 0 deletions vochain/indexer/migrations/0013_recreate_table_transactions.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
-- +goose Up
PRAGMA foreign_keys = OFF;

-- Create a new table with hash as primary key
CREATE TABLE transactions_new (
hash BLOB NOT NULL PRIMARY KEY,
block_height INTEGER NOT NULL,
block_index INTEGER NOT NULL,
type TEXT NOT NULL
);

-- Copy data from the old table to the new table
INSERT INTO transactions_new (hash, block_height, block_index, type)
SELECT hash, block_height, block_index, type
FROM transactions;

-- Drop the old table
DROP TABLE transactions;

-- Rename the new table to the old table name
ALTER TABLE transactions_new RENAME TO transactions;

-- Recreate necessary indexes
CREATE INDEX transactions_block_height_index
ON transactions(block_height, block_index);

PRAGMA foreign_keys = ON;

-- +goose Down
PRAGMA foreign_keys = OFF;

-- Recreate the old table structure
CREATE TABLE transactions (
id INTEGER NOT NULL PRIMARY KEY,
hash BLOB NOT NULL,
block_height INTEGER NOT NULL,
block_index INTEGER NOT NULL,
type TEXT NOT NULL
);

-- Copy data back from the new table to the old table
INSERT INTO transactions (hash, block_height, block_index, type)
SELECT hash, block_height, block_index, type
FROM transactions_new;

-- Drop the new table
DROP TABLE transactions_new;

-- Recreate the old indexes
CREATE INDEX transactions_hash
ON transactions(hash);

CREATE INDEX transactions_block_height_index
ON transactions(block_height, block_index);

PRAGMA foreign_keys = ON;
7 changes: 1 addition & 6 deletions vochain/indexer/queries/transactions.sql
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@ INSERT INTO transactions (
?, ?, ?, ?
);

-- name: GetTransaction :one
SELECT * FROM transactions
WHERE id = ?
LIMIT 1;

-- name: GetTransactionByHash :one
SELECT * FROM transactions
WHERE hash = ?
Expand All @@ -34,6 +29,6 @@ WITH results AS (
)
SELECT *, COUNT(*) OVER() AS total_count
FROM results
ORDER BY id DESC
ORDER BY block_height DESC, block_index DESC
LIMIT sqlc.arg(limit)
OFFSET sqlc.arg(offset);
13 changes: 0 additions & 13 deletions vochain/indexer/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,6 @@ func (idx *Indexer) CountTotalTransactions() (uint64, error) {
return uint64(count), err
}

// GetTransaction fetches the txReference for the given tx height
func (idx *Indexer) GetTransaction(id uint64) (*indexertypes.Transaction, error) {
sqlTxRef, err := idx.readOnlyQuery.GetTransaction(context.TODO(), int64(id))
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, ErrTransactionNotFound
}
return nil, fmt.Errorf("tx with id %d not found: %v", id, err)
}
return indexertypes.TransactionFromDB(&sqlTxRef), nil
}

// GetTxReferenceByBlockHeightAndBlockIndex fetches the txReference for the given tx height and block tx index
func (idx *Indexer) GetTxReferenceByBlockHeightAndBlockIndex(blockHeight, blockIndex int64) (*indexertypes.Transaction, error) {
sqlTxRef, err := idx.readOnlyQuery.GetTxReferenceByBlockHeightAndBlockIndex(context.TODO(), indexerdb.GetTxReferenceByBlockHeightAndBlockIndexParams{
Expand Down Expand Up @@ -83,7 +71,6 @@ func (idx *Indexer) SearchTransactions(limit, offset int, blockHeight uint64, tx
list := []*indexertypes.Transaction{}
for _, row := range results {
list = append(list, &indexertypes.Transaction{
Index: uint64(row.ID),
Hash: row.Hash,
BlockHeight: uint32(row.BlockHeight),
TxBlockIndex: int32(row.BlockIndex),
Expand Down

0 comments on commit 194de89

Please sign in to comment.