diff --git a/persist/sqlite/init.sql b/persist/sqlite/init.sql index 2ba74761..4d331c15 100644 --- a/persist/sqlite/init.sql +++ b/persist/sqlite/init.sql @@ -269,12 +269,11 @@ CREATE TABLE v2_block_transactions ( UNIQUE(block_id, block_order) ); CREATE INDEX v2_block_transactions_block_id_index ON v2_block_transactions(block_id); -CREATE INDEX v2_block_transactions_transaction_id_index ON v2_block_transactions(transaction_id); CREATE INDEX v2_block_transactions_transaction_id_block_id ON v2_block_transactions(transaction_id, block_id); CREATE TABLE v2_transaction_arbitrary_data ( transaction_id INTEGER REFERENCES v2_transactions(id) ON DELETE CASCADE NOT NULL, - data BLOB NOT NULL, + data BLOB, UNIQUE(transaction_id) ); diff --git a/persist/sqlite/v2consensus_test.go b/persist/sqlite/v2consensus_test.go index 365e32b3..6cf7c99a 100644 --- a/persist/sqlite/v2consensus_test.go +++ b/persist/sqlite/v2consensus_test.go @@ -354,3 +354,65 @@ func TestV2MinerFee(t *testing.T) { testutil.CheckV2Transaction(t, txn1, dbTxns[0]) } } + +func TestV2FoundationAddress(t *testing.T) { + log := zaptest.NewLogger(t) + dir := t.TempDir() + db, err := sqlite.OpenDatabase(filepath.Join(dir, "explored.sqlite3"), log.Named("sqlite3")) + if err != nil { + t.Fatal(err) + } + defer db.Close() + + bdb, err := coreutils.OpenBoltChainDB(filepath.Join(dir, "consensus.db")) + if err != nil { + t.Fatal(err) + } + defer bdb.Close() + + pk1 := types.GeneratePrivateKey() + addr1 := types.StandardUnlockHash(pk1.PublicKey()) + addr1Policy := types.SpendPolicy{types.PolicyTypeUnlockConditions(types.StandardUnlockConditions(pk1.PublicKey()))} + + pk2 := types.GeneratePrivateKey() + addr2 := types.StandardUnlockHash(pk2.PublicKey()) + + network, genesisBlock := ctestutil.V2Network() + network.HardforkFoundation.PrimaryAddress = addr1 + network.HardforkV2.AllowHeight = 1 + network.HardforkV2.RequireHeight = 2 + + genesisBlock.Transactions[0].SiacoinOutputs[0].Address = addr1 + giftSC := genesisBlock.Transactions[0].SiacoinOutputs[0].Value + + edb, _ := newConsensusDB(network, genesisBlock) + store, genesisState, err := chain.NewDBStore(bdb, network, genesisBlock) + if err != nil { + t.Fatal(err) + } + + cm := chain.NewManager(store, genesisState) + + txn1 := types.V2Transaction{ + SiacoinInputs: []types.V2SiacoinInput{{ + Parent: edb.sces[genesisBlock.Transactions[0].SiacoinOutputID(0)], + SatisfiedPolicy: types.SatisfiedPolicy{Policy: addr1Policy}, + }}, + MinerFee: giftSC, + NewFoundationAddress: &addr2, + } + testutil.SignV2Transaction(cm.TipState(), pk1, &txn1) + + if err := cm.AddBlocks([]types.Block{testutil.MineV2Block(cm.TipState(), []types.V2Transaction{txn1}, types.VoidAddress)}); err != nil { + t.Fatal(err) + } + v2SyncDB(t, edb, db, cm) + + { + dbTxns, err := db.V2Transactions([]types.TransactionID{txn1.ID()}) + if err != nil { + t.Fatal(err) + } + testutil.CheckV2Transaction(t, txn1, dbTxns[0]) + } +} diff --git a/persist/sqlite/v2transactions.go b/persist/sqlite/v2transactions.go index 36657998..c91f7717 100644 --- a/persist/sqlite/v2transactions.go +++ b/persist/sqlite/v2transactions.go @@ -104,9 +104,15 @@ WHERE id IN (` + queryPlaceHolders(len(txnIDs)) + `)` for rows.Next() { var txnID int64 var fields v2OtherFields - if err := rows.Scan(&txnID, decodeNull(&fields.newFoundationAddress), decode(&fields.minerFee)); err != nil { + var newFoundationAddress types.Address + if err := rows.Scan(&txnID, decodeNull(&newFoundationAddress), decode(&fields.minerFee)); err != nil { return nil, fmt.Errorf("failed to scan new foundation address and miner fee: %w", err) } + + if (newFoundationAddress != types.Address{}) { + fields.newFoundationAddress = &newFoundationAddress + } + result[txnID] = fields } return result, nil