mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-03 12:46:43 +00:00
Limit block mass instead of merge set limit + Introduce SigOpCount to TransactionInput (#1790)
* Update constants * Add to transaction SigOpCount * Update mass calculation, and move it from InContext to InIsolation * Update block validation accordingly * Add SigOpCount validation during TransactionInContext * Remove checking of mass vs maxMassAcceptedByBlock from consensusStateManager * Update mining manager with latest changes * Add SigOpCount to MsgTx.Copy() * Fix initTestTransactionAcceptanceDataForClone * Fix all tests in transaction_equal_clone_test.go * Fix TestBlockMass * Fix tests in transactionvalidator package * Add SigOpCount to sighash * Fix TestPruningDepth * Fix problems in libkaspawalelt * Fix integration tests * Fix CalculateSignatureHash tests * Remove remaining places talking about block size * Add sanity check to checkBlockMass to make sure all transactions have their mass filled * always add own sigOpCount to sigHash * Update protowire/rpc.md * Start working on removing any remaining reference to block/tx size * Update rpc transaction verbose data to include mass rather then size * Convert verboseData and block size check to mass * Remove remaining usages of tx size in mempool * Move transactionEstimatedSerializedSize to transactionvalidator * Add PopulateMass to fakeRelayInvsContext * Move PopulateMass to beggining of ValidateAndInsertTransaction + fix in it * Assign mass a new number for backward-compatibility
This commit is contained in:
parent
8022e4cbea
commit
369a3bac09
@ -2,6 +2,7 @@ package appmessage
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/blockheader"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
|
||||
@ -100,6 +101,7 @@ func domainTransactionInputToTxIn(domainTransactionInput *externalapi.DomainTran
|
||||
PreviousOutpoint: *domainOutpointToOutpoint(domainTransactionInput.PreviousOutpoint),
|
||||
SignatureScript: domainTransactionInput.SignatureScript,
|
||||
Sequence: domainTransactionInput.Sequence,
|
||||
SigOpCount: domainTransactionInput.SigOpCount,
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,6 +150,7 @@ func txInToDomainTransactionInput(txIn *TxIn) *externalapi.DomainTransactionInpu
|
||||
return &externalapi.DomainTransactionInput{
|
||||
PreviousOutpoint: *outpointToDomainOutpoint(&txIn.PreviousOutpoint), //TODO
|
||||
SignatureScript: txIn.SignatureScript,
|
||||
SigOpCount: txIn.SigOpCount,
|
||||
Sequence: txIn.Sequence,
|
||||
}
|
||||
}
|
||||
@ -175,6 +178,7 @@ func RPCTransactionToDomainTransaction(rpcTransaction *RPCTransaction) (*externa
|
||||
PreviousOutpoint: *previousOutpoint,
|
||||
SignatureScript: signatureScript,
|
||||
Sequence: input.Sequence,
|
||||
SigOpCount: input.SigOpCount,
|
||||
}
|
||||
}
|
||||
outputs := make([]*externalapi.DomainTransactionOutput, len(rpcTransaction.Outputs))
|
||||
@ -253,6 +257,7 @@ func DomainTransactionToRPCTransaction(transaction *externalapi.DomainTransactio
|
||||
PreviousOutpoint: previousOutpoint,
|
||||
SignatureScript: signatureScript,
|
||||
Sequence: input.Sequence,
|
||||
SigOpCount: input.SigOpCount,
|
||||
}
|
||||
}
|
||||
outputs := make([]*RPCTransactionOutput, len(transaction.Outputs))
|
||||
|
@ -90,16 +90,18 @@ type TxIn struct {
|
||||
PreviousOutpoint Outpoint
|
||||
SignatureScript []byte
|
||||
Sequence uint64
|
||||
SigOpCount byte
|
||||
}
|
||||
|
||||
// NewTxIn returns a new kaspa transaction input with the provided
|
||||
// previous outpoint point and signature script with a default sequence of
|
||||
// MaxTxInSequenceNum.
|
||||
func NewTxIn(prevOut *Outpoint, signatureScript []byte, sequence uint64) *TxIn {
|
||||
func NewTxIn(prevOut *Outpoint, signatureScript []byte, sequence uint64, sigOpCount byte) *TxIn {
|
||||
return &TxIn{
|
||||
PreviousOutpoint: *prevOut,
|
||||
SignatureScript: signatureScript,
|
||||
Sequence: sequence,
|
||||
SigOpCount: sigOpCount,
|
||||
}
|
||||
}
|
||||
|
||||
@ -206,6 +208,7 @@ func (msg *MsgTx) Copy() *MsgTx {
|
||||
PreviousOutpoint: newOutpoint,
|
||||
SignatureScript: newScript,
|
||||
Sequence: oldTxIn.Sequence,
|
||||
SigOpCount: oldTxIn.SigOpCount,
|
||||
}
|
||||
|
||||
// Finally, append this fully copied txin.
|
||||
|
@ -68,7 +68,7 @@ func TestTx(t *testing.T) {
|
||||
|
||||
// Ensure we get the same transaction input back out.
|
||||
sigScript := []byte{0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62}
|
||||
txIn := NewTxIn(prevOut, sigScript, constants.MaxTxInSequenceNum)
|
||||
txIn := NewTxIn(prevOut, sigScript, constants.MaxTxInSequenceNum, 1)
|
||||
if !reflect.DeepEqual(&txIn.PreviousOutpoint, prevOut) {
|
||||
t.Errorf("NewTxIn: wrong prev outpoint - got %v, want %v",
|
||||
spew.Sprint(&txIn.PreviousOutpoint),
|
||||
|
@ -61,6 +61,7 @@ type RPCTransactionInput struct {
|
||||
PreviousOutpoint *RPCOutpoint
|
||||
SignatureScript string
|
||||
Sequence uint64
|
||||
SigOpCount byte
|
||||
VerboseData *RPCTransactionInputVerboseData
|
||||
}
|
||||
|
||||
@ -98,7 +99,7 @@ type RPCUTXOEntry struct {
|
||||
type RPCTransactionVerboseData struct {
|
||||
TransactionID string
|
||||
Hash string
|
||||
Size uint64
|
||||
Mass uint64
|
||||
BlockHash string
|
||||
BlockTime uint64
|
||||
}
|
||||
|
@ -130,6 +130,10 @@ type fakeRelayInvsContext struct {
|
||||
rwLock sync.RWMutex
|
||||
}
|
||||
|
||||
func (f *fakeRelayInvsContext) PopulateMass(*externalapi.DomainTransaction) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (f *fakeRelayInvsContext) DeleteStagingConsensus() error {
|
||||
panic("implement me")
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ import (
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/estimatedsize"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
|
||||
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
@ -114,10 +113,11 @@ func (ctx *Context) PopulateTransactionWithVerboseData(
|
||||
return err
|
||||
}
|
||||
|
||||
ctx.Domain.Consensus().PopulateMass(domainTransaction)
|
||||
transaction.VerboseData = &appmessage.RPCTransactionVerboseData{
|
||||
TransactionID: consensushashing.TransactionID(domainTransaction).String(),
|
||||
Hash: consensushashing.TransactionHash(domainTransaction).String(),
|
||||
Size: estimatedsize.TransactionEstimatedSerializedSize(domainTransaction),
|
||||
Mass: domainTransaction.Mass,
|
||||
}
|
||||
if domainBlockHeader != nil {
|
||||
transaction.VerboseData.BlockHash = consensushashing.HeaderHash(domainBlockHeader).String()
|
||||
|
@ -89,7 +89,7 @@ type PartiallySignedInput struct {
|
||||
PrevOutput *TransactionOutput `protobuf:"bytes,2,opt,name=prevOutput,proto3" json:"prevOutput,omitempty"`
|
||||
MinimumSignatures uint32 `protobuf:"varint,3,opt,name=minimumSignatures,proto3" json:"minimumSignatures,omitempty"`
|
||||
PubKeySignaturePairs []*PubKeySignaturePair `protobuf:"bytes,4,rep,name=pubKeySignaturePairs,proto3" json:"pubKeySignaturePairs,omitempty"`
|
||||
DerivationPath string `protobuf:"bytes,5,opt,name=DerivationPath,proto3" json:"DerivationPath,omitempty"`
|
||||
DerivationPath string `protobuf:"bytes,5,opt,name=derivationPath,proto3" json:"derivationPath,omitempty"`
|
||||
}
|
||||
|
||||
func (x *PartiallySignedInput) Reset() {
|
||||
@ -364,6 +364,7 @@ type TransactionInput struct {
|
||||
PreviousOutpoint *Outpoint `protobuf:"bytes,1,opt,name=previousOutpoint,proto3" json:"previousOutpoint,omitempty"`
|
||||
SignatureScript []byte `protobuf:"bytes,2,opt,name=signatureScript,proto3" json:"signatureScript,omitempty"`
|
||||
Sequence uint64 `protobuf:"varint,3,opt,name=sequence,proto3" json:"sequence,omitempty"`
|
||||
SigOpCount uint32 `protobuf:"varint,4,opt,name=sigOpCount,proto3" json:"sigOpCount,omitempty"`
|
||||
}
|
||||
|
||||
func (x *TransactionInput) Reset() {
|
||||
@ -419,6 +420,13 @@ func (x *TransactionInput) GetSequence() uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *TransactionInput) GetSigOpCount() uint32 {
|
||||
if x != nil {
|
||||
return x.SigOpCount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Outpoint struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@ -664,9 +672,9 @@ var file_wallet_proto_rawDesc = []byte{
|
||||
0x6f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x50,
|
||||
0x75, 0x62, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x50, 0x61,
|
||||
0x69, 0x72, 0x52, 0x14, 0x70, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74,
|
||||
0x75, 0x72, 0x65, 0x50, 0x61, 0x69, 0x72, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x44, 0x65, 0x72, 0x69,
|
||||
0x75, 0x72, 0x65, 0x50, 0x61, 0x69, 0x72, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x64, 0x65, 0x72, 0x69,
|
||||
0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0e, 0x44, 0x65, 0x72, 0x69, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x74, 0x68,
|
||||
0x52, 0x0e, 0x64, 0x65, 0x72, 0x69, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x74, 0x68,
|
||||
0x22, 0x5b, 0x0a, 0x13, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74,
|
||||
0x75, 0x72, 0x65, 0x50, 0x61, 0x69, 0x72, 0x12, 0x26, 0x0a, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x6e,
|
||||
0x64, 0x65, 0x64, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
@ -695,7 +703,7 @@ var file_wallet_proto_rawDesc = []byte{
|
||||
0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x06, 0x20, 0x01,
|
||||
0x28, 0x04, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f,
|
||||
0x61, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61,
|
||||
0x64, 0x22, 0xa2, 0x01, 0x0a, 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
|
||||
0x64, 0x22, 0xc2, 0x01, 0x0a, 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x48, 0x0a, 0x10, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f,
|
||||
0x75, 0x73, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a,
|
||||
@ -705,7 +713,9 @@ var file_wallet_proto_rawDesc = []byte{
|
||||
0x69, 0x70, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x73, 0x69, 0x67, 0x6e, 0x61,
|
||||
0x74, 0x75, 0x72, 0x65, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65,
|
||||
0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65,
|
||||
0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x69, 0x0a, 0x08, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69,
|
||||
0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x4f, 0x70, 0x43,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x4f,
|
||||
0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x69, 0x0a, 0x08, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69,
|
||||
0x6e, 0x74, 0x12, 0x47, 0x0a, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54,
|
||||
|
@ -13,7 +13,7 @@ message PartiallySignedInput{
|
||||
TransactionOutput prevOutput = 2;
|
||||
uint32 minimumSignatures = 3;
|
||||
repeated PubKeySignaturePair pubKeySignaturePairs = 4;
|
||||
string DerivationPath = 5;
|
||||
string derivationPath = 5;
|
||||
}
|
||||
|
||||
message PubKeySignaturePair{
|
||||
@ -39,6 +39,7 @@ message TransactionInput{
|
||||
Outpoint previousOutpoint = 1;
|
||||
bytes signatureScript = 2;
|
||||
uint64 sequence = 3;
|
||||
uint32 sigOpCount = 4;
|
||||
}
|
||||
|
||||
message Outpoint{
|
||||
|
@ -1,12 +1,13 @@
|
||||
package serialization
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet/serialization/protoserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
|
||||
"github.com/pkg/errors"
|
||||
"math"
|
||||
)
|
||||
|
||||
// PartiallySignedTransaction is a type that is intended
|
||||
@ -190,6 +191,10 @@ func transactionToProto(tx *externalapi.DomainTransaction) *protoserialization.T
|
||||
}
|
||||
|
||||
func transactionInputFromProto(protoInput *protoserialization.TransactionInput) (*externalapi.DomainTransactionInput, error) {
|
||||
if protoInput.SigOpCount > math.MaxUint8 {
|
||||
return nil, errors.New("TransactionInput SigOpCount > math.MaxUint8")
|
||||
}
|
||||
|
||||
outpoint, err := outpointFromProto(protoInput.PreviousOutpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -199,6 +204,7 @@ func transactionInputFromProto(protoInput *protoserialization.TransactionInput)
|
||||
PreviousOutpoint: *outpoint,
|
||||
SignatureScript: protoInput.SignatureScript,
|
||||
Sequence: protoInput.Sequence,
|
||||
SigOpCount: byte(protoInput.SigOpCount),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -207,6 +213,7 @@ func transactionInputToProto(input *externalapi.DomainTransactionInput) *protose
|
||||
PreviousOutpoint: outpointToProto(&input.PreviousOutpoint),
|
||||
SignatureScript: input.SignatureScript,
|
||||
Sequence: input.Sequence,
|
||||
SigOpCount: uint32(input.SigOpCount),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,7 @@ func sign(params *dagconfig.Params, mnemonic string, partiallySignedTransaction
|
||||
false, // This is a fake value, because it's irrelevant for the signature
|
||||
0, // This is a fake value, because it's irrelevant for the signature
|
||||
)
|
||||
partiallySignedTransaction.Tx.Inputs[i].SigOpCount = byte(len(partiallySignedInput.PubKeySignaturePairs))
|
||||
}
|
||||
|
||||
signed := false
|
||||
|
@ -96,8 +96,7 @@ func (s *consensus) ValidateTransactionAndPopulateWithConsensusData(transaction
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.transactionValidator.ValidateTransactionInContextAndPopulateMassAndFee(
|
||||
return s.transactionValidator.ValidateTransactionInContextAndPopulateFee(
|
||||
stagingArea, transaction, model.VirtualBlockHash, virtualSelectedParentMedianTime)
|
||||
}
|
||||
|
||||
@ -556,3 +555,7 @@ func (s *consensus) EstimateNetworkHashesPerSecond(startHash *externalapi.Domain
|
||||
|
||||
return s.difficultyManager.EstimateNetworkHashesPerSecond(startHash, windowSize)
|
||||
}
|
||||
|
||||
func (s *consensus) PopulateMass(transaction *externalapi.DomainTransaction) {
|
||||
s.transactionValidator.PopulateMass(transaction)
|
||||
}
|
||||
|
@ -333,6 +333,7 @@ type DbTransactionInput struct {
|
||||
PreviousOutpoint *DbOutpoint `protobuf:"bytes,1,opt,name=previousOutpoint,proto3" json:"previousOutpoint,omitempty"`
|
||||
SignatureScript []byte `protobuf:"bytes,2,opt,name=signatureScript,proto3" json:"signatureScript,omitempty"`
|
||||
Sequence uint64 `protobuf:"varint,3,opt,name=sequence,proto3" json:"sequence,omitempty"`
|
||||
SigOpCount uint32 `protobuf:"varint,4,opt,name=sigOpCount,proto3" json:"sigOpCount,omitempty"`
|
||||
}
|
||||
|
||||
func (x *DbTransactionInput) Reset() {
|
||||
@ -388,6 +389,13 @@ func (x *DbTransactionInput) GetSequence() uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *DbTransactionInput) GetSigOpCount() uint32 {
|
||||
if x != nil {
|
||||
return x.SigOpCount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type DbOutpoint struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@ -1664,7 +1672,7 @@ var file_dbobjects_proto_rawDesc = []byte{
|
||||
0x49, 0x64, 0x52, 0x0c, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x44,
|
||||
0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x67,
|
||||
0x61, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x08, 0x20,
|
||||
0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xa1, 0x01, 0x0a,
|
||||
0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xc1, 0x01, 0x0a,
|
||||
0x12, 0x44, 0x62, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e,
|
||||
0x70, 0x75, 0x74, 0x12, 0x45, 0x0a, 0x10, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x4f,
|
||||
0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e,
|
||||
@ -1675,6 +1683,8 @@ var file_dbobjects_proto_rawDesc = []byte{
|
||||
0x01, 0x28, 0x0c, 0x52, 0x0f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x63,
|
||||
0x72, 0x69, 0x70, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65,
|
||||
0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x4f, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04,
|
||||
0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x4f, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x22, 0x68, 0x0a, 0x0a, 0x44, 0x62, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x44,
|
||||
0x0a, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a,
|
||||
|
@ -37,6 +37,7 @@ message DbTransactionInput {
|
||||
DbOutpoint previousOutpoint = 1;
|
||||
bytes signatureScript = 2;
|
||||
uint64 sequence = 3;
|
||||
uint32 sigOpCount = 4;
|
||||
}
|
||||
|
||||
message DbOutpoint {
|
||||
|
@ -1,9 +1,10 @@
|
||||
package serialization
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/pkg/errors"
|
||||
"math"
|
||||
)
|
||||
|
||||
// DomainTransactionToDbTransaction converts DomainTransaction to DbTransaction
|
||||
@ -14,6 +15,7 @@ func DomainTransactionToDbTransaction(domainTransaction *externalapi.DomainTrans
|
||||
PreviousOutpoint: DomainOutpointToDbOutpoint(&domainTransactionInput.PreviousOutpoint),
|
||||
SignatureScript: domainTransactionInput.SignatureScript,
|
||||
Sequence: domainTransactionInput.Sequence,
|
||||
SigOpCount: uint32(domainTransactionInput.SigOpCount),
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,6 +56,7 @@ func DbTransactionToDomainTransaction(dbTransaction *DbTransaction) (*externalap
|
||||
PreviousOutpoint: *domainPreviousOutpoint,
|
||||
SignatureScript: dbTransactionInput.SignatureScript,
|
||||
Sequence: dbTransactionInput.Sequence,
|
||||
SigOpCount: byte(dbTransactionInput.SigOpCount),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,14 @@
|
||||
package consensus
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/prefixmanager/prefix"
|
||||
"github.com/pkg/errors"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/prefixmanager/prefix"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
consensusdatabase "github.com/kaspanet/kaspad/domain/consensus/database"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/datastructures/acceptancedatastore"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/datastructures/blockheaderstore"
|
||||
@ -231,7 +232,7 @@ func (f *factory) NewConsensus(config *Config, db infrastructuredatabase.Databas
|
||||
config.SkipProofOfWork,
|
||||
genesisHash,
|
||||
config.EnableNonNativeSubnetworks,
|
||||
config.MaxBlockSize,
|
||||
config.MaxBlockMass,
|
||||
config.MergeSetSizeLimit,
|
||||
config.MaxBlockParents,
|
||||
config.TimestampDeviationTolerance,
|
||||
@ -259,7 +260,6 @@ func (f *factory) NewConsensus(config *Config, db infrastructuredatabase.Databas
|
||||
consensusStateManager, err := consensusstatemanager.New(
|
||||
dbManager,
|
||||
config.PruningDepth(),
|
||||
config.MaxMassAcceptedByBlock,
|
||||
config.MaxBlockParents,
|
||||
config.MergeSetSizeLimit,
|
||||
genesisHash,
|
||||
|
@ -9,7 +9,6 @@ import (
|
||||
)
|
||||
|
||||
func initTestTransactionAcceptanceDataForClone() []*externalapi.TransactionAcceptanceData {
|
||||
|
||||
tests := []*externalapi.TransactionAcceptanceData{
|
||||
{
|
||||
&externalapi.DomainTransaction{
|
||||
@ -18,6 +17,7 @@ func initTestTransactionAcceptanceDataForClone() []*externalapi.TransactionAccep
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
Outputs: []*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
@ -62,6 +62,7 @@ func initTransactionAcceptanceDataForEqual() []testTransactionAcceptanceDataStru
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
Outputs: []*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
@ -91,6 +92,7 @@ func initTransactionAcceptanceDataForEqual() []testTransactionAcceptanceDataStru
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
Outputs: []*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
@ -119,6 +121,7 @@ func initTransactionAcceptanceDataForEqual() []testTransactionAcceptanceDataStru
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
Outputs: []*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
@ -147,6 +150,7 @@ func initTransactionAcceptanceDataForEqual() []testTransactionAcceptanceDataStru
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
Outputs: []*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
@ -176,6 +180,7 @@ func initTransactionAcceptanceDataForEqual() []testTransactionAcceptanceDataStru
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
Outputs: []*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
@ -206,6 +211,7 @@ func initTransactionAcceptanceDataForEqual() []testTransactionAcceptanceDataStru
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
Outputs: []*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
@ -311,6 +317,7 @@ func initTestBlockAcceptanceDataForClone() []*externalapi.BlockAcceptanceData {
|
||||
0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
@ -358,6 +365,7 @@ func iniBlockAcceptanceDataForEqual() []testBlockAcceptanceDataStruct {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
@ -390,6 +398,7 @@ func iniBlockAcceptanceDataForEqual() []testBlockAcceptanceDataStruct {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
@ -422,6 +431,7 @@ func iniBlockAcceptanceDataForEqual() []testBlockAcceptanceDataStruct {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
@ -454,6 +464,7 @@ func iniBlockAcceptanceDataForEqual() []testBlockAcceptanceDataStruct {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
@ -487,6 +498,7 @@ func iniBlockAcceptanceDataForEqual() []testBlockAcceptanceDataStruct {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
@ -590,6 +602,7 @@ func initTestAcceptanceDataForClone() []externalapi.AcceptanceData {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
@ -639,6 +652,7 @@ func initAcceptanceDataForEqual() []testAcceptanceDataStruct {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
@ -671,6 +685,7 @@ func initAcceptanceDataForEqual() []testAcceptanceDataStruct {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
@ -703,6 +718,7 @@ func initAcceptanceDataForEqual() []testAcceptanceDataStruct {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
@ -735,6 +751,7 @@ func initAcceptanceDataForEqual() []testAcceptanceDataStruct {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
|
@ -35,4 +35,5 @@ type Consensus interface {
|
||||
GetHeadersSelectedTip() (*DomainHash, error)
|
||||
Anticone(blockHash *DomainHash) ([]*DomainHash, error)
|
||||
EstimateNetworkHashesPerSecond(startHash *DomainHash, windowSize int) (uint64, error)
|
||||
PopulateMass(transaction *DomainTransaction)
|
||||
}
|
||||
|
@ -131,13 +131,14 @@ type DomainTransactionInput struct {
|
||||
PreviousOutpoint DomainOutpoint
|
||||
SignatureScript []byte
|
||||
Sequence uint64
|
||||
SigOpCount byte
|
||||
|
||||
UTXOEntry UTXOEntry
|
||||
}
|
||||
|
||||
// If this doesn't compile, it means the type definition has been changed, so it's
|
||||
// an indication to update Equal and Clone accordingly.
|
||||
var _ = &DomainTransactionInput{DomainOutpoint{}, []byte{}, 0, nil}
|
||||
var _ = &DomainTransactionInput{DomainOutpoint{}, []byte{}, 0, 0, nil}
|
||||
|
||||
// Equal returns whether input equals to other
|
||||
func (input *DomainTransactionInput) Equal(other *DomainTransactionInput) bool {
|
||||
@ -157,6 +158,10 @@ func (input *DomainTransactionInput) Equal(other *DomainTransactionInput) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
if input.SigOpCount != other.SigOpCount {
|
||||
return false
|
||||
}
|
||||
|
||||
if input.UTXOEntry != nil && other.UTXOEntry != nil && !input.UTXOEntry.Equal(other.UTXOEntry) {
|
||||
panic(errors.New("identical inputs should always have the same UTXO entry"))
|
||||
}
|
||||
@ -173,6 +178,7 @@ func (input *DomainTransactionInput) Clone() *DomainTransactionInput {
|
||||
PreviousOutpoint: *input.PreviousOutpoint.Clone(),
|
||||
SignatureScript: signatureScriptClone,
|
||||
Sequence: input.Sequence,
|
||||
SigOpCount: input.SigOpCount,
|
||||
UTXOEntry: input.UTXOEntry,
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +71,7 @@ func initTestBaseTransaction() *externalapi.DomainTransaction {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
@ -99,6 +100,7 @@ func initTestTransactionToCompare() []*transactionToCompare {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 3}, Version: 0}}, //Changed
|
||||
@ -123,6 +125,7 @@ func initTestTransactionToCompare() []*transactionToCompare {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
@ -147,6 +150,7 @@ func initTestTransactionToCompare() []*transactionToCompare {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
@ -171,6 +175,7 @@ func initTestTransactionToCompare() []*transactionToCompare {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}}, {uint64(0xFFFF),
|
||||
@ -196,6 +201,7 @@ func initTestTransactionToCompare() []*transactionToCompare {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}}, {uint64(0xFFFF),
|
||||
@ -221,6 +227,7 @@ func initTestTransactionToCompare() []*transactionToCompare {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
@ -245,6 +252,7 @@ func initTestTransactionToCompare() []*transactionToCompare {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}}, {uint64(0xFFFF),
|
||||
@ -268,6 +276,7 @@ func initTestTransactionToCompare() []*transactionToCompare {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}}, {uint64(0xFFFF),
|
||||
@ -291,6 +300,7 @@ func initTestTransactionToCompare() []*transactionToCompare {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}}, {uint64(0xFFFF),
|
||||
@ -314,11 +324,13 @@ func initTestTransactionToCompare() []*transactionToCompare {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)},
|
||||
{externalapi.DomainOutpoint{
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}}, {uint64(0xFFFF),
|
||||
@ -342,6 +354,7 @@ func initTestTransactionToCompare() []*transactionToCompare {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}}, {uint64(0xFFFF),
|
||||
@ -366,6 +379,7 @@ func initTestTransactionToCompare() []*transactionToCompare {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}}, {uint64(0xFFFF),
|
||||
@ -386,6 +400,31 @@ func initTestTransactionToCompare() []*transactionToCompare {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFF0), // Changed sequence
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}}, {uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 3}, Version: 0}}},
|
||||
1,
|
||||
externalapi.DomainSubnetworkID{0x01},
|
||||
1,
|
||||
[]byte{0x01},
|
||||
0,
|
||||
1,
|
||||
externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
|
||||
},
|
||||
expectedResult: false,
|
||||
}, {
|
||||
tx: &externalapi.DomainTransaction{
|
||||
1,
|
||||
[]*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
3, // Changed SigOpCount
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}}, {uint64(0xFFFF),
|
||||
@ -410,6 +449,7 @@ func initTestTransactionToCompare() []*transactionToCompare {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)}},
|
||||
[]*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}},
|
||||
@ -442,6 +482,7 @@ func initTestDomainTransactionForClone() []*externalapi.DomainTransaction {
|
||||
*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2)},
|
||||
},
|
||||
Outputs: []*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
@ -556,6 +597,7 @@ func initTestBaseDomainTransactionInput() *externalapi.DomainTransactionInput {
|
||||
externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2),
|
||||
}
|
||||
return basetxInput
|
||||
@ -567,6 +609,7 @@ func initTestDomainTxInputToCompare() []*transactionInputToCompare {
|
||||
externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2),
|
||||
},
|
||||
expectedResult: true,
|
||||
@ -575,6 +618,7 @@ func initTestDomainTxInputToCompare() []*transactionInputToCompare {
|
||||
externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, false, 2), // Changed
|
||||
},
|
||||
expectsPanic: true,
|
||||
@ -583,6 +627,7 @@ func initTestDomainTxInputToCompare() []*transactionInputToCompare {
|
||||
externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
nil, // Changed
|
||||
},
|
||||
expectedResult: true,
|
||||
@ -591,6 +636,16 @@ func initTestDomainTxInputToCompare() []*transactionInputToCompare {
|
||||
externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFF0), // Changed
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2),
|
||||
},
|
||||
expectedResult: false,
|
||||
}, {
|
||||
tx: &externalapi.DomainTransactionInput{
|
||||
externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFF0),
|
||||
5, // Changed
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2),
|
||||
},
|
||||
expectedResult: false,
|
||||
@ -599,6 +654,7 @@ func initTestDomainTxInputToCompare() []*transactionInputToCompare {
|
||||
externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3, 4}, // Changed
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2),
|
||||
},
|
||||
expectedResult: false,
|
||||
@ -607,6 +663,7 @@ func initTestDomainTxInputToCompare() []*transactionInputToCompare {
|
||||
externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01, 0x02}), 0xFFFF}, // Changed
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2),
|
||||
},
|
||||
expectedResult: false,
|
||||
@ -615,6 +672,7 @@ func initTestDomainTxInputToCompare() []*transactionInputToCompare {
|
||||
externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01, 0x02}), 0xFFFF}, // Changed
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(2 /* Changed */, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2), // Changed
|
||||
},
|
||||
expectedResult: false,
|
||||
@ -623,6 +681,7 @@ func initTestDomainTxInputToCompare() []*transactionInputToCompare {
|
||||
externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01, 0x02}), 0xFFFF}, // Changed
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(3 /* Changed */, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 3), // Changed
|
||||
},
|
||||
expectedResult: false,
|
||||
@ -640,18 +699,21 @@ func initTestDomainTransactionInputForClone() []*externalapi.DomainTransactionIn
|
||||
externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2),
|
||||
}, {
|
||||
|
||||
externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFFF),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2),
|
||||
}, {
|
||||
|
||||
externalapi.DomainOutpoint{*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
|
||||
[]byte{1, 2, 3},
|
||||
uint64(0xFFFFFFF0),
|
||||
1,
|
||||
utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{Script: []byte{0, 1, 2, 3}, Version: 0}, true, 2),
|
||||
}}
|
||||
return txInput
|
||||
|
@ -10,6 +10,7 @@ type TransactionValidator interface {
|
||||
ValidateTransactionInIsolation(transaction *externalapi.DomainTransaction) error
|
||||
ValidateTransactionInContextIgnoringUTXO(stagingArea *StagingArea, tx *externalapi.DomainTransaction,
|
||||
povBlockHash *externalapi.DomainHash) error
|
||||
ValidateTransactionInContextAndPopulateMassAndFee(stagingArea *StagingArea,
|
||||
ValidateTransactionInContextAndPopulateFee(stagingArea *StagingArea,
|
||||
tx *externalapi.DomainTransaction, povBlockHash *externalapi.DomainHash, selectedParentMedianTime int64) error
|
||||
PopulateMass(transaction *externalapi.DomainTransaction)
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ func (bb *blockBuilder) validateTransaction(
|
||||
return err
|
||||
}
|
||||
|
||||
return bb.transactionValidator.ValidateTransactionInContextAndPopulateMassAndFee(
|
||||
return bb.transactionValidator.ValidateTransactionInContextAndPopulateFee(
|
||||
stagingArea, transaction, model.VirtualBlockHash, virtualSelectedParentMedianTime)
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,6 @@ func (bp *blockProcessor) setBlockStatusAfterBlockValidation(
|
||||
}
|
||||
|
||||
func (bp *blockProcessor) updateVirtualAcceptanceDataAfterImportingPruningPoint(stagingArea *model.StagingArea) error {
|
||||
|
||||
_, virtualAcceptanceData, virtualMultiset, err :=
|
||||
bp.consensusStateManager.CalculatePastUTXOAndAcceptanceData(stagingArea, model.VirtualBlockHash)
|
||||
if err != nil {
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/estimatedsize"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/merkle"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionhelper"
|
||||
@ -34,11 +33,6 @@ func (v *blockValidator) ValidateBodyInIsolation(stagingArea *model.StagingArea,
|
||||
return err
|
||||
}
|
||||
|
||||
err = v.checkBlockSize(block)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = v.checkBlockContainsAtLeastOneTransaction(block)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -69,6 +63,11 @@ func (v *blockValidator) ValidateBodyInIsolation(stagingArea *model.StagingArea,
|
||||
return err
|
||||
}
|
||||
|
||||
err = v.checkBlockMass(block)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = v.checkBlockDuplicateTransactions(block)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -215,16 +214,18 @@ func (v *blockValidator) validateGasLimit(block *externalapi.DomainBlock) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *blockValidator) checkBlockSize(block *externalapi.DomainBlock) error {
|
||||
size := uint64(0)
|
||||
size += v.headerEstimatedSerializedSize(block.Header)
|
||||
func (v *blockValidator) checkBlockMass(block *externalapi.DomainBlock) error {
|
||||
mass := uint64(0)
|
||||
mass += v.headerEstimatedSerializedSize(block.Header)
|
||||
|
||||
for _, tx := range block.Transactions {
|
||||
sizeBefore := size
|
||||
size += estimatedsize.TransactionEstimatedSerializedSize(tx)
|
||||
if size > v.maxBlockSize || size < sizeBefore {
|
||||
return errors.Wrapf(ruleerrors.ErrBlockSizeTooHigh, "block excceeded the size limit of %d",
|
||||
v.maxBlockSize)
|
||||
for _, transaction := range block.Transactions {
|
||||
v.transactionValidator.PopulateMass(transaction)
|
||||
|
||||
massBefore := mass
|
||||
mass += transaction.Mass
|
||||
if mass > v.maxBlockMass || mass < massBefore {
|
||||
return errors.Wrapf(ruleerrors.ErrBlockMassTooHigh, "block exceeded the mass limit of %d",
|
||||
v.maxBlockMass)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1027,17 +1027,16 @@ func TestCheckBlockHashMerkleRoot(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestBlockSize(t *testing.T) {
|
||||
func TestBlockMass(t *testing.T) {
|
||||
testutils.ForAllNets(t, true, func(t *testing.T, consensusConfig *consensus.Config) {
|
||||
|
||||
factory := consensus.NewFactory()
|
||||
tc, teardown, err := factory.NewTestConsensus(consensusConfig, "TestBlockSize")
|
||||
tc, teardown, err := factory.NewTestConsensus(consensusConfig, "TestBlockMass")
|
||||
if err != nil {
|
||||
t.Fatalf("Error setting up tc: %+v", err)
|
||||
}
|
||||
defer teardown(false)
|
||||
|
||||
block, _, err := initBlockWithInvalidBlockSize(consensusConfig, tc)
|
||||
block, _, err := initBlockWithInvalidBlockMass(consensusConfig, tc)
|
||||
if err != nil {
|
||||
t.Fatalf("Error BuildBlockWithParents : %+v", err)
|
||||
}
|
||||
@ -1046,14 +1045,14 @@ func TestBlockSize(t *testing.T) {
|
||||
tc.BlockStore().Stage(stagingArea, blockHash, block)
|
||||
|
||||
err = tc.BlockValidator().ValidateBodyInIsolation(stagingArea, blockHash)
|
||||
if err == nil || !errors.Is(err, ruleerrors.ErrBlockSizeTooHigh) {
|
||||
t.Fatalf("ValidateBodyInIsolationTest: TestBlockSize:"+
|
||||
" Unexpected error: Expected to: %v, but got : %v", ruleerrors.ErrBlockSizeTooHigh, err)
|
||||
if err == nil || !errors.Is(err, ruleerrors.ErrBlockMassTooHigh) {
|
||||
t.Fatalf("ValidateBodyInIsolationTest: TestBlockMass:"+
|
||||
" Unexpected error: Expected to: %v, but got : %v", ruleerrors.ErrBlockMassTooHigh, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func initBlockWithInvalidBlockSize(consensusConfig *consensus.Config, tc testapi.TestConsensus) (*externalapi.DomainBlock, externalapi.UTXODiff, error) {
|
||||
func initBlockWithInvalidBlockMass(consensusConfig *consensus.Config, tc testapi.TestConsensus) (*externalapi.DomainBlock, externalapi.UTXODiff, error) {
|
||||
emptyCoinbase := externalapi.DomainCoinbaseData{
|
||||
ScriptPublicKey: &externalapi.ScriptPublicKey{
|
||||
Script: nil,
|
||||
@ -1062,11 +1061,12 @@ func initBlockWithInvalidBlockSize(consensusConfig *consensus.Config, tc testapi
|
||||
}
|
||||
prevOutTxID := &externalapi.DomainTransactionID{}
|
||||
prevOutPoint := externalapi.DomainOutpoint{TransactionID: *prevOutTxID, Index: 1}
|
||||
bigSignatureScript := bytes.Repeat([]byte("01"), 25000)
|
||||
bigSignatureScript := bytes.Repeat([]byte("01"), 500000)
|
||||
txInput := externalapi.DomainTransactionInput{
|
||||
PreviousOutpoint: prevOutPoint,
|
||||
SignatureScript: bigSignatureScript,
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
SigOpCount: 10,
|
||||
UTXOEntry: utxo.NewUTXOEntry(
|
||||
100_000_000,
|
||||
&externalapi.ScriptPublicKey{},
|
||||
@ -1079,7 +1079,7 @@ func initBlockWithInvalidBlockSize(consensusConfig *consensus.Config, tc testapi
|
||||
Outputs: []*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}}, {uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 3}, Version: 0}}},
|
||||
Payload: []byte{0x01},
|
||||
Payload: []byte{},
|
||||
}
|
||||
|
||||
return tc.BuildBlockWithParents([]*externalapi.DomainHash{consensusConfig.GenesisHash}, &emptyCoinbase, []*externalapi.DomainTransaction{tx})
|
||||
|
@ -1,12 +1,12 @@
|
||||
package blockvalidator
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/util/difficulty"
|
||||
"math/big"
|
||||
"time"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/util/difficulty"
|
||||
)
|
||||
|
||||
// blockValidator exposes a set of validation classes, after which
|
||||
@ -17,7 +17,7 @@ type blockValidator struct {
|
||||
genesisHash *externalapi.DomainHash
|
||||
enableNonNativeSubnetworks bool
|
||||
powMaxBits uint32
|
||||
maxBlockSize uint64
|
||||
maxBlockMass uint64
|
||||
mergeSetSizeLimit uint64
|
||||
maxBlockParents model.KType
|
||||
timestampDeviationTolerance int
|
||||
@ -48,7 +48,7 @@ func New(powMax *big.Int,
|
||||
skipPoW bool,
|
||||
genesisHash *externalapi.DomainHash,
|
||||
enableNonNativeSubnetworks bool,
|
||||
maxBlockSize uint64,
|
||||
maxBlockMass uint64,
|
||||
mergeSetSizeLimit uint64,
|
||||
maxBlockParents model.KType,
|
||||
timestampDeviationTolerance int,
|
||||
@ -82,7 +82,7 @@ func New(powMax *big.Int,
|
||||
genesisHash: genesisHash,
|
||||
enableNonNativeSubnetworks: enableNonNativeSubnetworks,
|
||||
powMaxBits: difficulty.BigToCompact(powMax),
|
||||
maxBlockSize: maxBlockSize,
|
||||
maxBlockMass: maxBlockMass,
|
||||
mergeSetSizeLimit: mergeSetSizeLimit,
|
||||
maxBlockParents: maxBlockParents,
|
||||
|
||||
|
@ -237,7 +237,7 @@ func (csm *consensusStateManager) maybeAcceptTransaction(stagingArea *model.Stag
|
||||
log.Tracef("Transaction %s is the coinbase of block %s", transactionID, blockHash)
|
||||
} else {
|
||||
log.Tracef("Validating transaction %s in block %s", transactionID, blockHash)
|
||||
err = csm.transactionValidator.ValidateTransactionInContextAndPopulateMassAndFee(
|
||||
err = csm.transactionValidator.ValidateTransactionInContextAndPopulateFee(
|
||||
stagingArea, transaction, blockHash, selectedParentPastMedianTime)
|
||||
if err != nil {
|
||||
if !errors.As(err, &(ruleerrors.RuleError{})) {
|
||||
@ -249,14 +249,6 @@ func (csm *consensusStateManager) maybeAcceptTransaction(stagingArea *model.Stag
|
||||
return false, accumulatedMassBefore, nil
|
||||
}
|
||||
log.Tracef("Validation passed for transaction %s in block %s", transactionID, blockHash)
|
||||
|
||||
log.Tracef("Check mass for transaction %s in block %s", transactionID, blockHash)
|
||||
isAccepted, accumulatedMassAfter = csm.checkTransactionMass(transaction, accumulatedMassBefore)
|
||||
if !isAccepted {
|
||||
log.Tracef("Transaction %s in block %s has too much mass, "+
|
||||
"and cannot be accepted", transactionID, blockHash)
|
||||
return false, accumulatedMassBefore, nil
|
||||
}
|
||||
}
|
||||
|
||||
log.Tracef("Adding transaction %s in block %s to the accumulated diff", transactionID, blockHash)
|
||||
@ -268,27 +260,6 @@ func (csm *consensusStateManager) maybeAcceptTransaction(stagingArea *model.Stag
|
||||
return true, accumulatedMassAfter, nil
|
||||
}
|
||||
|
||||
func (csm *consensusStateManager) checkTransactionMass(transaction *externalapi.DomainTransaction, accumulatedMassBefore uint64) (
|
||||
isAccepted bool, accumulatedMassAfter uint64) {
|
||||
|
||||
transactionID := consensushashing.TransactionID(transaction)
|
||||
log.Tracef("checkTransactionMass start for transaction %s", transactionID)
|
||||
defer log.Tracef("checkTransactionMass end for transaction %s", transactionID)
|
||||
|
||||
log.Tracef("Adding transaction %s with mass %d to the "+
|
||||
"so-far accumulated mass of %d", transactionID, transaction.Mass, accumulatedMassBefore)
|
||||
accumulatedMassAfter = accumulatedMassBefore + transaction.Mass
|
||||
log.Tracef("Accumulated mass including transaction %s: %d", transactionID, accumulatedMassAfter)
|
||||
|
||||
// We could potentially overflow the accumulator so check for
|
||||
// overflow as well.
|
||||
if accumulatedMassAfter < transaction.Mass || accumulatedMassAfter > csm.maxMassAcceptedByBlock {
|
||||
return false, 0
|
||||
}
|
||||
|
||||
return true, accumulatedMassAfter
|
||||
}
|
||||
|
||||
// RestorePastUTXOSetIterator restores the given block's UTXOSet iterator, and returns it as a externalapi.ReadOnlyUTXOSetIterator
|
||||
func (csm *consensusStateManager) RestorePastUTXOSetIterator(stagingArea *model.StagingArea, blockHash *externalapi.DomainHash) (
|
||||
externalapi.ReadOnlyUTXOSetIterator, error) {
|
||||
|
@ -7,12 +7,11 @@ import (
|
||||
|
||||
// consensusStateManager manages the node's consensus state
|
||||
type consensusStateManager struct {
|
||||
pruningDepth uint64
|
||||
maxMassAcceptedByBlock uint64
|
||||
maxBlockParents model.KType
|
||||
mergeSetSizeLimit uint64
|
||||
genesisHash *externalapi.DomainHash
|
||||
databaseContext model.DBManager
|
||||
pruningDepth uint64
|
||||
maxBlockParents model.KType
|
||||
mergeSetSizeLimit uint64
|
||||
genesisHash *externalapi.DomainHash
|
||||
databaseContext model.DBManager
|
||||
|
||||
ghostdagManager model.GHOSTDAGManager
|
||||
dagTopologyManager model.DAGTopologyManager
|
||||
@ -46,7 +45,6 @@ type consensusStateManager struct {
|
||||
func New(
|
||||
databaseContext model.DBManager,
|
||||
pruningDepth uint64,
|
||||
maxMassAcceptedByBlock uint64,
|
||||
maxBlockParents model.KType,
|
||||
mergeSetSizeLimit uint64,
|
||||
genesisHash *externalapi.DomainHash,
|
||||
@ -77,12 +75,11 @@ func New(
|
||||
daaBlocksStore model.DAABlocksStore) (model.ConsensusStateManager, error) {
|
||||
|
||||
csm := &consensusStateManager{
|
||||
pruningDepth: pruningDepth,
|
||||
maxMassAcceptedByBlock: maxMassAcceptedByBlock,
|
||||
maxBlockParents: maxBlockParents,
|
||||
mergeSetSizeLimit: mergeSetSizeLimit,
|
||||
genesisHash: genesisHash,
|
||||
databaseContext: databaseContext,
|
||||
pruningDepth: pruningDepth,
|
||||
maxBlockParents: maxBlockParents,
|
||||
mergeSetSizeLimit: mergeSetSizeLimit,
|
||||
genesisHash: genesisHash,
|
||||
databaseContext: databaseContext,
|
||||
|
||||
ghostdagManager: ghostdagManager,
|
||||
dagTopologyManager: dagTopologyManager,
|
||||
|
@ -118,7 +118,7 @@ func (csm *consensusStateManager) importPruningPoint(
|
||||
continue
|
||||
}
|
||||
log.Tracef("Validating transaction %s and populating it with mass and fee", transactionID)
|
||||
err = csm.transactionValidator.ValidateTransactionInContextAndPopulateMassAndFee(
|
||||
err = csm.transactionValidator.ValidateTransactionInContextAndPopulateFee(
|
||||
stagingArea, transaction, newPruningPointHash, newPruningPointSelectedParentMedianTime)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -83,8 +83,8 @@ func (csm *consensusStateManager) validateBlockTransactionsAgainstPastUTXO(stagi
|
||||
return err
|
||||
}
|
||||
|
||||
log.Tracef("Validating transaction %s and populating it with mass and fee", transactionID)
|
||||
err = csm.transactionValidator.ValidateTransactionInContextAndPopulateMassAndFee(
|
||||
log.Tracef("Validating transaction %s and populating it with fee", transactionID)
|
||||
err = csm.transactionValidator.ValidateTransactionInContextAndPopulateFee(
|
||||
stagingArea, transaction, blockHash, selectedParentMedianTime)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -2,47 +2,99 @@ package transactionvalidator
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/estimatedsize"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionhelper"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
|
||||
)
|
||||
|
||||
func (v *transactionValidator) transactionMassStandalonePart(tx *externalapi.DomainTransaction) uint64 {
|
||||
size := estimatedsize.TransactionEstimatedSerializedSize(tx)
|
||||
func (v *transactionValidator) PopulateMass(transaction *externalapi.DomainTransaction) {
|
||||
if transaction.Mass != 0 {
|
||||
return
|
||||
}
|
||||
transaction.Mass = v.transactionMass(transaction)
|
||||
}
|
||||
|
||||
func (v *transactionValidator) transactionMass(transaction *externalapi.DomainTransaction) uint64 {
|
||||
if transactionhelper.IsCoinBase(transaction) {
|
||||
return 0
|
||||
}
|
||||
|
||||
// calculate mass for size
|
||||
size := transactionEstimatedSerializedSize(transaction)
|
||||
massForSize := size * v.massPerTxByte
|
||||
|
||||
// calculate mass for scriptPubKey
|
||||
totalScriptPubKeySize := uint64(0)
|
||||
for _, output := range tx.Outputs {
|
||||
for _, output := range transaction.Outputs {
|
||||
totalScriptPubKeySize += 2 //output.ScriptPublicKey.Version (uint16)
|
||||
totalScriptPubKeySize += uint64(len(output.ScriptPublicKey.Script))
|
||||
}
|
||||
massForScriptPubKey := totalScriptPubKeySize * v.massPerScriptPubKeyByte
|
||||
|
||||
return size*v.massPerTxByte + totalScriptPubKeySize*v.massPerScriptPubKeyByte
|
||||
// calculate mass for SigOps
|
||||
totalSigOpCount := uint64(0)
|
||||
for _, input := range transaction.Inputs {
|
||||
totalSigOpCount += uint64(input.SigOpCount)
|
||||
}
|
||||
massForSigOps := totalSigOpCount * v.massPerSigOp
|
||||
|
||||
// Sum all components of mass
|
||||
return massForSize + massForScriptPubKey + massForSigOps
|
||||
}
|
||||
|
||||
func (v *transactionValidator) transactionMass(tx *externalapi.DomainTransaction) (uint64, error) {
|
||||
// transactionEstimatedSerializedSize is the estimated size of a transaction in some
|
||||
// serialization. This has to be deterministic, but not necessarily accurate, since
|
||||
// it's only used as the size component in the transaction and block mass limit
|
||||
// calculation.
|
||||
func transactionEstimatedSerializedSize(tx *externalapi.DomainTransaction) uint64 {
|
||||
if transactionhelper.IsCoinBase(tx) {
|
||||
return 0, nil
|
||||
return 0
|
||||
}
|
||||
|
||||
standaloneMass := v.transactionMassStandalonePart(tx)
|
||||
sigOpsCount := uint64(0)
|
||||
var missingOutpoints []*externalapi.DomainOutpoint
|
||||
size := uint64(0)
|
||||
size += 2 // Txn Version
|
||||
size += 8 // number of inputs (uint64)
|
||||
for _, input := range tx.Inputs {
|
||||
utxoEntry := input.UTXOEntry
|
||||
if utxoEntry == nil {
|
||||
missingOutpoints = append(missingOutpoints, &input.PreviousOutpoint)
|
||||
continue
|
||||
}
|
||||
// Count the precise number of signature operations in the
|
||||
// referenced public key script.
|
||||
sigScript := input.SignatureScript
|
||||
isP2SH := txscript.IsPayToScriptHash(utxoEntry.ScriptPublicKey())
|
||||
sigOpsCount += uint64(txscript.GetPreciseSigOpCount(sigScript, utxoEntry.ScriptPublicKey(), isP2SH))
|
||||
}
|
||||
if len(missingOutpoints) > 0 {
|
||||
return 0, ruleerrors.NewErrMissingTxOut(missingOutpoints)
|
||||
size += transactionInputEstimatedSerializedSize(input)
|
||||
}
|
||||
|
||||
return standaloneMass + sigOpsCount*v.massPerSigOp, nil
|
||||
size += 8 // number of outputs (uint64)
|
||||
for _, output := range tx.Outputs {
|
||||
size += TransactionOutputEstimatedSerializedSize(output)
|
||||
}
|
||||
|
||||
size += 8 // lock time (uint64)
|
||||
size += externalapi.DomainSubnetworkIDSize
|
||||
size += 8 // gas (uint64)
|
||||
size += externalapi.DomainHashSize // payload hash
|
||||
|
||||
size += 8 // length of the payload (uint64)
|
||||
size += uint64(len(tx.Payload))
|
||||
|
||||
return size
|
||||
}
|
||||
|
||||
func transactionInputEstimatedSerializedSize(input *externalapi.DomainTransactionInput) uint64 {
|
||||
size := uint64(0)
|
||||
size += outpointEstimatedSerializedSize()
|
||||
|
||||
size += 8 // length of signature script (uint64)
|
||||
size += uint64(len(input.SignatureScript))
|
||||
|
||||
size += 8 // sequence (uint64)
|
||||
return size
|
||||
}
|
||||
|
||||
func outpointEstimatedSerializedSize() uint64 {
|
||||
size := uint64(0)
|
||||
size += externalapi.DomainHashSize // ID
|
||||
size += 4 // index (uint32)
|
||||
return size
|
||||
}
|
||||
|
||||
// TransactionOutputEstimatedSerializedSize is the same as transactionEstimatedSerializedSize but for outputs only
|
||||
func TransactionOutputEstimatedSerializedSize(output *externalapi.DomainTransactionOutput) uint64 {
|
||||
size := uint64(0)
|
||||
size += 8 // value (uint64)
|
||||
size += 2 // output.ScriptPublicKey.Version (uint 16)
|
||||
size += 8 // length of script public key (uint64)
|
||||
size += uint64(len(output.ScriptPublicKey.Script))
|
||||
return size
|
||||
}
|
||||
|
@ -65,11 +65,11 @@ func (v *transactionValidator) ValidateTransactionInContextIgnoringUTXO(stagingA
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidateTransactionInContextAndPopulateMassAndFee validates the transaction against its referenced UTXO, and
|
||||
// populates its mass and fee fields.
|
||||
// ValidateTransactionInContextAndPopulateFee validates the transaction against its referenced UTXO, and
|
||||
// populates its fee field.
|
||||
//
|
||||
// Note: if the function fails, there's no guarantee that the transaction mass and fee fields will remain unaffected.
|
||||
func (v *transactionValidator) ValidateTransactionInContextAndPopulateMassAndFee(stagingArea *model.StagingArea,
|
||||
// Note: if the function fails, there's no guarantee that the transaction fee field will remain unaffected.
|
||||
func (v *transactionValidator) ValidateTransactionInContextAndPopulateFee(stagingArea *model.StagingArea,
|
||||
tx *externalapi.DomainTransaction, povBlockHash *externalapi.DomainHash, selectedParentMedianTime int64) error {
|
||||
|
||||
err := v.checkTransactionCoinbaseMaturity(stagingArea, povBlockHash, tx)
|
||||
@ -94,12 +94,12 @@ func (v *transactionValidator) ValidateTransactionInContextAndPopulateMassAndFee
|
||||
return err
|
||||
}
|
||||
|
||||
err = v.validateTransactionScripts(tx)
|
||||
err = v.validateTransactionSigOpCounts(tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tx.Mass, err = v.transactionMass(tx)
|
||||
err = v.validateTransactionScripts(tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -399,3 +399,21 @@ func (v *transactionValidator) sequenceLockActive(sequenceLock *sequenceLock, bl
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (v *transactionValidator) validateTransactionSigOpCounts(tx *externalapi.DomainTransaction) error {
|
||||
for i, input := range tx.Inputs {
|
||||
utxoEntry := input.UTXOEntry
|
||||
|
||||
// Count the precise number of signature operations in the
|
||||
// referenced public key script.
|
||||
sigScript := input.SignatureScript
|
||||
isP2SH := txscript.IsPayToScriptHash(utxoEntry.ScriptPublicKey())
|
||||
sigOpCount := txscript.GetPreciseSigOpCount(sigScript, utxoEntry.ScriptPublicKey(), isP2SH)
|
||||
if sigOpCount != int(input.SigOpCount) {
|
||||
return errors.Wrapf(ruleerrors.ErrWrongSigOpCount,
|
||||
"input %d specifies SigOpCount %d while actual SigOpCount is %d",
|
||||
i, input.SigOpCount, sigOpCount)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// ValidateTransactionInIsolation validates the parts of the transaction that can be validated context-free
|
||||
func (v *transactionValidator) ValidateTransactionInIsolation(tx *externalapi.DomainTransaction) error {
|
||||
err := v.checkTransactionInputCount(tx)
|
||||
if err != nil {
|
||||
|
@ -20,10 +20,10 @@ type txSubnetworkData struct {
|
||||
payload []byte
|
||||
}
|
||||
|
||||
func TestValidateTransactionInIsolation(t *testing.T) {
|
||||
func TestValidateTransactionInIsolationAndPopulateMass(t *testing.T) {
|
||||
testutils.ForAllNets(t, true, func(t *testing.T, consensusConfig *consensus.Config) {
|
||||
factory := consensus.NewFactory()
|
||||
tc, teardown, err := factory.NewTestConsensus(consensusConfig, "TestValidateTransactionInIsolation")
|
||||
tc, teardown, err := factory.NewTestConsensus(consensusConfig, "TestValidateTransactionInIsolationAndPopulateMass")
|
||||
if err != nil {
|
||||
t.Fatalf("Error setting up consensus: %+v", err)
|
||||
}
|
||||
@ -111,7 +111,7 @@ func TestValidateTransactionInIsolation(t *testing.T) {
|
||||
|
||||
err := tc.TransactionValidator().ValidateTransactionInIsolation(tx)
|
||||
if !errors.Is(err, test.expectedErr) {
|
||||
t.Errorf("TestValidateTransactionInIsolation: '%s': unexpected error %+v", test.name, err)
|
||||
t.Errorf("TestValidateTransactionInIsolationAndPopulateMass: '%s': unexpected error %+v", test.name, err)
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -129,6 +129,7 @@ func createTxForTest(numInputs uint32, numOutputs uint32, outputValue uint64, su
|
||||
},
|
||||
SignatureScript: []byte{},
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
SigOpCount: 1,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ func (mdf *mocPastMedianTimeManager) PastMedianTime(*model.StagingArea, *externa
|
||||
return mdf.pastMedianTimeForTest, nil
|
||||
}
|
||||
|
||||
func TestValidateTransactionInContextAndPopulateMassAndFee(t *testing.T) {
|
||||
func TestValidateTransactionInContextAndPopulateFee(t *testing.T) {
|
||||
testutils.ForAllNets(t, true, func(t *testing.T, consensusConfig *consensus.Config) {
|
||||
|
||||
factory := consensus.NewFactory()
|
||||
@ -42,7 +42,7 @@ func TestValidateTransactionInContextAndPopulateMassAndFee(t *testing.T) {
|
||||
return pastMedianManager
|
||||
})
|
||||
tc, tearDown, err := factory.NewTestConsensus(consensusConfig,
|
||||
"TestValidateTransactionInContextAndPopulateMassAndFee")
|
||||
"TestValidateTransactionInContextAndPopulateFee")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed create a NewTestConsensus: %s", err)
|
||||
}
|
||||
@ -76,6 +76,7 @@ func TestValidateTransactionInContextAndPopulateMassAndFee(t *testing.T) {
|
||||
PreviousOutpoint: prevOutPoint,
|
||||
SignatureScript: []byte{},
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
SigOpCount: 1,
|
||||
UTXOEntry: utxo.NewUTXOEntry(
|
||||
100_000_000, // 1 KAS
|
||||
scriptPublicKey,
|
||||
@ -86,6 +87,7 @@ func TestValidateTransactionInContextAndPopulateMassAndFee(t *testing.T) {
|
||||
PreviousOutpoint: prevOutPoint,
|
||||
SignatureScript: []byte{},
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
SigOpCount: 1,
|
||||
UTXOEntry: utxo.NewUTXOEntry(
|
||||
100_000_000, // 1 KAS
|
||||
scriptPublicKey,
|
||||
@ -96,6 +98,7 @@ func TestValidateTransactionInContextAndPopulateMassAndFee(t *testing.T) {
|
||||
PreviousOutpoint: prevOutPoint,
|
||||
SignatureScript: []byte{},
|
||||
Sequence: constants.SequenceLockTimeIsSeconds,
|
||||
SigOpCount: 1,
|
||||
UTXOEntry: utxo.NewUTXOEntry(
|
||||
100000000, // 1 KAS
|
||||
scriptPublicKey,
|
||||
@ -106,12 +109,24 @@ func TestValidateTransactionInContextAndPopulateMassAndFee(t *testing.T) {
|
||||
PreviousOutpoint: prevOutPoint,
|
||||
SignatureScript: []byte{},
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
SigOpCount: 1,
|
||||
UTXOEntry: utxo.NewUTXOEntry(
|
||||
constants.MaxSompi,
|
||||
scriptPublicKey,
|
||||
true,
|
||||
uint64(5)),
|
||||
}
|
||||
txInputWithBadSigOpCount := externalapi.DomainTransactionInput{
|
||||
PreviousOutpoint: prevOutPoint,
|
||||
SignatureScript: []byte{},
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
SigOpCount: 2,
|
||||
UTXOEntry: utxo.NewUTXOEntry(
|
||||
100_000_000, // 1 KAS
|
||||
scriptPublicKey,
|
||||
true,
|
||||
uint64(5)),
|
||||
}
|
||||
|
||||
txOut := externalapi.DomainTransactionOutput{
|
||||
Value: 100000000, // 1 KAS
|
||||
@ -167,6 +182,13 @@ func TestValidateTransactionInContextAndPopulateMassAndFee(t *testing.T) {
|
||||
SubnetworkID: subnetworks.SubnetworkIDRegistry,
|
||||
Gas: 0,
|
||||
LockTime: 0}
|
||||
txWithBadSigOpCount := externalapi.DomainTransaction{
|
||||
Version: constants.MaxTransactionVersion,
|
||||
Inputs: []*externalapi.DomainTransactionInput{&txInputWithBadSigOpCount},
|
||||
Outputs: []*externalapi.DomainTransactionOutput{&txOut},
|
||||
SubnetworkID: subnetworks.SubnetworkIDRegistry,
|
||||
Gas: 0,
|
||||
LockTime: 0}
|
||||
|
||||
stagingArea := model.NewStagingArea()
|
||||
|
||||
@ -240,19 +262,27 @@ func TestValidateTransactionInContextAndPopulateMassAndFee(t *testing.T) {
|
||||
isValid: false,
|
||||
expectedError: ruleerrors.ErrScriptValidation,
|
||||
},
|
||||
{ // the SigOpCount in the input is wrong, and hence invalid
|
||||
name: "checkTransactionSigOpCounts",
|
||||
tx: &txWithBadSigOpCount,
|
||||
povBlockHash: povBlockHash,
|
||||
selectedParentMedianTime: 1,
|
||||
isValid: false,
|
||||
expectedError: ruleerrors.ErrWrongSigOpCount,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
err := tc.TransactionValidator().ValidateTransactionInContextAndPopulateMassAndFee(stagingArea, test.tx, test.povBlockHash, test.selectedParentMedianTime)
|
||||
err := tc.TransactionValidator().ValidateTransactionInContextAndPopulateFee(stagingArea, test.tx, test.povBlockHash, test.selectedParentMedianTime)
|
||||
|
||||
if test.isValid {
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error on TestValidateTransactionInContextAndPopulateMassAndFee"+
|
||||
t.Fatalf("Unexpected error on TestValidateTransactionInContextAndPopulateFee"+
|
||||
" on test '%v': %+v", test.name, err)
|
||||
}
|
||||
} else {
|
||||
if err == nil || !errors.Is(err, test.expectedError) {
|
||||
t.Fatalf("TestValidateTransactionInContextAndPopulateMassAndFee: test %v:"+
|
||||
t.Fatalf("TestValidateTransactionInContextAndPopulateFee: test %v:"+
|
||||
" Unexpected error: Expected to: %v, but got : %+v", test.name, test.expectedError, err)
|
||||
}
|
||||
}
|
||||
@ -335,16 +365,18 @@ func TestSigningTwoInputs(t *testing.T) {
|
||||
TransactionID: *consensushashing.TransactionID(block2.Transactions[0]),
|
||||
Index: 0,
|
||||
},
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
UTXOEntry: utxo.NewUTXOEntry(block2TxOut.Value, block2TxOut.ScriptPublicKey, true, 0),
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
SigOpCount: 1,
|
||||
UTXOEntry: utxo.NewUTXOEntry(block2TxOut.Value, block2TxOut.ScriptPublicKey, true, 0),
|
||||
},
|
||||
{
|
||||
PreviousOutpoint: externalapi.DomainOutpoint{
|
||||
TransactionID: *consensushashing.TransactionID(block3.Transactions[0]),
|
||||
Index: 0,
|
||||
},
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
UTXOEntry: utxo.NewUTXOEntry(block3TxOut.Value, block3TxOut.ScriptPublicKey, true, 0),
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
SigOpCount: 1,
|
||||
UTXOEntry: utxo.NewUTXOEntry(block3TxOut.Value, block3TxOut.ScriptPublicKey, true, 0),
|
||||
},
|
||||
},
|
||||
Outputs: []*externalapi.DomainTransactionOutput{{
|
||||
@ -459,16 +491,18 @@ func TestSigningTwoInputsECDSA(t *testing.T) {
|
||||
TransactionID: *consensushashing.TransactionID(block2.Transactions[0]),
|
||||
Index: 0,
|
||||
},
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
UTXOEntry: utxo.NewUTXOEntry(block2TxOut.Value, block2TxOut.ScriptPublicKey, true, 0),
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
SigOpCount: 1,
|
||||
UTXOEntry: utxo.NewUTXOEntry(block2TxOut.Value, block2TxOut.ScriptPublicKey, true, 0),
|
||||
},
|
||||
{
|
||||
PreviousOutpoint: externalapi.DomainOutpoint{
|
||||
TransactionID: *consensushashing.TransactionID(block3.Transactions[0]),
|
||||
Index: 0,
|
||||
},
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
UTXOEntry: utxo.NewUTXOEntry(block3TxOut.Value, block3TxOut.ScriptPublicKey, true, 0),
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
SigOpCount: 1,
|
||||
UTXOEntry: utxo.NewUTXOEntry(block3TxOut.Value, block3TxOut.ScriptPublicKey, true, 0),
|
||||
},
|
||||
},
|
||||
Outputs: []*externalapi.DomainTransactionOutput{{
|
||||
|
@ -10,10 +10,10 @@ import (
|
||||
|
||||
func TestPruningDepth(t *testing.T) {
|
||||
expectedResult := map[string]uint64{
|
||||
dagconfig.MainnetParams.Name: 244838,
|
||||
dagconfig.TestnetParams.Name: 244838,
|
||||
dagconfig.DevnetParams.Name: 244838,
|
||||
dagconfig.SimnetParams.Name: 192038,
|
||||
dagconfig.MainnetParams.Name: 185798,
|
||||
dagconfig.TestnetParams.Name: 185798,
|
||||
dagconfig.DevnetParams.Name: 185798,
|
||||
dagconfig.SimnetParams.Name: 132998,
|
||||
}
|
||||
testutils.ForAllNets(t, true, func(t *testing.T, consensusConfig *consensus.Config) {
|
||||
expected, found := expectedResult[consensusConfig.Name]
|
||||
|
@ -139,6 +139,9 @@ var (
|
||||
// a Payload
|
||||
ErrInvalidPayload = newRuleError("ErrInvalidPayload")
|
||||
|
||||
// ErrWrongSigOpCount transaction input specifies an incorrect SigOpCount
|
||||
ErrWrongSigOpCount = newRuleError("ErrWrongSigOpCount")
|
||||
|
||||
// ErrSubnetwork indicates that a block doesn't adhere to the subnetwork
|
||||
// registry rules
|
||||
ErrSubnetworkRegistry = newRuleError("ErrSubnetworkRegistry")
|
||||
@ -161,9 +164,9 @@ var (
|
||||
// In the same block
|
||||
ErrChainedTransactions = newRuleError("ErrChainedTransactions")
|
||||
|
||||
// ErrBlockSizeTooHigh indicates the size of a block exceeds the maximum
|
||||
// ErrBlockMassTooHigh indicates the mass of a block exceeds the maximum
|
||||
// allowed limits.
|
||||
ErrBlockSizeTooHigh = newRuleError("ErrBlockSizeTooHigh")
|
||||
ErrBlockMassTooHigh = newRuleError("ErrBlockMassTooHigh")
|
||||
|
||||
ErrKnownInvalid = newRuleError("ErrKnownInvalid")
|
||||
|
||||
|
@ -53,6 +53,7 @@ func (sht SigHashType) isSigHashAnyOneCanPay() bool {
|
||||
type SighashReusedValues struct {
|
||||
previousOutputsHash *externalapi.DomainHash
|
||||
sequencesHash *externalapi.DomainHash
|
||||
sigOpCountsHash *externalapi.DomainHash
|
||||
outputsHash *externalapi.DomainHash
|
||||
payloadHash *externalapi.DomainHash
|
||||
}
|
||||
@ -102,6 +103,9 @@ func calculateSignatureHash(tx *externalapi.DomainTransaction, inputIndex int, t
|
||||
sequencesHash := getSequencesHash(tx, hashType, reusedValues)
|
||||
infallibleWriteElement(hashWriter, sequencesHash)
|
||||
|
||||
sigOpCountsHash := getSigOpCountsHash(tx, hashType, reusedValues)
|
||||
infallibleWriteElement(hashWriter, sigOpCountsHash)
|
||||
|
||||
hashOutpoint(hashWriter, txIn.PreviousOutpoint)
|
||||
|
||||
infallibleWriteElement(hashWriter, prevScriptPublicKey.Version)
|
||||
@ -111,6 +115,8 @@ func calculateSignatureHash(tx *externalapi.DomainTransaction, inputIndex int, t
|
||||
|
||||
infallibleWriteElement(hashWriter, txIn.Sequence)
|
||||
|
||||
infallibleWriteElement(hashWriter, txIn.SigOpCount)
|
||||
|
||||
outputsHash := getOutputsHash(tx, inputIndex, hashType, reusedValues)
|
||||
infallibleWriteElement(hashWriter, outputsHash)
|
||||
|
||||
@ -159,6 +165,22 @@ func getSequencesHash(tx *externalapi.DomainTransaction, hashType SigHashType, r
|
||||
return reusedValues.sequencesHash
|
||||
}
|
||||
|
||||
func getSigOpCountsHash(tx *externalapi.DomainTransaction, hashType SigHashType, reusedValues *SighashReusedValues) *externalapi.DomainHash {
|
||||
if hashType.isSigHashAnyOneCanPay() {
|
||||
return externalapi.NewZeroHash()
|
||||
}
|
||||
|
||||
if reusedValues.sigOpCountsHash == nil {
|
||||
hashWriter := hashes.NewTransactionSigningHashWriter()
|
||||
for _, txIn := range tx.Inputs {
|
||||
infallibleWriteElement(hashWriter, txIn.SigOpCount)
|
||||
}
|
||||
reusedValues.sigOpCountsHash = hashWriter.Finalize()
|
||||
}
|
||||
|
||||
return reusedValues.sigOpCountsHash
|
||||
}
|
||||
|
||||
func getOutputsHash(tx *externalapi.DomainTransaction, inputIndex int, hashType SigHashType, reusedValues *SighashReusedValues) *externalapi.DomainHash {
|
||||
// SigHashNone: return zero-hash
|
||||
if hashType.isSigHashNone() {
|
||||
|
@ -108,86 +108,86 @@ func TestCalculateSignatureHashSchnorr(t *testing.T) {
|
||||
|
||||
// sigHashAll
|
||||
{name: "native-all-0", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||
expectedSignatureHash: "3e4a8effa6903dea5f762754ec410d732114ec2907e5bcbae7b6dd8d3f309a10"},
|
||||
expectedSignatureHash: "56071ab5533ce9635d2a65d911b15d50b5e5f3e3103797d53173188a11696962"},
|
||||
{name: "native-all-0-modify-input-1", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifyInput(1), // should change the hash
|
||||
expectedSignatureHash: "0bd2947383101f9708d94d5799626c69c1b8472d2de66523c90c4a674e99cc51"},
|
||||
expectedSignatureHash: "3ee15a1f5d3827b9c3bca740ebbe422a8d07fbde287944f855da26c06782d38b"},
|
||||
{name: "native-all-0-modify-output-1", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifyOutput(1), // should change the hash
|
||||
expectedSignatureHash: "ae69aa1372e958f069bf52d2628ead7ee789f195340b615ff0bcb6f01a995810"},
|
||||
expectedSignatureHash: "1794d1d074a587678174223788bea272d092a6155f031686b85caf11595ff6d8"},
|
||||
{name: "native-all-0-modify-sequence-1", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifySequence(1), // should change the hash
|
||||
expectedSignatureHash: "51295575e7efc1fe1c2e741ade49089e3d780d15d26e9a0b18b3d90e35caf795"},
|
||||
expectedSignatureHash: "8c580bd47a220e4ab6f343dde74a23f9e4b3971b2b519b0ed0ad34d682aa85d3"},
|
||||
{name: "native-all-anyonecanpay-0", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||
expectedSignatureHash: "0a13d3cab42a6cf3a7ef96f7b28c9bb0d98c209a3032ff85a6bfa7dac520f2c2"},
|
||||
expectedSignatureHash: "94dbee595dcbac18cc2c158e67315dacfdfc4af9ab08713d41d3546076daeb5a"},
|
||||
{name: "native-all-anyonecanpay-0-modify-input-0", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifyInput(0), // should change the hash
|
||||
expectedSignatureHash: "aeaa56f5bc99daea0be5ed4b047808ce0123a81ac89c6089b72fa7199f5cd1c6"},
|
||||
expectedSignatureHash: "29cca3e62ad1e7069ccb67a4589ad6858b741ecb2abd9d470d0ec72903467edc"},
|
||||
{name: "native-all-anyonecanpay-0-modify-input-1", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifyInput(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "0a13d3cab42a6cf3a7ef96f7b28c9bb0d98c209a3032ff85a6bfa7dac520f2c2"},
|
||||
expectedSignatureHash: "94dbee595dcbac18cc2c158e67315dacfdfc4af9ab08713d41d3546076daeb5a"},
|
||||
{name: "native-all-anyonecanpay-0-modify-sequence", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifySequence(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "0a13d3cab42a6cf3a7ef96f7b28c9bb0d98c209a3032ff85a6bfa7dac520f2c2"},
|
||||
expectedSignatureHash: "94dbee595dcbac18cc2c158e67315dacfdfc4af9ab08713d41d3546076daeb5a"},
|
||||
|
||||
// sigHashNone
|
||||
{name: "native-none-0", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||
expectedSignatureHash: "da53f7c726b55357adb1b644265fe7b9b7897cadde91a942d6127195c2ce99dc"},
|
||||
expectedSignatureHash: "af54114c72a3192d05cfa80fb4be60bad77fc484b0072798e5e264da692dc4db"},
|
||||
{name: "native-none-0-modify-output-1", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||
modificationFunction: modifyOutput(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "da53f7c726b55357adb1b644265fe7b9b7897cadde91a942d6127195c2ce99dc"},
|
||||
expectedSignatureHash: "af54114c72a3192d05cfa80fb4be60bad77fc484b0072798e5e264da692dc4db"},
|
||||
{name: "native-none-0-modify-sequence-0", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||
modificationFunction: modifySequence(0), // should change the hash
|
||||
expectedSignatureHash: "72c07c152a3792fb863d2de219ab4e863fe6779dc970a5c3958e26b3a3b9f139"},
|
||||
expectedSignatureHash: "52b3888a3680c79712b53c4010b7cdebd158e09b7574d95b846ba9989946c38b"},
|
||||
{name: "native-none-0-modify-sequence-1", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||
modificationFunction: modifySequence(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "da53f7c726b55357adb1b644265fe7b9b7897cadde91a942d6127195c2ce99dc"},
|
||||
expectedSignatureHash: "af54114c72a3192d05cfa80fb4be60bad77fc484b0072798e5e264da692dc4db"},
|
||||
{name: "native-none-anyonecanpay-0", tx: nativeTx, hashType: noneAnyoneCanPay, inputIndex: 0,
|
||||
expectedSignatureHash: "18eb79df328a516708f792cadfc4bf2be21b6add35fb6637a20347d532b1dce1"},
|
||||
expectedSignatureHash: "cf1fd4691c22a75011909e7444c0d9582610374f7eea3debc450bbe939862cac"},
|
||||
{name: "native-none-anyonecanpay-0-modify-amount-spent", tx: nativeTx, hashType: noneAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifyAmountSpent(0), // should change the hash
|
||||
expectedSignatureHash: "674a8e6effa0bbfdb3df3ca45a7b17ab695cc0f9b3e0519e5bff165de13604e2"},
|
||||
expectedSignatureHash: "f76731710af7731896e415d85da6518fa316cddebd8abcb4b2ee931679296a0a"},
|
||||
{name: "native-none-anyonecanpay-0-modify-script-public-key", tx: nativeTx, hashType: noneAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifyScriptPublicKey(0), // should change the hash
|
||||
expectedSignatureHash: "7a879d339c9b948c5264f1c0b8463f551221b2dcd575623f178cbbfcf7e01987"},
|
||||
expectedSignatureHash: "382e8196e1fe34ccc4c3004ad6e6d4c41b81b8a5dd6de24fe51065a1970ef00b"},
|
||||
|
||||
// sigHashSingle
|
||||
{name: "native-single-0", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
expectedSignatureHash: "99c0a4a381fed9dbd651450d6ca969a6e8cdd941e9d73be086a1ba6c90fb630f"},
|
||||
expectedSignatureHash: "80a8db8aa43c5cd5d067c69e32f998ac5c0820d89fcfda9beaf55c8df41c4c86"},
|
||||
{name: "native-single-0-modify-output-0", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
modificationFunction: modifyOutput(0), // should change the hash
|
||||
expectedSignatureHash: "92189a32391ca50a454d1853efed55acb1c49993911a1201df9891c866c483ee"},
|
||||
expectedSignatureHash: "ca882be7c6c3ae37badda62c9277be0808160d65a6a89feb514e41ed7a9658f0"},
|
||||
{name: "native-single-0-modify-output-1", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
modificationFunction: modifyOutput(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "99c0a4a381fed9dbd651450d6ca969a6e8cdd941e9d73be086a1ba6c90fb630f"},
|
||||
expectedSignatureHash: "80a8db8aa43c5cd5d067c69e32f998ac5c0820d89fcfda9beaf55c8df41c4c86"},
|
||||
{name: "native-single-0-modify-sequence-0", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
modificationFunction: modifySequence(0), // should change the hash
|
||||
expectedSignatureHash: "765e2289df98b3a5269f112d4b36d57fe32c74d42e04a3046c6a3c8dd78a4121"},
|
||||
expectedSignatureHash: "7dec3b5b7b5ccd3f82f93c6c08cd05acecb970d4a4d127fcd87a11d7e0dd96e3"},
|
||||
{name: "native-single-0-modify-sequence-1", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
modificationFunction: modifySequence(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "99c0a4a381fed9dbd651450d6ca969a6e8cdd941e9d73be086a1ba6c90fb630f"},
|
||||
expectedSignatureHash: "80a8db8aa43c5cd5d067c69e32f998ac5c0820d89fcfda9beaf55c8df41c4c86"},
|
||||
{name: "native-single-2-no-corresponding-output", tx: nativeTx, hashType: single, inputIndex: 2,
|
||||
expectedSignatureHash: "43de18c04d7fde81f49a40228d8730b4ceb0c66c77841c22622f59554769dd13"},
|
||||
expectedSignatureHash: "3c6daba7d6849df524517f505d6abb93e20930726f89b50416eb2b6d59f202c6"},
|
||||
{name: "native-single-2-no-corresponding-output-modify-output-1", tx: nativeTx, hashType: single, inputIndex: 2,
|
||||
modificationFunction: modifyOutput(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "43de18c04d7fde81f49a40228d8730b4ceb0c66c77841c22622f59554769dd13"},
|
||||
expectedSignatureHash: "3c6daba7d6849df524517f505d6abb93e20930726f89b50416eb2b6d59f202c6"},
|
||||
{name: "native-single-anyonecanpay-0", tx: nativeTx, hashType: singleAnyoneCanPay, inputIndex: 0,
|
||||
expectedSignatureHash: "2e270f86fd68f780a5aa8d250364ab6786d990040268e5d561d09dde365dfab7"},
|
||||
expectedSignatureHash: "35d28b074df6959cbef5aca8923e53312db3a88aab0039bd0a6b2fe92dff5aa7"},
|
||||
{name: "native-single-anyonecanpay-2-no-corresponding-output", tx: nativeTx, hashType: singleAnyoneCanPay, inputIndex: 2,
|
||||
expectedSignatureHash: "afc05dd6b4a530cc3a4d7d23126548bd1f31c793e9282cbbfa27ff5566219501"},
|
||||
expectedSignatureHash: "26a05df8e562f5c43cacab9a8126ae2da77e2137f8c28d13a330cd3d2b37d56b"},
|
||||
|
||||
// subnetwork transaction
|
||||
{name: "subnetwork-all-0", tx: subnetworkTx, hashType: all, inputIndex: 0,
|
||||
expectedSignatureHash: "5a67423ee048e067b94e2d4fc2960f62eceff6aa8b6c5ad71e3b7b7e5ff6bad7"},
|
||||
expectedSignatureHash: "1529c132cad68a014b01bac39992462f8d6c9ba6a34382e0d1d3054232e46c54"},
|
||||
{name: "subnetwork-all-modify-payload", tx: subnetworkTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifyPayload, // should change the hash
|
||||
expectedSignatureHash: "0d3bc5914da8dc8df081945fea1255359f380ca9baa8b31dfb3657c1e3c6038a"},
|
||||
expectedSignatureHash: "0366d1f0ab7a2150cd1b80b8f8944e7f6a42a38b846f2610adc4106fe70696ec"},
|
||||
{name: "subnetwork-all-modify-gas", tx: subnetworkTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifyGas, // should change the hash
|
||||
expectedSignatureHash: "70abe9f947d0a0f5d735f9a063db8af41fe5902940f2693a1782119063097094"},
|
||||
expectedSignatureHash: "19054bbf6dc75936dd018983373afd623a292ad1f39774cd1783b58074c3caa7"},
|
||||
{name: "subnetwork-all-subnetwork-id", tx: subnetworkTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifySubnetworkID, // should change the hash
|
||||
expectedSignatureHash: "571a0b7ea905b7a6ff7ab825b72d23f911bac0bfaa7c4c97a4887a3d090925d4"},
|
||||
expectedSignatureHash: "2fbfa5d3d24673b2e3530c3b268b58ecb6e7e34116d5c18849c27b0e7b6bfe4c"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
@ -230,86 +230,86 @@ func TestCalculateSignatureHashECDSA(t *testing.T) {
|
||||
|
||||
// sigHashAll
|
||||
{name: "native-all-0", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||
expectedSignatureHash: "150a2bcd0296f76a3395a4a9982df46bf24ce93f955bc39c10ffc95b6c524eb3"},
|
||||
expectedSignatureHash: "ea7b79230b41f503baa6d3c14edf2d3e2cabc62db5b384bbac451a84c7a69694"},
|
||||
{name: "native-all-0-modify-input-1", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifyInput(1), // should change the hash
|
||||
expectedSignatureHash: "8fb5304e181b003e0c123ea6f6677abc3704feec47054e8a1c218b827bf57ca0"},
|
||||
expectedSignatureHash: "9ba940467c07b4254f913a95398dc6f9fac0915e0dfe9560c58dfc1f87977c08"},
|
||||
{name: "native-all-0-modify-output-1", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifyOutput(1), // should change the hash
|
||||
expectedSignatureHash: "180cb36454aa80822694decde4fc711104e35a4bddf92286a83877f2b8d0aabb"},
|
||||
expectedSignatureHash: "ba413a6ef1101c4a4995ac30a9013fe5591ef5f6dd8d7aabaa5dd8cb74d4d765"},
|
||||
{name: "native-all-0-modify-sequence-1", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifySequence(1), // should change the hash
|
||||
expectedSignatureHash: "5b5f1c42a3c3c16bb4922777e2963c00e6a2cce39afa1980d2288053378f9632"},
|
||||
expectedSignatureHash: "a471958e25168ab6671a76629d6f83b7f197a22972b333ebfa55d62dcc0ef065"},
|
||||
{name: "native-all-anyonecanpay-0", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||
expectedSignatureHash: "9473ffbe0db4914f2cd8fe5d67479224a02eb031882d9170b785d0d2c7bfcd1b"},
|
||||
expectedSignatureHash: "1113e57a0a188f1b9d0e07889792193af37374112874af681b3e36bee0627c1f"},
|
||||
{name: "native-all-anyonecanpay-0-modify-input-0", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifyInput(0), // should change the hash
|
||||
expectedSignatureHash: "1208491d564c138d613f51b997394dbad23feca7c0ca88c7f36cdf6b9173327d"},
|
||||
expectedSignatureHash: "6cce1e9ac60a7921a08ced668c03f74d207df02064896e0beb46988a8d2c243d"},
|
||||
{name: "native-all-anyonecanpay-0-modify-input-1", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifyInput(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "9473ffbe0db4914f2cd8fe5d67479224a02eb031882d9170b785d0d2c7bfcd1b"},
|
||||
expectedSignatureHash: "1113e57a0a188f1b9d0e07889792193af37374112874af681b3e36bee0627c1f"},
|
||||
{name: "native-all-anyonecanpay-0-modify-sequence", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifySequence(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "9473ffbe0db4914f2cd8fe5d67479224a02eb031882d9170b785d0d2c7bfcd1b"},
|
||||
expectedSignatureHash: "1113e57a0a188f1b9d0e07889792193af37374112874af681b3e36bee0627c1f"},
|
||||
|
||||
// sigHashNone
|
||||
{name: "native-none-0", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||
expectedSignatureHash: "6e427f26e4a9c1a7fc556a8aabdedb8799a897bc5d42a0a18615e5a0f7639d8f"},
|
||||
expectedSignatureHash: "609c6f87c2cf10938ad1f69ceb0a6bb726690169b5e45d7c5797a420d244da55"},
|
||||
{name: "native-none-0-modify-output-1", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||
modificationFunction: modifyOutput(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "6e427f26e4a9c1a7fc556a8aabdedb8799a897bc5d42a0a18615e5a0f7639d8f"},
|
||||
expectedSignatureHash: "609c6f87c2cf10938ad1f69ceb0a6bb726690169b5e45d7c5797a420d244da55"},
|
||||
{name: "native-none-0-modify-sequence-0", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||
modificationFunction: modifySequence(0), // should change the hash
|
||||
expectedSignatureHash: "57d76e2568cd3fc3426b4f8836fe900a2d20e740fad744949126651fd549f75e"},
|
||||
expectedSignatureHash: "155e020f420fdaf62b31ccb3a13b6cb684c3db9ff85fc7062bb7e6a0653c7057"},
|
||||
{name: "native-none-0-modify-sequence-1", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||
modificationFunction: modifySequence(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "6e427f26e4a9c1a7fc556a8aabdedb8799a897bc5d42a0a18615e5a0f7639d8f"},
|
||||
expectedSignatureHash: "609c6f87c2cf10938ad1f69ceb0a6bb726690169b5e45d7c5797a420d244da55"},
|
||||
{name: "native-none-anyonecanpay-0", tx: nativeTx, hashType: noneAnyoneCanPay, inputIndex: 0,
|
||||
expectedSignatureHash: "ef97a0f89d623302619f9aa2a00fce1522e72d4d255e6c6d3ed225ffc02f38ff"},
|
||||
expectedSignatureHash: "3ee6c91cbbc998c52c02cad43b4a28743d6e96c9422393de69a0e15e08f470fb"},
|
||||
{name: "native-none-anyonecanpay-0-modify-amount-spent", tx: nativeTx, hashType: noneAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifyAmountSpent(0), // should change the hash
|
||||
expectedSignatureHash: "043a2a943f02607be126ac6609ab2324aae389d784a4147f27101e7da379311a"},
|
||||
expectedSignatureHash: "36e54667d08987a5d28d2124e7277ba5c2e93a9b8b9a7392bb7a57f1637edf76"},
|
||||
{name: "native-none-anyonecanpay-0-modify-script-public-key", tx: nativeTx, hashType: noneAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifyScriptPublicKey(0), // should change the hash
|
||||
expectedSignatureHash: "f2cd43d0d047cdcfbf8b6e12a86cfbf250f1e2c34dc5e631675a5f5b867bd9e6"},
|
||||
expectedSignatureHash: "bdce98b53163b42175f4e885f50e8a44821159fc05d7756e3870c5f91df2be2f"},
|
||||
|
||||
// sigHashSingle
|
||||
{name: "native-single-0", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
expectedSignatureHash: "1cf376b9f180f59a1b9a5e420390198c20e1ba79c39349271632145fda175247"},
|
||||
expectedSignatureHash: "354c6ac137e5a3d05e85e9740039909202c20f8e229d7a94abc9096da3118256"},
|
||||
{name: "native-single-0-modify-output-0", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
modificationFunction: modifyOutput(0), // should change the hash
|
||||
expectedSignatureHash: "c2c7e77516a15f0f47f886b14cc47af2045eea15f176a9a560a9d47d8866958f"},
|
||||
expectedSignatureHash: "394192ce7faee4f5055939c6fa3bf41a3008ec29e667d60bd5203987850debd4"},
|
||||
{name: "native-single-0-modify-output-1", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
modificationFunction: modifyOutput(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "1cf376b9f180f59a1b9a5e420390198c20e1ba79c39349271632145fda175247"},
|
||||
expectedSignatureHash: "354c6ac137e5a3d05e85e9740039909202c20f8e229d7a94abc9096da3118256"},
|
||||
{name: "native-single-0-modify-sequence-0", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
modificationFunction: modifySequence(0), // should change the hash
|
||||
expectedSignatureHash: "2034eec2acc08c49d3896cc1bda214904ca850fc5989518885465b5a3154ee7f"},
|
||||
expectedSignatureHash: "55b1a9f7ee395ea37a8a6da804c9a654216364a42e37d329c5dc69c349369825"},
|
||||
{name: "native-single-0-modify-sequence-1", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
modificationFunction: modifySequence(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "1cf376b9f180f59a1b9a5e420390198c20e1ba79c39349271632145fda175247"},
|
||||
expectedSignatureHash: "354c6ac137e5a3d05e85e9740039909202c20f8e229d7a94abc9096da3118256"},
|
||||
{name: "native-single-2-no-corresponding-output", tx: nativeTx, hashType: single, inputIndex: 2,
|
||||
expectedSignatureHash: "84ae3bb03202efc587d97e5aea7b80581b82242b969e6dea13b8daa32d24c0c1"},
|
||||
expectedSignatureHash: "8f386eefc0b389615279025f9c537102047fdf079df9a17ddad39d726130c736"},
|
||||
{name: "native-single-2-no-corresponding-output-modify-output-1", tx: nativeTx, hashType: single, inputIndex: 2,
|
||||
modificationFunction: modifyOutput(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "84ae3bb03202efc587d97e5aea7b80581b82242b969e6dea13b8daa32d24c0c1"},
|
||||
expectedSignatureHash: "8f386eefc0b389615279025f9c537102047fdf079df9a17ddad39d726130c736"},
|
||||
{name: "native-single-anyonecanpay-0", tx: nativeTx, hashType: singleAnyoneCanPay, inputIndex: 0,
|
||||
expectedSignatureHash: "b2ccf259a65c3231d741a03420967b95563c3928cc15d3d15e8e795f383ab48b"},
|
||||
expectedSignatureHash: "7062156c393e71c6308f9d451a9f4850d9c331f77372d165bb9bcf0296e6a3d3"},
|
||||
{name: "native-single-anyonecanpay-2-no-corresponding-output", tx: nativeTx, hashType: singleAnyoneCanPay, inputIndex: 2,
|
||||
expectedSignatureHash: "652c8cd0ac050e41aad347ea09ee788360eec70908ba22fe5bba5bdde49b8ae1"},
|
||||
expectedSignatureHash: "84b56500814e4c7de8569ef6a5dfc269ca35db3160adaebedd92e68fe9d2c02b"},
|
||||
|
||||
// subnetwork transaction
|
||||
{name: "subnetwork-all-0", tx: subnetworkTx, hashType: all, inputIndex: 0,
|
||||
expectedSignatureHash: "2e828c04f5f03e4ce4b3de1fa5303400da5fa504291b760f5f6d4e98fc24597f"},
|
||||
expectedSignatureHash: "ab783013148f1fbc6a0c29c5e2e320ea1dab61122f4b556810ef07c96871964a"},
|
||||
{name: "subnetwork-all-modify-payload", tx: subnetworkTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifyPayload, // should change the hash
|
||||
expectedSignatureHash: "d5f3993aa8b7f47df52f78f2be9965f928c9cca9ac9e9542f1190b9d5ed6c17d"},
|
||||
expectedSignatureHash: "bad87ce0a6d5fade1bb9eb5de572a3a9904e6d0ef5d627b97c69380818c1ad6f"},
|
||||
{name: "subnetwork-all-modify-gas", tx: subnetworkTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifyGas, // should change the hash
|
||||
expectedSignatureHash: "e74d4a9fa5cdf476299ebdfa03f3c8021a157f814731ea11f6a6d606dc5cd439"},
|
||||
expectedSignatureHash: "54bdd33d4c8ea1baac6e92a129ad8a6bb90803b7b21387cc4ec9640752f4bb61"},
|
||||
{name: "subnetwork-all-subnetwork-id", tx: subnetworkTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifySubnetworkID, // should change the hash
|
||||
expectedSignatureHash: "ca8bf9bc42cda2ec3ce8bee090011072e56ff4d0d8616d5c20cefe5f84d7fb37"},
|
||||
expectedSignatureHash: "e71d0226c6c0cc26e0a99146f597ff9b9b51406f64854235b18f741d4c87eac4"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
@ -1,65 +0,0 @@
|
||||
package estimatedsize
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionhelper"
|
||||
)
|
||||
|
||||
// TransactionEstimatedSerializedSize is the estimated size of a transaction in some
|
||||
// serialization. This has to be deterministic, but not necessarily accurate, since
|
||||
// it's only used as the size component in the transaction mass and block size limit
|
||||
// calculation.
|
||||
func TransactionEstimatedSerializedSize(tx *externalapi.DomainTransaction) uint64 {
|
||||
if transactionhelper.IsCoinBase(tx) {
|
||||
return 0
|
||||
}
|
||||
size := uint64(0)
|
||||
size += 2 // Txn Version
|
||||
size += 8 // number of inputs (uint64)
|
||||
for _, input := range tx.Inputs {
|
||||
size += transactionInputEstimatedSerializedSize(input)
|
||||
}
|
||||
|
||||
size += 8 // number of outputs (uint64)
|
||||
for _, output := range tx.Outputs {
|
||||
size += TransactionOutputEstimatedSerializedSize(output)
|
||||
}
|
||||
|
||||
size += 8 // lock time (uint64)
|
||||
size += externalapi.DomainSubnetworkIDSize
|
||||
size += 8 // gas (uint64)
|
||||
size += externalapi.DomainHashSize // payload hash
|
||||
|
||||
size += 8 // length of the payload (uint64)
|
||||
size += uint64(len(tx.Payload))
|
||||
|
||||
return size
|
||||
}
|
||||
|
||||
func transactionInputEstimatedSerializedSize(input *externalapi.DomainTransactionInput) uint64 {
|
||||
size := uint64(0)
|
||||
size += outpointEstimatedSerializedSize()
|
||||
|
||||
size += 8 // length of signature script (uint64)
|
||||
size += uint64(len(input.SignatureScript))
|
||||
|
||||
size += 8 // sequence (uint64)
|
||||
return size
|
||||
}
|
||||
|
||||
func outpointEstimatedSerializedSize() uint64 {
|
||||
size := uint64(0)
|
||||
size += externalapi.DomainHashSize // ID
|
||||
size += 4 // index (uint32)
|
||||
return size
|
||||
}
|
||||
|
||||
// TransactionOutputEstimatedSerializedSize is the same as TransactionEstimatedSerializedSize but for outputs only
|
||||
func TransactionOutputEstimatedSerializedSize(output *externalapi.DomainTransactionOutput) uint64 {
|
||||
size := uint64(0)
|
||||
size += 8 // value (uint64)
|
||||
size += 2 //output.ScriptPublicKey.Version (uint 16)
|
||||
size += 8 // length of script public key (uint64)
|
||||
size += uint64(len(output.ScriptPublicKey.Script))
|
||||
return size
|
||||
}
|
@ -242,13 +242,9 @@ func getSigOpCount(pops []parsedOpcode, precise bool) int {
|
||||
nSigs := 0
|
||||
for i, pop := range pops {
|
||||
switch pop.opcode.value {
|
||||
case OpCheckSig:
|
||||
fallthrough
|
||||
case OpCheckSigVerify:
|
||||
case OpCheckSig, OpCheckSigVerify, OpCheckSigECDSA:
|
||||
nSigs++
|
||||
case OpCheckMultiSig:
|
||||
fallthrough
|
||||
case OpCheckMultiSigVerify:
|
||||
case OpCheckMultiSig, OpCheckMultiSigVerify, OpCheckMultiSigECDSA:
|
||||
// If we are being precise then look for familiar
|
||||
// patterns for multisig, for now all we recognize is
|
||||
// OP_1 - OP_16 to signify the number of pubkeys.
|
||||
|
@ -1,8 +1,9 @@
|
||||
package dagconfig
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
||||
"time"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
||||
)
|
||||
|
||||
// The documentation refers to the following constants which aren't explicated in the code:
|
||||
@ -23,30 +24,32 @@ import (
|
||||
|
||||
const (
|
||||
defaultMaxCoinbasePayloadLength = 150
|
||||
// defaultMaxBlockSize is a bound on the size of a block in bytes, larger values increase the bound d
|
||||
// defaultMaxBlockMass is a bound on the mass of a block, larger values increase the bound d
|
||||
// on the round trip time of a block, which affects the other parameters as described below
|
||||
defaultMaxBlockSize = 50_000
|
||||
// defaultMaxBlockParents is the number of blocks any block can point to.
|
||||
// Should be about d/defaultTargetTimePerBlock where d is a bound on the round trip time of a block.
|
||||
defaultMaxBlockParents = 10
|
||||
defaultMaxBlockMass = 500_000
|
||||
// defaultMassPerTxByte, defaultMassPerScriptPubKeyByte and defaultMassPerSigOp define the number of grams per
|
||||
// transaction byte, script pub key byte and sig op respectively.
|
||||
// These values are used when calculating a transactions mass.
|
||||
defaultMassPerTxByte = 1
|
||||
defaultMassPerScriptPubKeyByte = 10
|
||||
defaultMassPerSigOp = 10000
|
||||
// defaultMergeSetSizeLimit is a bound on the size of the past of a block and the size of the past
|
||||
// of its selected parent. Any block which violates this bound is invalid.
|
||||
// Should be at least an order of magnitude smaller than defaultFinalityDuration/defaultTargetTimePerBlock.
|
||||
// (Higher values make pruning attacks easier by a constant, lower values make merging after a split or a spike
|
||||
// in block take longer)
|
||||
defaultMergeSetSizeLimit = 1000
|
||||
defaultMaxMassAcceptedByBlock = 500_000
|
||||
defaultBaseSubsidy = 50 * constants.SompiPerKaspa
|
||||
defaultCoinbasePayloadScriptPublicKeyMaxLength = 150
|
||||
defaultMassPerSigOp = 1000
|
||||
// defaultMaxBlockParents is the number of blocks any block can point to.
|
||||
// Should be about d/defaultTargetTimePerBlock where d is a bound on the round trip time of a block.
|
||||
defaultMaxBlockParents = 10
|
||||
// defaultGHOSTDAGK is a bound on the number of blue blocks in the anticone of a blue block. Approximates the maximal
|
||||
// width of the network.
|
||||
// Formula (1) in section 4.2 of the PHATOM paper shows how to calculate defaultGHOSTDAGK. The delta term represents a bound
|
||||
// on the expected fraction of the network life in which the width was higher than defaultGHOSTDAGK. The current value of K
|
||||
// was calculated for d = 5 seconds and delta = 0.05.
|
||||
defaultGHOSTDAGK = 18
|
||||
// defaultMergeSetSizeLimit is a bound on the size of the past of a block and the size of the past
|
||||
// of its selected parent. Any block which violates this bound is invalid.
|
||||
// Should be at least an order of magnitude smaller than defaultFinalityDuration/defaultTargetTimePerBlock.
|
||||
// (Higher values make pruning attacks easier by a constant, lower values make merging after a split or a spike
|
||||
// in block take longer)
|
||||
defaultMergeSetSizeLimit = defaultGHOSTDAGK * 10
|
||||
defaultBaseSubsidy = 50 * constants.SompiPerKaspa
|
||||
defaultCoinbasePayloadScriptPublicKeyMaxLength = 150
|
||||
// defaultDifficultyAdjustmentWindowSize is the number of blocks in a block's past used to calculate its difficulty
|
||||
// target.
|
||||
defaultDifficultyAdjustmentWindowSize = 2640
|
||||
|
@ -150,8 +150,8 @@ type Params struct {
|
||||
// MaxCoinbasePayloadLength is the maximum length in bytes allowed for a block's coinbase's payload
|
||||
MaxCoinbasePayloadLength uint64
|
||||
|
||||
// MaxBlockSize is the maximum size in bytes a block is allowed
|
||||
MaxBlockSize uint64
|
||||
// MaxBlockMass is the maximum mass a block is allowed
|
||||
MaxBlockMass uint64
|
||||
|
||||
// MaxBlockParents is the maximum number of blocks a block is allowed to point to
|
||||
MaxBlockParents model.KType
|
||||
@ -171,9 +171,6 @@ type Params struct {
|
||||
// MergeSetSizeLimit is the maximum number of blocks in a block's merge set
|
||||
MergeSetSizeLimit uint64
|
||||
|
||||
// MaxMassAcceptedByBlock is the maximum total transaction mass a block may accept.
|
||||
MaxMassAcceptedByBlock uint64
|
||||
|
||||
// CoinbasePayloadScriptPublicKeyMaxLength is the maximum allowed script public key in the coinbase's payload
|
||||
CoinbasePayloadScriptPublicKeyMaxLength uint8
|
||||
|
||||
@ -242,13 +239,12 @@ var MainnetParams = Params{
|
||||
DisableDifficultyAdjustment: false,
|
||||
|
||||
MaxCoinbasePayloadLength: defaultMaxCoinbasePayloadLength,
|
||||
MaxBlockSize: defaultMaxBlockSize,
|
||||
MaxBlockMass: defaultMaxBlockMass,
|
||||
MaxBlockParents: defaultMaxBlockParents,
|
||||
MassPerTxByte: defaultMassPerTxByte,
|
||||
MassPerScriptPubKeyByte: defaultMassPerScriptPubKeyByte,
|
||||
MassPerSigOp: defaultMassPerSigOp,
|
||||
MergeSetSizeLimit: defaultMergeSetSizeLimit,
|
||||
MaxMassAcceptedByBlock: defaultMaxMassAcceptedByBlock,
|
||||
BaseSubsidy: defaultBaseSubsidy,
|
||||
CoinbasePayloadScriptPublicKeyMaxLength: defaultCoinbasePayloadScriptPublicKeyMaxLength,
|
||||
}
|
||||
@ -299,13 +295,12 @@ var TestnetParams = Params{
|
||||
DisableDifficultyAdjustment: false,
|
||||
|
||||
MaxCoinbasePayloadLength: defaultMaxCoinbasePayloadLength,
|
||||
MaxBlockSize: defaultMaxBlockSize,
|
||||
MaxBlockMass: defaultMaxBlockMass,
|
||||
MaxBlockParents: defaultMaxBlockParents,
|
||||
MassPerTxByte: defaultMassPerTxByte,
|
||||
MassPerScriptPubKeyByte: defaultMassPerScriptPubKeyByte,
|
||||
MassPerSigOp: defaultMassPerSigOp,
|
||||
MergeSetSizeLimit: defaultMergeSetSizeLimit,
|
||||
MaxMassAcceptedByBlock: defaultMaxMassAcceptedByBlock,
|
||||
BaseSubsidy: defaultBaseSubsidy,
|
||||
CoinbasePayloadScriptPublicKeyMaxLength: defaultCoinbasePayloadScriptPublicKeyMaxLength,
|
||||
}
|
||||
@ -360,13 +355,12 @@ var SimnetParams = Params{
|
||||
DisableDifficultyAdjustment: true,
|
||||
|
||||
MaxCoinbasePayloadLength: defaultMaxCoinbasePayloadLength,
|
||||
MaxBlockSize: defaultMaxBlockSize,
|
||||
MaxBlockMass: defaultMaxBlockMass,
|
||||
MaxBlockParents: defaultMaxBlockParents,
|
||||
MassPerTxByte: defaultMassPerTxByte,
|
||||
MassPerScriptPubKeyByte: defaultMassPerScriptPubKeyByte,
|
||||
MassPerSigOp: defaultMassPerSigOp,
|
||||
MergeSetSizeLimit: defaultMergeSetSizeLimit,
|
||||
MaxMassAcceptedByBlock: defaultMaxMassAcceptedByBlock,
|
||||
BaseSubsidy: defaultBaseSubsidy,
|
||||
CoinbasePayloadScriptPublicKeyMaxLength: defaultCoinbasePayloadScriptPublicKeyMaxLength,
|
||||
}
|
||||
@ -417,13 +411,12 @@ var DevnetParams = Params{
|
||||
DisableDifficultyAdjustment: false,
|
||||
|
||||
MaxCoinbasePayloadLength: defaultMaxCoinbasePayloadLength,
|
||||
MaxBlockSize: defaultMaxBlockSize,
|
||||
MaxBlockMass: defaultMaxBlockMass,
|
||||
MaxBlockParents: defaultMaxBlockParents,
|
||||
MassPerTxByte: defaultMassPerTxByte,
|
||||
MassPerScriptPubKeyByte: defaultMassPerScriptPubKeyByte,
|
||||
MassPerSigOp: defaultMassPerSigOp,
|
||||
MergeSetSizeLimit: defaultMergeSetSizeLimit,
|
||||
MaxMassAcceptedByBlock: defaultMaxMassAcceptedByBlock,
|
||||
BaseSubsidy: defaultBaseSubsidy,
|
||||
CoinbasePayloadScriptPublicKeyMaxLength: defaultCoinbasePayloadScriptPublicKeyMaxLength,
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ func (f *factory) NewMiningManager(consensus externalapi.Consensus, params *dagc
|
||||
mempoolConfig *mempoolpkg.Config) MiningManager {
|
||||
|
||||
mempool := mempoolpkg.New(mempoolConfig, consensus)
|
||||
blockTemplateBuilder := blocktemplatebuilder.New(consensus, mempool, params.MaxMassAcceptedByBlock)
|
||||
blockTemplateBuilder := blocktemplatebuilder.New(consensus, mempool, params.MaxBlockMass)
|
||||
|
||||
return &miningManager{
|
||||
mempool: mempool,
|
||||
|
@ -3,11 +3,12 @@ package mempool
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/processes/transactionvalidator"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/estimatedsize"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
|
||||
"github.com/kaspanet/kaspad/util"
|
||||
)
|
||||
@ -36,10 +37,9 @@ const (
|
||||
// (1 + 15*74 + 3) + (15*34 + 3) + 23 = 1650
|
||||
maximumStandardSignatureScriptSize = 1650
|
||||
|
||||
// maximumStandardTransactionSize is the maximum size allowed for transactions that
|
||||
// are considered standard and will therefore be relayed and considered
|
||||
// for mining.
|
||||
maximumStandardTransactionSize = 100000
|
||||
// maximumStandardTransactionMass is the maximum mass allowed for transactions that
|
||||
// are considered standard and will therefore be relayed and considered for mining.
|
||||
maximumStandardTransactionMass = 100000
|
||||
)
|
||||
|
||||
func (mp *mempool) checkTransactionStandardInIsolation(transaction *externalapi.DomainTransaction) error {
|
||||
@ -59,10 +59,9 @@ func (mp *mempool) checkTransactionStandardInIsolation(transaction *externalapi.
|
||||
// almost as much to process as the sender fees, limit the maximum
|
||||
// size of a transaction. This also helps mitigate CPU exhaustion
|
||||
// attacks.
|
||||
serializedLength := estimatedsize.TransactionEstimatedSerializedSize(transaction)
|
||||
if serializedLength > maximumStandardTransactionSize {
|
||||
str := fmt.Sprintf("transaction size of %d is larger than max allowed size of %d",
|
||||
serializedLength, maximumStandardTransactionSize)
|
||||
if transaction.Mass > maximumStandardTransactionMass {
|
||||
str := fmt.Sprintf("transaction mass of %d is larger than max allowed size of %d",
|
||||
transaction.Mass, maximumStandardTransactionMass)
|
||||
return transactionRuleError(RejectNonstandard, str)
|
||||
}
|
||||
|
||||
@ -129,7 +128,7 @@ func (mp *mempool) IsTransactionOutputDust(output *externalapi.DomainTransaction
|
||||
// The most common scripts are pay-to-pubkey, and as per the above
|
||||
// breakdown, the minimum size of a p2pk input script is 148 bytes. So
|
||||
// that figure is used.
|
||||
totalSerializedSize := estimatedsize.TransactionOutputEstimatedSerializedSize(output) + 148
|
||||
totalSerializedSize := transactionvalidator.TransactionOutputEstimatedSerializedSize(output) + 148
|
||||
|
||||
// The output is considered dust if the cost to the network to spend the
|
||||
// coins is more than 1/3 of the minimum free transaction relay fee.
|
||||
@ -176,8 +175,7 @@ func (mp *mempool) checkTransactionStandardInContext(transaction *externalapi.Do
|
||||
}
|
||||
}
|
||||
|
||||
serializedSize := estimatedsize.TransactionEstimatedSerializedSize(transaction)
|
||||
minimumFee := mp.minimumRequiredTransactionRelayFee(serializedSize)
|
||||
minimumFee := mp.minimumRequiredTransactionRelayFee(transaction.Mass)
|
||||
if transaction.Fee < minimumFee {
|
||||
str := fmt.Sprintf("transaction %s has %d fees which is under the required amount of %d",
|
||||
consensushashing.TransactionID(transaction), transaction.Fee, minimumFee)
|
||||
@ -188,14 +186,12 @@ func (mp *mempool) checkTransactionStandardInContext(transaction *externalapi.Do
|
||||
}
|
||||
|
||||
// minimumRequiredTransactionRelayFee returns the minimum transaction fee required for a
|
||||
// transaction with the passed serialized size to be accepted into the memory
|
||||
// pool and relayed.
|
||||
func (mp *mempool) minimumRequiredTransactionRelayFee(serializedSize uint64) uint64 {
|
||||
// transaction with the passed mass to be accepted into the mampool and relayed.
|
||||
func (mp *mempool) minimumRequiredTransactionRelayFee(mass uint64) uint64 {
|
||||
// Calculate the minimum fee for a transaction to be allowed into the
|
||||
// mempool and relayed by scaling the base fee. MinimumRelayTransactionFee is in
|
||||
// sompi/kB so multiply by serializedSize (which is in bytes) and
|
||||
// divide by 1000 to get minimum sompis.
|
||||
minimumFee := (serializedSize * uint64(mp.config.MinimumRelayTransactionFee)) / 1000
|
||||
// sompi/kg so multiply by mass (which is in grams) and divide by 1000 to get minimum sompis.
|
||||
minimumFee := (mass * uint64(mp.config.MinimumRelayTransactionFee)) / 1000
|
||||
|
||||
if minimumFee == 0 && mp.config.MinimumRelayTransactionFee > 0 {
|
||||
minimumFee = uint64(mp.config.MinimumRelayTransactionFee)
|
||||
|
@ -44,13 +44,13 @@ func TestCalcMinRequiredTxRelayFee(t *testing.T) {
|
||||
},
|
||||
{
|
||||
"max standard tx size with default minimum relay fee",
|
||||
maximumStandardTransactionSize,
|
||||
maximumStandardTransactionMass,
|
||||
defaultMinimumRelayTransactionFee,
|
||||
100000,
|
||||
},
|
||||
{
|
||||
"max standard tx size with max sompi relay fee",
|
||||
maximumStandardTransactionSize,
|
||||
maximumStandardTransactionMass,
|
||||
util.MaxSompi,
|
||||
util.MaxSompi,
|
||||
},
|
||||
@ -244,7 +244,7 @@ func TestCheckTransactionStandardInIsolation(t *testing.T) {
|
||||
name: "Transaction size is too large",
|
||||
tx: &externalapi.DomainTransaction{Version: 0, Inputs: []*externalapi.DomainTransactionInput{&dummyTxIn}, Outputs: []*externalapi.DomainTransactionOutput{{
|
||||
Value: 0,
|
||||
ScriptPublicKey: &externalapi.ScriptPublicKey{bytes.Repeat([]byte{0x00}, maximumStandardTransactionSize+1), 0},
|
||||
ScriptPublicKey: &externalapi.ScriptPublicKey{bytes.Repeat([]byte{0x00}, maximumStandardTransactionMass+1), 0},
|
||||
}}},
|
||||
height: 300000,
|
||||
isStandard: false,
|
||||
|
@ -18,11 +18,13 @@ const (
|
||||
defaultOrphanExpireIntervalSeconds uint64 = 60
|
||||
defaultOrphanExpireScanIntervalSeconds uint64 = 10
|
||||
|
||||
defaultMaximumOrphanTransactionSize = 100000
|
||||
defaultMaximumOrphanTransactionMass = 100000
|
||||
// defaultMaximumOrphanTransactionCount should remain small as long as we have recursion in
|
||||
// removeOrphans when removeRedeemers = true
|
||||
defaultMaximumOrphanTransactionCount = 50
|
||||
|
||||
// defaultMinimumRelayTransactionFee specifies the minimum transaction fee for a transaction to be accepted to
|
||||
// the mempool and relayed. It is specified in sompi per 1kg (or 1000 grams) of transaction mass.
|
||||
defaultMinimumRelayTransactionFee = util.Amount(1000)
|
||||
|
||||
// Standard transaction version range might be different from what consensus accepts, therefore
|
||||
@ -41,10 +43,10 @@ type Config struct {
|
||||
TransactionExpireScanIntervalSeconds uint64
|
||||
OrphanExpireIntervalDAAScore uint64
|
||||
OrphanExpireScanIntervalDAAScore uint64
|
||||
MaximumOrphanTransactionSize uint64
|
||||
MaximumOrphanTransactionMass uint64
|
||||
MaximumOrphanTransactionCount uint64
|
||||
AcceptNonStandard bool
|
||||
MaximumMassAcceptedByBlock uint64
|
||||
MaximumMassPerBlock uint64
|
||||
MinimumRelayTransactionFee util.Amount
|
||||
MinimumStandardTransactionVersion uint16
|
||||
MaximumStandardTransactionVersion uint16
|
||||
@ -61,10 +63,10 @@ func DefaultConfig(dagParams *dagconfig.Params) *Config {
|
||||
TransactionExpireScanIntervalSeconds: defaultTransactionExpireScanIntervalSeconds,
|
||||
OrphanExpireIntervalDAAScore: defaultOrphanExpireIntervalSeconds / targetBlocksPerSecond,
|
||||
OrphanExpireScanIntervalDAAScore: defaultOrphanExpireScanIntervalSeconds / targetBlocksPerSecond,
|
||||
MaximumOrphanTransactionSize: defaultMaximumOrphanTransactionSize,
|
||||
MaximumOrphanTransactionMass: defaultMaximumOrphanTransactionMass,
|
||||
MaximumOrphanTransactionCount: defaultMaximumOrphanTransactionCount,
|
||||
AcceptNonStandard: dagParams.RelayNonStdTxs,
|
||||
MaximumMassAcceptedByBlock: dagParams.MaxMassAcceptedByBlock,
|
||||
MaximumMassPerBlock: dagParams.MaxBlockMass,
|
||||
MinimumRelayTransactionFee: defaultMinimumRelayTransactionFee,
|
||||
MinimumStandardTransactionVersion: defaultMinimumStandardTransactionVersion,
|
||||
MaximumStandardTransactionVersion: defaultMaximumStandardTransactionVersion,
|
||||
|
@ -10,7 +10,6 @@ import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/estimatedsize"
|
||||
"github.com/kaspanet/kaspad/domain/miningmanager/mempool/model"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@ -44,7 +43,7 @@ func (op *orphansPool) maybeAddOrphan(transaction *externalapi.DomainTransaction
|
||||
return err
|
||||
}
|
||||
|
||||
err = op.checkOrphanSize(transaction)
|
||||
err = op.checkOrphanMass(transaction)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -87,12 +86,11 @@ func (op *orphansPool) limitOrphanPoolSize() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (op *orphansPool) checkOrphanSize(transaction *externalapi.DomainTransaction) error {
|
||||
serializedLength := estimatedsize.TransactionEstimatedSerializedSize(transaction)
|
||||
if serializedLength > op.mempool.config.MaximumOrphanTransactionSize {
|
||||
func (op *orphansPool) checkOrphanMass(transaction *externalapi.DomainTransaction) error {
|
||||
if transaction.Mass > op.mempool.config.MaximumOrphanTransactionMass {
|
||||
str := fmt.Sprintf("orphan transaction size of %d bytes is "+
|
||||
"larger than max allowed size of %d bytes",
|
||||
serializedLength, op.mempool.config.MaximumOrphanTransactionSize)
|
||||
transaction.Mass, op.mempool.config.MaximumOrphanTransactionMass)
|
||||
return transactionRuleError(RejectBadOrphan, str)
|
||||
}
|
||||
return nil
|
||||
|
@ -16,6 +16,9 @@ func (mp *mempool) validateAndInsertTransaction(transaction *externalapi.DomainT
|
||||
fmt.Sprintf("validateAndInsertTransaction %s", consensushashing.TransactionID(transaction)))
|
||||
defer onEnd()
|
||||
|
||||
// Populate mass in the beginning, it will be used in multiple places throughout the validation and insertion.
|
||||
mp.consensus.PopulateMass(transaction)
|
||||
|
||||
err = mp.validateTransactionPreUTXOEntry(transaction)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -44,13 +44,6 @@ func (mp *mempool) validateTransactionInIsolation(transaction *externalapi.Domai
|
||||
}
|
||||
|
||||
func (mp *mempool) validateTransactionInContext(transaction *externalapi.DomainTransaction) error {
|
||||
transactionID := consensushashing.TransactionID(transaction)
|
||||
if transaction.Mass > mp.config.MaximumMassAcceptedByBlock {
|
||||
return transactionRuleError(RejectInvalid, fmt.Sprintf("transaction %s mass is %d which is "+
|
||||
"higher than the maxmimum of %d", transactionID,
|
||||
transaction.Mass, mp.config.MaximumMassAcceptedByBlock))
|
||||
}
|
||||
|
||||
if !mp.config.AcceptNonStandard {
|
||||
err := mp.checkTransactionStandardInContext(transaction)
|
||||
if err != nil {
|
||||
|
@ -28,8 +28,7 @@ type overrideDAGParamsConfig struct {
|
||||
K *model.KType `json:"k"`
|
||||
MaxBlockParents *model.KType `json:"maxBlockParents"`
|
||||
MergeSetSizeLimit *uint64 `json:"mergeSetSizeLimit"`
|
||||
MaxMassAcceptedByBlock *uint64 `json:"maxMassAcceptedByBlock"`
|
||||
MaxBlockSize *uint64 `json:"maxBlockSize"`
|
||||
MaxBlockMass *uint64 `json:"maxBlockMass"`
|
||||
MaxCoinbasePayloadLength *uint64 `json:"maxCoinbasePayloadLength"`
|
||||
MassPerTxByte *uint64 `json:"massPerTxByte"`
|
||||
MassPerScriptPubKeyByte *uint64 `json:"massPerScriptPubKeyByte"`
|
||||
@ -132,12 +131,8 @@ func (networkFlags *NetworkFlags) overrideDAGParams() error {
|
||||
networkFlags.ActiveNetParams.MergeSetSizeLimit = *config.MergeSetSizeLimit
|
||||
}
|
||||
|
||||
if config.MaxMassAcceptedByBlock != nil {
|
||||
networkFlags.ActiveNetParams.MaxMassAcceptedByBlock = *config.MaxMassAcceptedByBlock
|
||||
}
|
||||
|
||||
if config.MaxBlockSize != nil {
|
||||
networkFlags.ActiveNetParams.MaxBlockSize = *config.MaxBlockSize
|
||||
if config.MaxBlockMass != nil {
|
||||
networkFlags.ActiveNetParams.MaxBlockMass = *config.MaxBlockMass
|
||||
}
|
||||
|
||||
if config.MaxCoinbasePayloadLength != nil {
|
||||
|
@ -1,12 +1,13 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc v3.12.3
|
||||
// source: messages.proto
|
||||
|
||||
package protowire
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@ -20,6 +21,10 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
type KaspadMessage struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -11,8 +11,7 @@ import (
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
const _ = grpc.SupportPackageIsVersion6
|
||||
|
||||
// P2PClient is the client API for P2P service.
|
||||
//
|
||||
@ -30,7 +29,7 @@ func NewP2PClient(cc grpc.ClientConnInterface) P2PClient {
|
||||
}
|
||||
|
||||
func (c *p2PClient) MessageStream(ctx context.Context, opts ...grpc.CallOption) (P2P_MessageStreamClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &P2P_ServiceDesc.Streams[0], "/protowire.P2P/MessageStream", opts...)
|
||||
stream, err := c.cc.NewStream(ctx, &_P2P_serviceDesc.Streams[0], "/protowire.P2P/MessageStream", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -72,20 +71,13 @@ type P2PServer interface {
|
||||
type UnimplementedP2PServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedP2PServer) MessageStream(P2P_MessageStreamServer) error {
|
||||
func (*UnimplementedP2PServer) MessageStream(P2P_MessageStreamServer) error {
|
||||
return status.Errorf(codes.Unimplemented, "method MessageStream not implemented")
|
||||
}
|
||||
func (UnimplementedP2PServer) mustEmbedUnimplementedP2PServer() {}
|
||||
func (*UnimplementedP2PServer) mustEmbedUnimplementedP2PServer() {}
|
||||
|
||||
// UnsafeP2PServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to P2PServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeP2PServer interface {
|
||||
mustEmbedUnimplementedP2PServer()
|
||||
}
|
||||
|
||||
func RegisterP2PServer(s grpc.ServiceRegistrar, srv P2PServer) {
|
||||
s.RegisterService(&P2P_ServiceDesc, srv)
|
||||
func RegisterP2PServer(s *grpc.Server, srv P2PServer) {
|
||||
s.RegisterService(&_P2P_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _P2P_MessageStream_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
@ -114,10 +106,7 @@ func (x *p2PMessageStreamServer) Recv() (*KaspadMessage, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// P2P_ServiceDesc is the grpc.ServiceDesc for P2P service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var P2P_ServiceDesc = grpc.ServiceDesc{
|
||||
var _P2P_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "protowire.P2P",
|
||||
HandlerType: (*P2PServer)(nil),
|
||||
Methods: []grpc.MethodDesc{},
|
||||
@ -148,7 +137,7 @@ func NewRPCClient(cc grpc.ClientConnInterface) RPCClient {
|
||||
}
|
||||
|
||||
func (c *rPCClient) MessageStream(ctx context.Context, opts ...grpc.CallOption) (RPC_MessageStreamClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &RPC_ServiceDesc.Streams[0], "/protowire.RPC/MessageStream", opts...)
|
||||
stream, err := c.cc.NewStream(ctx, &_RPC_serviceDesc.Streams[0], "/protowire.RPC/MessageStream", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -190,20 +179,13 @@ type RPCServer interface {
|
||||
type UnimplementedRPCServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedRPCServer) MessageStream(RPC_MessageStreamServer) error {
|
||||
func (*UnimplementedRPCServer) MessageStream(RPC_MessageStreamServer) error {
|
||||
return status.Errorf(codes.Unimplemented, "method MessageStream not implemented")
|
||||
}
|
||||
func (UnimplementedRPCServer) mustEmbedUnimplementedRPCServer() {}
|
||||
func (*UnimplementedRPCServer) mustEmbedUnimplementedRPCServer() {}
|
||||
|
||||
// UnsafeRPCServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to RPCServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeRPCServer interface {
|
||||
mustEmbedUnimplementedRPCServer()
|
||||
}
|
||||
|
||||
func RegisterRPCServer(s grpc.ServiceRegistrar, srv RPCServer) {
|
||||
s.RegisterService(&RPC_ServiceDesc, srv)
|
||||
func RegisterRPCServer(s *grpc.Server, srv RPCServer) {
|
||||
s.RegisterService(&_RPC_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _RPC_MessageStream_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
@ -232,10 +214,7 @@ func (x *rPCMessageStreamServer) Recv() (*KaspadMessage, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// RPC_ServiceDesc is the grpc.ServiceDesc for RPC service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var RPC_ServiceDesc = grpc.ServiceDesc{
|
||||
var _RPC_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "protowire.RPC",
|
||||
HandlerType: (*RPCServer)(nil),
|
||||
Methods: []grpc.MethodDesc{},
|
||||
|
@ -1,12 +1,13 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc v3.12.3
|
||||
// source: p2p.proto
|
||||
|
||||
package protowire
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@ -20,6 +21,10 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
type RequestAddressesMessage struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@ -335,6 +340,7 @@ type TransactionInput struct {
|
||||
PreviousOutpoint *Outpoint `protobuf:"bytes,1,opt,name=previousOutpoint,proto3" json:"previousOutpoint,omitempty"`
|
||||
SignatureScript []byte `protobuf:"bytes,2,opt,name=signatureScript,proto3" json:"signatureScript,omitempty"`
|
||||
Sequence uint64 `protobuf:"varint,3,opt,name=sequence,proto3" json:"sequence,omitempty"`
|
||||
SigOpCount uint32 `protobuf:"varint,4,opt,name=sigOpCount,proto3" json:"sigOpCount,omitempty"`
|
||||
}
|
||||
|
||||
func (x *TransactionInput) Reset() {
|
||||
@ -390,6 +396,13 @@ func (x *TransactionInput) GetSequence() uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *TransactionInput) GetSigOpCount() uint32 {
|
||||
if x != nil {
|
||||
return x.SigOpCount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Outpoint struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@ -2269,7 +2282,7 @@ var file_p2p_proto_rawDesc = []byte{
|
||||
0x64, 0x52, 0x0c, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12,
|
||||
0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x67, 0x61,
|
||||
0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x08, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x99, 0x01, 0x0a, 0x10,
|
||||
0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xb9, 0x01, 0x0a, 0x10,
|
||||
0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74,
|
||||
0x12, 0x3f, 0x0a, 0x10, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x4f, 0x75, 0x74, 0x70,
|
||||
0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f,
|
||||
@ -2279,7 +2292,9 @@ var file_p2p_proto_rawDesc = []byte{
|
||||
0x72, 0x69, 0x70, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73,
|
||||
0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73,
|
||||
0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x60, 0x0a, 0x08, 0x4f, 0x75, 0x74, 0x70, 0x6f,
|
||||
0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x4f, 0x70,
|
||||
0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x69, 0x67,
|
||||
0x4f, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x60, 0x0a, 0x08, 0x4f, 0x75, 0x74, 0x70, 0x6f,
|
||||
0x69, 0x6e, 0x74, 0x12, 0x3e, 0x0a, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69,
|
||||
|
@ -36,6 +36,7 @@ message TransactionInput{
|
||||
Outpoint previousOutpoint = 1;
|
||||
bytes signatureScript = 2;
|
||||
uint64 sequence = 3;
|
||||
uint32 sigOpCount = 4;
|
||||
}
|
||||
|
||||
message Outpoint{
|
||||
|
@ -1,9 +1,10 @@
|
||||
package protowire
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/pkg/errors"
|
||||
"math"
|
||||
)
|
||||
|
||||
func (x *KaspadMessage_Transaction) toAppMessage() (appmessage.Message, error) {
|
||||
@ -64,11 +65,14 @@ func (x *TransactionInput) toAppMessage() (*appmessage.TxIn, error) {
|
||||
if x == nil {
|
||||
return nil, errors.Wrapf(errorNil, "TransactionInput is nil")
|
||||
}
|
||||
if x.SigOpCount > math.MaxUint8 {
|
||||
return nil, errors.New("TransactionInput SigOpCount > math.MaxUint8")
|
||||
}
|
||||
outpoint, err := x.PreviousOutpoint.toAppMessage()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return appmessage.NewTxIn(outpoint, x.SignatureScript, x.Sequence), nil
|
||||
return appmessage.NewTxIn(outpoint, x.SignatureScript, x.Sequence, byte(x.SigOpCount)), nil
|
||||
}
|
||||
|
||||
func (x *TransactionOutput) toAppMessage() (*appmessage.TxOut, error) {
|
||||
@ -95,6 +99,7 @@ func (x *TransactionMessage) fromAppMessage(msgTx *appmessage.MsgTx) {
|
||||
},
|
||||
SignatureScript: input.SignatureScript,
|
||||
Sequence: input.Sequence,
|
||||
SigOpCount: uint32(input.SigOpCount),
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,5 +123,4 @@ func (x *TransactionMessage) fromAppMessage(msgTx *appmessage.MsgTx) {
|
||||
Gas: msgTx.Gas,
|
||||
Payload: msgTx.Payload,
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -230,6 +230,7 @@ Receivers of any ResponseMessage are expected to check whether its error field i
|
||||
| previousOutpoint | [RpcOutpoint](#protowire.RpcOutpoint) | | |
|
||||
| signatureScript | [string](#string) | | |
|
||||
| sequence | [uint64](#uint64) | | |
|
||||
| sigOpCount | [uint32](#uint32) | | |
|
||||
| verboseData | [RpcTransactionInputVerboseData](#protowire.RpcTransactionInputVerboseData) | | |
|
||||
|
||||
|
||||
@ -727,6 +728,7 @@ SubmitTransactionRequestMessage submits a transaction to the mempool
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| transaction | [RpcTransaction](#protowire.RpcTransaction) | | |
|
||||
| allowOrphan | [bool](#bool) | | |
|
||||
|
||||
|
||||
|
||||
|
@ -10,13 +10,14 @@
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc v3.12.3
|
||||
// source: rpc.proto
|
||||
|
||||
package protowire
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@ -30,6 +31,10 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
type SubmitBlockResponseMessage_RejectReason int32
|
||||
|
||||
const (
|
||||
@ -501,6 +506,7 @@ type RpcTransactionInput struct {
|
||||
PreviousOutpoint *RpcOutpoint `protobuf:"bytes,1,opt,name=previousOutpoint,proto3" json:"previousOutpoint,omitempty"`
|
||||
SignatureScript string `protobuf:"bytes,2,opt,name=signatureScript,proto3" json:"signatureScript,omitempty"`
|
||||
Sequence uint64 `protobuf:"varint,3,opt,name=sequence,proto3" json:"sequence,omitempty"`
|
||||
SigOpCount uint32 `protobuf:"varint,5,opt,name=sigOpCount,proto3" json:"sigOpCount,omitempty"`
|
||||
VerboseData *RpcTransactionInputVerboseData `protobuf:"bytes,4,opt,name=verboseData,proto3" json:"verboseData,omitempty"`
|
||||
}
|
||||
|
||||
@ -557,6 +563,13 @@ func (x *RpcTransactionInput) GetSequence() uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *RpcTransactionInput) GetSigOpCount() uint32 {
|
||||
if x != nil {
|
||||
return x.SigOpCount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *RpcTransactionInput) GetVerboseData() *RpcTransactionInputVerboseData {
|
||||
if x != nil {
|
||||
return x.VerboseData
|
||||
@ -815,7 +828,7 @@ type RpcTransactionVerboseData struct {
|
||||
|
||||
TransactionId string `protobuf:"bytes,1,opt,name=transactionId,proto3" json:"transactionId,omitempty"`
|
||||
Hash string `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"`
|
||||
Size uint64 `protobuf:"varint,3,opt,name=size,proto3" json:"size,omitempty"`
|
||||
Mass uint64 `protobuf:"varint,4,opt,name=mass,proto3" json:"mass,omitempty"`
|
||||
BlockHash string `protobuf:"bytes,12,opt,name=blockHash,proto3" json:"blockHash,omitempty"`
|
||||
BlockTime uint64 `protobuf:"varint,14,opt,name=blockTime,proto3" json:"blockTime,omitempty"`
|
||||
}
|
||||
@ -866,9 +879,9 @@ func (x *RpcTransactionVerboseData) GetHash() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *RpcTransactionVerboseData) GetSize() uint64 {
|
||||
func (x *RpcTransactionVerboseData) GetMass() uint64 {
|
||||
if x != nil {
|
||||
return x.Size
|
||||
return x.Mass
|
||||
}
|
||||
return 0
|
||||
}
|
||||
@ -5337,7 +5350,7 @@ var file_rpc_proto_rawDesc = []byte{
|
||||
0x61, 0x74, 0x61, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x52, 0x70, 0x63, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x56, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x44, 0x61, 0x74, 0x61, 0x52,
|
||||
0x0b, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x44, 0x61, 0x74, 0x61, 0x22, 0xec, 0x01, 0x0a,
|
||||
0x0b, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x44, 0x61, 0x74, 0x61, 0x22, 0x8c, 0x02, 0x0a,
|
||||
0x13, 0x52, 0x70, 0x63, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49,
|
||||
0x6e, 0x70, 0x75, 0x74, 0x12, 0x42, 0x0a, 0x10, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73,
|
||||
0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16,
|
||||
@ -5347,7 +5360,9 @@ var file_rpc_proto_rawDesc = []byte{
|
||||
0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x0f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x63, 0x72, 0x69,
|
||||
0x70, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x4b,
|
||||
0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1e,
|
||||
0x0a, 0x0a, 0x73, 0x69, 0x67, 0x4f, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01,
|
||||
0x28, 0x0d, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x4f, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x4b,
|
||||
0x0a, 0x0b, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x44, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e,
|
||||
0x52, 0x70, 0x63, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e,
|
||||
@ -5392,8 +5407,8 @@ var file_rpc_proto_rawDesc = []byte{
|
||||
0x0a, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09,
|
||||
0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x61, 0x73, 0x73,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x6d, 0x61, 0x73, 0x73, 0x12, 0x1c, 0x0a, 0x09,
|
||||
0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x62,
|
||||
|
@ -61,6 +61,7 @@ message RpcTransactionInput {
|
||||
RpcOutpoint previousOutpoint = 1;
|
||||
string signatureScript = 2;
|
||||
uint64 sequence = 3;
|
||||
uint32 sigOpCount = 5;
|
||||
RpcTransactionInputVerboseData verboseData = 4;
|
||||
}
|
||||
|
||||
@ -90,7 +91,7 @@ message RpcUtxoEntry {
|
||||
message RpcTransactionVerboseData{
|
||||
string transactionId = 1;
|
||||
string hash = 2;
|
||||
uint64 size = 3;
|
||||
uint64 mass = 4;
|
||||
string blockHash = 12;
|
||||
uint64 blockTime = 14;
|
||||
}
|
||||
|
@ -146,6 +146,9 @@ func (x *RpcTransactionInput) toAppMessage() (*appmessage.RPCTransactionInput, e
|
||||
if x == nil {
|
||||
return nil, errors.Wrapf(errorNil, "RpcTransactionInput is nil")
|
||||
}
|
||||
if x.SigOpCount > math.MaxUint8 {
|
||||
return nil, errors.New("TransactionInput SigOpCount > math.MaxUint8")
|
||||
}
|
||||
outpoint, err := x.PreviousOutpoint.toAppMessage()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -163,6 +166,7 @@ func (x *RpcTransactionInput) toAppMessage() (*appmessage.RPCTransactionInput, e
|
||||
SignatureScript: x.SignatureScript,
|
||||
Sequence: x.Sequence,
|
||||
VerboseData: verboseData,
|
||||
SigOpCount: byte(x.SigOpCount),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -179,6 +183,7 @@ func (x *RpcTransactionInput) fromAppMessage(message *appmessage.RPCTransactionI
|
||||
SignatureScript: message.SignatureScript,
|
||||
Sequence: message.Sequence,
|
||||
VerboseData: verboseData,
|
||||
SigOpCount: uint32(message.SigOpCount),
|
||||
}
|
||||
}
|
||||
|
||||
@ -291,7 +296,7 @@ func (x *RpcTransactionVerboseData) toAppMessage() (*appmessage.RPCTransactionVe
|
||||
return &appmessage.RPCTransactionVerboseData{
|
||||
TransactionID: x.TransactionId,
|
||||
Hash: x.Hash,
|
||||
Size: x.Size,
|
||||
Mass: x.Mass,
|
||||
BlockHash: x.BlockHash,
|
||||
BlockTime: x.BlockTime,
|
||||
}, nil
|
||||
@ -301,7 +306,7 @@ func (x *RpcTransactionVerboseData) fromAppMessage(message *appmessage.RPCTransa
|
||||
*x = RpcTransactionVerboseData{
|
||||
TransactionId: message.TransactionID,
|
||||
Hash: message.Hash,
|
||||
Size: message.Size,
|
||||
Mass: message.Mass,
|
||||
BlockHash: message.BlockHash,
|
||||
BlockTime: message.BlockTime,
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ func waitForPayeeToReceiveBlock(t *testing.T, payeeBlockAddedChan chan *appmessa
|
||||
|
||||
func generateTx(t *testing.T, firstBlockCoinbase *externalapi.DomainTransaction, payer, payee *appHarness) *appmessage.MsgTx {
|
||||
txIns := make([]*appmessage.TxIn, 1)
|
||||
txIns[0] = appmessage.NewTxIn(appmessage.NewOutpoint(consensushashing.TransactionID(firstBlockCoinbase), 0), []byte{}, 0)
|
||||
txIns[0] = appmessage.NewTxIn(appmessage.NewOutpoint(consensushashing.TransactionID(firstBlockCoinbase), 0), []byte{}, 0, 1)
|
||||
|
||||
payeeAddress, err := util.DecodeAddress(payee.miningAddress, util.Bech32PrefixKaspaSim)
|
||||
if err != nil {
|
||||
|
@ -161,7 +161,7 @@ func buildTransactionForUTXOIndexTest(t *testing.T, entry *appmessage.UTXOsByAdd
|
||||
}
|
||||
|
||||
txIns := make([]*appmessage.TxIn, 1)
|
||||
txIns[0] = appmessage.NewTxIn(appmessage.NewOutpoint(transactionID, entry.Outpoint.Index), []byte{}, 0)
|
||||
txIns[0] = appmessage.NewTxIn(appmessage.NewOutpoint(transactionID, entry.Outpoint.Index), []byte{}, 0, 1)
|
||||
|
||||
payeeAddress, err := util.DecodeAddress(miningAddress1, util.Bech32PrefixKaspaSim)
|
||||
if err != nil {
|
||||
|
Loading…
x
Reference in New Issue
Block a user