From 5d46e02509d6854ce4f8294b3735a1b0201f4235 Mon Sep 17 00:00:00 2001 From: Ian Norden Date: Sun, 9 Feb 2020 15:58:37 -0600 Subject: [PATCH] tx inputs directly reference tx ouputs --- .../00043_create_btc_tx_inputs_table.sql | 14 --------- ... => 00043_create_btc_tx_outputs_table.sql} | 0 .../00044_create_btc_tx_inputs_table.sql | 13 ++++++++ db/schema.sql | 7 ++--- pkg/super_node/btc/indexer.go | 31 ++++++++++++------- pkg/super_node/btc/mocks/test_data.go | 25 +++++++++++++++ pkg/super_node/btc/models.go | 5 +-- 7 files changed, 63 insertions(+), 32 deletions(-) delete mode 100644 db/migrations/00043_create_btc_tx_inputs_table.sql rename db/migrations/{00044_create_btc_tx_outputs_table.sql => 00043_create_btc_tx_outputs_table.sql} (100%) create mode 100644 db/migrations/00044_create_btc_tx_inputs_table.sql diff --git a/db/migrations/00043_create_btc_tx_inputs_table.sql b/db/migrations/00043_create_btc_tx_inputs_table.sql deleted file mode 100644 index eb3746fa..00000000 --- a/db/migrations/00043_create_btc_tx_inputs_table.sql +++ /dev/null @@ -1,14 +0,0 @@ --- +goose Up -CREATE TABLE btc.tx_inputs ( - id SERIAL PRIMARY KEY, - tx_id INTEGER NOT NULL REFERENCES btc.transaction_cids (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, - index INTEGER NOT NULL, - witness BYTEA[], - sig_script BYTEA NOT NULL, - outpoint_tx_hash VARCHAR(66) REFERENCES btc.transaction_cids (tx_hash) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, - outpoint_index BIGINT NOT NULL, - UNIQUE (tx_id, index) -); - --- +goose Down -DROP TABLE btc.tx_inputs; \ No newline at end of file diff --git a/db/migrations/00044_create_btc_tx_outputs_table.sql b/db/migrations/00043_create_btc_tx_outputs_table.sql similarity index 100% rename from db/migrations/00044_create_btc_tx_outputs_table.sql rename to db/migrations/00043_create_btc_tx_outputs_table.sql diff --git a/db/migrations/00044_create_btc_tx_inputs_table.sql b/db/migrations/00044_create_btc_tx_inputs_table.sql new file mode 100644 index 00000000..94b26742 --- /dev/null +++ b/db/migrations/00044_create_btc_tx_inputs_table.sql @@ -0,0 +1,13 @@ +-- +goose Up +CREATE TABLE btc.tx_inputs ( + id SERIAL PRIMARY KEY, + tx_id INTEGER NOT NULL REFERENCES btc.transaction_cids (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, + index INTEGER NOT NULL, + witness BYTEA[], + sig_script BYTEA NOT NULL, + outpoint_id INTEGER REFERENCES btc.tx_outputs (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, + UNIQUE (tx_id, index) +); + +-- +goose Down +DROP TABLE btc.tx_inputs; \ No newline at end of file diff --git a/db/schema.sql b/db/schema.sql index 206dc16e..6d067c4e 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -112,8 +112,7 @@ CREATE TABLE btc.tx_inputs ( index integer NOT NULL, witness bytea[], sig_script bytea NOT NULL, - outpoint_tx_hash character varying(66), - outpoint_index bigint NOT NULL + outpoint_id integer ); @@ -1746,11 +1745,11 @@ ALTER TABLE ONLY btc.transaction_cids -- --- Name: tx_inputs tx_inputs_outpoint_tx_hash_fkey; Type: FK CONSTRAINT; Schema: btc; Owner: - +-- Name: tx_inputs tx_inputs_outpoint_id_fkey; Type: FK CONSTRAINT; Schema: btc; Owner: - -- ALTER TABLE ONLY btc.tx_inputs - ADD CONSTRAINT tx_inputs_outpoint_tx_hash_fkey FOREIGN KEY (outpoint_tx_hash) REFERENCES btc.transaction_cids(tx_hash) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; + ADD CONSTRAINT tx_inputs_outpoint_id_fkey FOREIGN KEY (outpoint_id) REFERENCES btc.tx_outputs(id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -- diff --git a/pkg/super_node/btc/indexer.go b/pkg/super_node/btc/indexer.go index 6a8bf3f9..4669229c 100644 --- a/pkg/super_node/btc/indexer.go +++ b/pkg/super_node/btc/indexer.go @@ -49,7 +49,6 @@ func (in *CIDIndexer) Index(cids shared.CIDsForIndexing) error { } headerID, err := in.indexHeaderCID(tx, cidWrapper.HeaderCID) if err != nil { - println("err") logrus.Error("btc indexer error when indexing header") return err } @@ -74,20 +73,17 @@ func (in *CIDIndexer) indexTransactionCIDs(tx *sqlx.Tx, transactions []TxModelWi for _, transaction := range transactions { txID, err := in.indexTransactionCID(tx, transaction, headerID) if err != nil { - println(0) logrus.Error("btc indexer error when indexing header") return err } for _, input := range transaction.TxInputs { if err := in.indexTxInput(tx, input, txID); err != nil { - println(1) logrus.Error("btc indexer error when indexing tx inputs") return err } } for _, output := range transaction.TxOutputs { if err := in.indexTxOutput(tx, output, txID); err != nil { - println(2) logrus.Error("btc indexer error when indexing tx outputs") return err } @@ -109,16 +105,27 @@ func (in *CIDIndexer) indexTransactionCID(tx *sqlx.Tx, transaction TxModelWithIn func (in *CIDIndexer) indexTxInput(tx *sqlx.Tx, txInput TxInput, txID int64) error { // resolve zero-value hash to null value (coinbase tx input with no referenced outputs) if txInput.PreviousOutPointHash == "0000000000000000000000000000000000000000000000000000000000000000" { - _, err := tx.Exec(`INSERT INTO btc.tx_inputs (tx_id, index, witness, sig_script, outpoint_tx_hash, outpoint_index) - VALUES ($1, $2, $3, $4, $5, $6) - ON CONFLICT (tx_id, index) DO UPDATE SET (witness, sig_script, outpoint_tx_hash, outpoint_index) = ($3, $4, $5, $6)`, - txID, txInput.Index, pq.Array(txInput.TxWitness), txInput.SignatureScript, nil, txInput.PreviousOutPointIndex) + _, err := tx.Exec(`INSERT INTO btc.tx_inputs (tx_id, index, witness, sig_script, outpoint_id) + VALUES ($1, $2, $3, $4, $5) + ON CONFLICT (tx_id, index) DO UPDATE SET (witness, sig_script, outpoint_id) = ($3, $4, $5)`, + txID, txInput.Index, pq.Array(txInput.TxWitness), txInput.SignatureScript, nil) return err } - _, err := tx.Exec(`INSERT INTO btc.tx_inputs (tx_id, index, witness, sig_script, outpoint_tx_hash, outpoint_index) - VALUES ($1, $2, $3, $4, $5, $6) - ON CONFLICT (tx_id, index) DO UPDATE SET (witness, sig_script, outpoint_tx_hash, outpoint_index) = ($3, $4, $5, $6)`, - txID, txInput.Index, pq.Array(txInput.TxWitness), txInput.SignatureScript, txInput.PreviousOutPointHash, txInput.PreviousOutPointIndex) + var referencedOutPutID int64 + if err := tx.Get(&referencedOutPutID, `SELECT tx_outputs.id FROM btc.transaction_cids, btc.tx_outputs + WHERE tx_outputs.tx_id = transaction_cids.id + AND tx_hash = $1 + AND tx_outputs.index = $2`, txInput.PreviousOutPointHash, txInput.PreviousOutPointIndex); err != nil { + logrus.Errorf("btc indexer could not find the tx output (tx hash %s, output index %d) referenced in tx input %d of tx id %d", txInput.PreviousOutPointHash, txInput.PreviousOutPointIndex, txInput.Index, txID) + return err + } + if referencedOutPutID == 0 { + return fmt.Errorf("btc indexer could not find the tx output (tx hash %s, output index %d) referenced in tx input %d of tx id %d", txInput.PreviousOutPointHash, txInput.PreviousOutPointIndex, txInput.Index, txID) + } + _, err := tx.Exec(`INSERT INTO btc.tx_inputs (tx_id, index, witness, sig_script, outpoint_id) + VALUES ($1, $2, $3, $4, $5) + ON CONFLICT (tx_id, index) DO UPDATE SET (witness, sig_script, outpoint_id) = ($3, $4, $5)`, + txID, txInput.Index, pq.Array(txInput.TxWitness), txInput.SignatureScript, referencedOutPutID) return err } diff --git a/pkg/super_node/btc/mocks/test_data.go b/pkg/super_node/btc/mocks/test_data.go index cd6a3279..62fa986d 100644 --- a/pkg/super_node/btc/mocks/test_data.go +++ b/pkg/super_node/btc/mocks/test_data.go @@ -699,11 +699,36 @@ var ( TxHash: "87a157f3fd88ac7907c05fc55e271dc4acdc5605d187d646604ca8c0e9382e03", CID: "dummyTx1", Index: 0, + TxOutputs: []btc.TxOutput{ + { + Index: 0, + RequiredSigs: 0, + Value: 0, + PkScript: []byte{}, + ScriptClass: 0, + }, + }, }, { TxHash: "cf4e2978d0611ce46592e02d7e7daf8627a316ab69759a9f3df109a7f2bf3ec3", CID: "dummyTx2", Index: 1, + TxOutputs: []btc.TxOutput{ + { + Index: 0, + RequiredSigs: 0, + Value: 0, + PkScript: []byte{}, + ScriptClass: 0, + }, + { + Index: 1, + RequiredSigs: 0, + Value: 0, + PkScript: []byte{}, + ScriptClass: 0, + }, + }, }, }, } diff --git a/pkg/super_node/btc/models.go b/pkg/super_node/btc/models.go index 7b3a93f6..05c06e01 100644 --- a/pkg/super_node/btc/models.go +++ b/pkg/super_node/btc/models.go @@ -60,8 +60,9 @@ type TxInput struct { Index int64 `db:"index"` TxWitness [][]byte `db:"witness"` SignatureScript []byte `db:"sig_script"` - PreviousOutPointIndex uint32 `db:"outpoint_index"` - PreviousOutPointHash string `db:"outpoint_tx_hash"` + PreviousOutPointID int64 `db:"outpoint_id"` + PreviousOutPointIndex uint32 + PreviousOutPointHash string } // TxOutput is the db model for btc.tx_outputs table