From debfb7b992081b0ef35467ca96c993ac0a3d482d Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 16 Mar 2021 12:36:35 -0500 Subject: [PATCH] blockchain: Convert to use new stdaddr package. This converts the blockchain package to use the stdaddr package instead of dcrutil.Address. All callers that use the package in the repository are updated accordingly to maintain code that continues to build and work properly as well as pass all tests. This is part of a series of commits to convert all packages in the repository to make use of the new stdaddr package. --- blockchain/chain_test.go | 5 ++- blockchain/chaingen/generator.go | 6 +-- blockchain/fullblocktests/generate.go | 42 ++++++++------------ blockchain/stakeext.go | 6 ++- blockchain/treasury_test.go | 35 ++++++++-------- internal/rpcserver/interface.go | 2 +- internal/rpcserver/rpcserver.go | 2 +- internal/rpcserver/rpcserverhandlers_test.go | 2 +- 8 files changed, 48 insertions(+), 52 deletions(-) diff --git a/blockchain/chain_test.go b/blockchain/chain_test.go index 61bd361d..124fafe5 100644 --- a/blockchain/chain_test.go +++ b/blockchain/chain_test.go @@ -1,5 +1,5 @@ // Copyright (c) 2013-2016 The btcsuite developers -// Copyright (c) 2015-2020 The Decred developers +// Copyright (c) 2015-2021 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -21,6 +21,7 @@ import ( "github.com/decred/dcrd/chaincfg/chainhash" "github.com/decred/dcrd/chaincfg/v3" "github.com/decred/dcrd/dcrutil/v4" + "github.com/decred/dcrd/txscript/v4/stdaddr" "github.com/decred/dcrd/wire" ) @@ -125,7 +126,7 @@ func TestBlockchainFunctions(t *testing.T) { "want %v, got %v", expectedVal, val) } - a, _ := dcrutil.DecodeAddress("SsbKpMkPnadDcZFFZqRPY8nvdFagrktKuzB", params) + a, _ := stdaddr.DecodeAddress("SsbKpMkPnadDcZFFZqRPY8nvdFagrktKuzB", params) hs, err := chain.TicketsWithAddress(a, noTreasury) if err != nil { t.Errorf("Failed to do TicketsWithAddress: %v", err) diff --git a/blockchain/chaingen/generator.go b/blockchain/chaingen/generator.go index 1dcfc43d..6034ac1a 100644 --- a/blockchain/chaingen/generator.go +++ b/blockchain/chaingen/generator.go @@ -492,8 +492,8 @@ func (g *Generator) CreateTicketPurchaseTx(spend *SpendableOut, ticketPrice, fee voteScriptVer, voteScript := g.p2shOpTrueAddr.VotingRightsScript() // Generate the commitment script. - commitScript := PurchaseCommitmentScript(g.p2shOpTrueAddr, ticketPrice+fee, - 0, ticketPrice) + commitScriptVer, commitScript := g.p2shOpTrueAddr.RewardCommitmentScript( + int64(ticketPrice+fee), 0, int64(ticketPrice)) // Calculate change and generate script to deliver it. change := spend.amount - ticketPrice - fee @@ -511,7 +511,7 @@ func (g *Generator) CreateTicketPurchaseTx(spend *SpendableOut, ticketPrice, fee SignatureScript: opTrueRedeemScript, }) tx.AddTxOut(newTxOut(int64(ticketPrice), voteScriptVer, voteScript)) - tx.AddTxOut(wire.NewTxOut(0, commitScript)) + tx.AddTxOut(newTxOut(0, commitScriptVer, commitScript)) tx.AddTxOut(newTxOut(int64(change), changeScriptVer, changeScript)) return tx } diff --git a/blockchain/fullblocktests/generate.go b/blockchain/fullblocktests/generate.go index 3e6a01fe..64ea868c 100644 --- a/blockchain/fullblocktests/generate.go +++ b/blockchain/fullblocktests/generate.go @@ -1,5 +1,5 @@ // Copyright (c) 2016 The btcsuite developers -// Copyright (c) 2016-2020 The Decred developers +// Copyright (c) 2016-2021 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -20,6 +20,7 @@ import ( "github.com/decred/dcrd/dcrec/secp256k1/v4" "github.com/decred/dcrd/dcrutil/v4" "github.com/decred/dcrd/txscript/v4" + "github.com/decred/dcrd/txscript/v4/stdaddr" "github.com/decred/dcrd/wire" ) @@ -41,11 +42,6 @@ const ( // whether or not to approve the previous block. voteBitNo = 0x0000 voteBitYes = 0x0001 - - // noTreasury signifies the treasury agenda should be treated as though - // it is inactive. It is used to increase the readability of the - // tests. - noTreasury = false ) var ( @@ -158,7 +154,7 @@ func (b RejectedNonCanonicalBlock) FullBlockTestInstance() {} // payToScriptHashScript returns a standard pay-to-script-hash for the provided // redeem script. func payToScriptHashScript(redeemScript []byte) []byte { - redeemScriptHash := dcrutil.Hash160(redeemScript) + redeemScriptHash := stdaddr.Hash160(redeemScript) script, err := txscript.NewScriptBuilder(). AddOp(txscript.OP_HASH160).AddData(redeemScriptHash). AddOp(txscript.OP_EQUAL).Script() @@ -825,21 +821,15 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) { g.SetTip("bf6") g.NextBlock("bbadtaxscript", outs[4], ticketOuts[4], func(b *wire.MsgBlock) { + h160 := g.Params().OrganizationPkScript[2:22] + p2pkhTaxAddr, err := stdaddr.NewAddressPubKeyHashEcdsaSecp256k1V0( + h160, g.Params()) + if err != nil { + panic(err) + } + p2pkhScriptVer, p2pkhScript := p2pkhTaxAddr.PaymentScript() taxOutput := b.Transactions[0].TxOut[0] - _, addrs, _, _ := txscript.ExtractPkScriptAddrs( - g.Params().OrganizationPkScriptVersion, - taxOutput.PkScript, g.Params(), noTreasury) - p2shTaxAddr := addrs[0].(*dcrutil.AddressScriptHash) - p2pkhTaxAddr, err := dcrutil.NewAddressPubKeyHash( - p2shTaxAddr.Hash160()[:], g.Params(), - dcrec.STEcdsaSecp256k1) - if err != nil { - panic(err) - } - p2pkhScript, err := txscript.PayToAddrScript(p2pkhTaxAddr) - if err != nil { - panic(err) - } + taxOutput.Version = p2pkhScriptVer taxOutput.PkScript = p2pkhScript }) rejected(blockchain.ErrNoTax) @@ -1280,12 +1270,12 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) { // \-> bv15(9) g.SetTip("bsl5") g.NextBlock("bv15", outs[9], ticketOuts[9], func(b *wire.MsgBlock) { - ticketFee := dcrutil.Amount(2) - ticketPrice := dcrutil.Amount(g.CalcNextReqStakeDifficulty(g.Tip())) + ticketFee := int64(2) + ticketPrice := g.CalcNextReqStakeDifficulty(g.Tip()) ticketPrice-- - b.STransactions[5].TxOut[1].PkScript = - chaingen.PurchaseCommitmentScript(g.P2shOpTrueAddr(), - ticketPrice+ticketFee, 0, ticketPrice) + commitTxOut := b.STransactions[5].TxOut[1] + commitTxOut.Version, commitTxOut.PkScript = g.P2shOpTrueAddr(). + RewardCommitmentScript(ticketPrice+ticketFee, 0, ticketPrice) }) rejected(blockchain.ErrTicketCommitment) diff --git a/blockchain/stakeext.go b/blockchain/stakeext.go index 19b7166a..8c6948a5 100644 --- a/blockchain/stakeext.go +++ b/blockchain/stakeext.go @@ -10,6 +10,7 @@ import ( "github.com/decred/dcrd/database/v2" "github.com/decred/dcrd/dcrutil/v4" "github.com/decred/dcrd/txscript/v4" + "github.com/decred/dcrd/txscript/v4/stdaddr" "github.com/decred/dcrd/wire" ) @@ -101,13 +102,14 @@ func (b *BlockChain) MissedTickets() ([]chainhash.Hash, error) { // corresponding to the given address. // // This function is safe for concurrent access. -func (b *BlockChain) TicketsWithAddress(address dcrutil.Address, isTreasuryEnabled bool) ([]chainhash.Hash, error) { +func (b *BlockChain) TicketsWithAddress(address stdaddr.Address, isTreasuryEnabled bool) ([]chainhash.Hash, error) { b.chainLock.RLock() sn := b.bestChain.Tip().stakeNode b.chainLock.RUnlock() tickets := sn.LiveTickets() + encodedAddr := address.Address() var ticketsWithAddr []chainhash.Hash err := b.db.View(func(dbTx database.Tx) error { for _, hash := range tickets { @@ -122,7 +124,7 @@ func (b *BlockChain) TicketsWithAddress(address dcrutil.Address, isTreasuryEnabl if err != nil { return err } - if addrs[0].Address() == address.Address() { + if addrs[0].Address() == encodedAddr { ticketsWithAddr = append(ticketsWithAddr, hash) } } diff --git a/blockchain/treasury_test.go b/blockchain/treasury_test.go index 9792dea2..46b0305a 100644 --- a/blockchain/treasury_test.go +++ b/blockchain/treasury_test.go @@ -1874,7 +1874,7 @@ func TestSpendableTreasuryTxs(t *testing.T) { // mining these txs. spendPrivKey := secp256k1.NewPrivateKey(new(secp256k1.ModNScalar).SetInt(1)) pubKey := spendPrivKey.PubKey().SerializeCompressed() - pubKeyHash := dcrutil.Hash160(pubKey) + pubKeyHash := stdaddr.Hash160(pubKey) spendP2pkhAddr, err := stdaddr.NewAddressPubKeyHashEcdsaSecp256k1V0( pubKeyHash, params) if err != nil { @@ -1889,7 +1889,7 @@ func TestSpendableTreasuryTxs(t *testing.T) { addPrivKey := secp256k1.NewPrivateKey(new(secp256k1.ModNScalar).SetInt(2)) pubKey = addPrivKey.PubKey().SerializeCompressed() - pubKeyHash = dcrutil.Hash160(pubKey) + pubKeyHash = stdaddr.Hash160(pubKey) addP2pkhAddr, err := stdaddr.NewAddressPubKeyHashEcdsaSecp256k1V0( pubKeyHash, params) if err != nil { @@ -3358,15 +3358,23 @@ func TestTreasuryBalance(t *testing.T) { } } +// newTxOut returns a new transaction output with the given parameters. +func newTxOut(amount int64, pkScriptVer uint16, pkScript []byte) *wire.TxOut { + return &wire.TxOut{ + Value: amount, + Version: pkScriptVer, + PkScript: pkScript, + } +} + func createTAdd(spend chaingen.SpendableOut, changeDivisor dcrutil.Amount, params *chaincfg.Params) func(b *wire.MsgBlock) { - p2shOpTrueAddr, err := dcrutil.NewAddressScriptHash([]byte{txscript.OP_TRUE}, - params) + redeemScript := []byte{txscript.OP_TRUE} + p2shOpTrueAddr, err := stdaddr.NewAddressScriptHashV0(redeemScript, params) if err != nil { panic(err) } return func(b *wire.MsgBlock) { - // Add TADD amount := spend.Amount() tx := wire.NewMsgTx() tx.AddTxIn(&wire.TxIn{ @@ -3375,25 +3383,20 @@ func createTAdd(spend chaingen.SpendableOut, changeDivisor dcrutil.Amount, param ValueIn: int64(amount), BlockHeight: spend.BlockHeight(), BlockIndex: spend.BlockIndex(), - SignatureScript: []byte{txscript.OP_DATA_1, - txscript.OP_TRUE}, + SignatureScript: []byte{txscript.OP_DATA_1, txscript.OP_TRUE}, }) // Add negative change. + trsyAddScript := []byte{txscript.OP_TADD} if changeDivisor != 0 { - changeScript, err := txscript.PayToSStxChange(p2shOpTrueAddr) - if err != nil { - panic(err) - } + changeScriptVer, changeScript := p2shOpTrueAddr.StakeChangeScript() change := spend.Amount() / changeDivisor amount := spend.Amount() - change - tx.AddTxOut(wire.NewTxOut(int64(amount), - []byte{txscript.OP_TADD})) - tx.AddTxOut(wire.NewTxOut(int64(change), changeScript)) + tx.AddTxOut(wire.NewTxOut(int64(amount), trsyAddScript)) + tx.AddTxOut(newTxOut(int64(change), changeScriptVer, changeScript)) } else { - tx.AddTxOut(wire.NewTxOut(int64(amount), - []byte{txscript.OP_TADD})) + tx.AddTxOut(wire.NewTxOut(int64(amount), trsyAddScript)) } tx.Version = wire.TxVersionTreasury b.AddSTransaction(tx) diff --git a/internal/rpcserver/interface.go b/internal/rpcserver/interface.go index b24b4a3e..e0c4b250 100644 --- a/internal/rpcserver/interface.go +++ b/internal/rpcserver/interface.go @@ -373,7 +373,7 @@ type Chain interface { // TicketsWithAddress returns a slice of ticket hashes that are currently // live corresponding to the given address. - TicketsWithAddress(address dcrutil.Address, isTreasuryEnabled bool) ([]chainhash.Hash, error) + TicketsWithAddress(address stdaddr.Address, isTreasuryEnabled bool) ([]chainhash.Hash, error) // TipGeneration returns the entire generation of blocks stemming from the // parent of the current tip. diff --git a/internal/rpcserver/rpcserver.go b/internal/rpcserver/rpcserver.go index d6ca5b59..cafee8c3 100644 --- a/internal/rpcserver/rpcserver.go +++ b/internal/rpcserver/rpcserver.go @@ -5083,7 +5083,7 @@ func handleTicketsForAddress(_ context.Context, s *Server, cmd interface{}) (int // Decode the provided address. This also ensures the network encoded // with the address matches the network the server is currently on. - addr, err := dcrutil.DecodeAddress(c.Address, s.cfg.ChainParams) + addr, err := stdaddr.DecodeAddress(c.Address, s.cfg.ChainParams) if err != nil { return nil, rpcInvalidError("Invalid address: %v", err) } diff --git a/internal/rpcserver/rpcserverhandlers_test.go b/internal/rpcserver/rpcserverhandlers_test.go index 24f9e6a8..c97c3200 100644 --- a/internal/rpcserver/rpcserverhandlers_test.go +++ b/internal/rpcserver/rpcserverhandlers_test.go @@ -393,7 +393,7 @@ func (c *testRPCChain) TicketPoolValue() (dcrutil.Amount, error) { // TicketsWithAddress returns a mocked slice of ticket hashes that are currently // live corresponding to the given address. -func (c *testRPCChain) TicketsWithAddress(address dcrutil.Address, isTreasuryEnabled bool) ([]chainhash.Hash, error) { +func (c *testRPCChain) TicketsWithAddress(address stdaddr.Address, isTreasuryEnabled bool) ([]chainhash.Hash, error) { return c.ticketsWithAddress, c.ticketsWithAddressErr }