Compare commits

..

15 Commits

Author SHA1 Message Date
gazenw
58334dd3e4 Merge pull request #72 from gaze-network/develop
feat: add etching tx hash for runes info api
2024-10-26 20:56:01 +07:00
Gaze
cffe378beb feat: add etching tx hash for runes info api 2024-10-25 16:22:24 +07:00
gazenw
9a7ee49228 Merge pull request #71 from gaze-network/develop
Release v0.6.0
2024-10-17 14:35:19 +07:00
gazenw
9739f61067 feat: implement batch insert using multirow inserts (#70)
* feat: add new batch inserts

* fix: migration

* fix: add casting to unnest with patch

* fix: add UTC() to timestamp mappers

* chore: unused imports

* chore: remove unnecessary comments
2024-10-17 14:34:04 +07:00
gazenw
f1267b387e Merge pull request #69 from gaze-network/develop
Release v0.5.6
2024-10-15 17:59:34 +07:00
gazenw
8883c24c77 fix: only call VerifyStates if not api only (#68) 2024-10-15 17:58:51 +07:00
gazenw
e9ce8df01a Merge pull request #67 from gaze-network/develop
Release v0.5.5
2024-10-11 14:25:05 +07:00
Gaze
3ff73a99f8 Merge branch 'main' into develop 2024-10-11 14:24:36 +07:00
gazenw
96afdfd255 fix: order get ongoing tokens by mint transactions (#66) 2024-10-11 14:23:31 +07:00
gazenw
c49e39be97 feat: optimize flush speed for Runes (#65)
* feat: switch to batchexec for faster inserts

* feat: add time taken log

* feat: add process time log

* feat: add event logs
2024-10-11 14:21:26 +07:00
Gaze
12985ae432 feat: remove conns timeout 2024-10-08 01:14:24 +07:00
Gaze
2d51e52b83 feat: support to config 2024-10-08 01:12:49 +07:00
Gaze
618220d0cb feat: support high httpclient conns 2024-10-08 00:44:24 +07:00
gazenw
6004744721 Merge pull request #64 from gaze-network/develop
Release v0.5.1
2024-10-07 21:18:11 +07:00
gazenw
90ed7bc350 fix: update sql (#63) 2024-10-07 21:17:16 +07:00
16 changed files with 1088 additions and 371 deletions

View File

@@ -41,13 +41,14 @@ type entryTerms struct {
}
type entry struct {
Divisibility uint8 `json:"divisibility"`
Premine uint128.Uint128 `json:"premine"`
Rune runes.Rune `json:"rune"`
Spacers uint32 `json:"spacers"`
Symbol string `json:"symbol"`
Terms entryTerms `json:"terms"`
Turbo bool `json:"turbo"`
Divisibility uint8 `json:"divisibility"`
Premine uint128.Uint128 `json:"premine"`
Rune runes.Rune `json:"rune"`
Spacers uint32 `json:"spacers"`
Symbol string `json:"symbol"`
Terms entryTerms `json:"terms"`
Turbo bool `json:"turbo"`
EtchingTxHash string `json:"etchingTxHash"`
}
type tokenInfoExtend struct {
@@ -170,7 +171,8 @@ func (h *HttpHandler) GetTokenInfo(ctx *fiber.Ctx) (err error) {
OffsetStart: terms.OffsetStart,
OffsetEnd: terms.OffsetEnd,
},
Turbo: runeEntry.Turbo,
Turbo: runeEntry.Turbo,
EtchingTxHash: runeEntry.EtchingTxHash.String(),
},
},
},

View File

@@ -1,6 +1,6 @@
BEGIN;
CREATE EXTENSION pg_trgm;
CREATE EXTENSION IF NOT EXISTS pg_trgm;
-- Indexer Client Information
CREATE TABLE IF NOT EXISTS "runes_indexer_stats" (

View File

@@ -0,0 +1,104 @@
-- name: BatchCreateRunesBalances :exec
INSERT INTO runes_balances ("pkscript", "block_height", "rune_id", "amount")
VALUES(
unnest(@pkscript_arr::TEXT[]),
unnest(@block_height_arr::INT[]),
unnest(@rune_id_arr::TEXT[]),
unnest(@amount_arr::DECIMAL[])
);
-- name: BatchCreateRuneEntries :exec
INSERT INTO runes_entries ("rune_id", "rune", "number", "spacers", "premine", "symbol", "divisibility", "terms", "terms_amount", "terms_cap", "terms_height_start", "terms_height_end", "terms_offset_start", "terms_offset_end", "turbo", "etching_block", "etching_tx_hash", "etched_at")
VALUES(
unnest(@rune_id_arr::TEXT[]),
unnest(@rune_arr::TEXT[]),
unnest(@number_arr::BIGINT[]),
unnest(@spacers_arr::INT[]),
unnest(@premine_arr::DECIMAL[]),
unnest(@symbol_arr::INT[]),
unnest(@divisibility_arr::SMALLINT[]),
unnest(@terms_arr::BOOLEAN[]),
unnest(@terms_amount_arr::DECIMAL[]),
unnest(@terms_cap_arr::DECIMAL[]),
unnest(@terms_height_start_arr::INT[]), -- nullable (need patch)
unnest(@terms_height_end_arr::INT[]), -- nullable (need patch)
unnest(@terms_offset_start_arr::INT[]), -- nullable (need patch)
unnest(@terms_offset_end_arr::INT[]), -- nullable (need patch)
unnest(@turbo_arr::BOOLEAN[]),
unnest(@etching_block_arr::INT[]),
unnest(@etching_tx_hash_arr::TEXT[]),
unnest(@etched_at_arr::TIMESTAMP[])
);
-- name: BatchCreateRuneEntryStates :exec
INSERT INTO runes_entry_states ("rune_id", "block_height", "mints", "burned_amount", "completed_at", "completed_at_height")
VALUES(
unnest(@rune_id_arr::TEXT[]),
unnest(@block_height_arr::INT[]),
unnest(@mints_arr::DECIMAL[]),
unnest(@burned_amount_arr::DECIMAL[]),
unnest(@completed_at_arr::TIMESTAMP[]),
unnest(@completed_at_height_arr::INT[]) -- nullable (need patch)
);
-- name: BatchCreateRunesOutpointBalances :exec
INSERT INTO runes_outpoint_balances ("rune_id", "pkscript", "tx_hash", "tx_idx", "amount", "block_height", "spent_height")
VALUES(
unnest(@rune_id_arr::TEXT[]),
unnest(@pkscript_arr::TEXT[]),
unnest(@tx_hash_arr::TEXT[]),
unnest(@tx_idx_arr::INT[]),
unnest(@amount_arr::DECIMAL[]),
unnest(@block_height_arr::INT[]),
unnest(@spent_height_arr::INT[]) -- nullable (need patch)
);
-- name: BatchSpendOutpointBalances :exec
UPDATE runes_outpoint_balances
SET "spent_height" = @spent_height::INT
FROM (
SELECT
unnest(@tx_hash_arr::TEXT[]) AS tx_hash,
unnest(@tx_idx_arr::INT[]) AS tx_idx
) AS input
WHERE "runes_outpoint_balances"."tx_hash" = "input"."tx_hash" AND "runes_outpoint_balances"."tx_idx" = "input"."tx_idx";
-- name: BatchCreateRunestones :exec
INSERT INTO runes_runestones ("tx_hash", "block_height", "etching", "etching_divisibility", "etching_premine", "etching_rune", "etching_spacers", "etching_symbol", "etching_terms", "etching_terms_amount", "etching_terms_cap", "etching_terms_height_start", "etching_terms_height_end", "etching_terms_offset_start", "etching_terms_offset_end", "etching_turbo", "edicts", "mint", "pointer", "cenotaph", "flaws")
VALUES(
unnest(@tx_hash_arr::TEXT[]),
unnest(@block_height_arr::INT[]),
unnest(@etching_arr::BOOLEAN[]),
unnest(@etching_divisibility_arr::SMALLINT[]), -- nullable (need patch)
unnest(@etching_premine_arr::DECIMAL[]),
unnest(@etching_rune_arr::TEXT[]), -- nullable (need patch)
unnest(@etching_spacers_arr::INT[]), -- nullable (need patch)
unnest(@etching_symbol_arr::INT[]), -- nullable (need patch)
unnest(@etching_terms_arr::BOOLEAN[]), -- nullable (need patch)
unnest(@etching_terms_amount_arr::DECIMAL[]),
unnest(@etching_terms_cap_arr::DECIMAL[]),
unnest(@etching_terms_height_start_arr::INT[]), -- nullable (need patch)
unnest(@etching_terms_height_end_arr::INT[]), -- nullable (need patch)
unnest(@etching_terms_offset_start_arr::INT[]), -- nullable (need patch)
unnest(@etching_terms_offset_end_arr::INT[]), -- nullable (need patch)
unnest(@etching_turbo_arr::BOOLEAN[]), -- nullable (need patch)
unnest(@edicts_arr::JSONB[]),
unnest(@mint_arr::TEXT[]), -- nullable (need patch)
unnest(@pointer_arr::INT[]), -- nullable (need patch)
unnest(@cenotaph_arr::BOOLEAN[]),
unnest(@flaws_arr::INT[])
);
-- name: BatchCreateRuneTransactions :exec
INSERT INTO runes_transactions ("hash", "block_height", "index", "timestamp", "inputs", "outputs", "mints", "burns", "rune_etched")
VALUES (
unnest(@hash_arr::TEXT[]),
unnest(@block_height_arr::INT[]),
unnest(@index_arr::INT[]),
unnest(@timestamp_arr::TIMESTAMP[]),
unnest(@inputs_arr::JSONB[]),
unnest(@outputs_arr::JSONB[]),
unnest(@mints_arr::JSONB[]),
unnest(@burns_arr::JSONB[]),
unnest(@rune_etched_arr::BOOLEAN[])
);

View File

@@ -86,6 +86,8 @@ SELECT * FROM runes_entries
LEFT JOIN states ON runes_entries.rune_id = states.rune_id
WHERE (
runes_entries.terms = TRUE AND
COALESCE(runes_entries.terms_amount, 0) != 0 AND
COALESCE(runes_entries.terms_cap, 0) != 0 AND
states.mints < runes_entries.terms_cap AND
(
runes_entries.terms_height_start IS NULL OR runes_entries.terms_height_start <= @height::integer
@@ -99,9 +101,9 @@ SELECT * FROM runes_entries
) AND (
@search::text = '' OR
runes_entries.rune ILIKE @search::text || '%'
runes_entries.rune ILIKE '%' || @search::text || '%'
)
ORDER BY (states.mints / runes_entries.terms_cap::float) DESC
ORDER BY states.mints DESC
LIMIT @_limit OFFSET @_offset;
-- name: GetRuneIdFromRune :one
@@ -148,13 +150,13 @@ INSERT INTO runes_transactions (hash, block_height, index, timestamp, inputs, ou
INSERT INTO runes_runestones (tx_hash, block_height, etching, etching_divisibility, etching_premine, etching_rune, etching_spacers, etching_symbol, etching_terms, etching_terms_amount, etching_terms_cap, etching_terms_height_start, etching_terms_height_end, etching_terms_offset_start, etching_terms_offset_end, etching_turbo, edicts, mint, pointer, cenotaph, flaws)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21);
-- name: CreateOutPointBalances :batchexec
-- name: CreateOutPointBalance :exec
INSERT INTO runes_outpoint_balances (rune_id, pkscript, tx_hash, tx_idx, amount, block_height, spent_height) VALUES ($1, $2, $3, $4, $5, $6, $7);
-- name: SpendOutPointBalances :exec
-- name: SpendOutPointBalance :exec
UPDATE runes_outpoint_balances SET spent_height = $1 WHERE tx_hash = $2 AND tx_idx = $3;
-- name: CreateRuneBalanceAtBlock :batchexec
-- name: CreateRuneBalance :exec
INSERT INTO runes_balances (pkscript, block_height, rune_id, amount) VALUES ($1, $2, $3, $4);
-- name: GetLatestIndexedBlock :one

View File

@@ -8,7 +8,6 @@ import (
"github.com/gaze-network/indexer-network/core/types"
"github.com/gaze-network/indexer-network/modules/runes/internal/entity"
"github.com/gaze-network/indexer-network/modules/runes/runes"
"github.com/gaze-network/uint128"
)
type RunesDataGateway interface {
@@ -65,12 +64,12 @@ type RunesReaderDataGateway interface {
}
type RunesWriterDataGateway interface {
CreateRuneEntry(ctx context.Context, entry *runes.RuneEntry, blockHeight uint64) error
CreateRuneEntryState(ctx context.Context, entry *runes.RuneEntry, blockHeight uint64) error
CreateRuneEntries(ctx context.Context, entries []*runes.RuneEntry) error
CreateRuneEntryStates(ctx context.Context, entries []*runes.RuneEntry, blockHeight uint64) error
CreateOutPointBalances(ctx context.Context, outPointBalances []*entity.OutPointBalance) error
SpendOutPointBalances(ctx context.Context, outPoint wire.OutPoint, blockHeight uint64) error
CreateRuneBalances(ctx context.Context, params []CreateRuneBalancesParams) error
CreateRuneTransaction(ctx context.Context, tx *entity.RuneTransaction) error
SpendOutPointBalancesBatch(ctx context.Context, outPoints []wire.OutPoint, blockHeight uint64) error
CreateRuneBalances(ctx context.Context, params []*entity.Balance) error
CreateRuneTransactions(ctx context.Context, txs []*entity.RuneTransaction) error
CreateIndexedBlock(ctx context.Context, block *entity.IndexedBlock) error
// TODO: collapse these into a single function (ResetStateToHeight)?
@@ -83,10 +82,3 @@ type RunesWriterDataGateway interface {
UnspendOutPointBalancesSinceHeight(ctx context.Context, height uint64) error
DeleteRuneBalancesSinceHeight(ctx context.Context, height uint64) error
}
type CreateRuneBalancesParams struct {
PkScript []byte
RuneId runes.RuneId
Balance uint128.Uint128
BlockHeight uint64
}

View File

@@ -145,7 +145,10 @@ func (p *Processor) ensureGenesisRune(ctx context.Context, network common.Networ
EtchingTxHash: genesisRuneConfig.EtchingTxHash,
EtchedAt: genesisRuneConfig.EtchedAt,
}
if err := p.runesDg.CreateRuneEntry(ctx, runeEntry, genesisRuneConfig.RuneId.BlockHeight); err != nil {
if err := p.runesDg.CreateRuneEntries(ctx, []*runes.RuneEntry{runeEntry}); err != nil {
return errors.Wrap(err, "failed to create genesis rune entry")
}
if err := p.runesDg.CreateRuneEntryStates(ctx, []*runes.RuneEntry{runeEntry}, genesisRuneConfig.RuneId.BlockHeight); err != nil {
return errors.Wrap(err, "failed to create genesis rune entry")
}
}

View File

@@ -14,7 +14,6 @@ import (
"github.com/gaze-network/indexer-network/common/errs"
"github.com/gaze-network/indexer-network/core/types"
"github.com/gaze-network/indexer-network/modules/runes/constants"
"github.com/gaze-network/indexer-network/modules/runes/datagateway"
"github.com/gaze-network/indexer-network/modules/runes/internal/entity"
"github.com/gaze-network/indexer-network/modules/runes/runes"
"github.com/gaze-network/indexer-network/pkg/logger"
@@ -27,19 +26,26 @@ import (
func (p *Processor) Process(ctx context.Context, blocks []*types.Block) error {
for _, block := range blocks {
ctx := logger.WithContext(ctx, slog.Int64("height", block.Header.Height))
logger.DebugContext(ctx, "Processing new block", slog.Int("txs", len(block.Transactions)))
logger.InfoContext(ctx, "Processing new block",
slogx.String("event", "runes_processor_processing_block"),
slog.Int("txs", len(block.Transactions)),
)
start := time.Now()
for _, tx := range block.Transactions {
if err := p.processTx(ctx, tx, block.Header); err != nil {
return errors.Wrap(err, "failed to process tx")
}
}
timeTakenToProcess := time.Since(start)
logger.InfoContext(ctx, "Processed block",
slogx.String("event", "runes_processor_processed_block"),
slog.Duration("time_taken", timeTakenToProcess),
)
if err := p.flushBlock(ctx, block.Header); err != nil {
return errors.Wrap(err, "failed to flush block")
}
logger.DebugContext(ctx, "Inserted new block")
}
return nil
}
@@ -669,6 +675,7 @@ func (p *Processor) getRunesBalancesAtOutPoint(ctx context.Context, outPoint wir
}
func (p *Processor) flushBlock(ctx context.Context, blockHeader types.BlockHeader) error {
start := time.Now()
runesDgTx, err := p.runesDg.BeginRunesTx(ctx)
if err != nil {
return errors.Wrap(err, "failed to begin runes tx")
@@ -715,78 +722,82 @@ func (p *Processor) flushBlock(ctx context.Context, blockHeader types.BlockHeade
return errors.Wrap(err, "failed to create indexed block")
}
// flush new rune entries
{
for _, runeEntry := range p.newRuneEntries {
if err := runesDgTx.CreateRuneEntry(ctx, runeEntry, uint64(blockHeader.Height)); err != nil {
return errors.Wrap(err, "failed to create rune entry")
}
}
p.newRuneEntries = make(map[runes.RuneId]*runes.RuneEntry)
newRuneEntries := lo.Values(p.newRuneEntries)
if err := runesDgTx.CreateRuneEntries(ctx, newRuneEntries); err != nil {
return errors.Wrap(err, "failed to create rune entry")
}
p.newRuneEntries = make(map[runes.RuneId]*runes.RuneEntry)
// flush new rune entry states
{
for _, runeEntry := range p.newRuneEntryStates {
if err := runesDgTx.CreateRuneEntryState(ctx, runeEntry, uint64(blockHeader.Height)); err != nil {
return errors.Wrap(err, "failed to create rune entry state")
}
}
p.newRuneEntryStates = make(map[runes.RuneId]*runes.RuneEntry)
newRuneEntryStates := lo.Values(p.newRuneEntryStates)
if err := runesDgTx.CreateRuneEntryStates(ctx, newRuneEntryStates, uint64(blockHeader.Height)); err != nil {
return errors.Wrap(err, "failed to create rune entry state")
}
p.newRuneEntryStates = make(map[runes.RuneId]*runes.RuneEntry)
// flush new outpoint balances
{
newBalances := make([]*entity.OutPointBalance, 0)
for _, balances := range p.newOutPointBalances {
newBalances = append(newBalances, balances...)
}
if err := runesDgTx.CreateOutPointBalances(ctx, newBalances); err != nil {
return errors.Wrap(err, "failed to create outpoint balances")
}
p.newOutPointBalances = make(map[wire.OutPoint][]*entity.OutPointBalance)
newOutpointBalances := make([]*entity.OutPointBalance, 0)
for _, balances := range p.newOutPointBalances {
newOutpointBalances = append(newOutpointBalances, balances...)
}
if err := runesDgTx.CreateOutPointBalances(ctx, newOutpointBalances); err != nil {
return errors.Wrap(err, "failed to create outpoint balances")
}
p.newOutPointBalances = make(map[wire.OutPoint][]*entity.OutPointBalance)
// flush new spend outpoints
{
for _, outPoint := range p.newSpendOutPoints {
if err := runesDgTx.SpendOutPointBalances(ctx, outPoint, uint64(blockHeader.Height)); err != nil {
return errors.Wrap(err, "failed to create spend outpoint")
}
}
p.newSpendOutPoints = make([]wire.OutPoint, 0)
newSpendOutPoints := p.newSpendOutPoints
if err := runesDgTx.SpendOutPointBalancesBatch(ctx, newSpendOutPoints, uint64(blockHeader.Height)); err != nil {
return errors.Wrap(err, "failed to create spend outpoint")
}
// flush new balances
{
params := make([]datagateway.CreateRuneBalancesParams, 0)
for pkScriptStr, balances := range p.newBalances {
pkScript, err := hex.DecodeString(pkScriptStr)
if err != nil {
return errors.Wrap(err, "failed to decode pk script")
}
for runeId, balance := range balances {
params = append(params, datagateway.CreateRuneBalancesParams{
PkScript: pkScript,
RuneId: runeId,
Balance: balance,
BlockHeight: uint64(blockHeader.Height),
})
}
p.newSpendOutPoints = make([]wire.OutPoint, 0)
// flush new newBalances
newBalances := make([]*entity.Balance, 0)
for pkScriptStr, balances := range p.newBalances {
pkScript, err := hex.DecodeString(pkScriptStr)
if err != nil {
return errors.Wrap(err, "failed to decode pk script")
}
if err := runesDgTx.CreateRuneBalances(ctx, params); err != nil {
return errors.Wrap(err, "failed to create balances at block")
for runeId, balance := range balances {
newBalances = append(newBalances, &entity.Balance{
PkScript: pkScript,
RuneId: runeId,
Amount: balance,
BlockHeight: uint64(blockHeader.Height),
})
}
p.newBalances = make(map[string]map[runes.RuneId]uint128.Uint128)
}
if err := runesDgTx.CreateRuneBalances(ctx, newBalances); err != nil {
return errors.Wrap(err, "failed to create balances at block")
}
p.newBalances = make(map[string]map[runes.RuneId]uint128.Uint128)
// flush new rune transactions
{
for _, runeTx := range p.newRuneTxs {
if err := runesDgTx.CreateRuneTransaction(ctx, runeTx); err != nil {
return errors.Wrap(err, "failed to create rune transaction")
}
}
p.newRuneTxs = make([]*entity.RuneTransaction, 0)
newRuneTxs := p.newRuneTxs
if err := runesDgTx.CreateRuneTransactions(ctx, newRuneTxs); err != nil {
return errors.Wrap(err, "failed to create rune transaction")
}
p.newRuneTxs = make([]*entity.RuneTransaction, 0)
if err := runesDgTx.Commit(ctx); err != nil {
return errors.Wrap(err, "failed to commit runes tx")
}
timeTaken := time.Since(start)
logger.InfoContext(ctx, "Flushed block",
slogx.String("event", "runes_processor_flushed_block"),
slog.Int64("height", blockHeader.Height),
slog.String("hash", blockHeader.Hash.String()),
slog.String("event_hash", hex.EncodeToString(eventHash[:])),
slog.String("cumulative_event_hash", hex.EncodeToString(cumulativeEventHash[:])),
slog.Int("new_rune_entries", len(newRuneEntries)),
slog.Int("new_rune_entry_states", len(newRuneEntryStates)),
slog.Int("new_outpoint_balances", len(newOutpointBalances)),
slog.Int("new_spend_outpoints", len(newSpendOutPoints)),
slog.Int("new_balances", len(newBalances)),
slog.Int("new_rune_txs", len(newRuneTxs)),
slogx.Duration("time_taken", timeTaken),
)
// submit event to reporting system
if p.reportingClient != nil {

View File

@@ -1,130 +0,0 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.27.0
// source: batch.go
package gen
import (
"context"
"errors"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgtype"
)
var (
ErrBatchAlreadyClosed = errors.New("batch already closed")
)
const createOutPointBalances = `-- name: CreateOutPointBalances :batchexec
INSERT INTO runes_outpoint_balances (rune_id, pkscript, tx_hash, tx_idx, amount, block_height, spent_height) VALUES ($1, $2, $3, $4, $5, $6, $7)
`
type CreateOutPointBalancesBatchResults struct {
br pgx.BatchResults
tot int
closed bool
}
type CreateOutPointBalancesParams struct {
RuneID string
Pkscript string
TxHash string
TxIdx int32
Amount pgtype.Numeric
BlockHeight int32
SpentHeight pgtype.Int4
}
func (q *Queries) CreateOutPointBalances(ctx context.Context, arg []CreateOutPointBalancesParams) *CreateOutPointBalancesBatchResults {
batch := &pgx.Batch{}
for _, a := range arg {
vals := []interface{}{
a.RuneID,
a.Pkscript,
a.TxHash,
a.TxIdx,
a.Amount,
a.BlockHeight,
a.SpentHeight,
}
batch.Queue(createOutPointBalances, vals...)
}
br := q.db.SendBatch(ctx, batch)
return &CreateOutPointBalancesBatchResults{br, len(arg), false}
}
func (b *CreateOutPointBalancesBatchResults) Exec(f func(int, error)) {
defer b.br.Close()
for t := 0; t < b.tot; t++ {
if b.closed {
if f != nil {
f(t, ErrBatchAlreadyClosed)
}
continue
}
_, err := b.br.Exec()
if f != nil {
f(t, err)
}
}
}
func (b *CreateOutPointBalancesBatchResults) Close() error {
b.closed = true
return b.br.Close()
}
const createRuneBalanceAtBlock = `-- name: CreateRuneBalanceAtBlock :batchexec
INSERT INTO runes_balances (pkscript, block_height, rune_id, amount) VALUES ($1, $2, $3, $4)
`
type CreateRuneBalanceAtBlockBatchResults struct {
br pgx.BatchResults
tot int
closed bool
}
type CreateRuneBalanceAtBlockParams struct {
Pkscript string
BlockHeight int32
RuneID string
Amount pgtype.Numeric
}
func (q *Queries) CreateRuneBalanceAtBlock(ctx context.Context, arg []CreateRuneBalanceAtBlockParams) *CreateRuneBalanceAtBlockBatchResults {
batch := &pgx.Batch{}
for _, a := range arg {
vals := []interface{}{
a.Pkscript,
a.BlockHeight,
a.RuneID,
a.Amount,
}
batch.Queue(createRuneBalanceAtBlock, vals...)
}
br := q.db.SendBatch(ctx, batch)
return &CreateRuneBalanceAtBlockBatchResults{br, len(arg), false}
}
func (b *CreateRuneBalanceAtBlockBatchResults) Exec(f func(int, error)) {
defer b.br.Close()
for t := 0; t < b.tot; t++ {
if b.closed {
if f != nil {
f(t, ErrBatchAlreadyClosed)
}
continue
}
_, err := b.br.Exec()
if f != nil {
f(t, err)
}
}
}
func (b *CreateRuneBalanceAtBlockBatchResults) Close() error {
b.closed = true
return b.br.Close()
}

View File

@@ -0,0 +1,319 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.27.0
// source: batch.sql
package gen
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const batchCreateRuneEntries = `-- name: BatchCreateRuneEntries :exec
INSERT INTO runes_entries ("rune_id", "rune", "number", "spacers", "premine", "symbol", "divisibility", "terms", "terms_amount", "terms_cap", "terms_height_start", "terms_height_end", "terms_offset_start", "terms_offset_end", "turbo", "etching_block", "etching_tx_hash", "etched_at")
VALUES(
unnest($1::TEXT[]),
unnest($2::TEXT[]),
unnest($3::BIGINT[]),
unnest($4::INT[]),
unnest($5::DECIMAL[]),
unnest($6::INT[]),
unnest($7::SMALLINT[]),
unnest($8::BOOLEAN[]),
unnest($9::DECIMAL[]),
unnest($10::DECIMAL[]),
unnest($11::INT[]), -- nullable (need patch)
unnest($12::INT[]), -- nullable (need patch)
unnest($13::INT[]), -- nullable (need patch)
unnest($14::INT[]), -- nullable (need patch)
unnest($15::BOOLEAN[]),
unnest($16::INT[]),
unnest($17::TEXT[]),
unnest($18::TIMESTAMP[])
)
`
type BatchCreateRuneEntriesParams struct {
RuneIDArr []string
RuneArr []string
NumberArr []int64
SpacersArr []int32
PremineArr []pgtype.Numeric
SymbolArr []int32
DivisibilityArr []int16
TermsArr []bool
TermsAmountArr []pgtype.Numeric
TermsCapArr []pgtype.Numeric
TermsHeightStartArr []int32
TermsHeightEndArr []int32
TermsOffsetStartArr []int32
TermsOffsetEndArr []int32
TurboArr []bool
EtchingBlockArr []int32
EtchingTxHashArr []string
EtchedAtArr []pgtype.Timestamp
}
func (q *Queries) BatchCreateRuneEntries(ctx context.Context, arg BatchCreateRuneEntriesParams) error {
_, err := q.db.Exec(ctx, batchCreateRuneEntries,
arg.RuneIDArr,
arg.RuneArr,
arg.NumberArr,
arg.SpacersArr,
arg.PremineArr,
arg.SymbolArr,
arg.DivisibilityArr,
arg.TermsArr,
arg.TermsAmountArr,
arg.TermsCapArr,
arg.TermsHeightStartArr,
arg.TermsHeightEndArr,
arg.TermsOffsetStartArr,
arg.TermsOffsetEndArr,
arg.TurboArr,
arg.EtchingBlockArr,
arg.EtchingTxHashArr,
arg.EtchedAtArr,
)
return err
}
const batchCreateRuneEntryStates = `-- name: BatchCreateRuneEntryStates :exec
INSERT INTO runes_entry_states ("rune_id", "block_height", "mints", "burned_amount", "completed_at", "completed_at_height")
VALUES(
unnest($1::TEXT[]),
unnest($2::INT[]),
unnest($3::DECIMAL[]),
unnest($4::DECIMAL[]),
unnest($5::TIMESTAMP[]),
unnest($6::INT[]) -- nullable (need patch)
)
`
type BatchCreateRuneEntryStatesParams struct {
RuneIDArr []string
BlockHeightArr []int32
MintsArr []pgtype.Numeric
BurnedAmountArr []pgtype.Numeric
CompletedAtArr []pgtype.Timestamp
CompletedAtHeightArr []int32
}
func (q *Queries) BatchCreateRuneEntryStates(ctx context.Context, arg BatchCreateRuneEntryStatesParams) error {
_, err := q.db.Exec(ctx, batchCreateRuneEntryStates,
arg.RuneIDArr,
arg.BlockHeightArr,
arg.MintsArr,
arg.BurnedAmountArr,
arg.CompletedAtArr,
arg.CompletedAtHeightArr,
)
return err
}
const batchCreateRuneTransactions = `-- name: BatchCreateRuneTransactions :exec
INSERT INTO runes_transactions ("hash", "block_height", "index", "timestamp", "inputs", "outputs", "mints", "burns", "rune_etched")
VALUES (
unnest($1::TEXT[]),
unnest($2::INT[]),
unnest($3::INT[]),
unnest($4::TIMESTAMP[]),
unnest($5::JSONB[]),
unnest($6::JSONB[]),
unnest($7::JSONB[]),
unnest($8::JSONB[]),
unnest($9::BOOLEAN[])
)
`
type BatchCreateRuneTransactionsParams struct {
HashArr []string
BlockHeightArr []int32
IndexArr []int32
TimestampArr []pgtype.Timestamp
InputsArr [][]byte
OutputsArr [][]byte
MintsArr [][]byte
BurnsArr [][]byte
RuneEtchedArr []bool
}
func (q *Queries) BatchCreateRuneTransactions(ctx context.Context, arg BatchCreateRuneTransactionsParams) error {
_, err := q.db.Exec(ctx, batchCreateRuneTransactions,
arg.HashArr,
arg.BlockHeightArr,
arg.IndexArr,
arg.TimestampArr,
arg.InputsArr,
arg.OutputsArr,
arg.MintsArr,
arg.BurnsArr,
arg.RuneEtchedArr,
)
return err
}
const batchCreateRunesBalances = `-- name: BatchCreateRunesBalances :exec
INSERT INTO runes_balances ("pkscript", "block_height", "rune_id", "amount")
VALUES(
unnest($1::TEXT[]),
unnest($2::INT[]),
unnest($3::TEXT[]),
unnest($4::DECIMAL[])
)
`
type BatchCreateRunesBalancesParams struct {
PkscriptArr []string
BlockHeightArr []int32
RuneIDArr []string
AmountArr []pgtype.Numeric
}
func (q *Queries) BatchCreateRunesBalances(ctx context.Context, arg BatchCreateRunesBalancesParams) error {
_, err := q.db.Exec(ctx, batchCreateRunesBalances,
arg.PkscriptArr,
arg.BlockHeightArr,
arg.RuneIDArr,
arg.AmountArr,
)
return err
}
const batchCreateRunesOutpointBalances = `-- name: BatchCreateRunesOutpointBalances :exec
INSERT INTO runes_outpoint_balances ("rune_id", "pkscript", "tx_hash", "tx_idx", "amount", "block_height", "spent_height")
VALUES(
unnest($1::TEXT[]),
unnest($2::TEXT[]),
unnest($3::TEXT[]),
unnest($4::INT[]),
unnest($5::DECIMAL[]),
unnest($6::INT[]),
unnest($7::INT[]) -- nullable (need patch)
)
`
type BatchCreateRunesOutpointBalancesParams struct {
RuneIDArr []string
PkscriptArr []string
TxHashArr []string
TxIdxArr []int32
AmountArr []pgtype.Numeric
BlockHeightArr []int32
SpentHeightArr []int32
}
func (q *Queries) BatchCreateRunesOutpointBalances(ctx context.Context, arg BatchCreateRunesOutpointBalancesParams) error {
_, err := q.db.Exec(ctx, batchCreateRunesOutpointBalances,
arg.RuneIDArr,
arg.PkscriptArr,
arg.TxHashArr,
arg.TxIdxArr,
arg.AmountArr,
arg.BlockHeightArr,
arg.SpentHeightArr,
)
return err
}
const batchCreateRunestones = `-- name: BatchCreateRunestones :exec
INSERT INTO runes_runestones ("tx_hash", "block_height", "etching", "etching_divisibility", "etching_premine", "etching_rune", "etching_spacers", "etching_symbol", "etching_terms", "etching_terms_amount", "etching_terms_cap", "etching_terms_height_start", "etching_terms_height_end", "etching_terms_offset_start", "etching_terms_offset_end", "etching_turbo", "edicts", "mint", "pointer", "cenotaph", "flaws")
VALUES(
unnest($1::TEXT[]),
unnest($2::INT[]),
unnest($3::BOOLEAN[]),
unnest($4::SMALLINT[]), -- nullable (need patch)
unnest($5::DECIMAL[]),
unnest($6::TEXT[]), -- nullable (need patch)
unnest($7::INT[]), -- nullable (need patch)
unnest($8::INT[]), -- nullable (need patch)
unnest($9::BOOLEAN[]), -- nullable (need patch)
unnest($10::DECIMAL[]),
unnest($11::DECIMAL[]),
unnest($12::INT[]), -- nullable (need patch)
unnest($13::INT[]), -- nullable (need patch)
unnest($14::INT[]), -- nullable (need patch)
unnest($15::INT[]), -- nullable (need patch)
unnest($16::BOOLEAN[]), -- nullable (need patch)
unnest($17::JSONB[]),
unnest($18::TEXT[]), -- nullable (need patch)
unnest($19::INT[]), -- nullable (need patch)
unnest($20::BOOLEAN[]),
unnest($21::INT[])
)
`
type BatchCreateRunestonesParams struct {
TxHashArr []string
BlockHeightArr []int32
EtchingArr []bool
EtchingDivisibilityArr []int16
EtchingPremineArr []pgtype.Numeric
EtchingRuneArr []string
EtchingSpacersArr []int32
EtchingSymbolArr []int32
EtchingTermsArr []bool
EtchingTermsAmountArr []pgtype.Numeric
EtchingTermsCapArr []pgtype.Numeric
EtchingTermsHeightStartArr []int32
EtchingTermsHeightEndArr []int32
EtchingTermsOffsetStartArr []int32
EtchingTermsOffsetEndArr []int32
EtchingTurboArr []bool
EdictsArr [][]byte
MintArr []string
PointerArr []int32
CenotaphArr []bool
FlawsArr []int32
}
func (q *Queries) BatchCreateRunestones(ctx context.Context, arg BatchCreateRunestonesParams) error {
_, err := q.db.Exec(ctx, batchCreateRunestones,
arg.TxHashArr,
arg.BlockHeightArr,
arg.EtchingArr,
arg.EtchingDivisibilityArr,
arg.EtchingPremineArr,
arg.EtchingRuneArr,
arg.EtchingSpacersArr,
arg.EtchingSymbolArr,
arg.EtchingTermsArr,
arg.EtchingTermsAmountArr,
arg.EtchingTermsCapArr,
arg.EtchingTermsHeightStartArr,
arg.EtchingTermsHeightEndArr,
arg.EtchingTermsOffsetStartArr,
arg.EtchingTermsOffsetEndArr,
arg.EtchingTurboArr,
arg.EdictsArr,
arg.MintArr,
arg.PointerArr,
arg.CenotaphArr,
arg.FlawsArr,
)
return err
}
const batchSpendOutpointBalances = `-- name: BatchSpendOutpointBalances :exec
UPDATE runes_outpoint_balances
SET "spent_height" = $1::INT
FROM (
SELECT
unnest($2::TEXT[]) AS tx_hash,
unnest($3::INT[]) AS tx_idx
) AS input
WHERE "runes_outpoint_balances"."tx_hash" = "input"."tx_hash" AND "runes_outpoint_balances"."tx_idx" = "input"."tx_idx"
`
type BatchSpendOutpointBalancesParams struct {
SpentHeight int32
TxHashArr []string
TxIdxArr []int32
}
func (q *Queries) BatchSpendOutpointBalances(ctx context.Context, arg BatchSpendOutpointBalancesParams) error {
_, err := q.db.Exec(ctx, batchSpendOutpointBalances, arg.SpentHeight, arg.TxHashArr, arg.TxIdxArr)
return err
}

View File

@@ -0,0 +1,118 @@
package gen
import (
"context"
"github.com/cockroachdb/errors"
"github.com/jackc/pgx/v5/pgtype"
)
type BatchCreateRuneEntriesPatchedParams struct {
BatchCreateRuneEntriesParams
TermsHeightStartArr []pgtype.Int4
TermsHeightEndArr []pgtype.Int4
TermsOffsetStartArr []pgtype.Int4
TermsOffsetEndArr []pgtype.Int4
}
func (q *Queries) BatchCreateRuneEntriesPatched(ctx context.Context, arg BatchCreateRuneEntriesPatchedParams) error {
_, err := q.db.Exec(ctx, batchCreateRuneEntries,
arg.RuneIDArr,
arg.RuneArr,
arg.NumberArr,
arg.SpacersArr,
arg.PremineArr,
arg.SymbolArr,
arg.DivisibilityArr,
arg.TermsArr,
arg.TermsAmountArr,
arg.TermsCapArr,
arg.TermsHeightStartArr,
arg.TermsHeightEndArr,
arg.TermsOffsetStartArr,
arg.TermsOffsetEndArr,
arg.TurboArr,
arg.EtchingBlockArr,
arg.EtchingTxHashArr,
arg.EtchedAtArr,
)
return errors.WithStack(err)
}
type BatchCreateRuneEntryStatesPatchedParams struct {
BatchCreateRuneEntryStatesParams
CompletedAtHeightArr []pgtype.Int4
}
func (q *Queries) BatchCreateRuneEntryStatesPatched(ctx context.Context, arg BatchCreateRuneEntryStatesPatchedParams) error {
_, err := q.db.Exec(ctx, batchCreateRuneEntryStates,
arg.RuneIDArr,
arg.BlockHeightArr,
arg.MintsArr,
arg.BurnedAmountArr,
arg.CompletedAtArr,
arg.CompletedAtHeightArr,
)
return errors.WithStack(err)
}
type BatchCreateRunesOutpointBalancesPatchedParams struct {
BatchCreateRunesOutpointBalancesParams
SpentHeightArr []pgtype.Int4
}
func (q *Queries) BatchCreateRunesOutpointBalancesPatched(ctx context.Context, arg BatchCreateRunesOutpointBalancesPatchedParams) error {
_, err := q.db.Exec(ctx, batchCreateRunesOutpointBalances,
arg.RuneIDArr,
arg.PkscriptArr,
arg.TxHashArr,
arg.TxIdxArr,
arg.AmountArr,
arg.BlockHeightArr,
arg.SpentHeightArr,
)
return errors.WithStack(err)
}
type BatchCreateRunestonesPatchedParams struct {
BatchCreateRunestonesParams
EtchingDivisibilityArr []pgtype.Int2
EtchingRuneArr []pgtype.Text
EtchingSpacersArr []pgtype.Int4
EtchingSymbolArr []pgtype.Int4
EtchingTermsArr []pgtype.Bool
EtchingTermsHeightStartArr []pgtype.Int4
EtchingTermsHeightEndArr []pgtype.Int4
EtchingTermsOffsetStartArr []pgtype.Int4
EtchingTermsOffsetEndArr []pgtype.Int4
EtchingTurboArr []pgtype.Bool
MintArr []pgtype.Text
PointerArr []pgtype.Int4
}
func (q *Queries) BatchCreateRunestonesPatched(ctx context.Context, arg BatchCreateRunestonesPatchedParams) error {
_, err := q.db.Exec(ctx, batchCreateRunestones,
arg.TxHashArr,
arg.BlockHeightArr,
arg.EtchingArr,
arg.EtchingDivisibilityArr,
arg.EtchingPremineArr,
arg.EtchingRuneArr,
arg.EtchingSpacersArr,
arg.EtchingSymbolArr,
arg.EtchingTermsArr,
arg.EtchingTermsAmountArr,
arg.EtchingTermsCapArr,
arg.EtchingTermsHeightStartArr,
arg.EtchingTermsHeightEndArr,
arg.EtchingTermsOffsetStartArr,
arg.EtchingTermsOffsetEndArr,
arg.EtchingTurboArr,
arg.EdictsArr,
arg.MintArr,
arg.PointerArr,
arg.CenotaphArr,
arg.FlawsArr,
)
return errors.WithStack(err)
}

View File

@@ -45,6 +45,54 @@ func (q *Queries) CreateIndexedBlock(ctx context.Context, arg CreateIndexedBlock
return err
}
const createOutPointBalance = `-- name: CreateOutPointBalance :exec
INSERT INTO runes_outpoint_balances (rune_id, pkscript, tx_hash, tx_idx, amount, block_height, spent_height) VALUES ($1, $2, $3, $4, $5, $6, $7)
`
type CreateOutPointBalanceParams struct {
RuneID string
Pkscript string
TxHash string
TxIdx int32
Amount pgtype.Numeric
BlockHeight int32
SpentHeight pgtype.Int4
}
func (q *Queries) CreateOutPointBalance(ctx context.Context, arg CreateOutPointBalanceParams) error {
_, err := q.db.Exec(ctx, createOutPointBalance,
arg.RuneID,
arg.Pkscript,
arg.TxHash,
arg.TxIdx,
arg.Amount,
arg.BlockHeight,
arg.SpentHeight,
)
return err
}
const createRuneBalance = `-- name: CreateRuneBalance :exec
INSERT INTO runes_balances (pkscript, block_height, rune_id, amount) VALUES ($1, $2, $3, $4)
`
type CreateRuneBalanceParams struct {
Pkscript string
BlockHeight int32
RuneID string
Amount pgtype.Numeric
}
func (q *Queries) CreateRuneBalance(ctx context.Context, arg CreateRuneBalanceParams) error {
_, err := q.db.Exec(ctx, createRuneBalance,
arg.Pkscript,
arg.BlockHeight,
arg.RuneID,
arg.Amount,
)
return err
}
const createRuneEntry = `-- name: CreateRuneEntry :exec
INSERT INTO runes_entries (rune_id, rune, number, spacers, premine, symbol, divisibility, terms, terms_amount, terms_cap, terms_height_start, terms_height_end, terms_offset_start, terms_offset_end, turbo, etching_block, etching_tx_hash, etched_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)
@@ -437,6 +485,8 @@ SELECT runes_entries.rune_id, number, rune, spacers, premine, symbol, divisibili
LEFT JOIN states ON runes_entries.rune_id = states.rune_id
WHERE (
runes_entries.terms = TRUE AND
COALESCE(runes_entries.terms_amount, 0) != 0 AND
COALESCE(runes_entries.terms_cap, 0) != 0 AND
states.mints < runes_entries.terms_cap AND
(
runes_entries.terms_height_start IS NULL OR runes_entries.terms_height_start <= $1::integer
@@ -450,9 +500,9 @@ SELECT runes_entries.rune_id, number, rune, spacers, premine, symbol, divisibili
) AND (
$2::text = '' OR
runes_entries.rune ILIKE $2::text || '%'
runes_entries.rune ILIKE '%' || $2::text || '%'
)
ORDER BY (states.mints / runes_entries.terms_cap::float) DESC
ORDER BY states.mints DESC
LIMIT $4 OFFSET $3
`
@@ -1219,18 +1269,18 @@ func (q *Queries) GetTotalHoldersByRuneIds(ctx context.Context, arg GetTotalHold
return items, nil
}
const spendOutPointBalances = `-- name: SpendOutPointBalances :exec
const spendOutPointBalance = `-- name: SpendOutPointBalance :exec
UPDATE runes_outpoint_balances SET spent_height = $1 WHERE tx_hash = $2 AND tx_idx = $3
`
type SpendOutPointBalancesParams struct {
type SpendOutPointBalanceParams struct {
SpentHeight pgtype.Int4
TxHash string
TxIdx int32
}
func (q *Queries) SpendOutPointBalances(ctx context.Context, arg SpendOutPointBalancesParams) error {
_, err := q.db.Exec(ctx, spendOutPointBalances, arg.SpentHeight, arg.TxHash, arg.TxIdx)
func (q *Queries) SpendOutPointBalance(ctx context.Context, arg SpendOutPointBalanceParams) error {
_, err := q.db.Exec(ctx, spendOutPointBalance, arg.SpentHeight, arg.TxHash, arg.TxIdx)
return err
}

View File

@@ -15,7 +15,6 @@ type DBTX interface {
Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
Query(context.Context, string, ...interface{}) (pgx.Rows, error)
QueryRow(context.Context, string, ...interface{}) pgx.Row
SendBatch(context.Context, *pgx.Batch) pgx.BatchResults
}
func New(db DBTX) *Queries {

View File

@@ -11,6 +11,7 @@ import (
"github.com/gaze-network/indexer-network/modules/runes/internal/entity"
"github.com/gaze-network/indexer-network/modules/runes/repository/postgres/gen"
"github.com/gaze-network/indexer-network/modules/runes/runes"
"github.com/gaze-network/uint128"
"github.com/jackc/pgx/v5/pgtype"
"github.com/samber/lo"
@@ -47,7 +48,7 @@ func numericFromUint128(src *uint128.Uint128) (pgtype.Numeric, error) {
func mapIndexerStateModelToType(src gen.RunesIndexerState) entity.IndexerState {
var createdAt time.Time
if src.CreatedAt.Valid {
createdAt = src.CreatedAt.Time
createdAt = src.CreatedAt.Time.UTC()
}
return entity.IndexerState{
DBVersion: src.DbVersion,
@@ -86,7 +87,7 @@ func mapRuneEntryModelToType(src gen.GetRuneEntriesRow) (runes.RuneEntry, error)
}
var completedAt time.Time
if src.CompletedAt.Valid {
completedAt = src.CompletedAt.Time
completedAt = src.CompletedAt.Time.UTC()
}
var completedAtHeight *uint64
if src.CompletedAtHeight.Valid {
@@ -132,7 +133,7 @@ func mapRuneEntryModelToType(src gen.GetRuneEntriesRow) (runes.RuneEntry, error)
}
var etchedAt time.Time
if src.EtchedAt.Valid {
etchedAt = src.EtchedAt.Time
etchedAt = src.EtchedAt.Time.UTC()
}
return runes.RuneEntry{
RuneId: runeId,
@@ -153,31 +154,13 @@ func mapRuneEntryModelToType(src gen.GetRuneEntriesRow) (runes.RuneEntry, error)
}, nil
}
func mapRuneEntryTypeToParams(src runes.RuneEntry, blockHeight uint64) (gen.CreateRuneEntryParams, gen.CreateRuneEntryStateParams, error) {
func mapRuneEntryTypeToParams(src runes.RuneEntry) (gen.CreateRuneEntryParams, error) {
runeId := src.RuneId.String()
rune := src.SpacedRune.Rune.String()
spacers := int32(src.SpacedRune.Spacers)
mints, err := numericFromUint128(&src.Mints)
if err != nil {
return gen.CreateRuneEntryParams{}, gen.CreateRuneEntryStateParams{}, errors.Wrap(err, "failed to parse mints")
}
burnedAmount, err := numericFromUint128(&src.BurnedAmount)
if err != nil {
return gen.CreateRuneEntryParams{}, gen.CreateRuneEntryStateParams{}, errors.Wrap(err, "failed to parse burned amount")
}
premine, err := numericFromUint128(&src.Premine)
if err != nil {
return gen.CreateRuneEntryParams{}, gen.CreateRuneEntryStateParams{}, errors.Wrap(err, "failed to parse premine")
}
var completedAt pgtype.Timestamp
if !src.CompletedAt.IsZero() {
completedAt.Time = src.CompletedAt
completedAt.Valid = true
}
var completedAtHeight pgtype.Int4
if src.CompletedAtHeight != nil {
completedAtHeight.Int32 = int32(*src.CompletedAtHeight)
completedAtHeight.Valid = true
return gen.CreateRuneEntryParams{}, errors.Wrap(err, "failed to parse premine")
}
var terms bool
var termsAmount, termsCap pgtype.Numeric
@@ -187,13 +170,13 @@ func mapRuneEntryTypeToParams(src runes.RuneEntry, blockHeight uint64) (gen.Crea
if src.Terms.Amount != nil {
termsAmount, err = numericFromUint128(src.Terms.Amount)
if err != nil {
return gen.CreateRuneEntryParams{}, gen.CreateRuneEntryStateParams{}, errors.Wrap(err, "failed to parse terms amount")
return gen.CreateRuneEntryParams{}, errors.Wrap(err, "failed to parse terms amount")
}
}
if src.Terms.Cap != nil {
termsCap, err = numericFromUint128(src.Terms.Cap)
if err != nil {
return gen.CreateRuneEntryParams{}, gen.CreateRuneEntryStateParams{}, errors.Wrap(err, "failed to parse terms cap")
return gen.CreateRuneEntryParams{}, errors.Wrap(err, "failed to parse terms cap")
}
}
if src.Terms.HeightStart != nil {
@@ -221,51 +204,150 @@ func mapRuneEntryTypeToParams(src runes.RuneEntry, blockHeight uint64) (gen.Crea
}
}
}
etchedAt := pgtype.Timestamp{Time: src.EtchedAt, Valid: true}
etchedAt := pgtype.Timestamp{Time: src.EtchedAt.UTC(), Valid: true}
return gen.CreateRuneEntryParams{
RuneID: runeId,
Rune: rune,
Number: int64(src.Number),
Spacers: spacers,
Premine: premine,
Symbol: src.Symbol,
Divisibility: int16(src.Divisibility),
Terms: terms,
TermsAmount: termsAmount,
TermsCap: termsCap,
TermsHeightStart: termsHeightStart,
TermsHeightEnd: termsHeightEnd,
TermsOffsetStart: termsOffsetStart,
TermsOffsetEnd: termsOffsetEnd,
Turbo: src.Turbo,
EtchingBlock: int32(src.EtchingBlock),
EtchingTxHash: src.EtchingTxHash.String(),
EtchedAt: etchedAt,
}, gen.CreateRuneEntryStateParams{
BlockHeight: int32(blockHeight),
RuneID: runeId,
Mints: mints,
BurnedAmount: burnedAmount,
CompletedAt: completedAt,
CompletedAtHeight: completedAtHeight,
}, nil
RuneID: runeId,
Rune: rune,
Number: int64(src.Number),
Spacers: spacers,
Premine: premine,
Symbol: src.Symbol,
Divisibility: int16(src.Divisibility),
Terms: terms,
TermsAmount: termsAmount,
TermsCap: termsCap,
TermsHeightStart: termsHeightStart,
TermsHeightEnd: termsHeightEnd,
TermsOffsetStart: termsOffsetStart,
TermsOffsetEnd: termsOffsetEnd,
Turbo: src.Turbo,
EtchingBlock: int32(src.EtchingBlock),
EtchingTxHash: src.EtchingTxHash.String(),
EtchedAt: etchedAt,
}, nil
}
// mapRuneTransactionModelToType returns params for creating a new rune transaction and (optionally) a runestone.
func mapRuneTransactionTypeToParams(src entity.RuneTransaction) (gen.CreateRuneTransactionParams, *gen.CreateRunestoneParams, error) {
func mapRuneEntryStatesTypeToParams(src runes.RuneEntry, blockHeight uint64) (gen.CreateRuneEntryStateParams, error) {
runeId := src.RuneId.String()
mints, err := numericFromUint128(&src.Mints)
if err != nil {
return gen.CreateRuneEntryStateParams{}, errors.Wrap(err, "failed to parse mints")
}
burnedAmount, err := numericFromUint128(&src.BurnedAmount)
if err != nil {
return gen.CreateRuneEntryStateParams{}, errors.Wrap(err, "failed to parse burned amount")
}
var completedAt pgtype.Timestamp
if !src.CompletedAt.IsZero() {
completedAt.Time = src.CompletedAt.UTC()
completedAt.Valid = true
}
var completedAtHeight pgtype.Int4
if src.CompletedAtHeight != nil {
completedAtHeight.Int32 = int32(*src.CompletedAtHeight)
completedAtHeight.Valid = true
}
return gen.CreateRuneEntryStateParams{
BlockHeight: int32(blockHeight),
RuneID: runeId,
Mints: mints,
BurnedAmount: burnedAmount,
CompletedAt: completedAt,
CompletedAtHeight: completedAtHeight,
}, nil
}
func mapRuneEntryTypeToParamsBatch(srcs []*runes.RuneEntry) (gen.BatchCreateRuneEntriesPatchedParams, error) {
var batchParams gen.BatchCreateRuneEntriesPatchedParams
batchParams.RuneIDArr = make([]string, 0, len(srcs))
batchParams.RuneArr = make([]string, 0, len(srcs))
batchParams.NumberArr = make([]int64, 0, len(srcs))
batchParams.SpacersArr = make([]int32, 0, len(srcs))
batchParams.PremineArr = make([]pgtype.Numeric, 0, len(srcs))
batchParams.SymbolArr = make([]int32, 0, len(srcs))
batchParams.DivisibilityArr = make([]int16, 0, len(srcs))
batchParams.TermsArr = make([]bool, 0, len(srcs))
batchParams.TermsAmountArr = make([]pgtype.Numeric, 0, len(srcs))
batchParams.TermsCapArr = make([]pgtype.Numeric, 0, len(srcs))
batchParams.TermsHeightStartArr = make([]pgtype.Int4, 0, len(srcs))
batchParams.TermsHeightEndArr = make([]pgtype.Int4, 0, len(srcs))
batchParams.TermsOffsetStartArr = make([]pgtype.Int4, 0, len(srcs))
batchParams.TermsOffsetEndArr = make([]pgtype.Int4, 0, len(srcs))
batchParams.TurboArr = make([]bool, 0, len(srcs))
batchParams.EtchingBlockArr = make([]int32, 0, len(srcs))
batchParams.EtchingTxHashArr = make([]string, 0, len(srcs))
batchParams.EtchedAtArr = make([]pgtype.Timestamp, 0, len(srcs))
for i, src := range srcs {
param, err := mapRuneEntryTypeToParams(*src)
if err != nil {
return gen.BatchCreateRuneEntriesPatchedParams{}, errors.Wrapf(err, "failed to map rune entry to params batch at index %d", i)
}
batchParams.RuneIDArr = append(batchParams.RuneIDArr, param.RuneID)
batchParams.RuneArr = append(batchParams.RuneArr, param.Rune)
batchParams.NumberArr = append(batchParams.NumberArr, param.Number)
batchParams.SpacersArr = append(batchParams.SpacersArr, param.Spacers)
batchParams.PremineArr = append(batchParams.PremineArr, param.Premine)
batchParams.SymbolArr = append(batchParams.SymbolArr, param.Symbol)
batchParams.DivisibilityArr = append(batchParams.DivisibilityArr, param.Divisibility)
batchParams.TermsArr = append(batchParams.TermsArr, param.Terms)
batchParams.TermsAmountArr = append(batchParams.TermsAmountArr, param.TermsAmount)
batchParams.TermsCapArr = append(batchParams.TermsCapArr, param.TermsCap)
batchParams.TermsHeightStartArr = append(batchParams.TermsHeightStartArr, param.TermsHeightStart)
batchParams.TermsHeightEndArr = append(batchParams.TermsHeightEndArr, param.TermsHeightEnd)
batchParams.TermsOffsetStartArr = append(batchParams.TermsOffsetStartArr, param.TermsOffsetStart)
batchParams.TermsOffsetEndArr = append(batchParams.TermsOffsetEndArr, param.TermsOffsetEnd)
batchParams.TurboArr = append(batchParams.TurboArr, param.Turbo)
batchParams.EtchingBlockArr = append(batchParams.EtchingBlockArr, param.EtchingBlock)
batchParams.EtchingTxHashArr = append(batchParams.EtchingTxHashArr, param.EtchingTxHash)
batchParams.EtchedAtArr = append(batchParams.EtchedAtArr, param.EtchedAt)
}
return batchParams, nil
}
func mapRuneEntryStatesTypeToParamsBatch(srcs []*runes.RuneEntry, blockHeight uint64) (gen.BatchCreateRuneEntryStatesPatchedParams, error) {
var batchParams gen.BatchCreateRuneEntryStatesPatchedParams
batchParams.RuneIDArr = make([]string, 0, len(srcs))
batchParams.BlockHeightArr = make([]int32, 0, len(srcs))
batchParams.MintsArr = make([]pgtype.Numeric, 0, len(srcs))
batchParams.BurnedAmountArr = make([]pgtype.Numeric, 0, len(srcs))
batchParams.CompletedAtArr = make([]pgtype.Timestamp, 0, len(srcs))
batchParams.CompletedAtHeightArr = make([]pgtype.Int4, 0, len(srcs))
for i, src := range srcs {
param, err := mapRuneEntryStatesTypeToParams(*src, blockHeight)
if err != nil {
return gen.BatchCreateRuneEntryStatesPatchedParams{}, errors.Wrapf(err, "failed to map rune entry states to params batch at index %d", i)
}
batchParams.RuneIDArr = append(batchParams.RuneIDArr, param.RuneID)
batchParams.BlockHeightArr = append(batchParams.BlockHeightArr, param.BlockHeight)
batchParams.MintsArr = append(batchParams.MintsArr, param.Mints)
batchParams.BurnedAmountArr = append(batchParams.BurnedAmountArr, param.BurnedAmount)
batchParams.CompletedAtArr = append(batchParams.CompletedAtArr, param.CompletedAt)
batchParams.CompletedAtHeightArr = append(batchParams.CompletedAtHeightArr, param.CompletedAtHeight)
}
return batchParams, nil
}
func mapRuneTransactionTypeToParams(src entity.RuneTransaction) (gen.CreateRuneTransactionParams, error) {
var timestamp pgtype.Timestamp
if !src.Timestamp.IsZero() {
timestamp.Time = src.Timestamp
timestamp.Time = src.Timestamp.UTC()
timestamp.Valid = true
}
inputsBytes, err := json.Marshal(src.Inputs)
if err != nil {
return gen.CreateRuneTransactionParams{}, nil, errors.Wrap(err, "failed to marshal inputs")
return gen.CreateRuneTransactionParams{}, errors.Wrap(err, "failed to marshal inputs")
}
outputsBytes, err := json.Marshal(src.Outputs)
if err != nil {
return gen.CreateRuneTransactionParams{}, nil, errors.Wrap(err, "failed to marshal outputs")
return gen.CreateRuneTransactionParams{}, errors.Wrap(err, "failed to marshal outputs")
}
mints := make(map[string]uint128.Uint128)
for key, value := range src.Mints {
@@ -273,7 +355,7 @@ func mapRuneTransactionTypeToParams(src entity.RuneTransaction) (gen.CreateRuneT
}
mintsBytes, err := json.Marshal(mints)
if err != nil {
return gen.CreateRuneTransactionParams{}, nil, errors.Wrap(err, "failed to marshal mints")
return gen.CreateRuneTransactionParams{}, errors.Wrap(err, "failed to marshal mints")
}
burns := make(map[string]uint128.Uint128)
for key, value := range src.Burns {
@@ -281,16 +363,7 @@ func mapRuneTransactionTypeToParams(src entity.RuneTransaction) (gen.CreateRuneT
}
burnsBytes, err := json.Marshal(burns)
if err != nil {
return gen.CreateRuneTransactionParams{}, nil, errors.Wrap(err, "failed to marshal burns")
}
var runestoneParams *gen.CreateRunestoneParams
if src.Runestone != nil {
params, err := mapRunestoneTypeToParams(*src.Runestone, src.Hash, src.BlockHeight)
if err != nil {
return gen.CreateRuneTransactionParams{}, nil, errors.Wrap(err, "failed to map runestone to params")
}
runestoneParams = &params
return gen.CreateRuneTransactionParams{}, errors.Wrap(err, "failed to marshal burns")
}
return gen.CreateRuneTransactionParams{
@@ -303,7 +376,46 @@ func mapRuneTransactionTypeToParams(src entity.RuneTransaction) (gen.CreateRuneT
Mints: mintsBytes,
Burns: burnsBytes,
RuneEtched: src.RuneEtched,
}, runestoneParams, nil
}, nil
}
func mapRuneTransactionTypeToParamsBatch(srcs []*entity.RuneTransaction) (gen.BatchCreateRuneTransactionsParams, error) {
batchParams := gen.BatchCreateRuneTransactionsParams{
HashArr: make([]string, 0, len(srcs)),
BlockHeightArr: make([]int32, 0, len(srcs)),
IndexArr: make([]int32, 0, len(srcs)),
TimestampArr: make([]pgtype.Timestamp, 0, len(srcs)),
RuneEtchedArr: make([]bool, 0, len(srcs)),
}
inputsArr := make([][]byte, 0, len(srcs))
outputsArr := make([][]byte, 0, len(srcs))
mintsArr := make([][]byte, 0, len(srcs))
burnsArr := make([][]byte, 0, len(srcs))
for i, src := range srcs {
param, err := mapRuneTransactionTypeToParams(*src)
if err != nil {
return gen.BatchCreateRuneTransactionsParams{}, errors.Wrapf(err, "failed to map rune transaction to params batch at index %d", i)
}
batchParams.HashArr = append(batchParams.HashArr, param.Hash)
batchParams.BlockHeightArr = append(batchParams.BlockHeightArr, param.BlockHeight)
batchParams.IndexArr = append(batchParams.IndexArr, param.Index)
batchParams.TimestampArr = append(batchParams.TimestampArr, param.Timestamp)
batchParams.RuneEtchedArr = append(batchParams.RuneEtchedArr, param.RuneEtched)
inputsArr = append(inputsArr, param.Inputs)
outputsArr = append(outputsArr, param.Outputs)
mintsArr = append(mintsArr, param.Mints)
burnsArr = append(burnsArr, param.Burns)
}
batchParams.InputsArr = inputsArr
batchParams.OutputsArr = outputsArr
batchParams.MintsArr = mintsArr
batchParams.BurnsArr = burnsArr
return batchParams, nil
}
func extractModelRuneTxAndRunestone(src gen.GetRuneTransactionsRow) (gen.RunesTransaction, *gen.RunesRunestone, error) {
@@ -488,6 +600,65 @@ func mapRunestoneTypeToParams(src runes.Runestone, txHash chainhash.Hash, blockH
return runestoneParams, nil
}
func mapRunestoneTypeToParamsBatch(srcs []*entity.RuneTransaction) (gen.BatchCreateRunestonesPatchedParams, error) {
var batchParams gen.BatchCreateRunestonesPatchedParams
batchParams.TxHashArr = make([]string, 0, len(srcs))
batchParams.BlockHeightArr = make([]int32, 0, len(srcs))
batchParams.EtchingArr = make([]bool, 0, len(srcs))
batchParams.EtchingDivisibilityArr = make([]pgtype.Int2, 0, len(srcs))
batchParams.EtchingPremineArr = make([]pgtype.Numeric, 0, len(srcs))
batchParams.EtchingRuneArr = make([]pgtype.Text, 0, len(srcs))
batchParams.EtchingSpacersArr = make([]pgtype.Int4, 0, len(srcs))
batchParams.EtchingSymbolArr = make([]pgtype.Int4, 0, len(srcs))
batchParams.EtchingTermsArr = make([]pgtype.Bool, 0, len(srcs))
batchParams.EtchingTermsAmountArr = make([]pgtype.Numeric, 0, len(srcs))
batchParams.EtchingTermsCapArr = make([]pgtype.Numeric, 0, len(srcs))
batchParams.EtchingTermsHeightStartArr = make([]pgtype.Int4, 0, len(srcs))
batchParams.EtchingTermsHeightEndArr = make([]pgtype.Int4, 0, len(srcs))
batchParams.EtchingTermsOffsetStartArr = make([]pgtype.Int4, 0, len(srcs))
batchParams.EtchingTermsOffsetEndArr = make([]pgtype.Int4, 0, len(srcs))
batchParams.EtchingTurboArr = make([]pgtype.Bool, 0, len(srcs))
batchParams.EdictsArr = make([][]byte, 0, len(srcs))
batchParams.MintArr = make([]pgtype.Text, 0, len(srcs))
batchParams.PointerArr = make([]pgtype.Int4, 0, len(srcs))
batchParams.CenotaphArr = make([]bool, 0, len(srcs))
batchParams.FlawsArr = make([]int32, 0, len(srcs))
for i, src := range srcs {
if src.Runestone == nil {
continue
}
param, err := mapRunestoneTypeToParams(*src.Runestone, src.Hash, src.BlockHeight)
if err != nil {
return gen.BatchCreateRunestonesPatchedParams{}, errors.Wrapf(err, "failed to map runestone to params batch at index %d", i)
}
batchParams.TxHashArr = append(batchParams.TxHashArr, param.TxHash)
batchParams.BlockHeightArr = append(batchParams.BlockHeightArr, param.BlockHeight)
batchParams.EtchingArr = append(batchParams.EtchingArr, param.Etching)
batchParams.EtchingDivisibilityArr = append(batchParams.EtchingDivisibilityArr, param.EtchingDivisibility)
batchParams.EtchingPremineArr = append(batchParams.EtchingPremineArr, param.EtchingPremine)
batchParams.EtchingRuneArr = append(batchParams.EtchingRuneArr, param.EtchingRune)
batchParams.EtchingSpacersArr = append(batchParams.EtchingSpacersArr, param.EtchingSpacers)
batchParams.EtchingSymbolArr = append(batchParams.EtchingSymbolArr, param.EtchingSymbol)
batchParams.EtchingTermsArr = append(batchParams.EtchingTermsArr, param.EtchingTerms)
batchParams.EtchingTermsAmountArr = append(batchParams.EtchingTermsAmountArr, param.EtchingTermsAmount)
batchParams.EtchingTermsCapArr = append(batchParams.EtchingTermsCapArr, param.EtchingTermsCap)
batchParams.EtchingTermsHeightStartArr = append(batchParams.EtchingTermsHeightStartArr, param.EtchingTermsHeightStart)
batchParams.EtchingTermsHeightEndArr = append(batchParams.EtchingTermsHeightEndArr, param.EtchingTermsHeightEnd)
batchParams.EtchingTermsOffsetStartArr = append(batchParams.EtchingTermsOffsetStartArr, param.EtchingTermsOffsetStart)
batchParams.EtchingTermsOffsetEndArr = append(batchParams.EtchingTermsOffsetEndArr, param.EtchingTermsOffsetEnd)
batchParams.EtchingTurboArr = append(batchParams.EtchingTurboArr, param.EtchingTurbo)
batchParams.EdictsArr = append(batchParams.EdictsArr, param.Edicts)
batchParams.MintArr = append(batchParams.MintArr, param.Mint)
batchParams.PointerArr = append(batchParams.PointerArr, param.Pointer)
batchParams.CenotaphArr = append(batchParams.CenotaphArr, param.Cenotaph)
batchParams.FlawsArr = append(batchParams.FlawsArr, param.Flaws)
}
return batchParams, nil
}
func mapRunestoneModelToType(src gen.RunesRunestone) (runes.Runestone, error) {
runestone := runes.Runestone{
Cenotaph: src.Cenotaph,
@@ -602,6 +773,42 @@ func mapBalanceModelToType(src gen.RunesBalance) (*entity.Balance, error) {
}, nil
}
func mapBalanceTypeToParams(src entity.Balance) (gen.CreateRuneBalanceParams, error) {
amount, err := numericFromUint128(&src.Amount)
if err != nil {
return gen.CreateRuneBalanceParams{}, errors.Wrap(err, "failed to parse amount")
}
return gen.CreateRuneBalanceParams{
RuneID: src.RuneId.String(),
Amount: amount,
Pkscript: hex.EncodeToString(src.PkScript),
BlockHeight: int32(src.BlockHeight),
}, nil
}
func mapBalanceTypeToParamsBatch(srcs []*entity.Balance) (gen.BatchCreateRunesBalancesParams, error) {
batchParams := gen.BatchCreateRunesBalancesParams{
RuneIDArr: make([]string, 0, len(srcs)),
AmountArr: make([]pgtype.Numeric, 0, len(srcs)),
PkscriptArr: make([]string, 0, len(srcs)),
BlockHeightArr: make([]int32, 0, len(srcs)),
}
for i, src := range srcs {
param, err := mapBalanceTypeToParams(*src)
if err != nil {
return gen.BatchCreateRunesBalancesParams{}, errors.Wrapf(err, "failed to map balance to params batch at index %d", i)
}
batchParams.RuneIDArr = append(batchParams.RuneIDArr, param.RuneID)
batchParams.AmountArr = append(batchParams.AmountArr, param.Amount)
batchParams.PkscriptArr = append(batchParams.PkscriptArr, param.Pkscript)
batchParams.BlockHeightArr = append(batchParams.BlockHeightArr, param.BlockHeight)
}
return batchParams, nil
}
func mapIndexedBlockModelToType(src gen.RunesIndexedBlock) (*entity.IndexedBlock, error) {
hash, err := chainhash.NewHashFromStr(src.Hash)
if err != nil {
@@ -738,16 +945,16 @@ func mapOutPointBalanceModelToType(src gen.RunesOutpointBalance) (entity.OutPoin
}, nil
}
func mapOutPointBalanceTypeToParams(src entity.OutPointBalance) (gen.CreateOutPointBalancesParams, error) {
func mapOutPointBalanceTypeToParams(src entity.OutPointBalance) (gen.CreateOutPointBalanceParams, error) {
amount, err := numericFromUint128(&src.Amount)
if err != nil {
return gen.CreateOutPointBalancesParams{}, errors.Wrap(err, "failed to parse amount")
return gen.CreateOutPointBalanceParams{}, errors.Wrap(err, "failed to parse amount")
}
var spentHeight pgtype.Int4
if src.SpentHeight != nil {
spentHeight = pgtype.Int4{Int32: int32(*src.SpentHeight), Valid: true}
}
return gen.CreateOutPointBalancesParams{
return gen.CreateOutPointBalanceParams{
TxHash: src.OutPoint.Hash.String(),
TxIdx: int32(src.OutPoint.Index),
Pkscript: hex.EncodeToString(src.PkScript),
@@ -757,3 +964,31 @@ func mapOutPointBalanceTypeToParams(src entity.OutPointBalance) (gen.CreateOutPo
SpentHeight: spentHeight,
}, nil
}
func mapOutPointBalanceTypeToParamsBatch(srcs []*entity.OutPointBalance) (gen.BatchCreateRunesOutpointBalancesPatchedParams, error) {
var batchParams gen.BatchCreateRunesOutpointBalancesPatchedParams
batchParams.TxHashArr = make([]string, 0, len(srcs))
batchParams.TxIdxArr = make([]int32, 0, len(srcs))
batchParams.PkscriptArr = make([]string, 0, len(srcs))
batchParams.RuneIDArr = make([]string, 0, len(srcs))
batchParams.AmountArr = make([]pgtype.Numeric, 0, len(srcs))
batchParams.BlockHeightArr = make([]int32, 0, len(srcs))
batchParams.SpentHeightArr = make([]pgtype.Int4, 0, len(srcs))
for i, src := range srcs {
param, err := mapOutPointBalanceTypeToParams(*src)
if err != nil {
return gen.BatchCreateRunesOutpointBalancesPatchedParams{}, errors.Wrapf(err, "failed to map outpoint balance to params batch at index %d", i)
}
batchParams.TxHashArr = append(batchParams.TxHashArr, param.TxHash)
batchParams.TxIdxArr = append(batchParams.TxIdxArr, param.TxIdx)
batchParams.PkscriptArr = append(batchParams.PkscriptArr, param.Pkscript)
batchParams.RuneIDArr = append(batchParams.RuneIDArr, param.RuneID)
batchParams.AmountArr = append(batchParams.AmountArr, param.Amount)
batchParams.BlockHeightArr = append(batchParams.BlockHeightArr, param.BlockHeight)
batchParams.SpentHeightArr = append(batchParams.SpentHeightArr, param.SpentHeight)
}
return batchParams, nil
}

View File

@@ -478,111 +478,116 @@ func (r *Repository) GetTotalHoldersByRuneIds(ctx context.Context, runeIds []run
return holders, nil
}
func (r *Repository) CreateRuneTransaction(ctx context.Context, tx *entity.RuneTransaction) error {
if tx == nil {
func (r *Repository) CreateRuneTransactions(ctx context.Context, txs []*entity.RuneTransaction) error {
if len(txs) == 0 {
return nil
}
txParams, runestoneParams, err := mapRuneTransactionTypeToParams(*tx)
txParams, err := mapRuneTransactionTypeToParamsBatch(txs)
if err != nil {
return errors.Wrap(err, "failed to map rune transaction to params")
return errors.Wrap(err, "failed to map rune transactions to params")
}
if err = r.queries.CreateRuneTransaction(ctx, txParams); err != nil {
return errors.Wrap(err, "error during exec CreateRuneTransaction")
if err := r.queries.BatchCreateRuneTransactions(ctx, txParams); err != nil {
return errors.Wrap(err, "error during exec BatchCreateRuneTransactions")
}
if runestoneParams != nil {
if err = r.queries.CreateRunestone(ctx, *runestoneParams); err != nil {
return errors.Wrap(err, "error during exec CreateRunestone")
}
runestoneParams, err := mapRunestoneTypeToParamsBatch(txs)
if err != nil {
return errors.Wrap(err, "failed to map runestones to params")
}
if err := r.queries.BatchCreateRunestonesPatched(ctx, runestoneParams); err != nil {
return errors.Wrap(err, "error during exec BatchCreateRunestones")
}
return nil
}
func (r *Repository) CreateRuneEntry(ctx context.Context, entry *runes.RuneEntry, blockHeight uint64) error {
if entry == nil {
func (r *Repository) CreateRuneEntries(ctx context.Context, entries []*runes.RuneEntry) error {
if len(entries) == 0 {
return nil
}
createParams, _, err := mapRuneEntryTypeToParams(*entry, blockHeight)
params, err := mapRuneEntryTypeToParamsBatch(entries)
if err != nil {
return errors.Wrap(err, "failed to map rune entry to params")
return errors.Wrap(err, "failed to map rune entries to params")
}
if err = r.queries.CreateRuneEntry(ctx, createParams); err != nil {
return errors.Wrap(err, "error during exec CreateRuneEntry")
if err := r.queries.BatchCreateRuneEntriesPatched(ctx, params); err != nil {
return errors.Wrap(err, "error during exec")
}
return nil
}
func (r *Repository) CreateRuneEntryState(ctx context.Context, entry *runes.RuneEntry, blockHeight uint64) error {
if entry == nil {
func (r *Repository) CreateRuneEntryStates(ctx context.Context, entries []*runes.RuneEntry, blockHeight uint64) error {
if len(entries) == 0 {
return nil
}
_, createStateParams, err := mapRuneEntryTypeToParams(*entry, blockHeight)
params, err := mapRuneEntryStatesTypeToParamsBatch(entries, blockHeight)
if err != nil {
return errors.Wrap(err, "failed to map rune entry to params")
return errors.Wrap(err, "failed to map rune entry states to params")
}
if err = r.queries.CreateRuneEntryState(ctx, createStateParams); err != nil {
return errors.Wrap(err, "error during exec CreateRuneEntryState")
if err := r.queries.BatchCreateRuneEntryStatesPatched(ctx, params); err != nil {
return errors.Wrap(err, "error during exec")
}
return nil
}
func (r *Repository) CreateOutPointBalances(ctx context.Context, outPointBalances []*entity.OutPointBalance) error {
params := make([]gen.CreateOutPointBalancesParams, 0, len(outPointBalances))
for _, balance := range outPointBalances {
param, err := mapOutPointBalanceTypeToParams(*balance)
if err != nil {
return errors.Wrap(err, "failed to map outpoint balance to params")
}
params = append(params, param)
if len(outPointBalances) == 0 {
return nil
}
result := r.queries.CreateOutPointBalances(ctx, params)
var execErrors []error
result.Exec(func(i int, err error) {
if err != nil {
execErrors = append(execErrors, err)
}
})
if len(execErrors) > 0 {
return errors.Wrap(errors.Join(execErrors...), "error during exec")
}
return nil
}
func (r *Repository) SpendOutPointBalances(ctx context.Context, outPoint wire.OutPoint, blockHeight uint64) error {
if err := r.queries.SpendOutPointBalances(ctx, gen.SpendOutPointBalancesParams{
TxHash: outPoint.Hash.String(),
TxIdx: int32(outPoint.Index),
SpentHeight: pgtype.Int4{Int32: int32(blockHeight), Valid: true},
}); err != nil {
params, err := mapOutPointBalanceTypeToParamsBatch(outPointBalances)
if err != nil {
return errors.Wrap(err, "failed to map outpoint balances to params")
}
if err := r.queries.BatchCreateRunesOutpointBalancesPatched(ctx, params); err != nil {
return errors.Wrap(err, "error during exec")
}
return nil
}
func (r *Repository) CreateRuneBalances(ctx context.Context, params []datagateway.CreateRuneBalancesParams) error {
insertParams := make([]gen.CreateRuneBalanceAtBlockParams, 0, len(params))
for _, param := range params {
param := param
amount, err := numericFromUint128(&param.Balance)
if err != nil {
return errors.Wrap(err, "failed to convert balance to numeric")
}
insertParams = append(insertParams, gen.CreateRuneBalanceAtBlockParams{
Pkscript: hex.EncodeToString(param.PkScript),
BlockHeight: int32(param.BlockHeight),
RuneID: param.RuneId.String(),
Amount: amount,
})
func (r *Repository) SpendOutPointBalancesBatch(ctx context.Context, outPoints []wire.OutPoint, blockHeight uint64) error {
if len(outPoints) == 0 {
return nil
}
result := r.queries.CreateRuneBalanceAtBlock(ctx, insertParams)
var execErrors []error
result.Exec(func(i int, err error) {
if err != nil {
execErrors = append(execErrors, err)
}
})
if len(execErrors) > 0 {
return errors.Wrap(errors.Join(execErrors...), "error during exec")
params := gen.BatchSpendOutpointBalancesParams{
TxHashArr: make([]string, 0, len(outPoints)),
TxIdxArr: make([]int32, 0, len(outPoints)),
SpentHeight: int32(blockHeight),
}
for _, outPoint := range outPoints {
params.TxHashArr = append(params.TxHashArr, outPoint.Hash.String())
params.TxIdxArr = append(params.TxIdxArr, int32(outPoint.Index))
}
if err := r.queries.BatchSpendOutpointBalances(ctx, params); err != nil {
return errors.Wrap(err, "error during exec")
}
return nil
}
func (r *Repository) CreateRuneBalances(ctx context.Context, balances []*entity.Balance) error {
if len(balances) == 0 {
return nil
}
params, err := mapBalanceTypeToParamsBatch(balances)
if err != nil {
return errors.Wrap(err, "failed to map rune balances to params")
}
if err := r.queries.BatchCreateRunesBalances(ctx, params); err != nil {
return errors.Wrap(err, "error during exec")
}
return nil
}

View File

@@ -67,10 +67,11 @@ func New(injector do.Injector) (indexer.IndexerWorker, error) {
}
processor := NewProcessor(runesDg, indexerInfoDg, bitcoinClient, conf.Network, reportingClient, cleanupFuncs)
if err := processor.VerifyStates(ctx); err != nil {
return nil, errors.WithStack(err)
if !conf.APIOnly {
if err := processor.VerifyStates(ctx); err != nil {
return nil, errors.WithStack(err)
}
}
// Mount API
apiHandlers := lo.Uniq(conf.Modules.Runes.APIHandlers)
for _, handler := range apiHandlers {

View File

@@ -14,6 +14,12 @@ import (
"github.com/valyala/fasthttp"
)
var DefaultClient = fasthttp.Client{
MaxConnsPerHost: 10240, // default is 512
ReadBufferSize: 4 * 1024,
WriteBufferSize: 4 * 1024,
}
type Config struct {
// Enable debug mode
Debug bool
@@ -143,7 +149,7 @@ func (h *Client) request(ctx context.Context, reqOptions RequestOptions) (*HttpR
fasthttp.ReleaseRequest(req)
}()
if err := fasthttp.Do(req, resp); err != nil {
if err := DefaultClient.Do(req, resp); err != nil {
return nil, errors.Wrapf(err, "url: %s", url)
}