Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

blockchain: remove impossible to hit validation errors. #1306

Closed
wants to merge 1 commit into from
Closed
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
10 changes: 0 additions & 10 deletions blockchain/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,10 +320,6 @@ const (
// of an SStx did not match those found in the commitment outputs.
ErrSStxCommitment

// ErrInvalidSSGenInput indicates that the input SStx to the SSGen tx was
// invalid because it was not an SStx.
ErrInvalidSSGenInput

// ErrSSGenPayeeNum indicates that the number of payees from the referenced
// SSGen's SStx was not the same as the number of the payees in the outputs
// of the SSGen tx.
Expand All @@ -335,10 +331,6 @@ const (
// to the null data outputs given in the originating SStx.
ErrSSGenPayeeOuts

// ErrSSGenSubsidy indicates that there was an error in the amount of subsidy
// generated in the vote.
ErrSSGenSubsidy

// ErrSStxInImmature indicates that the OP_SSTX tagged output used as input
// was not yet TicketMaturity many blocks old.
ErrSStxInImmature
Expand Down Expand Up @@ -526,10 +518,8 @@ var errorCodeStrings = map[ErrorCode]string{
ErrRevocationsMismatch: "ErrRevocationsMismatch",
ErrTooManyRevocations: "ErrTooManyRevocations",
ErrSStxCommitment: "ErrSStxCommitment",
ErrInvalidSSGenInput: "ErrInvalidSSGenInput",
ErrSSGenPayeeNum: "ErrSSGenPayeeNum",
ErrSSGenPayeeOuts: "ErrSSGenPayeeOuts",
ErrSSGenSubsidy: "ErrSSGenSubsidy",
ErrSStxInImmature: "ErrSStxInImmature",
ErrSStxInScrType: "ErrSStxInScrType",
ErrInvalidSSRtxInput: "ErrInvalidSSRtxInput",
Expand Down
2 changes: 0 additions & 2 deletions blockchain/error_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,8 @@ func TestErrorCodeStringer(t *testing.T) {
{ErrRevocationsMismatch, "ErrRevocationsMismatch"},
{ErrTooManyRevocations, "ErrTooManyRevocations"},
{ErrSStxCommitment, "ErrSStxCommitment"},
{ErrInvalidSSGenInput, "ErrInvalidSSGenInput"},
{ErrSSGenPayeeNum, "ErrSSGenPayeeNum"},
{ErrSSGenPayeeOuts, "ErrSSGenPayeeOuts"},
{ErrSSGenSubsidy, "ErrSSGenSubsidy"},
{ErrSStxInImmature, "ErrSStxInImmature"},
{ErrSStxInScrType, "ErrSStxInScrType"},
{ErrInvalidSSRtxInput, "ErrInvalidSSRtxInput"},
Expand Down
86 changes: 2 additions & 84 deletions blockchain/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -1338,8 +1338,7 @@ func CheckTransactionInputs(subsidyCache *SubsidyCache, tx *dcrutil.Tx, txHeight
// Also check to ensure that there is congruency for output PKH from
// SStx to SSGen outputs. Check also that the input transaction was
// an SStx.
// 2. Make sure the second input is an SStx tagged output.
// 3. Check to make sure that the difference in height between the
// 2. Check to make sure that the difference in height between the
// current block and the block the SStx was included in is >
// ticketMaturity.

Expand Down Expand Up @@ -1392,25 +1391,6 @@ func CheckTransactionInputs(subsidyCache *SubsidyCache, tx *dcrutil.Tx, txHeight
return 0, ruleError(ErrMissingTxOut, str)
}

// While we're here, double check to make sure that the input
// is from an SStx. By doing so, you also ensure the first
// output is OP_SSTX tagged.
if utxoEntrySstx.TransactionType() != stake.TxTypeSStx {
errStr := fmt.Sprintf("Input transaction %v for SSGen"+
" was not an SStx tx (given input: %v)", txHash,
sstxHash)
return 0, ruleError(ErrInvalidSSGenInput, errStr)
}

// Make sure it's using the 0th output.
if sstxIn.PreviousOutPoint.Index != 0 {
errStr := fmt.Sprintf("Input transaction %v for SSGen"+
" did not reference the first output (given "+
"idx %v)", txHash,
sstxIn.PreviousOutPoint.Index)
return 0, ruleError(ErrInvalidSSGenInput, errStr)
}

minOutsSStx := ConvertUtxosToMinimalOutputs(utxoEntrySstx)
if len(minOutsSStx) == 0 {
return 0, AssertError("missing stake extra data for " +
Expand Down Expand Up @@ -1455,19 +1435,7 @@ func CheckTransactionInputs(subsidyCache *SubsidyCache, tx *dcrutil.Tx, txHeight
return 0, ruleError(ErrSSGenPayeeOuts, errStr)
}

// 2. Check to make sure that the second input was an OP_SSTX
// tagged output from the referenced SStx.
if txscript.GetScriptClass(utxoEntrySstx.ScriptVersionByIndex(0),
utxoEntrySstx.PkScriptByIndex(0)) !=
txscript.StakeSubmissionTy {
errStr := fmt.Sprintf("First SStx output in SStx %v "+
"referenced by SSGen %v should have been "+
"OP_SSTX tagged, but it was not", sstxHash,
txHash)
return 0, ruleError(ErrInvalidSSGenInput, errStr)
}

// 3. Check to ensure that ticket maturity number of blocks
// 2. Check to ensure that ticket maturity number of blocks
// have passed between the block the SSGen plans to go into
// and the block in which the SStx was originally found in.
originHeight := utxoEntrySstx.BlockHeight()
Expand Down Expand Up @@ -2007,50 +1975,6 @@ func checkNumSigOps(tx *dcrutil.Tx, utxoView *UtxoViewpoint, index int, txTree b
return cumulativeSigOps, nil
}

// checkStakeBaseAmounts calculates the total amount given as subsidy from
// single stakebase transactions (votes) within a block. This function skips a
// ton of checks already performed by CheckTransactionInputs.
func checkStakeBaseAmounts(subsidyCache *SubsidyCache, height int64, params *chaincfg.Params, txs []*dcrutil.Tx, utxoView *UtxoViewpoint) error {
for _, tx := range txs {
msgTx := tx.MsgTx()
if stake.IsSSGen(msgTx) {
// Ensure the input is available.
txInHash := &msgTx.TxIn[1].PreviousOutPoint.Hash
utxoEntry, exists := utxoView.entries[*txInHash]
if !exists || utxoEntry == nil {
str := fmt.Sprintf("couldn't find input tx %v "+
"for stakebase amounts check", txInHash)
return ruleError(ErrTicketUnavailable, str)
}

originTxIndex := msgTx.TxIn[1].PreviousOutPoint.Index
originTxAtom := utxoEntry.AmountByIndex(originTxIndex)

totalOutputs := int64(0)
// Sum up the outputs.
for _, out := range msgTx.TxOut {
totalOutputs += out.Value
}

difference := totalOutputs - originTxAtom

// Subsidy aligns with the height we're voting on, not
// with the height of the current block.
calcSubsidy := CalcStakeVoteSubsidy(subsidyCache,
height-1, params)

if difference > calcSubsidy {
str := fmt.Sprintf("ssgen tx %v spent more "+
"than allowed (spent %v, allowed %v)",
tx.Hash(), difference, calcSubsidy)
return ruleError(ErrSSGenSubsidy, str)
}
}
}

return nil
}

// getStakeBaseAmounts calculates the total amount given as subsidy from the
// collective stakebase transactions (votes) within a block. This function
// skips a ton of checks already performed by CheckTransactionInputs.
Expand Down Expand Up @@ -2248,12 +2172,6 @@ func (b *BlockChain) checkTransactionsAndConnect(subsidyCache *SubsidyCache, inp
return ruleError(ErrNoStakeTx, str)
}

err := checkStakeBaseAmounts(subsidyCache, node.height,
b.chainParams, txs, utxoView)
if err != nil {
return err
}

totalAtomOutStake, err := getStakeBaseAmounts(txs, utxoView)
if err != nil {
return err
Expand Down