mirror of
https://github.com/LBRYFoundation/lbcd.git
synced 2025-08-23 17:47:24 +00:00
txscript: convert all new segwit error types to ErrorCode's
This commit is contained in:
parent
80dd96ac5d
commit
ff6cb25e89
4 changed files with 101 additions and 60 deletions
|
@ -259,7 +259,7 @@ func (vm *Engine) verifyWitnessProgram(witness [][]byte) error {
|
||||||
if len(witness) != 2 {
|
if len(witness) != 2 {
|
||||||
err := fmt.Sprintf("should have exactly two "+
|
err := fmt.Sprintf("should have exactly two "+
|
||||||
"items in witness, instead have %v", len(witness))
|
"items in witness, instead have %v", len(witness))
|
||||||
return scriptError(ErrWitnessScriptMismatch, err)
|
return scriptError(ErrWitnessProgramMismatch, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we'll resume execution as if it were a regular
|
// Now we'll resume execution as if it were a regular
|
||||||
|
@ -280,7 +280,6 @@ func (vm *Engine) verifyWitnessProgram(witness [][]byte) error {
|
||||||
vm.SetStack(witness)
|
vm.SetStack(witness)
|
||||||
|
|
||||||
case payToWitnessScriptHashDataSize: // P2WSH
|
case payToWitnessScriptHashDataSize: // P2WSH
|
||||||
|
|
||||||
// Additionally, The witness stack MUST NOT be empty at
|
// Additionally, The witness stack MUST NOT be empty at
|
||||||
// this point.
|
// this point.
|
||||||
if len(witness) == 0 {
|
if len(witness) == 0 {
|
||||||
|
@ -303,7 +302,7 @@ func (vm *Engine) verifyWitnessProgram(witness [][]byte) error {
|
||||||
// the witness stack matches the witness program.
|
// the witness stack matches the witness program.
|
||||||
witnessHash := sha256.Sum256(witnessScript)
|
witnessHash := sha256.Sum256(witnessScript)
|
||||||
if !bytes.Equal(witnessHash[:], vm.witnessProgram) {
|
if !bytes.Equal(witnessHash[:], vm.witnessProgram) {
|
||||||
return scriptError(ErrWitnessScriptMismatch,
|
return scriptError(ErrWitnessProgramMismatch,
|
||||||
"witness program hash mismatch")
|
"witness program hash mismatch")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,8 +329,9 @@ func (vm *Engine) verifyWitnessProgram(witness [][]byte) error {
|
||||||
return scriptError(ErrWitnessProgramWrongLength, errStr)
|
return scriptError(ErrWitnessProgramWrongLength, errStr)
|
||||||
}
|
}
|
||||||
} else if vm.hasFlag(ScriptVerifyDiscourageUpgradeableWitnessProgram) {
|
} else if vm.hasFlag(ScriptVerifyDiscourageUpgradeableWitnessProgram) {
|
||||||
return fmt.Errorf("new witness program versions invalid: %v",
|
errStr := fmt.Sprintf("new witness program versions "+
|
||||||
vm.witnessVersion)
|
"invalid: %v", vm.witnessProgram)
|
||||||
|
return scriptError(ErrDiscourageUpgradableWitnessProgram, errStr)
|
||||||
} else {
|
} else {
|
||||||
// If we encounter an unknown witness program version and we
|
// If we encounter an unknown witness program version and we
|
||||||
// aren't discouraging future unknown witness based soft-forks,
|
// aren't discouraging future unknown witness based soft-forks,
|
||||||
|
|
|
@ -209,6 +209,15 @@ const (
|
||||||
// operations.
|
// operations.
|
||||||
ErrNullFail
|
ErrNullFail
|
||||||
|
|
||||||
|
// ErrWitnessMalleated is returned if ScriptVerifyWitness is set and a
|
||||||
|
// native p2wsh program is encountered which has a non-empty sigScript.
|
||||||
|
ErrWitnessMalleated
|
||||||
|
|
||||||
|
// ErrWitnessMalleatedP2SH is returned if ScriptVerifyWitness if set
|
||||||
|
// and the validation logic for nested p2sh encounters a sigScript
|
||||||
|
// which isn't *exactyl* a datapush of the witness program.
|
||||||
|
ErrWitnessMalleatedP2SH
|
||||||
|
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
// Failures related to soft forks.
|
// Failures related to soft forks.
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
|
@ -227,34 +236,46 @@ const (
|
||||||
// reached.
|
// reached.
|
||||||
ErrUnsatisfiedLockTime
|
ErrUnsatisfiedLockTime
|
||||||
|
|
||||||
|
// ErrMinimalIf is returned if ScriptVerifyWitness is set and the
|
||||||
|
// operand of an OP_IF/OP_NOF_IF are not either an empty vector or
|
||||||
|
// [0x01].
|
||||||
|
ErrMinimalIf
|
||||||
|
|
||||||
|
// ErrDiscourageUpgradableWitnessProgram is returned if
|
||||||
|
// ScriptVerifyWitness is set and the versino of an executing witness
|
||||||
|
// program is outside the set of currently defined witness program
|
||||||
|
// vesions.
|
||||||
|
ErrDiscourageUpgradableWitnessProgram
|
||||||
|
|
||||||
|
// ----------------------------------------
|
||||||
|
// Failures related to segregated witness.
|
||||||
|
// ----------------------------------------
|
||||||
|
|
||||||
// ErrWitnessProgramEmpty is returned if ScriptVerifyWitness is set and
|
// ErrWitnessProgramEmpty is returned if ScriptVerifyWitness is set and
|
||||||
// the witness stack itself is empty.
|
// the witness stack itself is empty.
|
||||||
ErrWitnessProgramEmpty
|
ErrWitnessProgramEmpty
|
||||||
|
|
||||||
// ErrWitnessScriptMismatch is returned if ScriptVerifyWitness is set
|
// ErrWitnessProgramMismatch is returned if ScriptVerifyWitness is set
|
||||||
// and the witness itself for a p2wkh witness program isn't *exactly* 2
|
// and the witness itself for a p2wkh witness program isn't *exactly* 2
|
||||||
// items.
|
// items or if the witness for a p2wsh isn't the sha255 of the witness
|
||||||
ErrWitnessScriptMismatch
|
// script.
|
||||||
|
ErrWitnessProgramMismatch
|
||||||
|
|
||||||
// ErrWitnessProgramWrongLength is returned if ScriptVerifyWitness is
|
// ErrWitnessProgramWrongLength is returned if ScriptVerifyWitness is
|
||||||
// set and the length of the witness program violates the length as
|
// set and the length of the witness program violates the length as
|
||||||
// dictated by the current witness version.
|
// dictated by the current witness version.
|
||||||
ErrWitnessProgramWrongLength
|
ErrWitnessProgramWrongLength
|
||||||
|
|
||||||
// ErrWitnessMalleated is returned if ScriptVerifyWitness is set and a
|
|
||||||
// native p2wsh program is encountered which has a non-empty sigScript.
|
|
||||||
ErrWitnessMalleated
|
|
||||||
|
|
||||||
// ErrWitnessMalleatedP2SH is returned if ScriptVerifyWitness if set
|
|
||||||
// and the validation logic for nested p2sh encounters a sigScript
|
|
||||||
// which isn't *exactyl* a datapush of the witness program.
|
|
||||||
ErrWitnessMalleatedP2SH
|
|
||||||
|
|
||||||
// ErrWitnessUnexpected is returned if ScriptVerifyWitness is set and a
|
// ErrWitnessUnexpected is returned if ScriptVerifyWitness is set and a
|
||||||
// transaction includes witness data but doesn't spend an which is a
|
// transaction includes witness data but doesn't spend an which is a
|
||||||
// witness program (nested or native).
|
// witness program (nested or native).
|
||||||
ErrWitnessUnexpected
|
ErrWitnessUnexpected
|
||||||
|
|
||||||
|
// ErrWitnessPubKeyType is returned if ScriptVerifyWitness is set and
|
||||||
|
// the public key used in either a check-sig or check-multi-sig isn't
|
||||||
|
// serialized in a compressed format.
|
||||||
|
ErrWitnessPubKeyType
|
||||||
|
|
||||||
// numErrorCodes is the maximum error code number used in tests. This
|
// numErrorCodes is the maximum error code number used in tests. This
|
||||||
// entry MUST be the last entry in the enum.
|
// entry MUST be the last entry in the enum.
|
||||||
numErrorCodes
|
numErrorCodes
|
||||||
|
@ -262,47 +283,56 @@ const (
|
||||||
|
|
||||||
// Map of ErrorCode values back to their constant names for pretty printing.
|
// Map of ErrorCode values back to their constant names for pretty printing.
|
||||||
var errorCodeStrings = map[ErrorCode]string{
|
var errorCodeStrings = map[ErrorCode]string{
|
||||||
ErrInternal: "ErrInternal",
|
ErrInternal: "ErrInternal",
|
||||||
ErrInvalidFlags: "ErrInvalidFlags",
|
ErrInvalidFlags: "ErrInvalidFlags",
|
||||||
ErrInvalidIndex: "ErrInvalidIndex",
|
ErrInvalidIndex: "ErrInvalidIndex",
|
||||||
ErrUnsupportedAddress: "ErrUnsupportedAddress",
|
ErrUnsupportedAddress: "ErrUnsupportedAddress",
|
||||||
ErrNotMultisigScript: "ErrNotMultisigScript",
|
ErrNotMultisigScript: "ErrNotMultisigScript",
|
||||||
ErrTooManyRequiredSigs: "ErrTooManyRequiredSigs",
|
ErrTooManyRequiredSigs: "ErrTooManyRequiredSigs",
|
||||||
ErrTooMuchNullData: "ErrTooMuchNullData",
|
ErrTooMuchNullData: "ErrTooMuchNullData",
|
||||||
ErrEarlyReturn: "ErrEarlyReturn",
|
ErrEarlyReturn: "ErrEarlyReturn",
|
||||||
ErrEmptyStack: "ErrEmptyStack",
|
ErrEmptyStack: "ErrEmptyStack",
|
||||||
ErrEvalFalse: "ErrEvalFalse",
|
ErrEvalFalse: "ErrEvalFalse",
|
||||||
ErrScriptUnfinished: "ErrScriptUnfinished",
|
ErrScriptUnfinished: "ErrScriptUnfinished",
|
||||||
ErrInvalidProgramCounter: "ErrInvalidProgramCounter",
|
ErrInvalidProgramCounter: "ErrInvalidProgramCounter",
|
||||||
ErrScriptTooBig: "ErrScriptTooBig",
|
ErrScriptTooBig: "ErrScriptTooBig",
|
||||||
ErrElementTooBig: "ErrElementTooBig",
|
ErrElementTooBig: "ErrElementTooBig",
|
||||||
ErrTooManyOperations: "ErrTooManyOperations",
|
ErrTooManyOperations: "ErrTooManyOperations",
|
||||||
ErrStackOverflow: "ErrStackOverflow",
|
ErrStackOverflow: "ErrStackOverflow",
|
||||||
ErrInvalidPubKeyCount: "ErrInvalidPubKeyCount",
|
ErrInvalidPubKeyCount: "ErrInvalidPubKeyCount",
|
||||||
ErrInvalidSignatureCount: "ErrInvalidSignatureCount",
|
ErrInvalidSignatureCount: "ErrInvalidSignatureCount",
|
||||||
ErrNumberTooBig: "ErrNumberTooBig",
|
ErrNumberTooBig: "ErrNumberTooBig",
|
||||||
ErrVerify: "ErrVerify",
|
ErrVerify: "ErrVerify",
|
||||||
ErrEqualVerify: "ErrEqualVerify",
|
ErrEqualVerify: "ErrEqualVerify",
|
||||||
ErrNumEqualVerify: "ErrNumEqualVerify",
|
ErrNumEqualVerify: "ErrNumEqualVerify",
|
||||||
ErrCheckSigVerify: "ErrCheckSigVerify",
|
ErrCheckSigVerify: "ErrCheckSigVerify",
|
||||||
ErrCheckMultiSigVerify: "ErrCheckMultiSigVerify",
|
ErrCheckMultiSigVerify: "ErrCheckMultiSigVerify",
|
||||||
ErrDisabledOpcode: "ErrDisabledOpcode",
|
ErrDisabledOpcode: "ErrDisabledOpcode",
|
||||||
ErrReservedOpcode: "ErrReservedOpcode",
|
ErrReservedOpcode: "ErrReservedOpcode",
|
||||||
ErrMalformedPush: "ErrMalformedPush",
|
ErrMalformedPush: "ErrMalformedPush",
|
||||||
ErrInvalidStackOperation: "ErrInvalidStackOperation",
|
ErrInvalidStackOperation: "ErrInvalidStackOperation",
|
||||||
ErrUnbalancedConditional: "ErrUnbalancedConditional",
|
ErrUnbalancedConditional: "ErrUnbalancedConditional",
|
||||||
ErrMinimalData: "ErrMinimalData",
|
ErrMinimalData: "ErrMinimalData",
|
||||||
ErrInvalidSigHashType: "ErrInvalidSigHashType",
|
ErrInvalidSigHashType: "ErrInvalidSigHashType",
|
||||||
ErrSigDER: "ErrSigDER",
|
ErrSigDER: "ErrSigDER",
|
||||||
ErrSigHighS: "ErrSigHighS",
|
ErrSigHighS: "ErrSigHighS",
|
||||||
ErrNotPushOnly: "ErrNotPushOnly",
|
ErrNotPushOnly: "ErrNotPushOnly",
|
||||||
ErrSigNullDummy: "ErrSigNullDummy",
|
ErrSigNullDummy: "ErrSigNullDummy",
|
||||||
ErrPubKeyType: "ErrPubKeyType",
|
ErrPubKeyType: "ErrPubKeyType",
|
||||||
ErrCleanStack: "ErrCleanStack",
|
ErrCleanStack: "ErrCleanStack",
|
||||||
ErrNullFail: "ErrNullFail",
|
ErrNullFail: "ErrNullFail",
|
||||||
ErrDiscourageUpgradableNOPs: "ErrDiscourageUpgradableNOPs",
|
ErrDiscourageUpgradableNOPs: "ErrDiscourageUpgradableNOPs",
|
||||||
ErrNegativeLockTime: "ErrNegativeLockTime",
|
ErrNegativeLockTime: "ErrNegativeLockTime",
|
||||||
ErrUnsatisfiedLockTime: "ErrUnsatisfiedLockTime",
|
ErrUnsatisfiedLockTime: "ErrUnsatisfiedLockTime",
|
||||||
|
ErrWitnessProgramEmpty: "ErrWitnessProgramEmpty",
|
||||||
|
ErrWitnessProgramMismatch: "ErrWitnessProgramMismatch",
|
||||||
|
ErrWitnessProgramWrongLength: "ErrWitnessProgramWrongLength",
|
||||||
|
ErrWitnessMalleated: "ErrWitnessMalleated",
|
||||||
|
ErrWitnessMalleatedP2SH: "ErrWitnessMalleatedP2SH",
|
||||||
|
ErrWitnessUnexpected: "ErrWitnessUnexpected",
|
||||||
|
ErrMinimalIf: "ErrMinimalIf",
|
||||||
|
ErrWitnessPubKeyType: "ErrWitnessPubKeyType",
|
||||||
|
ErrDiscourageUpgradableWitnessProgram: "ErrDiscourageUpgradableWitnessProgram",
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns the ErrorCode as a human-readable name.
|
// String returns the ErrorCode as a human-readable name.
|
||||||
|
|
|
@ -57,6 +57,15 @@ func TestErrorCodeStringer(t *testing.T) {
|
||||||
{ErrDiscourageUpgradableNOPs, "ErrDiscourageUpgradableNOPs"},
|
{ErrDiscourageUpgradableNOPs, "ErrDiscourageUpgradableNOPs"},
|
||||||
{ErrNegativeLockTime, "ErrNegativeLockTime"},
|
{ErrNegativeLockTime, "ErrNegativeLockTime"},
|
||||||
{ErrUnsatisfiedLockTime, "ErrUnsatisfiedLockTime"},
|
{ErrUnsatisfiedLockTime, "ErrUnsatisfiedLockTime"},
|
||||||
|
{ErrWitnessProgramEmpty, "ErrWitnessProgramEmpty"},
|
||||||
|
{ErrWitnessProgramMismatch, "ErrWitnessProgramMismatch"},
|
||||||
|
{ErrWitnessProgramWrongLength, "ErrWitnessProgramWrongLength"},
|
||||||
|
{ErrWitnessMalleated, "ErrWitnessMalleated"},
|
||||||
|
{ErrWitnessMalleatedP2SH, "ErrWitnessMalleatedP2SH"},
|
||||||
|
{ErrWitnessUnexpected, "ErrWitnessUnexpected"},
|
||||||
|
{ErrMinimalIf, "ErrMinimalIf"},
|
||||||
|
{ErrWitnessPubKeyType, "ErrWitnessPubKeyType"},
|
||||||
|
{ErrDiscourageUpgradableWitnessProgram, "ErrDiscourageUpgradableWitnessProgram"},
|
||||||
{0xffff, "Unknown ErrorCode (65535)"},
|
{0xffff, "Unknown ErrorCode (65535)"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -446,12 +446,14 @@ func PayToAddrScript(addr btcutil.Address) ([]byte, error) {
|
||||||
|
|
||||||
case *btcutil.AddressWitnessPubKeyHash:
|
case *btcutil.AddressWitnessPubKeyHash:
|
||||||
if addr == nil {
|
if addr == nil {
|
||||||
return nil, ErrUnsupportedAddress
|
return nil, scriptError(ErrUnsupportedAddress,
|
||||||
|
nilAddrErrStr)
|
||||||
}
|
}
|
||||||
return payToWitnessPubKeyHashScript(addr.ScriptAddress())
|
return payToWitnessPubKeyHashScript(addr.ScriptAddress())
|
||||||
case *btcutil.AddressWitnessScriptHash:
|
case *btcutil.AddressWitnessScriptHash:
|
||||||
if addr == nil {
|
if addr == nil {
|
||||||
return nil, ErrUnsupportedAddress
|
return nil, scriptError(ErrUnsupportedAddress,
|
||||||
|
nilAddrErrStr)
|
||||||
}
|
}
|
||||||
return payToWitnessScriptHashScript(addr.ScriptAddress())
|
return payToWitnessScriptHashScript(addr.ScriptAddress())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue