Merge branch 'dev' into add-tx-index

This commit is contained in:
D-Stacks 2022-10-09 20:40:16 +02:00 committed by GitHub
commit 3b317fcb98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 222 additions and 113 deletions

View File

@ -133,8 +133,8 @@ func TestTx(t *testing.T) {
// TestTxHash tests the ability to generate the hash of a transaction accurately. // TestTxHash tests the ability to generate the hash of a transaction accurately.
func TestTxHashAndID(t *testing.T) { func TestTxHashAndID(t *testing.T) {
txHash1Str := "93663e597f6c968d32d229002f76408edf30d6a0151ff679fc729812d8cb2acc" txHash1Str := "b06f8b650115b5cf4d59499e10764a9312742930cb43c9b4ff6495d76f332ed7"
txID1Str := "24079c6d2bdf602fc389cc307349054937744a9c8dc0f07c023e6af0e949a4e7" txID1Str := "e20225c3d065ee41743607ee627db44d01ef396dc9779b05b2caf55bac50e12d"
wantTxID1, err := transactionid.FromString(txID1Str) wantTxID1, err := transactionid.FromString(txID1Str)
if err != nil { if err != nil {
t.Fatalf("NewTxIDFromStr: %v", err) t.Fatalf("NewTxIDFromStr: %v", err)
@ -185,7 +185,7 @@ func TestTxHashAndID(t *testing.T) {
spew.Sprint(tx1ID), spew.Sprint(wantTxID1)) spew.Sprint(tx1ID), spew.Sprint(wantTxID1))
} }
hash2Str := "8dafd1bec24527d8e3b443ceb0a3b92fffc0d60026317f890b2faf5e9afc177a" hash2Str := "fa16a8ce88d52ca1ff45187bbba0d33044e9f5fe309e8d0b22d4812dcf1782b7"
wantHash2, err := externalapi.NewDomainHashFromString(hash2Str) wantHash2, err := externalapi.NewDomainHashFromString(hash2Str)
if err != nil { if err != nil {
t.Errorf("NewTxIDFromStr: %v", err) t.Errorf("NewTxIDFromStr: %v", err)

View File

@ -25,7 +25,7 @@ func (flow *handleIBDFlow) ibdWithHeadersProof(
return err return err
} }
log.Infof("IBD with pruning proof from %s was unsuccessful. Deleting the staging consensus.", flow.peer) log.Infof("IBD with pruning proof from %s was unsuccessful. Deleting the staging consensus. (%s)", flow.peer, err)
deleteStagingConsensusErr := flow.Domain().DeleteStagingConsensus() deleteStagingConsensusErr := flow.Domain().DeleteStagingConsensus()
if deleteStagingConsensusErr != nil { if deleteStagingConsensusErr != nil {
return deleteStagingConsensusErr return deleteStagingConsensusErr

View File

@ -122,6 +122,7 @@ func (ctx *Context) PopulateTransactionWithVerboseData(
} }
ctx.Domain.Consensus().PopulateMass(domainTransaction) ctx.Domain.Consensus().PopulateMass(domainTransaction)
transaction.VerboseData = &appmessage.RPCTransactionVerboseData{ transaction.VerboseData = &appmessage.RPCTransactionVerboseData{
TransactionID: consensushashing.TransactionID(domainTransaction).String(), TransactionID: consensushashing.TransactionID(domainTransaction).String(),
Hash: consensushashing.TransactionHash(domainTransaction).String(), Hash: consensushashing.TransactionHash(domainTransaction).String(),

View File

@ -78,6 +78,11 @@ func create(conf *createConfig) error {
return err return err
} }
err = file.TryLock()
if err != nil {
return err
}
err = file.Save() err = file.Save()
if err != nil { if err != nil {
return err return err

View File

@ -77,6 +77,11 @@ func Start(params *dagconfig.Params, listen, rpcServer string, keysFilePath stri
return (errors.Wrapf(err, "Error reading keys file %s", keysFilePath)) return (errors.Wrapf(err, "Error reading keys file %s", keysFilePath))
} }
err = keysFile.TryLock()
if err != nil {
return err
}
serverInstance := &server{ serverInstance := &server{
rpcClient: rpcClient, rpcClient: rpcClient,
params: params, params: params,

View File

@ -6,6 +6,7 @@ import (
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/gofrs/flock"
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
@ -400,3 +401,28 @@ func decryptMnemonic(numThreads uint8, encryptedPrivateKey *EncryptedMnemonic, p
return string(decrypted), nil return string(decrypted), nil
} }
// flockMap is a map that holds all lock file handlers. This map guarantees that
// the associated locked file handler will never get cleaned by the GC, because
// once they are cleaned the associated file will be unlocked.
var flockMap = make(map[string]*flock.Flock)
// TryLock tries to acquire an exclusive lock for the file.
func (d *File) TryLock() error {
if _, ok := flockMap[d.path]; ok {
return errors.Errorf("file %s is already locked", d.path)
}
lockFile := flock.New(d.path + ".lock")
flockMap[d.path] = lockFile
success, err := lockFile.TryLock()
if err != nil {
return err
}
if !success {
return errors.Errorf("%s is locked and cannot be used. Make sure that no other active wallet command is using it.", d.path)
}
return nil
}

View File

@ -3,6 +3,8 @@ package main
import ( import (
"context" "context"
"fmt" "fmt"
"os"
"strings"
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/client" "github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/client"
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb" "github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
@ -49,6 +51,10 @@ func send(conf *sendConfig) error {
} }
mnemonics, err := keysFile.DecryptMnemonics(conf.Password) mnemonics, err := keysFile.DecryptMnemonics(conf.Password)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "message authentication failed") {
fmt.Fprintf(os.Stderr, "Password decryption failed. Sometimes this is a result of not "+
"specifying the same keys file used by the wallet daemon process.\n")
}
return err return err
} }

View File

@ -216,6 +216,8 @@ func (f *factory) NewConsensus(config *Config, db infrastructuredatabase.Databas
transactionValidator := transactionvalidator.New(config.BlockCoinbaseMaturity, transactionValidator := transactionvalidator.New(config.BlockCoinbaseMaturity,
config.EnableNonNativeSubnetworks, config.EnableNonNativeSubnetworks,
config.MaxCoinbasePayloadLength, config.MaxCoinbasePayloadLength,
config.K,
config.CoinbasePayloadScriptPublicKeyMaxLength,
dbManager, dbManager,
pastMedianTimeManager, pastMedianTimeManager,
ghostdagDataStore, ghostdagDataStore,
@ -237,12 +239,14 @@ func (f *factory) NewConsensus(config *Config, db infrastructuredatabase.Databas
config.GenesisBlock.Header.Bits()) config.GenesisBlock.Header.Bits())
coinbaseManager := coinbasemanager.New( coinbaseManager := coinbasemanager.New(
dbManager, dbManager,
config.SubsidyGenesisReward, config.SubsidyGenesisReward,
config.PreDeflationaryPhaseBaseSubsidy, config.PreDeflationaryPhaseBaseSubsidy,
config.CoinbasePayloadScriptPublicKeyMaxLength, config.CoinbasePayloadScriptPublicKeyMaxLength,
config.GenesisHash, config.GenesisHash,
config.DeflationaryPhaseDaaScore, config.DeflationaryPhaseDaaScore,
config.DeflationaryPhaseBaseSubsidy, config.DeflationaryPhaseBaseSubsidy,
dagTraversalManager, dagTraversalManager,
ghostdagDataStore, ghostdagDataStore,
acceptanceDataStore, acceptanceDataStore,

View File

@ -169,10 +169,10 @@ var unOrderedParentsBlock = externalapi.DomainBlock{
}), }),
}}, }},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{ externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
0x31, 0x33, 0x37, 0x72, 0x5c, 0xde, 0x1c, 0xdf, 0x7e, 0xe2, 0x10, 0x4e, 0x21, 0x2f, 0x2a, 0xb1,
0xf5, 0x9f, 0xde, 0x16, 0x74, 0xbf, 0x0c, 0x64, 0x7d, 0x22, 0xf5, 0xe8, 0xa0, 0x98, 0xef, 0x53,
0x37, 0x40, 0x49, 0xdf, 0x02, 0x05, 0xca, 0x6d, 0x83, 0xae, 0x59, 0x1f, 0x83, 0xf3, 0x78, 0x5d,
0x52, 0x23, 0x6f, 0xc2, 0x2b, 0xec, 0xad, 0x42, 0x30, 0xae, 0x3e, 0xb3, 0x06, 0x08, 0x6f, 0x79,
}), }),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{ externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
0x80, 0xf7, 0x00, 0xe3, 0x16, 0x3d, 0x04, 0x95, 0x80, 0xf7, 0x00, 0xe3, 0x16, 0x3d, 0x04, 0x95,
@ -202,20 +202,7 @@ var unOrderedParentsBlock = externalapi.DomainBlock{
Transactions: []*externalapi.DomainTransaction{ Transactions: []*externalapi.DomainTransaction{
{ {
Version: 0, Version: 0,
Inputs: []*externalapi.DomainTransactionInput{ Inputs: nil,
{
PreviousOutpoint: externalapi.DomainOutpoint{
TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{}),
Index: 0xffffffff,
},
SignatureScript: []byte{
0x02, 0x10, 0x27, 0x08, 0xac, 0x29, 0x2f, 0x2f,
0xcf, 0x70, 0xb0, 0x7e, 0x0b, 0x2f, 0x50, 0x32,
0x53, 0x48, 0x2f, 0x62, 0x74, 0x63, 0x64, 0x2f,
},
Sequence: math.MaxUint64,
},
},
Outputs: []*externalapi.DomainTransactionOutput{ Outputs: []*externalapi.DomainTransactionOutput{
{ {
Value: 0x12a05f200, // 5000000000 Value: 0x12a05f200, // 5000000000
@ -446,10 +433,10 @@ var exampleValidBlock = externalapi.DomainBlock{
}), }),
}}, }},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{ externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
0x86, 0x8b, 0x73, 0xcd, 0x20, 0x51, 0x23, 0x60, 0x46, 0xec, 0xf4, 0x5b, 0xe3, 0xba, 0xca, 0x34,
0xea, 0x62, 0x99, 0x9b, 0x87, 0xf6, 0xdd, 0x8d, 0x9d, 0xfe, 0x8a, 0x78, 0xde, 0xaf, 0x05, 0x3b,
0xa4, 0x0b, 0xd7, 0xcf, 0xc6, 0x32, 0x38, 0xee, 0x0a, 0xa6, 0xd5, 0x38, 0x97, 0x4d, 0xa5, 0x0f,
0xd9, 0x68, 0x72, 0x1f, 0xa2, 0x51, 0xe4, 0x28, 0xd6, 0xef, 0xb4, 0xd2, 0x66, 0xbc, 0x8d, 0x21,
}), }),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{ externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
0x8a, 0xb7, 0xd6, 0x73, 0x1b, 0xe6, 0xc5, 0xd3, 0x8a, 0xb7, 0xd6, 0x73, 0x1b, 0xe6, 0xc5, 0xd3,
@ -474,21 +461,7 @@ var exampleValidBlock = externalapi.DomainBlock{
Transactions: []*externalapi.DomainTransaction{ Transactions: []*externalapi.DomainTransaction{
{ {
Version: 0, Version: 0,
Inputs: []*externalapi.DomainTransactionInput{ Inputs: nil,
{
PreviousOutpoint: externalapi.DomainOutpoint{
TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
0x9b, 0x22, 0x59, 0x44, 0x66, 0xf0, 0xbe, 0x50,
0x7c, 0x1c, 0x8a, 0xf6, 0x06, 0x27, 0xe6, 0x33,
0x38, 0x7e, 0xd1, 0xd5, 0x8c, 0x42, 0x59, 0x1a,
0x31, 0xac, 0x9a, 0xa6, 0x2e, 0xd5, 0x2b, 0x0f,
}),
Index: 0xffffffff,
},
SignatureScript: nil,
Sequence: math.MaxUint64,
},
},
Outputs: []*externalapi.DomainTransactionOutput{ Outputs: []*externalapi.DomainTransactionOutput{
{ {
Value: 0x12a05f200, // 5000000000 Value: 0x12a05f200, // 5000000000
@ -751,10 +724,10 @@ var blockWithWrongTxOrder = externalapi.DomainBlock{
}), }),
}}, }},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{ externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
0x7b, 0x25, 0x8b, 0xfa, 0xfb, 0x49, 0xe4, 0x94, 0xd5, 0xd2, 0x32, 0xe4, 0xbe, 0x9c, 0x33, 0xbd,
0x48, 0x2c, 0xf9, 0x74, 0xdd, 0xad, 0x9d, 0x6f, 0xf1, 0x0a, 0xd2, 0x9d, 0x0c, 0xbd, 0xe5, 0xae,
0x98, 0x8f, 0xfb, 0x01, 0x9d, 0x49, 0x29, 0xbe, 0xcb, 0x1a, 0xf9, 0x5a, 0x3e, 0xfb, 0xf3, 0xc7,
0x3c, 0xec, 0x90, 0xfe, 0xa5, 0x0c, 0xaf, 0x6b, 0x2b, 0x4d, 0x10, 0xa6, 0xbd, 0x5f, 0x07, 0xe7,
}), }),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{ externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
0xa0, 0x69, 0x2d, 0x16, 0xb5, 0xd7, 0xe4, 0xf3, 0xa0, 0x69, 0x2d, 0x16, 0xb5, 0xd7, 0xe4, 0xf3,

View File

@ -0,0 +1,57 @@
package coinbasemanager_test
import (
"github.com/kaspanet/kaspad/domain/consensus"
"github.com/kaspanet/kaspad/domain/consensus/model"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/utils/testutils"
"testing"
)
func TestExtractCoinbaseDataBlueScoreAndSubsidy(t *testing.T) {
testutils.ForAllNets(t, true, func(t *testing.T, consensusConfig *consensus.Config) {
factory := consensus.NewFactory()
tc, teardown, err := factory.NewTestConsensus(consensusConfig, "TestBlockStatus")
if err != nil {
t.Fatalf("Error setting up consensus: %+v", err)
}
defer teardown(false)
tests := []struct {
name string
scriptPublicKeyVersion uint16
}{
{
name: "below 255",
scriptPublicKeyVersion: 100,
},
{
name: "above 255",
scriptPublicKeyVersion: 300,
},
}
for _, test := range tests {
coinbaseTx, _, err := tc.CoinbaseManager().ExpectedCoinbaseTransaction(model.NewStagingArea(), model.VirtualBlockHash, &externalapi.DomainCoinbaseData{
ScriptPublicKey: &externalapi.ScriptPublicKey{
Script: nil,
Version: test.scriptPublicKeyVersion,
},
ExtraData: nil,
})
if err != nil {
t.Fatal(err)
}
_, cbData, _, err := tc.CoinbaseManager().ExtractCoinbaseDataBlueScoreAndSubsidy(coinbaseTx)
if err != nil {
t.Fatal(err)
}
if cbData.ScriptPublicKey.Version != test.scriptPublicKeyVersion {
t.Fatalf("test %s post HF expected %d but got %d", test.name, test.scriptPublicKeyVersion, cbData.ScriptPublicKey.Version)
}
}
})
}

View File

@ -28,7 +28,7 @@ func (c *coinbaseManager) serializeCoinbasePayload(blueScore uint64,
binary.LittleEndian.PutUint64(payload[:uint64Len], blueScore) binary.LittleEndian.PutUint64(payload[:uint64Len], blueScore)
binary.LittleEndian.PutUint64(payload[uint64Len:], subsidy) binary.LittleEndian.PutUint64(payload[uint64Len:], subsidy)
payload[uint64Len+lengthOfSubsidy] = uint8(coinbaseData.ScriptPublicKey.Version) binary.LittleEndian.PutUint16(payload[uint64Len+lengthOfSubsidy:], coinbaseData.ScriptPublicKey.Version)
payload[uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey] = uint8(len(coinbaseData.ScriptPublicKey.Script)) payload[uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey] = uint8(len(coinbaseData.ScriptPublicKey.Script))
copy(payload[uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey+lengthOfScriptPubKeyLength:], coinbaseData.ScriptPublicKey.Script) copy(payload[uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey+lengthOfScriptPubKeyLength:], coinbaseData.ScriptPublicKey.Script)
copy(payload[uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey+lengthOfScriptPubKeyLength+scriptLengthOfScriptPubKey:], coinbaseData.ExtraData) copy(payload[uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey+lengthOfScriptPubKeyLength+scriptLengthOfScriptPubKey:], coinbaseData.ExtraData)
@ -52,7 +52,7 @@ func ModifyCoinbasePayload(payload []byte, coinbaseData *externalapi.DomainCoinb
payload = newPayload payload = newPayload
} }
payload[uint64Len+lengthOfSubsidy] = uint8(coinbaseData.ScriptPublicKey.Version) binary.LittleEndian.PutUint16(payload[uint64Len+lengthOfSubsidy:uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey], coinbaseData.ScriptPublicKey.Version)
payload[uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey] = uint8(len(coinbaseData.ScriptPublicKey.Script)) payload[uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey] = uint8(len(coinbaseData.ScriptPublicKey.Script))
copy(payload[uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey+lengthOfScriptPubKeyLength:], coinbaseData.ScriptPublicKey.Script) copy(payload[uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey+lengthOfScriptPubKeyLength:], coinbaseData.ScriptPublicKey.Script)
copy(payload[uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey+lengthOfScriptPubKeyLength+scriptLengthOfScriptPubKey:], coinbaseData.ExtraData) copy(payload[uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey+lengthOfScriptPubKeyLength+scriptLengthOfScriptPubKey:], coinbaseData.ExtraData)
@ -73,7 +73,8 @@ func (c *coinbaseManager) ExtractCoinbaseDataBlueScoreAndSubsidy(coinbaseTx *ext
blueScore = binary.LittleEndian.Uint64(coinbaseTx.Payload[:uint64Len]) blueScore = binary.LittleEndian.Uint64(coinbaseTx.Payload[:uint64Len])
subsidy = binary.LittleEndian.Uint64(coinbaseTx.Payload[uint64Len:]) subsidy = binary.LittleEndian.Uint64(coinbaseTx.Payload[uint64Len:])
scriptPubKeyVersion := uint16(coinbaseTx.Payload[uint64Len+lengthOfSubsidy]) scriptPubKeyVersion := binary.LittleEndian.Uint16(coinbaseTx.Payload[uint64Len+lengthOfSubsidy : uint64Len+lengthOfSubsidy+uint16Len])
scriptPubKeyScriptLength := coinbaseTx.Payload[uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey] scriptPubKeyScriptLength := coinbaseTx.Payload[uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey]
if scriptPubKeyScriptLength > c.coinbasePayloadScriptPublicKeyMaxLength { if scriptPubKeyScriptLength > c.coinbasePayloadScriptPublicKeyMaxLength {

View File

@ -72,7 +72,8 @@ func New(
maxBlockParents: maxBlockParents, maxBlockParents: maxBlockParents,
mergeSetSizeLimit: mergeSetSizeLimit, mergeSetSizeLimit: mergeSetSizeLimit,
genesisHash: genesisHash, genesisHash: genesisHash,
databaseContext: databaseContext,
databaseContext: databaseContext,
ghostdagManager: ghostdagManager, ghostdagManager: ghostdagManager,
dagTopologyManager: dagTopologyManager, dagTopologyManager: dagTopologyManager,

View File

@ -350,6 +350,7 @@ func (v *transactionValidator) validateTransactionSigOpCounts(tx *externalapi.Do
sigScript := input.SignatureScript sigScript := input.SignatureScript
isP2SH := txscript.IsPayToScriptHash(utxoEntry.ScriptPublicKey()) isP2SH := txscript.IsPayToScriptHash(utxoEntry.ScriptPublicKey())
sigOpCount := txscript.GetPreciseSigOpCount(sigScript, utxoEntry.ScriptPublicKey(), isP2SH) sigOpCount := txscript.GetPreciseSigOpCount(sigScript, utxoEntry.ScriptPublicKey(), isP2SH)
if sigOpCount != int(input.SigOpCount) { if sigOpCount != int(input.SigOpCount) {
return errors.Wrapf(ruleerrors.ErrWrongSigOpCount, return errors.Wrapf(ruleerrors.ErrWrongSigOpCount,
"input %d specifies SigOpCount %d while actual SigOpCount is %d", "input %d specifies SigOpCount %d while actual SigOpCount is %d",

View File

@ -23,7 +23,7 @@ func (v *transactionValidator) ValidateTransactionInIsolation(tx *externalapi.Do
if err != nil { if err != nil {
return err return err
} }
err = v.checkCoinbaseLength(tx) err = v.checkCoinbaseInIsolation(tx)
if err != nil { if err != nil {
return err return err
} }
@ -114,7 +114,7 @@ func (v *transactionValidator) checkDuplicateTransactionInputs(tx *externalapi.D
return nil return nil
} }
func (v *transactionValidator) checkCoinbaseLength(tx *externalapi.DomainTransaction) error { func (v *transactionValidator) checkCoinbaseInIsolation(tx *externalapi.DomainTransaction) error {
if !transactionhelper.IsCoinBase(tx) { if !transactionhelper.IsCoinBase(tx) {
return nil return nil
} }
@ -127,6 +127,22 @@ func (v *transactionValidator) checkCoinbaseLength(tx *externalapi.DomainTransac
payloadLen, v.maxCoinbasePayloadLength) payloadLen, v.maxCoinbasePayloadLength)
} }
if len(tx.Inputs) != 0 {
return errors.Wrap(ruleerrors.ErrCoinbaseWithInputs, "coinbase has inputs")
}
outputsLimit := uint64(v.ghostdagK) + 2
if uint64(len(tx.Outputs)) > outputsLimit {
return errors.Wrapf(ruleerrors.ErrCoinbaseTooManyOutputs, "coinbase has too many outputs: got %d where the limit is %d", len(tx.Outputs), outputsLimit)
}
for i, output := range tx.Outputs {
if len(output.ScriptPublicKey.Script) > int(v.coinbasePayloadScriptPublicKeyMaxLength) {
return errors.Wrapf(ruleerrors.ErrCoinbaseTooLongScriptPublicKey, "coinbase output %d has a too long script public key", i)
}
}
return nil return nil
} }

View File

@ -76,7 +76,7 @@ func TestValidateTransactionInIsolationAndPopulateMass(t *testing.T) {
subnetworks.SubnetworkIDNative, subnetworks.SubnetworkIDNative,
&txSubnetworkData{subnetworks.SubnetworkIDCoinbase, 0, nil}, &txSubnetworkData{subnetworks.SubnetworkIDCoinbase, 0, nil},
nil, nil,
nil, 0}, ruleerrors.ErrCoinbaseWithInputs, 0},
{"no inputs coinbase", {"no inputs coinbase",
0, 0,
1, 1,

View File

@ -2,6 +2,7 @@ package transactionvalidator
import ( import (
"github.com/kaspanet/kaspad/domain/consensus/model" "github.com/kaspanet/kaspad/domain/consensus/model"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript" "github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
"github.com/kaspanet/kaspad/util/txmass" "github.com/kaspanet/kaspad/util/txmass"
) )
@ -11,22 +12,26 @@ const sigCacheSize = 10_000
// transactionValidator exposes a set of validation classes, after which // transactionValidator exposes a set of validation classes, after which
// it's possible to determine whether either a transaction is valid // it's possible to determine whether either a transaction is valid
type transactionValidator struct { type transactionValidator struct {
blockCoinbaseMaturity uint64 blockCoinbaseMaturity uint64
databaseContext model.DBReader databaseContext model.DBReader
pastMedianTimeManager model.PastMedianTimeManager pastMedianTimeManager model.PastMedianTimeManager
ghostdagDataStore model.GHOSTDAGDataStore ghostdagDataStore model.GHOSTDAGDataStore
daaBlocksStore model.DAABlocksStore daaBlocksStore model.DAABlocksStore
enableNonNativeSubnetworks bool enableNonNativeSubnetworks bool
maxCoinbasePayloadLength uint64 maxCoinbasePayloadLength uint64
sigCache *txscript.SigCache ghostdagK externalapi.KType
sigCacheECDSA *txscript.SigCacheECDSA coinbasePayloadScriptPublicKeyMaxLength uint8
txMassCalculator *txmass.Calculator sigCache *txscript.SigCache
sigCacheECDSA *txscript.SigCacheECDSA
txMassCalculator *txmass.Calculator
} }
// New instantiates a new TransactionValidator // New instantiates a new TransactionValidator
func New(blockCoinbaseMaturity uint64, func New(blockCoinbaseMaturity uint64,
enableNonNativeSubnetworks bool, enableNonNativeSubnetworks bool,
maxCoinbasePayloadLength uint64, maxCoinbasePayloadLength uint64,
ghostdagK externalapi.KType,
coinbasePayloadScriptPublicKeyMaxLength uint8,
databaseContext model.DBReader, databaseContext model.DBReader,
pastMedianTimeManager model.PastMedianTimeManager, pastMedianTimeManager model.PastMedianTimeManager,
ghostdagDataStore model.GHOSTDAGDataStore, ghostdagDataStore model.GHOSTDAGDataStore,
@ -34,15 +39,17 @@ func New(blockCoinbaseMaturity uint64,
txMassCalculator *txmass.Calculator) model.TransactionValidator { txMassCalculator *txmass.Calculator) model.TransactionValidator {
return &transactionValidator{ return &transactionValidator{
blockCoinbaseMaturity: blockCoinbaseMaturity, blockCoinbaseMaturity: blockCoinbaseMaturity,
enableNonNativeSubnetworks: enableNonNativeSubnetworks, enableNonNativeSubnetworks: enableNonNativeSubnetworks,
maxCoinbasePayloadLength: maxCoinbasePayloadLength, maxCoinbasePayloadLength: maxCoinbasePayloadLength,
databaseContext: databaseContext, ghostdagK: ghostdagK,
pastMedianTimeManager: pastMedianTimeManager, coinbasePayloadScriptPublicKeyMaxLength: coinbasePayloadScriptPublicKeyMaxLength,
ghostdagDataStore: ghostdagDataStore, databaseContext: databaseContext,
daaBlocksStore: daaBlocksStore, pastMedianTimeManager: pastMedianTimeManager,
sigCache: txscript.NewSigCache(sigCacheSize), ghostdagDataStore: ghostdagDataStore,
sigCacheECDSA: txscript.NewSigCacheECDSA(sigCacheSize), daaBlocksStore: daaBlocksStore,
txMassCalculator: txMassCalculator, sigCache: txscript.NewSigCache(sigCacheSize),
sigCacheECDSA: txscript.NewSigCacheECDSA(sigCacheSize),
txMassCalculator: txMassCalculator,
} }
} }

View File

@ -109,18 +109,6 @@ func TestValidateTransactionInContextAndPopulateFee(t *testing.T) {
0), 0),
} }
txInputWithBadSigOpCount := externalapi.DomainTransactionInput{
PreviousOutpoint: prevOutPoint,
SignatureScript: []byte{},
Sequence: constants.MaxTxInSequenceNum,
SigOpCount: 2,
UTXOEntry: utxo.NewUTXOEntry(
100_000_000, // 1 KAS
scriptPublicKey,
true,
uint64(5)),
}
txOutput := externalapi.DomainTransactionOutput{ txOutput := externalapi.DomainTransactionOutput{
Value: 100000000, // 1 KAS Value: 100000000, // 1 KAS
ScriptPublicKey: scriptPublicKey, ScriptPublicKey: scriptPublicKey,
@ -193,13 +181,6 @@ func TestValidateTransactionInContextAndPopulateFee(t *testing.T) {
SubnetworkID: subnetworks.SubnetworkIDRegistry, SubnetworkID: subnetworks.SubnetworkIDRegistry,
Gas: 0, Gas: 0,
LockTime: 0} LockTime: 0}
txWithBadSigOpCount := externalapi.DomainTransaction{
Version: constants.MaxTransactionVersion,
Inputs: []*externalapi.DomainTransactionInput{&txInputWithBadSigOpCount},
Outputs: []*externalapi.DomainTransactionOutput{&txOutput},
SubnetworkID: subnetworks.SubnetworkIDRegistry,
Gas: 0,
LockTime: 0}
stagingArea := model.NewStagingArea() stagingArea := model.NewStagingArea()
@ -266,13 +247,6 @@ func TestValidateTransactionInContextAndPopulateFee(t *testing.T) {
isValid: false, isValid: false,
expectedError: ruleerrors.ErrScriptValidation, expectedError: ruleerrors.ErrScriptValidation,
}, },
{ // the SigOpCount in the input is wrong, and hence invalid
name: "checkTransactionSigOpCounts",
tx: &txWithBadSigOpCount,
povBlockHash: povBlockHash,
isValid: false,
expectedError: ruleerrors.ErrWrongSigOpCount,
},
} }
for _, test := range tests { for _, test := range tests {

View File

@ -241,6 +241,9 @@ var (
ErrPruningProofEmpty = newRuleError("ErrPruningProofEmpty") ErrPruningProofEmpty = newRuleError("ErrPruningProofEmpty")
ErrWrongCoinbaseSubsidy = newRuleError("ErrWrongCoinbaseSubsidy") ErrWrongCoinbaseSubsidy = newRuleError("ErrWrongCoinbaseSubsidy")
ErrWrongBlockVersion = newRuleError("ErrWrongBlockVersion") ErrWrongBlockVersion = newRuleError("ErrWrongBlockVersion")
ErrCoinbaseWithInputs = newRuleError("ErrCoinbaseWithInputs")
ErrCoinbaseTooManyOutputs = newRuleError("ErrCoinbaseTooManyOutputs")
ErrCoinbaseTooLongScriptPublicKey = newRuleError("ErrCoinbaseTooLongScriptPublicKey")
) )
// RuleError identifies a rule violation. It is used to indicate that // RuleError identifies a rule violation. It is used to indicate that

View File

@ -139,11 +139,19 @@ func writeTransactionInput(w io.Writer, ti *externalapi.DomainTransactionInput,
if encodingFlags&txEncodingExcludeSignatureScript != txEncodingExcludeSignatureScript { if encodingFlags&txEncodingExcludeSignatureScript != txEncodingExcludeSignatureScript {
err = writeVarBytes(w, ti.SignatureScript) err = writeVarBytes(w, ti.SignatureScript)
if err != nil {
return err
}
_, err = w.Write([]byte{ti.SigOpCount})
if err != nil {
return err
}
} else { } else {
err = writeVarBytes(w, []byte{}) err = writeVarBytes(w, []byte{})
} if err != nil {
if err != nil { return err
return err }
} }
return binaryserializer.PutUint64(w, ti.Sequence) return binaryserializer.PutUint64(w, ti.Sequence)

View File

@ -297,7 +297,11 @@ var TestnetParams = Params{
Net: appmessage.Testnet, Net: appmessage.Testnet,
RPCPort: "16210", RPCPort: "16210",
DefaultPort: "16211", DefaultPort: "16211",
DNSSeeds: []string{"testnet-10-dnsseed.kas.pa"}, DNSSeeds: []string{
"testnet-10-dnsseed.kas.pa",
// This DNS seeder is run by Tiram
"seeder1-testnet.kaspad.net",
},
// DAG parameters // DAG parameters
GenesisBlock: &testnetGenesisBlock, GenesisBlock: &testnetGenesisBlock,

2
go.mod
View File

@ -9,6 +9,7 @@ require (
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd
github.com/btcsuite/winsvc v1.0.0 github.com/btcsuite/winsvc v1.0.0
github.com/davecgh/go-spew v1.1.1 github.com/davecgh/go-spew v1.1.1
github.com/gofrs/flock v0.8.1
github.com/golang/protobuf v1.5.2 github.com/golang/protobuf v1.5.2
github.com/jessevdk/go-flags v1.4.0 github.com/jessevdk/go-flags v1.4.0
github.com/jrick/logrotate v1.0.0 github.com/jrick/logrotate v1.0.0
@ -30,6 +31,5 @@ require (
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 // indirect golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 // indirect
golang.org/x/text v0.3.5 // indirect golang.org/x/text v0.3.5 // indirect
google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08 // indirect google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08 // indirect
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0 // indirect
gopkg.in/yaml.v2 v2.3.0 // indirect gopkg.in/yaml.v2 v2.3.0 // indirect
) )

10
go.sum
View File

@ -26,6 +26,8 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@ -118,8 +120,6 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea h1:+WiDlPBBaO+h9vPNZi8uJ3k4BkKQB7Iow3aqwHVA5hI=
golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 h1:id054HUawV2/6IGm2IV8KZQjqtwAOo2CYlOToYqa0d0= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 h1:id054HUawV2/6IGm2IV8KZQjqtwAOo2CYlOToYqa0d0=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@ -155,8 +155,6 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0 h1:TLkBREm4nIsEcexnCjgQd5GQWaHcqMzwQV0TX9pq8S0=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0/go.mod h1:DNq5QpG7LJqD2AamLZ7zvKE0DEpVl2BSEVjFycAAjRY=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -167,12 +165,10 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=

View File

@ -2,8 +2,12 @@ package grpcserver
import ( import (
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/infrastructure/logger" "github.com/kaspanet/kaspad/infrastructure/logger"
"io" "io"
"os"
"strconv"
"sync"
"time" "time"
routerpkg "github.com/kaspanet/kaspad/infrastructure/network/netadapter/router" routerpkg "github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
@ -25,6 +29,9 @@ func (c *gRPCConnection) connectionLoops() error {
return err return err
} }
var blockDelayOnce sync.Once
var blockDelay = 0
func (c *gRPCConnection) sendLoop() error { func (c *gRPCConnection) sendLoop() error {
outgoingRoute := c.router.OutgoingRoute() outgoingRoute := c.router.OutgoingRoute()
for c.IsConnected() { for c.IsConnected() {
@ -36,6 +43,20 @@ func (c *gRPCConnection) sendLoop() error {
return err return err
} }
blockDelayOnce.Do(func() {
experimentalDelayEnv := os.Getenv("KASPA_EXPERIMENTAL_DELAY")
if experimentalDelayEnv != "" {
blockDelay, err = strconv.Atoi(experimentalDelayEnv)
if err != nil {
panic(err)
}
}
})
if blockDelay != 0 && message.Command() == appmessage.CmdBlock {
time.Sleep(time.Duration(blockDelay) * time.Second)
}
log.Debugf("outgoing '%s' message to %s", message.Command(), c) log.Debugf("outgoing '%s' message to %s", message.Command(), c)
log.Tracef("outgoing '%s' message to %s: %s", message.Command(), c, logger.NewLogClosure(func() string { log.Tracef("outgoing '%s' message to %s: %s", message.Command(), c, logger.NewLogClosure(func() string {
return spew.Sdump(message) return spew.Sdump(message)

View File

@ -35,7 +35,7 @@ func (x *KaspadMessage_GetConnectedPeerInfoResponse) fromAppMessage(message *app
TimeOffset: info.TimeOffset, TimeOffset: info.TimeOffset,
UserAgent: info.UserAgent, UserAgent: info.UserAgent,
AdvertisedProtocolVersion: info.AdvertisedProtocolVersion, AdvertisedProtocolVersion: info.AdvertisedProtocolVersion,
TimeConnected: info.TimeOffset, TimeConnected: info.TimeConnected,
IsIbdPeer: info.IsIBDPeer, IsIbdPeer: info.IsIBDPeer,
} }
} }

View File

@ -72,7 +72,7 @@ func (c *RPCClient) connect() error {
remoteVersion := getInfoResponse.ServerVersion remoteVersion := getInfoResponse.ServerVersion
if localVersion != remoteVersion { if localVersion != remoteVersion {
return errors.Errorf("Server version mismatch, expect: %s, got: %s", localVersion, remoteVersion) log.Warnf("version mismatch, client: %s, server: %s - expected responses and requests may deviate", localVersion, remoteVersion)
} }
return nil return nil

View File

@ -11,7 +11,7 @@ const validCharacters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrs
const ( const (
appMajor uint = 0 appMajor uint = 0
appMinor uint = 12 appMinor uint = 12
appPatch uint = 6 appPatch uint = 8
) )
// appBuild is defined as a variable so it can be overridden during the build // appBuild is defined as a variable so it can be overridden during the build