Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions blockchain/fullblocktests/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,10 @@ const (
// amount required by the commitment.
ErrBadPayeeValue = ErrorKind("ErrBadPayeeValue")

// ErrInvalidRevokeInput indicates that an input to a revocation transaction
// is either not a stake ticket submission or is not a supported version.
ErrInvalidRevokeInput = ErrorKind("ErrInvalidRevokeInput")

// ErrTxSStxOutSpend indicates that a non SSGen or SSRtx tx attempted to
// spend an OP_SSTX tagged output from an SStx.
ErrTxSStxOutSpend = ErrorKind("ErrTxSStxOutSpend")
Expand Down
3 changes: 2 additions & 1 deletion blockchain/fullblocktests/error_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2022 The Decred developers
// Copyright (c) 2022-2026 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

Expand Down Expand Up @@ -67,6 +67,7 @@ func TestErrorKindStringer(t *testing.T) {
{ErrBadNumPayees, "ErrBadNumPayees"},
{ErrMismatchedPayeeHash, "ErrMismatchedPayeeHash"},
{ErrBadPayeeValue, "ErrBadPayeeValue"},
{ErrInvalidRevokeInput, "ErrInvalidRevokeInput"},
{ErrTxSStxOutSpend, "ErrTxSStxOutSpend"},
{ErrRegTxCreateStakeOut, "ErrRegTxCreateStakeOut"},
{ErrInvalidFinalState, "ErrInvalidFinalState"},
Expand Down
45 changes: 33 additions & 12 deletions blockchain/fullblocktests/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -2857,12 +2857,33 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) {
g.AssertTipNumRevocations(2)
rejected(ErrInvalidSSRtx)

// Create block that has a revocation that references the wrong output
// index of the associated ticket.
//
// ... -> brt1(24)
// \-> brt7(25)
g.SetTip("brt1")
g.NextBlock("brt7", outs[25], ticketOuts[25], func(b *wire.MsgBlock) {
g.AssertBlockRevocationTx(b, 10)

// Modify the revocation to reference the ticket change output
// instead of the required ticket submission output. The change
// output still exists in the utxo set, so the input existence
// checks pass and the wrong index condition itself causes the
// rejection.
const ticketChangeOutputIdx = 2
prevOut := &b.STransactions[10].TxIn[0].PreviousOutPoint
prevOut.Index = ticketChangeOutputIdx
})
g.AssertTipNumRevocations(1)
rejected(ErrInvalidRevokeInput)

// Create block that contains a revocation due to previous missed vote.
//
// ... -> brt1(24) -> brt7(25)
// ... -> brt1(24) -> brt8(25)
g.SetTip("brt1")
g.NextBlock("brt7", outs[25], ticketOuts[25])
brt7Tx1Out := chaingen.MakeSpendableOut(g.Tip(), 1, 0)
g.NextBlock("brt8", outs[25], ticketOuts[25])
brt8Tx1Out := chaingen.MakeSpendableOut(g.Tip(), 1, 0)
g.AssertTipNumRevocations(1)
accepted()

Expand All @@ -2873,9 +2894,9 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) {
// Create block that disapproves the regular transaction tree of the prev
// block and tries to spend a transaction from it.
//
// ... -> brt7(25)
// ... -> brt8(25)
// \-> bdt1(26)
g.NextBlock("bdt1", &brt7Tx1Out, ticketOuts[26], func(b *wire.MsgBlock) {
g.NextBlock("bdt1", &brt8Tx1Out, ticketOuts[26], func(b *wire.MsgBlock) {
b.Header.VoteBits &^= voteBitYes
for i := 0; i < 5; i++ {
g.ReplaceVoteBitsN(i, voteBitNo)(b)
Expand All @@ -2889,22 +2910,22 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) {
// regular transaction tree of a block that will be disapproved via a side
// chain.
//
// ... -> brt7(25) -> bdt2(26) -> bdt3(27)
g.SetTip("brt7")
g.NextBlock("bdt2", &brt7Tx1Out, ticketOuts[26])
// ... -> brt8(25) -> bdt2(26) -> bdt3(27)
g.SetTip("brt8")
g.NextBlock("bdt2", &brt8Tx1Out, ticketOuts[26])
accepted()

g.NextBlock("bdt3", outs[27], ticketOuts[27])
accepted()

// Create a fork from brt7 that contains a couple of subsequent valid blocks
// Create a fork from brt8 that contains a couple of subsequent valid blocks
// that disapprove the regular transaction tree of the previous blocks and
// extend it to force a reorg to the chain that contains the disapproving
// blocks.
//
// ... -> brt7(25) -> bdt2(26) -> bdt3(27)
// ... -> brt8(25) -> bdt2(26) -> bdt3(27)
// \-> bdt4(26) -> bdt5(27) -> bdt6(28)
g.SetTip("brt7")
g.SetTip("brt8")
g.NextBlock("bdt4", outs[26], ticketOuts[26], func(b *wire.MsgBlock) {
b.Header.VoteBits &^= voteBitYes
for i := 0; i < 5; i++ {
Expand All @@ -2929,7 +2950,7 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) {
// Extend the original bdt3 fork in order to make the first chain longer and
// force a reorg that removes the disapproving blocks.
//
// ... -> brt7(25) -> bdt2(26) -> bdt3(27) -> bdt7(28) -> bdt8(29)
// ... -> brt8(25) -> bdt2(26) -> bdt3(27) -> bdt7(28) -> bdt8(29)
// \-> bdt4(26) -> bdt5(27) -> bdt6(28)
g.SetTip("bdt3")
g.NextBlock("bdt7", outs[28], ticketOuts[28])
Expand Down
4 changes: 3 additions & 1 deletion internal/blockchain/fullblocks_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2016 The btcsuite developers
// Copyright (c) 2016-2022 The Decred developers
// Copyright (c) 2016-2026 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

Expand Down Expand Up @@ -125,6 +125,8 @@ func fullBlockTestErrToLocalErr(t *testing.T, kind fullblocktests.ErrorKind) Err
return ErrMismatchedPayeeHash
case fullblocktests.ErrBadPayeeValue:
return ErrBadPayeeValue
case fullblocktests.ErrInvalidRevokeInput:
return ErrInvalidRevokeInput
case fullblocktests.ErrTxSStxOutSpend:
return ErrTxSStxOutSpend
case fullblocktests.ErrRegTxCreateStakeOut:
Expand Down