diff --git a/cmd/hemictl/hemictl.go b/cmd/hemictl/hemictl.go index ccf46e9f..ccd3ec4c 100644 --- a/cmd/hemictl/hemictl.go +++ b/cmd/hemictl/hemictl.go @@ -453,13 +453,11 @@ func tbcdb() error { return fmt.Errorf("chainhash: %w", err) } - bh, err := s.DB().BlocksByTxId(ctx, chtxid) + bh, err := s.DB().BlockByTxId(ctx, chtxid) if err != nil { return fmt.Errorf("block by txid: %w", err) } - for k := range bh { - fmt.Printf("%v\n", bh[k]) - } + fmt.Printf("%v\n", bh) case "txbyid": txid := args["txid"] diff --git a/database/tbcd/database.go b/database/tbcd/database.go index 0d983326..96882ac6 100644 --- a/database/tbcd/database.go +++ b/database/tbcd/database.go @@ -69,7 +69,7 @@ type Database interface { // Transactions BlockUtxoUpdate(ctx context.Context, direction int, utxos map[Outpoint]CacheOutput) error BlockTxUpdate(ctx context.Context, direction int, txs map[TxKey]*TxValue) error - BlocksByTxId(ctx context.Context, txId *chainhash.Hash) ([]*chainhash.Hash, error) + BlockByTxId(ctx context.Context, txId *chainhash.Hash) (*chainhash.Hash, error) SpentOutputsByTxId(ctx context.Context, txId *chainhash.Hash) ([]SpentInfo, error) // ScriptHash returns the sha256 of PkScript for the provided outpoint. diff --git a/database/tbcd/level/level.go b/database/tbcd/level/level.go index fb2f547f..1c800f42 100644 --- a/database/tbcd/level/level.go +++ b/database/tbcd/level/level.go @@ -766,9 +766,9 @@ func (l *ldb) BlockByHash(ctx context.Context, hash *chainhash.Hash) (*btcutil.B return b, nil } -func (l *ldb) BlocksByTxId(ctx context.Context, txId *chainhash.Hash) ([]*chainhash.Hash, error) { - log.Tracef("BlocksByTxId") - defer log.Tracef("BlocksByTxId exit") +func (l *ldb) BlockByTxId(ctx context.Context, txId *chainhash.Hash) (*chainhash.Hash, error) { + log.Tracef("BlockByTxId") + defer log.Tracef("BlockByTxId exit") blocks := make([]*chainhash.Hash, 0, 2) txDB := l.pool[level.TransactionsDB] @@ -787,11 +787,15 @@ func (l *ldb) BlocksByTxId(ctx context.Context, txId *chainhash.Hash) ([]*chainh if err := it.Error(); err != nil { return nil, fmt.Errorf("blocks by id iterator: %w", err) } - if len(blocks) == 0 { + switch len(blocks) { + case 0: return nil, database.NotFoundError(fmt.Sprintf("tx not found: %v", txId)) + case 1: + return blocks[0], nil + default: + panic(fmt.Sprintf("invalid blocks count %v: %v", + len(blocks), spew.Sdump(blocks))) } - - return blocks, nil } func (l *ldb) SpentOutputsByTxId(ctx context.Context, txId *chainhash.Hash) ([]tbcd.SpentInfo, error) { diff --git a/service/tbc/crawler.go b/service/tbc/crawler.go index 6e8d1862..f3ab1656 100644 --- a/service/tbc/crawler.go +++ b/service/tbc/crawler.go @@ -301,18 +301,11 @@ func (s *Server) scriptValue(ctx context.Context, op tbcd.Outpoint) ([]byte, int txIndex := op.TxIndex() // Find block hashes - blockHashes, err := s.db.BlocksByTxId(ctx, txId) + blockHash, err := s.db.BlockByTxId(ctx, txId) if err != nil { - return nil, 0, fmt.Errorf("blocks by txid: %w", err) + return nil, 0, fmt.Errorf("block by txid: %w", err) } - // Note that we may have more than one block hash however since the - // TxID is generated from the actual Tx the script hash and value - // should be identical and thus we can return the values from the first - // block found. - if len(blockHashes) == 0 { - return nil, 0, errors.New("script value: no block hashes") - } - b, err := s.db.BlockByHash(ctx, blockHashes[0]) + b, err := s.db.BlockByHash(ctx, blockHash) if err != nil { return nil, 0, fmt.Errorf("block by hash: %w", err) } diff --git a/service/tbc/tbc.go b/service/tbc/tbc.go index 136eacfe..643a54c7 100644 --- a/service/tbc/tbc.go +++ b/service/tbc/tbc.go @@ -1778,28 +1778,17 @@ func (s *Server) TxById(ctx context.Context, txId *chainhash.Hash) (*wire.MsgTx, log.Tracef("TxById") defer log.Tracef("TxById exit") - blockHashes, err := s.db.BlocksByTxId(ctx, txId) + blockHash, err := s.db.BlockByTxId(ctx, txId) if err != nil { return nil, err } - - if len(blockHashes) > 1 { - panic("fix me blockhashes len") + block, err := s.db.BlockByHash(ctx, blockHash) + if err != nil { + return nil, err } - - // XXX investigate if this is indeed correct. As it is written now it - // returns the first block the tx exists in. This however must be the - // canonical block. This function must also return the blockhash. - - for _, blockHash := range blockHashes { - block, err := s.db.BlockByHash(ctx, blockHash) - if err != nil { - return nil, err - } - for _, tx := range block.Transactions() { - if tx.Hash().IsEqual(txId) { - return tx.MsgTx(), nil - } + for _, tx := range block.Transactions() { + if tx.Hash().IsEqual(txId) { + return tx.MsgTx(), nil } }