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
49 changes: 28 additions & 21 deletions blockchain/compress.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,34 +181,46 @@ const (
numSpecialScripts = 64
)

// isPubKeyHash returns whether or not the passed public key script is a
// standard pay-to-pubkey-hash script along with the pubkey hash it is paying to
// if it is.
func isPubKeyHash(script []byte) (bool, []byte) {
// extractPubKeyHash extracts a pubkey hash that is being paid from the passed
// public key script if it is a standard pay-to-pubkey-hash script. It will
// return nil otherwise.
func extractPubKeyHash(script []byte) []byte {
if len(script) == 25 && script[0] == txscript.OP_DUP &&
script[1] == txscript.OP_HASH160 &&
script[2] == txscript.OP_DATA_20 &&
script[23] == txscript.OP_EQUALVERIFY &&
script[24] == txscript.OP_CHECKSIG {

return true, script[3:23]
return script[3:23]
}

return false, nil
return nil
}

// isScriptHash returns whether or not the passed public key script is a
// standard pay-to-script-hash script along with the script hash it is paying to
// if it is.
func isScriptHash(script []byte) (bool, []byte) {
// isPubKeyHash returns whether or not the passed public key script is a
// standard pay-to-pubkey-hash script.
func isPubKeyHash(script []byte) bool {
return extractPubKeyHash(script) != nil
}

// extractScriptHash extracts a script hash that is being paid from the passed
// public key script if it is a standard pay-to-script-hash script. It will
// return nil otherwise.
func extractScriptHash(script []byte) []byte {
if len(script) == 23 && script[0] == txscript.OP_HASH160 &&
script[1] == txscript.OP_DATA_20 &&
script[22] == txscript.OP_EQUAL {

return true, script[2:22]
return script[2:22]
}

return false, nil
return nil
}

// isScriptHash returns whether or not the passed public key script is a
// standard pay-to-script-hash script.
func isScriptHash(script []byte) bool {
return extractScriptHash(script) != nil
}

// isPubKey returns whether or not the passed public key script is a standard
Expand Down Expand Up @@ -253,13 +265,8 @@ func isPubKey(script []byte) (bool, []byte) {
// when encoded with the domain specific compression algorithm described above.
func compressedScriptSize(scriptVersion uint16, pkScript []byte,
compressionVersion uint32) int {
// Pay-to-pubkey-hash script.
if valid, _ := isPubKeyHash(pkScript); valid {
return 21
}

// Pay-to-script-hash script.
if valid, _ := isScriptHash(pkScript); valid {
// Pay-to-pubkey-hash or pay-to-script-hash script.
if isPubKeyHash(pkScript) || isScriptHash(pkScript) {
return 21
}

Expand Down Expand Up @@ -315,14 +322,14 @@ func putCompressedScript(target []byte, scriptVersion uint16, pkScript []byte,
}

// Pay-to-pubkey-hash script.
if valid, hash := isPubKeyHash(pkScript); valid {
if hash := extractPubKeyHash(pkScript); hash != nil {
target[0] = cstPayToPubKeyHash
copy(target[1:21], hash)
return 21
}

// Pay-to-script-hash script.
if valid, hash := isScriptHash(pkScript); valid {
if hash := extractScriptHash(pkScript); hash != nil {
target[0] = cstPayToScriptHash
copy(target[1:21], hash)
return 21
Expand Down
96 changes: 55 additions & 41 deletions blockchain/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ const (
// maximum allowed size.
ErrBlockTooBig

// ErrWrongBlockSize indicates that the block size from the header was
// not the actual serialized size of the block.
// ErrWrongBlockSize indicates that the block size in the header is not
// the actual serialized size of the block.
ErrWrongBlockSize

// ErrBlockVersionTooOld indicates the block version is too old and is
Expand Down Expand Up @@ -316,45 +316,55 @@ const (
// than were allowed.
ErrTooManyRevocations

// ErrSStxCommitment indicates that the propotional amounts from the inputs
// of an SStx did not match those found in the commitment outputs.
ErrSStxCommitment
// ErrTicketCommitment indicates that a ticket commitment contains an amount
// that does not coincide with the associated ticket input amount.
ErrTicketCommitment

// ErrInvalidSSGenInput indicates that the input SStx to the SSGen tx was
// invalid because it was not an SStx.
ErrInvalidSSGenInput
// ErrInvalidVoteInput indicates that an input to a vote transaction is
// either not a stake ticket submission or is not a supported version.
ErrInvalidVoteInput

// 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.
ErrSSGenPayeeNum
// ErrBadNumPayees indicates that either a vote or revocation transaction
// does not make the correct number of payments per the associated ticket
// commitments.
ErrBadNumPayees

// ErrSSGenPayeeOuts indicates that the SSGen payee outputs were either not
// the values that would be expected given the rewards and input amounts of
// the original SStx, or that the SSGen addresses did not correctly correspond
// to the null data outputs given in the originating SStx.
ErrSSGenPayeeOuts
// ErrBadPayeeScriptVersion indicates that either a vote or revocation
// transaction output that corresponds to a ticket commitment does not use
// a supported script version.
ErrBadPayeeScriptVersion

// ErrBadPayeeScriptType indicates that either a vote or revocation
// transaction output that corresponds to a ticket commitment does not pay
// to the same script type required by the commitment.
ErrBadPayeeScriptType

// ErrBadPayeeScriptType indicates that either a vote or revocation
// transaction output that corresponds to a ticket commitment does not pay
// to the hash required by the commitment.
ErrMismatchedPayeeHash

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ErrMismatchedPayeeHash currently has ErrBadPayeeScriptType's description.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected.


// ErrBadPayeeValue indicates that either a vote or revocation transaction
// output that corresponds to a ticket commitment does not pay the expected
// amount required by the commitment.
ErrBadPayeeValue

// 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

// ErrSStxInScrType indicates that the input used in an sstx was not
// pay-to-pubkeyhash or pay-to-script-hash, which is required. It can
// be OP_SS* tagged, but it must be P2PKH or P2SH.
ErrSStxInScrType
// ErrImmatureTicketSpend indicates that a vote or revocation is attempting
// to spend a ticket submission output that has not yet reached the required
// maturity.
ErrImmatureTicketSpend

// ErrInvalidSSRtxInput indicates that the input for the SSRtx was not from
// an SStx.
ErrInvalidSSRtxInput
// ErrTicketInputScript indicates that a ticket input is not one of the
// supported script forms or versions.
ErrTicketInputScript

// ErrSSRtxPayeesMismatch means that the number of payees in an SSRtx was
// not the same as the number of payees in the outputs of the input SStx.
ErrSSRtxPayeesMismatch
// ErrInvalidRevokeInput indicates that an input to a revocation transaction
// is either not a stake ticket submission or is not a supported version.
ErrInvalidRevokeInput

// ErrSSRtxPayees indicates that the SSRtx failed to pay out to the committed
// addresses or amounts from the originating SStx.
Expand Down Expand Up @@ -431,10 +441,12 @@ const (
// ErrFraudAmountIn indicates the witness amount given was fraudulent.
ErrFraudAmountIn

// ErrFraudBlockHeight indicates the witness block height given was fraudulent.
// ErrFraudBlockHeight indicates the witness block height given was
// fraudulent.
ErrFraudBlockHeight

// ErrFraudBlockIndex indicates the witness block index given was fraudulent.
// ErrFraudBlockIndex indicates the witness block index given was
// fraudulent.
ErrFraudBlockIndex

// ErrZeroValueOutputSpend indicates that a transaction attempted to spend a
Expand Down Expand Up @@ -529,15 +541,17 @@ var errorCodeStrings = map[ErrorCode]string{
ErrInvalidSSRtx: "ErrInvalidSSRtx",
ErrRevocationsMismatch: "ErrRevocationsMismatch",
ErrTooManyRevocations: "ErrTooManyRevocations",
ErrSStxCommitment: "ErrSStxCommitment",
ErrInvalidSSGenInput: "ErrInvalidSSGenInput",
ErrSSGenPayeeNum: "ErrSSGenPayeeNum",
ErrSSGenPayeeOuts: "ErrSSGenPayeeOuts",
ErrTicketCommitment: "ErrTicketCommitment",
ErrInvalidVoteInput: "ErrInvalidVoteInput",
ErrBadNumPayees: "ErrBadNumPayees",
ErrBadPayeeScriptVersion: "ErrBadPayeeScriptVersion",
ErrBadPayeeScriptType: "ErrBadPayeeScriptType",
ErrMismatchedPayeeHash: "ErrMismatchedPayeeHash",
ErrBadPayeeValue: "ErrBadPayeeValue",
ErrSSGenSubsidy: "ErrSSGenSubsidy",
ErrSStxInImmature: "ErrSStxInImmature",
ErrSStxInScrType: "ErrSStxInScrType",
ErrInvalidSSRtxInput: "ErrInvalidSSRtxInput",
ErrSSRtxPayeesMismatch: "ErrSSRtxPayeesMismatch",
ErrImmatureTicketSpend: "ErrImmatureTicketSpend",
ErrTicketInputScript: "ErrTicketInputScript",
ErrInvalidRevokeInput: "ErrInvalidRevokeInput",
ErrSSRtxPayees: "ErrSSRtxPayees",
ErrTxSStxOutSpend: "ErrTxSStxOutSpend",
ErrRegTxCreateStakeOut: "ErrRegTxCreateStakeOut",
Expand Down
18 changes: 10 additions & 8 deletions blockchain/error_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,17 @@ func TestErrorCodeStringer(t *testing.T) {
{ErrInvalidSSRtx, "ErrInvalidSSRtx"},
{ErrRevocationsMismatch, "ErrRevocationsMismatch"},
{ErrTooManyRevocations, "ErrTooManyRevocations"},
{ErrSStxCommitment, "ErrSStxCommitment"},
{ErrInvalidSSGenInput, "ErrInvalidSSGenInput"},
{ErrSSGenPayeeNum, "ErrSSGenPayeeNum"},
{ErrSSGenPayeeOuts, "ErrSSGenPayeeOuts"},
{ErrTicketCommitment, "ErrTicketCommitment"},
{ErrInvalidVoteInput, "ErrInvalidVoteInput"},
{ErrBadNumPayees, "ErrBadNumPayees"},
{ErrBadPayeeScriptVersion, "ErrBadPayeeScriptVersion"},
{ErrBadPayeeScriptType, "ErrBadPayeeScriptType"},
{ErrMismatchedPayeeHash, "ErrMismatchedPayeeHash"},
{ErrBadPayeeValue, "ErrBadPayeeValue"},
{ErrSSGenSubsidy, "ErrSSGenSubsidy"},
{ErrSStxInImmature, "ErrSStxInImmature"},
{ErrSStxInScrType, "ErrSStxInScrType"},
{ErrInvalidSSRtxInput, "ErrInvalidSSRtxInput"},
{ErrSSRtxPayeesMismatch, "ErrSSRtxPayeesMismatch"},
{ErrImmatureTicketSpend, "ErrImmatureTicketSpend"},
{ErrTicketInputScript, "ErrTicketInputScript"},
{ErrInvalidRevokeInput, "ErrInvalidRevokeInput"},
{ErrSSRtxPayees, "ErrSSRtxPayees"},
{ErrTxSStxOutSpend, "ErrTxSStxOutSpend"},
{ErrRegTxCreateStakeOut, "ErrRegTxCreateStakeOut"},
Expand Down
12 changes: 6 additions & 6 deletions blockchain/fullblocktests/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -1344,7 +1344,7 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) {
chaingen.PurchaseCommitmentScript(g.P2shOpTrueAddr(),
ticketPrice+ticketFee, 0, ticketPrice)
})
rejected(blockchain.ErrSStxCommitment)
rejected(blockchain.ErrTicketCommitment)

// Attempt to add block with a ticket purchase using output from
// disapproved block.
Expand Down Expand Up @@ -1459,7 +1459,7 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) {
g.NextBlock("bss3", outs[9], ticketOuts[9], func(b *wire.MsgBlock) {
b.STransactions[0].TxOut[2].PkScript[8] ^= 0x55
})
rejected(blockchain.ErrSSGenPayeeOuts)
rejected(blockchain.ErrMismatchedPayeeHash)

// Attempt to add a block with an incorrect vote payee output amount.
//
Expand All @@ -1469,7 +1469,7 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) {
g.NextBlock("bss4", outs[9], ticketOuts[9], func(b *wire.MsgBlock) {
b.STransactions[0].TxOut[2].Value++
})
rejected(blockchain.ErrSSGenPayeeOuts)
rejected(blockchain.ErrBadPayeeValue)

// ---------------------------------------------------------------------
// Multisig[Verify]/ChecksigVerifiy signature operation count tests.
Expand Down Expand Up @@ -2852,7 +2852,7 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) {
b.STransactions[10].TxOut[0])
})
g.AssertTipNumRevocations(1)
rejected(blockchain.ErrSSRtxPayeesMismatch)
rejected(blockchain.ErrBadNumPayees)

// Create block that has a revocation paying more than the original
// amount to the committed address.
Expand All @@ -2864,7 +2864,7 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) {
b.STransactions[10].TxOut[0].Value++
})
g.AssertTipNumRevocations(1)
rejected(blockchain.ErrSSRtxPayees)
rejected(blockchain.ErrBadPayeeValue)

// Create block that has a revocation using a corrupted pay-to-address
// script.
Expand All @@ -2876,7 +2876,7 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) {
b.STransactions[10].TxOut[0].PkScript[8] ^= 0x55
})
g.AssertTipNumRevocations(1)
rejected(blockchain.ErrSSRtxPayees)
rejected(blockchain.ErrMismatchedPayeeHash)

// Create block that has a revocation for a voted ticket.
//
Expand Down
Loading