mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-10-14 00:59:33 +00:00
Add script pubkey version to signature hash (#1360)
* Replace 0xffff with math.MaxUint16 on version checks * Add script version to the signature hash Co-authored-by: Ori Newman <orinewman1@gmail.com>
This commit is contained in:
parent
d8293ef635
commit
4577023e44
@ -4,6 +4,7 @@ import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/blockheader"
|
||||
"github.com/pkg/errors"
|
||||
"math"
|
||||
)
|
||||
|
||||
// DomainBlockHeaderToDbBlockHeader converts BlockHeader to DbBlockHeader
|
||||
@ -38,7 +39,7 @@ func DbBlockHeaderToDomainBlockHeader(dbBlockHeader *DbBlockHeader) (externalapi
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dbBlockHeader.Version > 0xffff {
|
||||
if dbBlockHeader.Version > math.MaxUint16 {
|
||||
return nil, errors.Errorf("Invalid header version - bigger then uint16")
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package serialization
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/pkg/errors"
|
||||
"math"
|
||||
)
|
||||
|
||||
// DomainTransactionToDbTransaction converts DomainTransaction to DbTransaction
|
||||
@ -73,7 +74,7 @@ func DbTransactionToDomainTransaction(dbTransaction *DbTransaction) (*externalap
|
||||
}
|
||||
}
|
||||
|
||||
if dbTransaction.Version > 0xFFFF {
|
||||
if dbTransaction.Version > math.MaxUint16 {
|
||||
return nil, errors.Errorf("The transaction version is bigger then uint16.")
|
||||
}
|
||||
return &externalapi.DomainTransaction{
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
|
||||
"github.com/pkg/errors"
|
||||
"math"
|
||||
)
|
||||
|
||||
// ScriptPublicKeyToDBScriptPublicKey converts ScriptPublicKey to DBScriptPublicKey
|
||||
@ -13,7 +14,7 @@ func ScriptPublicKeyToDBScriptPublicKey(scriptPublicKey *externalapi.ScriptPubli
|
||||
|
||||
// DBScriptPublicKeyToScriptPublicKey convert DbScriptPublicKey ro ScriptPublicKey
|
||||
func DBScriptPublicKeyToScriptPublicKey(dbScriptPublicKey *DbScriptPublicKey) (*externalapi.ScriptPublicKey, error) {
|
||||
if dbScriptPublicKey.Version > 0xFFFF {
|
||||
if dbScriptPublicKey.Version > math.MaxUint16 {
|
||||
return nil, errors.Errorf("The version on ScriptPublicKey is bigger then uint16.")
|
||||
}
|
||||
return &externalapi.ScriptPublicKey{Script: dbScriptPublicKey.Script, Version: uint16(dbScriptPublicKey.Version)}, nil
|
||||
|
@ -39,7 +39,7 @@ const (
|
||||
|
||||
// Engine is the virtual machine that executes scripts.
|
||||
type Engine struct {
|
||||
isKnownVersion bool
|
||||
scriptVersion uint16
|
||||
scripts [][]parsedOpcode
|
||||
scriptIdx int
|
||||
scriptOff int
|
||||
@ -315,7 +315,7 @@ func (vm *Engine) Step() (done bool, err error) {
|
||||
// Execute will execute all scripts in the script engine and return either nil
|
||||
// for successful validation or an error if one occurred.
|
||||
func (vm *Engine) Execute() (err error) {
|
||||
if !vm.isKnownVersion {
|
||||
if vm.scriptVersion > constants.MaxScriptPublicKeyVersion {
|
||||
log.Tracef("The version of the scriptPublicKey is higher than the known version - the Execute function returns true.")
|
||||
return nil
|
||||
}
|
||||
@ -454,13 +454,11 @@ func NewEngine(scriptPubKey *externalapi.ScriptPublicKey, tx *externalapi.Domain
|
||||
return nil, scriptError(ErrEvalFalse,
|
||||
"false stack entry at end of script execution")
|
||||
}
|
||||
vm := Engine{flags: flags, sigCache: sigCache}
|
||||
vm := Engine{scriptVersion: scriptPubKey.Version, flags: flags, sigCache: sigCache}
|
||||
|
||||
if scriptPubKey.Version > constants.MaxScriptPublicKeyVersion {
|
||||
vm.isKnownVersion = false
|
||||
if vm.scriptVersion > constants.MaxScriptPublicKeyVersion {
|
||||
return &vm, nil
|
||||
}
|
||||
vm.isKnownVersion = true
|
||||
parsedScriptSig, err := parseScriptAndVerifySize(scriptSig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -2034,7 +2034,7 @@ func opcodeCheckSig(op *parsedOpcode, vm *Engine) error {
|
||||
script := vm.currentScript()
|
||||
|
||||
// Generate the signature hash based on the signature hash type.
|
||||
sigHash, err := calcSignatureHash(script, hashType, &vm.tx, vm.txIdx)
|
||||
sigHash, err := calcSignatureHash(script, vm.scriptVersion, hashType, &vm.tx, vm.txIdx)
|
||||
if err != nil {
|
||||
vm.dstack.PushBool(false)
|
||||
return nil
|
||||
@ -2241,7 +2241,7 @@ func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error {
|
||||
}
|
||||
|
||||
// Generate the signature hash based on the signature hash type.
|
||||
sigHash, err := calcSignatureHash(script, hashType, &vm.tx, vm.txIdx)
|
||||
sigHash, err := calcSignatureHash(script, vm.scriptVersion, hashType, &vm.tx, vm.txIdx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ package txscript
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
||||
|
||||
@ -295,13 +296,13 @@ func CalcSignatureHash(script *externalapi.ScriptPublicKey, hashType SigHashType
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("cannot parse output script: %s", err)
|
||||
}
|
||||
return calcSignatureHash(parsedScript, hashType, tx, idx)
|
||||
return calcSignatureHash(parsedScript, script.Version, hashType, tx, idx)
|
||||
}
|
||||
|
||||
// calcSignatureHash will, given a script and hash type for the current script
|
||||
// engine instance, calculate the signature hash to be used for signing and
|
||||
// verification.
|
||||
func calcSignatureHash(script []parsedOpcode, hashType SigHashType, tx *externalapi.DomainTransaction, idx int) (*externalapi.DomainHash, error) {
|
||||
func calcSignatureHash(prevScriptPublicKey []parsedOpcode, scriptVersion uint16, hashType SigHashType, tx *externalapi.DomainTransaction, idx int) (*externalapi.DomainHash, error) {
|
||||
// The SigHashSingle signature type signs only the corresponding input
|
||||
// and output (the output with the same index number as the input).
|
||||
//
|
||||
@ -320,8 +321,10 @@ func calcSignatureHash(script []parsedOpcode, hashType SigHashType, tx *external
|
||||
if i == idx {
|
||||
// UnparseScript cannot fail here because removeOpcode
|
||||
// above only returns a valid script.
|
||||
sigScript, _ := unparseScript(script)
|
||||
txCopy.Inputs[idx].SignatureScript = sigScript
|
||||
sigScript, _ := unparseScript(prevScriptPublicKey)
|
||||
var version [2]byte
|
||||
binary.LittleEndian.PutUint16(version[:], scriptVersion)
|
||||
txCopy.Inputs[idx].SignatureScript = append(version[:], sigScript...)
|
||||
} else {
|
||||
txCopy.Inputs[i].SignatureScript = nil
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/util/mstime"
|
||||
"github.com/pkg/errors"
|
||||
"math"
|
||||
)
|
||||
|
||||
func (x *BlockHeaderMessage) toAppMessage() (*appmessage.MsgBlockHeader, error) {
|
||||
@ -31,7 +32,7 @@ func (x *BlockHeaderMessage) toAppMessage() (*appmessage.MsgBlockHeader, error)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if x.Version > 0xffff {
|
||||
if x.Version > math.MaxUint16 {
|
||||
return nil, errors.Errorf("Invalid block header version - bigger then uint16")
|
||||
}
|
||||
return &appmessage.MsgBlockHeader{
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/pkg/errors"
|
||||
"math"
|
||||
)
|
||||
|
||||
func (x *KaspadMessage_Transaction) toAppMessage() (appmessage.Message, error) {
|
||||
@ -30,7 +31,7 @@ func (x *TransactionMessage) toAppMessage() (appmessage.Message, error) {
|
||||
|
||||
outputs := make([]*appmessage.TxOut, len(x.Outputs))
|
||||
for i, protoOutput := range x.Outputs {
|
||||
if protoOutput.ScriptPublicKey.Version > 0xFFFF {
|
||||
if protoOutput.ScriptPublicKey.Version > math.MaxUint16 {
|
||||
return nil, errors.Errorf("The version on ScriptPublicKey is bigger then uint16.")
|
||||
}
|
||||
outputs[i] = &appmessage.TxOut{
|
||||
@ -55,7 +56,7 @@ func (x *TransactionMessage) toAppMessage() (appmessage.Message, error) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if x.Version > 0xffff {
|
||||
if x.Version > math.MaxUint16 {
|
||||
return nil, errors.Errorf("Invalid transaction version - bigger then uint16")
|
||||
}
|
||||
return &appmessage.MsgTx{
|
||||
|
@ -3,6 +3,7 @@ package protowire
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/pkg/errors"
|
||||
"math"
|
||||
)
|
||||
|
||||
func (x *KaspadMessage_GetBlockRequest) toAppMessage() (appmessage.Message, error) {
|
||||
@ -72,7 +73,7 @@ func (x *BlockVerboseData) toAppMessage() (*appmessage.BlockVerboseData, error)
|
||||
transactionVerboseData[i] = appTransactionVerboseDatum
|
||||
}
|
||||
|
||||
if x.Version > 0xffff {
|
||||
if x.Version > math.MaxUint16 {
|
||||
return nil, errors.Errorf("Invalid block header version - bigger then uint16")
|
||||
}
|
||||
|
||||
@ -154,7 +155,7 @@ func (x *TransactionVerboseData) toAppMessage() (*appmessage.TransactionVerboseD
|
||||
ScriptPubKey: scriptPubKey,
|
||||
}
|
||||
}
|
||||
if x.Version > 0xffff {
|
||||
if x.Version > math.MaxUint16 {
|
||||
return nil, errors.Errorf("Invalid transaction version - bigger then uint16")
|
||||
}
|
||||
return &appmessage.TransactionVerboseData{
|
||||
|
@ -3,6 +3,7 @@ package protowire
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/pkg/errors"
|
||||
"math"
|
||||
)
|
||||
|
||||
func (x *KaspadMessage_SubmitTransactionRequest) toAppMessage() (appmessage.Message, error) {
|
||||
@ -71,7 +72,7 @@ func (x *RpcTransaction) toAppMessage() (*appmessage.RPCTransaction, error) {
|
||||
}
|
||||
}
|
||||
|
||||
if x.Version > 0xffff {
|
||||
if x.Version > math.MaxUint16 {
|
||||
return nil, errors.Errorf("Invalid RPC txn version - bigger then uint16")
|
||||
}
|
||||
|
||||
@ -89,7 +90,7 @@ func (x *RpcTransaction) toAppMessage() (*appmessage.RPCTransaction, error) {
|
||||
|
||||
// ConvertFromAppMsgRPCScriptPubKeyToRPCScriptPubKey converts from RpcScriptPubKey to RPCScriptPublicKey.
|
||||
func ConvertFromAppMsgRPCScriptPubKeyToRPCScriptPubKey(toConvert *RpcScriptPublicKey) (*appmessage.RPCScriptPublicKey, error) {
|
||||
if toConvert.Version > 0xffff {
|
||||
if toConvert.Version > math.MaxUint16 {
|
||||
return nil, errors.Errorf("Invalid header version - bigger then uint16")
|
||||
}
|
||||
version := uint16(toConvert.Version)
|
||||
|
Loading…
x
Reference in New Issue
Block a user