mirror of
https://github.com/alexgo-io/gaze-indexer.git
synced 2026-04-30 12:41:59 +08:00
feat: implement get indexed block
This commit is contained in:
@@ -32,6 +32,9 @@ SELECT * FROM runes_processor_state;
|
||||
-- name: UpdateLatestBlock :exec
|
||||
UPDATE runes_processor_state SET latest_block_height = $1, latest_block_hash = $2, latest_prev_block_hash = $3;
|
||||
|
||||
-- name: GetIndexedBlockByHeight :one
|
||||
SELECT * FROM runes_indexed_blocks WHERE height = $1;
|
||||
|
||||
-- name: CreateIndexedBlock :exec
|
||||
INSERT INTO runes_indexed_blocks (hash, height, event_hash, cumulative_event_hash) VALUES ($1, $2, $3, $4);
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package datagateway
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/gaze-network/indexer-network/core/types"
|
||||
"github.com/gaze-network/indexer-network/modules/runes/internal/entity"
|
||||
@@ -17,6 +18,7 @@ type RunesDataGateway interface {
|
||||
|
||||
type RunesReaderDataGateway interface {
|
||||
GetLatestBlock(ctx context.Context) (types.BlockHeader, error)
|
||||
GetIndexedBlockByHeight(ctx context.Context, height int64) (*entity.IndexedBlock, error)
|
||||
|
||||
GetRunesBalancesAtOutPoint(ctx context.Context, outPoint wire.OutPoint) (map[runes.RuneId]uint128.Uint128, error)
|
||||
// GetRuneEntryByRune returns the RuneEntry for the given rune. Returns errs.NotFound if the rune entry is not found.
|
||||
@@ -47,6 +49,9 @@ type RunesWriterDataGateway interface {
|
||||
CreateRuneBalancesAtOutPoint(ctx context.Context, outPoint wire.OutPoint, balances map[runes.RuneId]uint128.Uint128) error
|
||||
CreateRuneBalancesAtBlock(ctx context.Context, params []CreateRuneBalancesAtBlockParams) error
|
||||
UpdateLatestBlock(ctx context.Context, blockHeader types.BlockHeader) error
|
||||
|
||||
CreateIndexedBlock(ctx context.Context, block *entity.IndexedBlock) error
|
||||
DeleteIndexedBlockByHash(ctx context.Context, hash chainhash.Hash) error
|
||||
}
|
||||
|
||||
type CreateRuneBalancesAtBlockParams struct {
|
||||
|
||||
10
modules/runes/internal/entity/indexed_block.go
Normal file
10
modules/runes/internal/entity/indexed_block.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package entity
|
||||
|
||||
import "github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
|
||||
type IndexedBlock struct {
|
||||
Height int64
|
||||
Hash chainhash.Hash
|
||||
EventHash chainhash.Hash
|
||||
CumulativeEventHash chainhash.Hash
|
||||
}
|
||||
@@ -109,6 +109,22 @@ func (q *Queries) GetBalancesByRuneId(ctx context.Context, arg GetBalancesByRune
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getIndexedBlockByHeight = `-- name: GetIndexedBlockByHeight :one
|
||||
SELECT hash, height, event_hash, cumulative_event_hash FROM runes_indexed_blocks WHERE height = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetIndexedBlockByHeight(ctx context.Context, height int32) (RunesIndexedBlock, error) {
|
||||
row := q.db.QueryRow(ctx, getIndexedBlockByHeight, height)
|
||||
var i RunesIndexedBlock
|
||||
err := row.Scan(
|
||||
&i.Hash,
|
||||
&i.Height,
|
||||
&i.EventHash,
|
||||
&i.CumulativeEventHash,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getOutPointBalances = `-- name: GetOutPointBalances :many
|
||||
SELECT rune_id, tx_hash, tx_idx, amount, block_height, spent_height FROM runes_outpoint_balances WHERE tx_hash = $1 AND tx_idx = $2
|
||||
`
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/hex"
|
||||
"time"
|
||||
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/cockroachdb/errors"
|
||||
"github.com/gaze-network/indexer-network/modules/runes/internal/entity"
|
||||
"github.com/gaze-network/indexer-network/modules/runes/internal/repository/postgres/gen"
|
||||
@@ -217,3 +218,33 @@ func mapBalanceModelToType(src gen.RunesBalance) (*entity.Balance, error) {
|
||||
BlockHeight: uint64(src.BlockHeight),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func mapIndexedBlockModelToType(src gen.RunesIndexedBlock) (*entity.IndexedBlock, error) {
|
||||
hash, err := chainhash.NewHashFromStr(src.Hash)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parse block hash")
|
||||
}
|
||||
eventHash, err := chainhash.NewHashFromStr(src.EventHash)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parse event hash")
|
||||
}
|
||||
cumulativeEventHash, err := chainhash.NewHashFromStr(src.CumulativeEventHash)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parse cumulative event hash")
|
||||
}
|
||||
return &entity.IndexedBlock{
|
||||
Height: int64(src.Height),
|
||||
Hash: *hash,
|
||||
EventHash: *eventHash,
|
||||
CumulativeEventHash: *cumulativeEventHash,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func mapIndexedBlockTypeToParams(src entity.IndexedBlock) (gen.CreateIndexedBlockParams, error) {
|
||||
return gen.CreateIndexedBlockParams{
|
||||
Height: int32(src.Height),
|
||||
Hash: src.Hash.String(),
|
||||
EventHash: src.EventHash.String(),
|
||||
CumulativeEventHash: src.CumulativeEventHash.String(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ import (
|
||||
|
||||
var _ datagateway.RunesDataGateway = (*Repository)(nil)
|
||||
|
||||
// warning: GetLatestBlock currently returns a types.BlockHeader with only Height, Hash, and PrevBlock fields populated.
|
||||
// This is because it is known that all usage of this function only requires these fields. In the future, we may want to populate all fields for type safety.
|
||||
func (r *Repository) GetLatestBlock(ctx context.Context) (types.BlockHeader, error) {
|
||||
state, err := r.queries.GetRunesProcessorState(ctx)
|
||||
if err != nil {
|
||||
@@ -40,6 +42,19 @@ func (r *Repository) GetLatestBlock(ctx context.Context) (types.BlockHeader, err
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *Repository) GetIndexedBlockByHeight(ctx context.Context, height int64) (*entity.IndexedBlock, error) {
|
||||
indexedBlockModel, err := r.queries.GetIndexedBlockByHeight(ctx, int32(height))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error during query")
|
||||
}
|
||||
|
||||
indexedBlock, err := mapIndexedBlockModelToType(indexedBlockModel)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parse indexed block model")
|
||||
}
|
||||
return indexedBlock, nil
|
||||
}
|
||||
|
||||
func (r *Repository) GetRunesBalancesAtOutPoint(ctx context.Context, outPoint wire.OutPoint) (map[runes.RuneId]uint128.Uint128, error) {
|
||||
balances, err := r.queries.GetOutPointBalances(ctx, gen.GetOutPointBalancesParams{
|
||||
TxHash: outPoint.Hash.String(),
|
||||
@@ -241,3 +256,24 @@ func (r *Repository) GetBalancesByRuneId(ctx context.Context, runeId runes.RuneI
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (r *Repository) CreateIndexedBlock(ctx context.Context, block *entity.IndexedBlock) error {
|
||||
if block == nil {
|
||||
return nil
|
||||
}
|
||||
params, err := mapIndexedBlockTypeToParams(*block)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to map indexed block to params")
|
||||
}
|
||||
if err = r.queries.CreateIndexedBlock(ctx, params); err != nil {
|
||||
return errors.Wrap(err, "error during exec")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Repository) DeleteIndexedBlockByHash(ctx context.Context, hash chainhash.Hash) error {
|
||||
if err := r.queries.DeleteIndexedBlockByHash(ctx, hash.String()); err != nil {
|
||||
return errors.Wrap(err, "error during exec")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -45,6 +45,19 @@ func (p *Processor) CurrentBlock(ctx context.Context) (types.BlockHeader, error)
|
||||
return blockHeader, nil
|
||||
}
|
||||
|
||||
// warning: GetIndexedBlock currently returns a types.BlockHeader with only Height, Hash fields populated.
|
||||
// This is because it is known that all usage of this function only requires these fields. In the future, we may want to populate all fields for type safety.
|
||||
func (p *Processor) GetIndexedBlock(ctx context.Context, height int64) (types.BlockHeader, error) {
|
||||
block, err := p.runesDg.GetIndexedBlockByHeight(ctx, height)
|
||||
if err != nil {
|
||||
return types.BlockHeader{}, errors.Wrap(err, "failed to get indexed block")
|
||||
}
|
||||
return types.BlockHeader{
|
||||
Height: block.Height,
|
||||
Hash: block.Hash,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *Processor) PrepareData(ctx context.Context, from, to int64) ([]*types.Block, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ func (p *Processor) Process(ctx context.Context, blocks []*types.Block) error {
|
||||
return errors.Wrap(err, "failed to process tx")
|
||||
}
|
||||
}
|
||||
// TODO: create indexed block in db
|
||||
}
|
||||
if err := p.runesDg.Commit(ctx); err != nil {
|
||||
return errors.Wrap(err, "failed to commit transaction")
|
||||
|
||||
Reference in New Issue
Block a user