mirror of
https://github.com/kaspanet/kaspad.git
synced 2026-02-22 11:39:15 +00:00
Compare commits
1 Commits
someone235
...
rust-ref
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
242513c5a2 |
@@ -7,6 +7,8 @@ Kaspad
|
||||
|
||||
Kaspad is the reference full node Kaspa implementation written in Go (golang).
|
||||
|
||||
This project is currently under active development and is in Beta state.
|
||||
|
||||
## What is kaspa
|
||||
|
||||
Kaspa is an attempt at a proof-of-work cryptocurrency with instant confirmations and sub-second block times. It is based on [the PHANTOM protocol](https://eprint.iacr.org/2018/104.pdf), a generalization of Nakamoto consensus.
|
||||
|
||||
@@ -133,8 +133,8 @@ func TestTx(t *testing.T) {
|
||||
|
||||
// TestTxHash tests the ability to generate the hash of a transaction accurately.
|
||||
func TestTxHashAndID(t *testing.T) {
|
||||
txHash1Str := "b06f8b650115b5cf4d59499e10764a9312742930cb43c9b4ff6495d76f332ed7"
|
||||
txID1Str := "e20225c3d065ee41743607ee627db44d01ef396dc9779b05b2caf55bac50e12d"
|
||||
txHash1Str := "93663e597f6c968d32d229002f76408edf30d6a0151ff679fc729812d8cb2acc"
|
||||
txID1Str := "24079c6d2bdf602fc389cc307349054937744a9c8dc0f07c023e6af0e949a4e7"
|
||||
wantTxID1, err := transactionid.FromString(txID1Str)
|
||||
if err != nil {
|
||||
t.Fatalf("NewTxIDFromStr: %v", err)
|
||||
@@ -185,7 +185,7 @@ func TestTxHashAndID(t *testing.T) {
|
||||
spew.Sprint(tx1ID), spew.Sprint(wantTxID1))
|
||||
}
|
||||
|
||||
hash2Str := "fa16a8ce88d52ca1ff45187bbba0d33044e9f5fe309e8d0b22d4812dcf1782b7"
|
||||
hash2Str := "8dafd1bec24527d8e3b443ceb0a3b92fffc0d60026317f890b2faf5e9afc177a"
|
||||
wantHash2, err := externalapi.NewDomainHashFromString(hash2Str)
|
||||
if err != nil {
|
||||
t.Errorf("NewTxIDFromStr: %v", err)
|
||||
|
||||
@@ -27,15 +27,18 @@ func HandleIBDBlockRequests(context HandleIBDBlockRequestsContext, incomingRoute
|
||||
log.Debugf("Got request for %d ibd blocks", len(msgRequestIBDBlocks.Hashes))
|
||||
for i, hash := range msgRequestIBDBlocks.Hashes {
|
||||
// Fetch the block from the database.
|
||||
block, found, err := context.Domain().Consensus().GetBlock(hash)
|
||||
blockInfo, err := context.Domain().Consensus().GetBlockInfo(hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !blockInfo.HasBody() {
|
||||
return protocolerrors.Errorf(true, "block %s not found (v5)", hash)
|
||||
}
|
||||
block, err := context.Domain().Consensus().GetBlock(hash)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unable to fetch requested block hash %s", hash)
|
||||
}
|
||||
|
||||
if !found {
|
||||
return protocolerrors.Errorf(false, "IBD block %s not found", hash)
|
||||
}
|
||||
|
||||
// TODO (Partial nodes): Convert block to partial block if needed
|
||||
|
||||
blockMessage := appmessage.DomainBlockToMsgBlock(block)
|
||||
|
||||
@@ -119,15 +119,11 @@ func HandlePruningPointAndItsAnticoneRequests(context PruningPointAndItsAnticone
|
||||
}
|
||||
|
||||
for i, blockHash := range pointAndItsAnticone {
|
||||
block, found, err := context.Domain().Consensus().GetBlock(blockHash)
|
||||
block, err := context.Domain().Consensus().GetBlock(blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !found {
|
||||
return protocolerrors.Errorf(false, "pruning point anticone block %s not found", blockHash)
|
||||
}
|
||||
|
||||
err = outgoingRoute.Enqueue(appmessage.DomainBlockWithTrustedDataToBlockWithTrustedDataV4(block, trustedDataDAABlockIndexes[*blockHash], trustedDataGHOSTDAGDataIndexes[*blockHash]))
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -28,15 +28,18 @@ func HandleRelayBlockRequests(context RelayBlockRequestsContext, incomingRoute *
|
||||
log.Debugf("Got request for relay blocks with hashes %s", getRelayBlocksMessage.Hashes)
|
||||
for _, hash := range getRelayBlocksMessage.Hashes {
|
||||
// Fetch the block from the database.
|
||||
block, found, err := context.Domain().Consensus().GetBlock(hash)
|
||||
blockInfo, err := context.Domain().Consensus().GetBlockInfo(hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !blockInfo.HasBody() {
|
||||
return protocolerrors.Errorf(true, "block %s not found", hash)
|
||||
}
|
||||
block, err := context.Domain().Consensus().GetBlock(hash)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unable to fetch requested block hash %s", hash)
|
||||
}
|
||||
|
||||
if !found {
|
||||
return protocolerrors.Errorf(false, "Relay block %s not found", hash)
|
||||
}
|
||||
|
||||
// TODO (Partial nodes): Convert block to partial block if needed
|
||||
|
||||
err = outgoingRoute.Enqueue(appmessage.DomainBlockToMsgBlock(block))
|
||||
|
||||
@@ -211,14 +211,10 @@ func (flow *handleRelayInvsFlow) start() error {
|
||||
continue
|
||||
}
|
||||
virtualHasNewParents = true
|
||||
block, found, err := flow.Domain().Consensus().GetBlock(parent)
|
||||
block, err := flow.Domain().Consensus().GetBlock(parent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !found {
|
||||
return protocolerrors.Errorf(false, "Virtual parent %s not found", parent)
|
||||
}
|
||||
blockHash := consensushashing.BlockHash(block)
|
||||
log.Debugf("Relaying block %s", blockHash)
|
||||
err = flow.relayBlock(block)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package blockrelay
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/app/protocol/common"
|
||||
peerpkg "github.com/kaspanet/kaspad/app/protocol/peer"
|
||||
@@ -71,17 +70,16 @@ func (flow *handleIBDFlow) runIBDIfNotRunning(block *externalapi.DomainBlock) er
|
||||
}
|
||||
|
||||
isFinishedSuccessfully := false
|
||||
var err error
|
||||
defer func() {
|
||||
flow.UnsetIBDRunning()
|
||||
flow.logIBDFinished(isFinishedSuccessfully, err)
|
||||
flow.logIBDFinished(isFinishedSuccessfully)
|
||||
}()
|
||||
|
||||
relayBlockHash := consensushashing.BlockHash(block)
|
||||
|
||||
log.Infof("IBD started with peer %s and relayBlockHash %s", flow.peer, relayBlockHash)
|
||||
log.Infof("Syncing blocks up to %s", relayBlockHash)
|
||||
log.Infof("Trying to find highest known syncer chain block from peer %s with relay hash %s", flow.peer, relayBlockHash)
|
||||
log.Debugf("IBD started with peer %s and relayBlockHash %s", flow.peer, relayBlockHash)
|
||||
log.Debugf("Syncing blocks up to %s", relayBlockHash)
|
||||
log.Debugf("Trying to find highest known syncer chain block from peer %s with relay hash %s", flow.peer, relayBlockHash)
|
||||
|
||||
syncerHeaderSelectedTipHash, highestKnownSyncerChainHash, err := flow.negotiateMissingSyncerChainSegment()
|
||||
if err != nil {
|
||||
@@ -100,7 +98,7 @@ func (flow *handleIBDFlow) runIBDIfNotRunning(block *externalapi.DomainBlock) er
|
||||
|
||||
if shouldDownloadHeadersProof {
|
||||
log.Infof("Starting IBD with headers proof")
|
||||
err = flow.ibdWithHeadersProof(syncerHeaderSelectedTipHash, relayBlockHash, block.Header.DAAScore())
|
||||
err := flow.ibdWithHeadersProof(syncerHeaderSelectedTipHash, relayBlockHash, block.Header.DAAScore())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -183,10 +181,6 @@ func (flow *handleIBDFlow) negotiateMissingSyncerChainSegment() (*externalapi.Do
|
||||
return nil, nil, err
|
||||
}
|
||||
if info.Exists {
|
||||
if info.BlockStatus == externalapi.StatusInvalid {
|
||||
return nil, nil, protocolerrors.Errorf(true, "Sent invalid chain block %s", syncerChainHash)
|
||||
}
|
||||
|
||||
currentHighestKnownSyncerChainHash = syncerChainHash
|
||||
break
|
||||
}
|
||||
@@ -267,7 +261,7 @@ func (flow *handleIBDFlow) negotiateMissingSyncerChainSegment() (*externalapi.Do
|
||||
}
|
||||
}
|
||||
|
||||
log.Infof("Found highest known syncer chain block %s from peer %s",
|
||||
log.Debugf("Found highest known syncer chain block %s from peer %s",
|
||||
highestKnownSyncerChainHash, flow.peer)
|
||||
|
||||
return syncerHeaderSelectedTipHash, highestKnownSyncerChainHash, nil
|
||||
@@ -282,10 +276,10 @@ func (flow *handleIBDFlow) isGenesisVirtualSelectedParent() (bool, error) {
|
||||
return virtualSelectedParent.Equal(flow.Config().NetParams().GenesisHash), nil
|
||||
}
|
||||
|
||||
func (flow *handleIBDFlow) logIBDFinished(isFinishedSuccessfully bool, err error) {
|
||||
func (flow *handleIBDFlow) logIBDFinished(isFinishedSuccessfully bool) {
|
||||
successString := "successfully"
|
||||
if !isFinishedSuccessfully {
|
||||
successString = fmt.Sprintf("(interrupted: %s)", err)
|
||||
successString = "(interrupted)"
|
||||
}
|
||||
log.Infof("IBD with peer %s finished %s", flow.peer, successString)
|
||||
}
|
||||
@@ -624,12 +618,6 @@ func (flow *handleIBDFlow) syncMissingBlockBodies(highHash *externalapi.DomainHa
|
||||
progressReporter := newIBDProgressReporter(lowBlockHeader.DAAScore(), highBlockHeader.DAAScore(), "blocks")
|
||||
highestProcessedDAAScore := lowBlockHeader.DAAScore()
|
||||
|
||||
// If the IBD is small, we want to update the virtual after each block in order to avoid complications and possible bugs.
|
||||
updateVirtual, err := flow.Domain().Consensus().IsNearlySynced()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for offset := 0; offset < len(hashes); offset += ibdBatchSize {
|
||||
var hashesToRequest []*externalapi.DomainHash
|
||||
if offset+ibdBatchSize < len(hashes) {
|
||||
@@ -666,7 +654,7 @@ func (flow *handleIBDFlow) syncMissingBlockBodies(highHash *externalapi.DomainHa
|
||||
return err
|
||||
}
|
||||
|
||||
err = flow.Domain().Consensus().ValidateAndInsertBlock(block, updateVirtual)
|
||||
err = flow.Domain().Consensus().ValidateAndInsertBlock(block, false)
|
||||
if err != nil {
|
||||
if errors.Is(err, ruleerrors.ErrDuplicateBlock) {
|
||||
log.Debugf("Skipping IBD Block %s as it has already been added to the DAG", blockHash)
|
||||
@@ -685,15 +673,7 @@ func (flow *handleIBDFlow) syncMissingBlockBodies(highHash *externalapi.DomainHa
|
||||
progressReporter.reportProgress(len(hashesToRequest), highestProcessedDAAScore)
|
||||
}
|
||||
|
||||
// We need to resolve virtual only if it wasn't updated while syncing block bodies
|
||||
if !updateVirtual {
|
||||
err := flow.resolveVirtual(highestProcessedDAAScore)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return flow.OnNewBlockTemplate()
|
||||
return flow.resolveVirtual(highestProcessedDAAScore)
|
||||
}
|
||||
|
||||
func (flow *handleIBDFlow) banIfBlockIsHeaderOnly(block *externalapi.DomainBlock) error {
|
||||
@@ -725,5 +705,9 @@ func (flow *handleIBDFlow) resolveVirtual(estimatedVirtualDAAScoreTarget uint64)
|
||||
}
|
||||
|
||||
log.Infof("Resolved virtual")
|
||||
err = flow.OnNewBlockTemplate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ func (flow *handleIBDFlow) ibdWithHeadersProof(
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("IBD with pruning proof from %s was unsuccessful. Deleting the staging consensus. (%s)", flow.peer, err)
|
||||
log.Infof("IBD with pruning proof from %s was unsuccessful. Deleting the staging consensus.", flow.peer)
|
||||
deleteStagingConsensusErr := flow.Domain().DeleteStagingConsensus()
|
||||
if deleteStagingConsensusErr != nil {
|
||||
return deleteStagingConsensusErr
|
||||
@@ -55,12 +55,7 @@ func (flow *handleIBDFlow) shouldSyncAndShouldDownloadHeadersProof(
|
||||
|
||||
var highestSharedBlockFound, isPruningPointInSharedBlockChain bool
|
||||
if highestKnownSyncerChainHash != nil {
|
||||
blockInfo, err := flow.Domain().Consensus().GetBlockInfo(highestKnownSyncerChainHash)
|
||||
if err != nil {
|
||||
return false, false, err
|
||||
}
|
||||
|
||||
highestSharedBlockFound = blockInfo.HasBody()
|
||||
highestSharedBlockFound = true
|
||||
pruningPoint, err := flow.Domain().Consensus().PruningPoint()
|
||||
if err != nil {
|
||||
return false, false, err
|
||||
@@ -92,21 +87,21 @@ func (flow *handleIBDFlow) shouldSyncAndShouldDownloadHeadersProof(
|
||||
}
|
||||
|
||||
func (flow *handleIBDFlow) checkIfHighHashHasMoreBlueWorkThanSelectedTipAndPruningDepthMoreBlueScore(relayBlock *externalapi.DomainBlock) (bool, error) {
|
||||
virtualSelectedParent, err := flow.Domain().Consensus().GetVirtualSelectedParent()
|
||||
headersSelectedTip, err := flow.Domain().Consensus().GetHeadersSelectedTip()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
virtualSelectedTipInfo, err := flow.Domain().Consensus().GetBlockInfo(virtualSelectedParent)
|
||||
headersSelectedTipInfo, err := flow.Domain().Consensus().GetBlockInfo(headersSelectedTip)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if relayBlock.Header.BlueScore() < virtualSelectedTipInfo.BlueScore+flow.Config().NetParams().PruningDepth() {
|
||||
if relayBlock.Header.BlueScore() < headersSelectedTipInfo.BlueScore+flow.Config().NetParams().PruningDepth() {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return relayBlock.Header.BlueWork().Cmp(virtualSelectedTipInfo.BlueWork) > 0, nil
|
||||
return relayBlock.Header.BlueWork().Cmp(headersSelectedTipInfo.BlueWork) > 0, nil
|
||||
}
|
||||
|
||||
func (flow *handleIBDFlow) syncAndValidatePruningPointProof() (*externalapi.DomainHash, error) {
|
||||
|
||||
@@ -122,7 +122,6 @@ func (ctx *Context) PopulateTransactionWithVerboseData(
|
||||
}
|
||||
|
||||
ctx.Domain.Consensus().PopulateMass(domainTransaction)
|
||||
|
||||
transaction.VerboseData = &appmessage.RPCTransactionVerboseData{
|
||||
TransactionID: consensushashing.TransactionID(domainTransaction).String(),
|
||||
Hash: consensushashing.TransactionHash(domainTransaction).String(),
|
||||
|
||||
@@ -37,7 +37,7 @@ func HandleGetBlocks(context *rpccontext.Context, _ *router.Router, request appm
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !blockInfo.HasHeader() {
|
||||
if !blockInfo.Exists {
|
||||
return &appmessage.GetBlocksResponseMessage{
|
||||
Error: appmessage.RPCErrorf("Could not find lowHash %s", getBlocksRequest.LowHash),
|
||||
}, nil
|
||||
|
||||
@@ -1,34 +1,3 @@
|
||||
Kaspad v0.12.9 - 2022-10-23
|
||||
===========================
|
||||
|
||||
* Create directory before locking lock file (#2160)
|
||||
|
||||
Kaspad v0.12.8 - 2022-10-23
|
||||
===========================
|
||||
|
||||
* Remove hard fork activation rules (#2152)
|
||||
* Add lock file to kaspawallet (#2154)
|
||||
* Add a new testnet DNS seeder (#2156)
|
||||
* Use utxo diff algo for pruning point move and use acceptance data method only as a fall-back (#2157)
|
||||
* Make more checks if status is invalid even if the block exists (#2158)
|
||||
|
||||
|
||||
Kaspad v0.12.7 - 2022-09-21
|
||||
===========================
|
||||
|
||||
* Security Fix + Hard fork - Full details can be seen here: https://medium.com/@michaelsuttonil/kaspa-security-patch-and-hard-fork-september-2022-12da617b0094
|
||||
|
||||
Kaspad v0.12.6 - 2022-09-09
|
||||
===========================
|
||||
|
||||
* Remove tests from docker files (#2133)
|
||||
|
||||
Wallet new features:
|
||||
* Optionally show serialized transactions on send (#2135)
|
||||
|
||||
Bug fixes:
|
||||
* Update virtual on IBD if nearly synced (#2134)
|
||||
|
||||
Kaspad v0.12.5 - 2022-08-28
|
||||
===========================
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ RUN mkdir -p /go/src/github.com/kaspanet/kaspad
|
||||
WORKDIR /go/src/github.com/kaspanet/kaspad
|
||||
|
||||
RUN apk add --no-cache curl git openssh binutils gcc musl-dev
|
||||
RUN go get -u golang.org/x/lint/golint \
|
||||
honnef.co/go/tools/cmd/staticcheck
|
||||
|
||||
COPY go.mod .
|
||||
COPY go.sum .
|
||||
@@ -16,6 +18,10 @@ COPY . .
|
||||
|
||||
WORKDIR /go/src/github.com/kaspanet/kaspad/cmd/kaspactl
|
||||
|
||||
RUN GOFMT_RESULT=`go fmt ./...`; echo $GOFMT_RESULT; test -z "$GOFMT_RESULT"
|
||||
RUN go vet ./...
|
||||
RUN golint -set_exit_status ./...
|
||||
RUN staticcheck -checks SA4006 ./...
|
||||
RUN GOOS=linux go build -a -installsuffix cgo -o kaspactl .
|
||||
|
||||
# --- multistage docker build: stage #2: runtime image
|
||||
|
||||
@@ -6,6 +6,8 @@ RUN mkdir -p /go/src/github.com/kaspanet/kaspad
|
||||
WORKDIR /go/src/github.com/kaspanet/kaspad
|
||||
|
||||
RUN apk add --no-cache curl git openssh binutils gcc musl-dev
|
||||
RUN go get -u golang.org/x/lint/golint \
|
||||
honnef.co/go/tools/cmd/staticcheck
|
||||
|
||||
COPY go.mod .
|
||||
COPY go.sum .
|
||||
@@ -15,6 +17,11 @@ RUN go mod download
|
||||
COPY . .
|
||||
|
||||
WORKDIR /go/src/github.com/kaspanet/kaspad/cmd/kaspaminer
|
||||
|
||||
RUN GOFMT_RESULT=`go fmt ./...`; echo $GOFMT_RESULT; test -z "$GOFMT_RESULT"
|
||||
RUN go vet ./...
|
||||
RUN golint -set_exit_status ./...
|
||||
RUN staticcheck -checks SA4006 ./...
|
||||
RUN GOOS=linux go build -a -installsuffix cgo -o kaspaminer .
|
||||
|
||||
# --- multistage docker build: stage #2: runtime image
|
||||
|
||||
@@ -59,7 +59,6 @@ type sendConfig struct {
|
||||
FromAddresses []string `long:"from-address" short:"a" description:"Specific public address to send Kaspa from. Use multiple times to accept several addresses" required:"false"`
|
||||
SendAmount float64 `long:"send-amount" short:"v" description:"An amount to send in Kaspa (e.g. 1234.12345678)" required:"true"`
|
||||
UseExistingChangeAddress bool `long:"use-existing-change-address" short:"u" description:"Will use an existing change address (in case no change address was ever used, it will use a new one)"`
|
||||
Verbose bool `long:"show-serialized" short:"s" description:"Show a list of hex encoded sent transactions"`
|
||||
config.NetworkFlags
|
||||
}
|
||||
|
||||
|
||||
@@ -78,11 +78,6 @@ func create(conf *createConfig) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = file.TryLock()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = file.Save()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -2,7 +2,6 @@ package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/server"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@@ -17,7 +16,7 @@ func Connect(address string) (pb.KaspawalletdClient, func(), error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
defer cancel()
|
||||
|
||||
conn, err := grpc.DialContext(ctx, address, grpc.WithInsecure(), grpc.WithBlock(), grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(server.MaxDaemonSendMsgSize)))
|
||||
conn, err := grpc.DialContext(ctx, address, grpc.WithInsecure(), grpc.WithBlock())
|
||||
if err != nil {
|
||||
if errors.Is(err, context.DeadlineExceeded) {
|
||||
return nil, nil, errors.New("kaspawallet daemon is not running, start it with `kaspawallet start-daemon`")
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc v3.12.3
|
||||
// source: kaspawalletd.proto
|
||||
|
||||
package pb
|
||||
|
||||
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 GetBalanceRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -1073,8 +1078,7 @@ type SendResponse struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
TxIDs []string `protobuf:"bytes,1,rep,name=txIDs,proto3" json:"txIDs,omitempty"`
|
||||
SignedTransactions [][]byte `protobuf:"bytes,2,rep,name=signedTransactions,proto3" json:"signedTransactions,omitempty"`
|
||||
TxIDs []string `protobuf:"bytes,1,rep,name=txIDs,proto3" json:"txIDs,omitempty"`
|
||||
}
|
||||
|
||||
func (x *SendResponse) Reset() {
|
||||
@@ -1116,13 +1120,6 @@ func (x *SendResponse) GetTxIDs() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *SendResponse) GetSignedTransactions() [][]byte {
|
||||
if x != nil {
|
||||
return x.SignedTransactions
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Since SignRequest contains a password - this command should only be used on a trusted or secure connection
|
||||
type SignRequest struct {
|
||||
state protoimpl.MessageState
|
||||
@@ -1336,12 +1333,9 @@ var file_kaspawalletd_proto_rawDesc = []byte{
|
||||
0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x41, 0x64, 0x64, 0x72,
|
||||
0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x75, 0x73, 0x65, 0x45, 0x78,
|
||||
0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x41, 0x64, 0x64, 0x72,
|
||||
0x65, 0x73, 0x73, 0x22, 0x54, 0x0a, 0x0c, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x65, 0x73, 0x73, 0x22, 0x24, 0x0a, 0x0c, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x78, 0x49, 0x44, 0x73, 0x18, 0x01, 0x20, 0x03,
|
||||
0x28, 0x09, 0x52, 0x05, 0x74, 0x78, 0x49, 0x44, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x73, 0x69, 0x67,
|
||||
0x6e, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18,
|
||||
0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x12, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61,
|
||||
0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x5d, 0x0a, 0x0b, 0x53, 0x69, 0x67,
|
||||
0x28, 0x09, 0x52, 0x05, 0x74, 0x78, 0x49, 0x44, 0x73, 0x22, 0x5d, 0x0a, 0x0b, 0x53, 0x69, 0x67,
|
||||
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x14, 0x75, 0x6e, 0x73, 0x69,
|
||||
0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73,
|
||||
0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x14, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64,
|
||||
|
||||
@@ -113,7 +113,6 @@ message SendRequest{
|
||||
|
||||
message SendResponse{
|
||||
repeated string txIDs = 1;
|
||||
repeated bytes signedTransactions = 2;
|
||||
}
|
||||
|
||||
// Since SignRequest contains a password - this command should only be used on a trusted or secure connection
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.2.0
|
||||
// - protoc v3.12.3
|
||||
// source: kaspawalletd.proto
|
||||
|
||||
package pb
|
||||
|
||||
@@ -15,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
|
||||
|
||||
// KaspawalletdClient is the client API for Kaspawalletd service.
|
||||
//
|
||||
@@ -146,44 +141,37 @@ type KaspawalletdServer interface {
|
||||
type UnimplementedKaspawalletdServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedKaspawalletdServer) GetBalance(context.Context, *GetBalanceRequest) (*GetBalanceResponse, error) {
|
||||
func (*UnimplementedKaspawalletdServer) GetBalance(context.Context, *GetBalanceRequest) (*GetBalanceResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetBalance not implemented")
|
||||
}
|
||||
func (UnimplementedKaspawalletdServer) GetExternalSpendableUTXOs(context.Context, *GetExternalSpendableUTXOsRequest) (*GetExternalSpendableUTXOsResponse, error) {
|
||||
func (*UnimplementedKaspawalletdServer) GetExternalSpendableUTXOs(context.Context, *GetExternalSpendableUTXOsRequest) (*GetExternalSpendableUTXOsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetExternalSpendableUTXOs not implemented")
|
||||
}
|
||||
func (UnimplementedKaspawalletdServer) CreateUnsignedTransactions(context.Context, *CreateUnsignedTransactionsRequest) (*CreateUnsignedTransactionsResponse, error) {
|
||||
func (*UnimplementedKaspawalletdServer) CreateUnsignedTransactions(context.Context, *CreateUnsignedTransactionsRequest) (*CreateUnsignedTransactionsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CreateUnsignedTransactions not implemented")
|
||||
}
|
||||
func (UnimplementedKaspawalletdServer) ShowAddresses(context.Context, *ShowAddressesRequest) (*ShowAddressesResponse, error) {
|
||||
func (*UnimplementedKaspawalletdServer) ShowAddresses(context.Context, *ShowAddressesRequest) (*ShowAddressesResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ShowAddresses not implemented")
|
||||
}
|
||||
func (UnimplementedKaspawalletdServer) NewAddress(context.Context, *NewAddressRequest) (*NewAddressResponse, error) {
|
||||
func (*UnimplementedKaspawalletdServer) NewAddress(context.Context, *NewAddressRequest) (*NewAddressResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method NewAddress not implemented")
|
||||
}
|
||||
func (UnimplementedKaspawalletdServer) Shutdown(context.Context, *ShutdownRequest) (*ShutdownResponse, error) {
|
||||
func (*UnimplementedKaspawalletdServer) Shutdown(context.Context, *ShutdownRequest) (*ShutdownResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Shutdown not implemented")
|
||||
}
|
||||
func (UnimplementedKaspawalletdServer) Broadcast(context.Context, *BroadcastRequest) (*BroadcastResponse, error) {
|
||||
func (*UnimplementedKaspawalletdServer) Broadcast(context.Context, *BroadcastRequest) (*BroadcastResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Broadcast not implemented")
|
||||
}
|
||||
func (UnimplementedKaspawalletdServer) Send(context.Context, *SendRequest) (*SendResponse, error) {
|
||||
func (*UnimplementedKaspawalletdServer) Send(context.Context, *SendRequest) (*SendResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Send not implemented")
|
||||
}
|
||||
func (UnimplementedKaspawalletdServer) Sign(context.Context, *SignRequest) (*SignResponse, error) {
|
||||
func (*UnimplementedKaspawalletdServer) Sign(context.Context, *SignRequest) (*SignResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Sign not implemented")
|
||||
}
|
||||
func (UnimplementedKaspawalletdServer) mustEmbedUnimplementedKaspawalletdServer() {}
|
||||
func (*UnimplementedKaspawalletdServer) mustEmbedUnimplementedKaspawalletdServer() {}
|
||||
|
||||
// UnsafeKaspawalletdServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to KaspawalletdServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeKaspawalletdServer interface {
|
||||
mustEmbedUnimplementedKaspawalletdServer()
|
||||
}
|
||||
|
||||
func RegisterKaspawalletdServer(s grpc.ServiceRegistrar, srv KaspawalletdServer) {
|
||||
s.RegisterService(&Kaspawalletd_ServiceDesc, srv)
|
||||
func RegisterKaspawalletdServer(s *grpc.Server, srv KaspawalletdServer) {
|
||||
s.RegisterService(&_Kaspawalletd_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _Kaspawalletd_GetBalance_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
@@ -348,10 +336,7 @@ func _Kaspawalletd_Sign_Handler(srv interface{}, ctx context.Context, dec func(i
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// Kaspawalletd_ServiceDesc is the grpc.ServiceDesc for Kaspawalletd service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var Kaspawalletd_ServiceDesc = grpc.ServiceDesc{
|
||||
var _Kaspawalletd_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "kaspawalletd.kaspawalletd",
|
||||
HandlerType: (*KaspawalletdServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
|
||||
@@ -10,33 +10,27 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (s *server) changeAddress(useExisting bool, fromAddresses []*walletAddress) (util.Address, *walletAddress, error) {
|
||||
var walletAddr *walletAddress
|
||||
if len(fromAddresses) != 0 && useExisting {
|
||||
walletAddr = fromAddresses[0]
|
||||
} else {
|
||||
internalIndex := uint32(0)
|
||||
if !useExisting {
|
||||
err := s.keysFile.SetLastUsedInternalIndex(s.keysFile.LastUsedInternalIndex() + 1)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
err = s.keysFile.Save()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
internalIndex = s.keysFile.LastUsedInternalIndex()
|
||||
func (s *server) changeAddress(useFirst bool) (util.Address, *walletAddress, error) {
|
||||
internalIndex := uint32(0)
|
||||
if !useFirst {
|
||||
err := s.keysFile.SetLastUsedInternalIndex(s.keysFile.LastUsedInternalIndex() + 1)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
walletAddr = &walletAddress{
|
||||
index: internalIndex,
|
||||
cosignerIndex: s.keysFile.CosignerIndex,
|
||||
keyChain: libkaspawallet.InternalKeychain,
|
||||
err = s.keysFile.Save()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
internalIndex = s.keysFile.LastUsedInternalIndex()
|
||||
}
|
||||
|
||||
walletAddr := &walletAddress{
|
||||
index: internalIndex,
|
||||
cosignerIndex: s.keysFile.CosignerIndex,
|
||||
keyChain: libkaspawallet.InternalKeychain,
|
||||
}
|
||||
path := s.walletAddressPath(walletAddr)
|
||||
address, err := libkaspawallet.Address(s.params, s.keysFile.ExtendedPublicKeys, s.keysFile.MinimumSignatures, path, s.keysFile.ECDSA)
|
||||
if err != nil {
|
||||
|
||||
@@ -61,7 +61,7 @@ func (s *server) createUnsignedTransactions(address string, amount uint64, fromA
|
||||
return nil, err
|
||||
}
|
||||
|
||||
changeAddress, changeWalletAddress, err := s.changeAddress(useExistingChangeAddress, fromAddresses)
|
||||
changeAddress, changeWalletAddress, err := s.changeAddress(useExistingChangeAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -25,5 +25,5 @@ func (s *server) Send(_ context.Context, request *pb.SendRequest) (*pb.SendRespo
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.SendResponse{TxIDs: txIDs, SignedTransactions: signedTransactions}, nil
|
||||
return &pb.SendResponse{TxIDs: txIDs}, nil
|
||||
}
|
||||
|
||||
@@ -44,10 +44,6 @@ type server struct {
|
||||
maxProcessedAddressesForLog uint32
|
||||
}
|
||||
|
||||
// MaxDaemonSendMsgSize is the max send message size used for the daemon server.
|
||||
// Currently, set to 100MB
|
||||
const MaxDaemonSendMsgSize = 100_000_000
|
||||
|
||||
// Start starts the kaspawalletd server
|
||||
func Start(params *dagconfig.Params, listen, rpcServer string, keysFilePath string, profile string, timeout uint32) error {
|
||||
initLog(defaultLogFile, defaultErrLogFile)
|
||||
@@ -77,11 +73,6 @@ func Start(params *dagconfig.Params, listen, rpcServer string, keysFilePath stri
|
||||
return (errors.Wrapf(err, "Error reading keys file %s", keysFilePath))
|
||||
}
|
||||
|
||||
err = keysFile.TryLock()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
serverInstance := &server{
|
||||
rpcClient: rpcClient,
|
||||
params: params,
|
||||
@@ -105,7 +96,7 @@ func Start(params *dagconfig.Params, listen, rpcServer string, keysFilePath stri
|
||||
}
|
||||
})
|
||||
|
||||
grpcServer := grpc.NewServer(grpc.MaxSendMsgSize(MaxDaemonSendMsgSize))
|
||||
grpcServer := grpc.NewServer()
|
||||
pb.RegisterKaspawalletdServer(grpcServer, serverInstance)
|
||||
|
||||
spawn("grpcServer.Serve", func() {
|
||||
|
||||
@@ -121,7 +121,7 @@ func testEstimateMassIncreaseForSignaturesSetUp(t *testing.T, consensusConfig *c
|
||||
t.Fatalf("AddBlock: %+v", err)
|
||||
}
|
||||
|
||||
block1, _, err := tc.GetBlock(block1Hash)
|
||||
block1, err := tc.GetBlock(block1Hash)
|
||||
if err != nil {
|
||||
t.Fatalf("GetBlock: %+v", err)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/gofrs/flock"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
@@ -401,33 +400,3 @@ func decryptMnemonic(numThreads uint8, encryptedPrivateKey *EncryptedMnemonic, p
|
||||
|
||||
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")
|
||||
err := createFileDirectoryIfDoesntExist(lockFile.Path())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ func TestMultisig(t *testing.T) {
|
||||
t.Fatalf("AddBlock: %+v", err)
|
||||
}
|
||||
|
||||
block1, _, err := tc.GetBlock(block1Hash)
|
||||
block1, err := tc.GetBlock(block1Hash)
|
||||
if err != nil {
|
||||
t.Fatalf("GetBlock: %+v", err)
|
||||
}
|
||||
@@ -245,7 +245,7 @@ func TestP2PK(t *testing.T) {
|
||||
t.Fatalf("AddBlock: %+v", err)
|
||||
}
|
||||
|
||||
block1, _, err := tc.GetBlock(block1Hash)
|
||||
block1, err := tc.GetBlock(block1Hash)
|
||||
if err != nil {
|
||||
t.Fatalf("GetBlock: %+v", err)
|
||||
}
|
||||
@@ -377,17 +377,17 @@ func TestMaxSompi(t *testing.T) {
|
||||
t.Fatalf("AddBlock: %+v", err)
|
||||
}
|
||||
|
||||
fundingBlock2, _, err := tc.GetBlock(fundingBlock2Hash)
|
||||
fundingBlock2, err := tc.GetBlock(fundingBlock2Hash)
|
||||
if err != nil {
|
||||
t.Fatalf("GetBlock: %+v", err)
|
||||
}
|
||||
|
||||
fundingBlock3, _, err := tc.GetBlock(fundingBlock3Hash)
|
||||
fundingBlock3, err := tc.GetBlock(fundingBlock3Hash)
|
||||
if err != nil {
|
||||
t.Fatalf("GetBlock: %+v", err)
|
||||
}
|
||||
|
||||
fundingBlock4, _, err := tc.GetBlock(fundingBlock4Hash)
|
||||
fundingBlock4, err := tc.GetBlock(fundingBlock4Hash)
|
||||
if err != nil {
|
||||
t.Fatalf("GetBlock: %+v", err)
|
||||
}
|
||||
@@ -397,7 +397,7 @@ func TestMaxSompi(t *testing.T) {
|
||||
t.Fatalf("AddBlock: %+v", err)
|
||||
}
|
||||
|
||||
block1, _, err := tc.GetBlock(block1Hash)
|
||||
block1, err := tc.GetBlock(block1Hash)
|
||||
if err != nil {
|
||||
t.Fatalf("GetBlock: %+v", err)
|
||||
}
|
||||
|
||||
@@ -3,8 +3,6 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/client"
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
|
||||
@@ -51,10 +49,6 @@ func send(conf *sendConfig) error {
|
||||
}
|
||||
mnemonics, err := keysFile.DecryptMnemonics(conf.Password)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -86,12 +80,5 @@ func send(conf *sendConfig) error {
|
||||
fmt.Printf("\t%s\n", txID)
|
||||
}
|
||||
|
||||
if conf.Verbose {
|
||||
fmt.Println("Serialized Transaction(s) (can be parsed via the `parse` command or resent via `broadcast`): ")
|
||||
for _, signedTx := range signedTransactions {
|
||||
fmt.Printf("\t%x\n\n", signedTx)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -26,8 +26,5 @@ func showAddresses(conf *showAddressesConfig) error {
|
||||
for _, address := range response.Address {
|
||||
fmt.Println(address)
|
||||
}
|
||||
|
||||
fmt.Printf("\nNote: the above are only addresses that were manually created by the 'new-address' command. If you want to see a list of all addresses, including change addresses, " +
|
||||
"that have a positive balance, use the command 'balance -v'\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -10,13 +10,19 @@ RUN apk add --no-cache curl git openssh binutils gcc musl-dev
|
||||
COPY go.mod .
|
||||
COPY go.sum .
|
||||
|
||||
RUN go get -u golang.org/x/lint/golint \
|
||||
github.com/kisielk/errcheck \
|
||||
github.com/opennota/check/cmd/aligncheck \
|
||||
github.com/opennota/check/cmd/structcheck \
|
||||
github.com/opennota/check/cmd/varcheck \
|
||||
honnef.co/go/tools/cmd/staticcheck
|
||||
|
||||
# Cache kaspad dependencies
|
||||
RUN go mod download
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN go build $FLAGS -o kaspad .
|
||||
RUN ./build_and_test.sh
|
||||
|
||||
# --- multistage docker build: stage #2: runtime image
|
||||
FROM alpine
|
||||
|
||||
@@ -357,7 +357,7 @@ func (s *consensus) ValidateTransactionAndPopulateWithConsensusData(transaction
|
||||
stagingArea, transaction, model.VirtualBlockHash)
|
||||
}
|
||||
|
||||
func (s *consensus) GetBlock(blockHash *externalapi.DomainHash) (*externalapi.DomainBlock, bool, error) {
|
||||
func (s *consensus) GetBlock(blockHash *externalapi.DomainHash) (*externalapi.DomainBlock, error) {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
@@ -366,11 +366,11 @@ func (s *consensus) GetBlock(blockHash *externalapi.DomainHash) (*externalapi.Do
|
||||
block, err := s.blockStore.Block(s.databaseContext, stagingArea, blockHash)
|
||||
if err != nil {
|
||||
if errors.Is(err, database.ErrNotFound) {
|
||||
return nil, false, nil
|
||||
return nil, errors.Wrapf(err, "block %s does not exist", blockHash)
|
||||
}
|
||||
return nil, false, err
|
||||
return nil, err
|
||||
}
|
||||
return block, true, nil
|
||||
return block, nil
|
||||
}
|
||||
|
||||
func (s *consensus) GetBlockEvenIfHeaderOnly(blockHash *externalapi.DomainHash) (*externalapi.DomainBlock, error) {
|
||||
@@ -853,16 +853,12 @@ func (s *consensus) GetVirtualSelectedParentChainFromBlock(blockHash *externalap
|
||||
}
|
||||
|
||||
func (s *consensus) validateBlockHashExists(stagingArea *model.StagingArea, blockHash *externalapi.DomainHash) error {
|
||||
status, err := s.blockStatusStore.Get(s.databaseContext, stagingArea, blockHash)
|
||||
if database.IsNotFoundError(err) {
|
||||
return errors.Errorf("block %s does not exist", blockHash)
|
||||
}
|
||||
exists, err := s.blockStatusStore.Exists(s.databaseContext, stagingArea, blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if status == externalapi.StatusInvalid {
|
||||
return errors.Errorf("block %s is invalid", blockHash)
|
||||
if !exists {
|
||||
return errors.Errorf("block %s does not exist", blockHash)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -216,8 +216,6 @@ func (f *factory) NewConsensus(config *Config, db infrastructuredatabase.Databas
|
||||
transactionValidator := transactionvalidator.New(config.BlockCoinbaseMaturity,
|
||||
config.EnableNonNativeSubnetworks,
|
||||
config.MaxCoinbasePayloadLength,
|
||||
config.K,
|
||||
config.CoinbasePayloadScriptPublicKeyMaxLength,
|
||||
dbManager,
|
||||
pastMedianTimeManager,
|
||||
ghostdagDataStore,
|
||||
@@ -239,14 +237,12 @@ func (f *factory) NewConsensus(config *Config, db infrastructuredatabase.Databas
|
||||
config.GenesisBlock.Header.Bits())
|
||||
coinbaseManager := coinbasemanager.New(
|
||||
dbManager,
|
||||
|
||||
config.SubsidyGenesisReward,
|
||||
config.PreDeflationaryPhaseBaseSubsidy,
|
||||
config.CoinbasePayloadScriptPublicKeyMaxLength,
|
||||
config.GenesisHash,
|
||||
config.DeflationaryPhaseDaaScore,
|
||||
config.DeflationaryPhaseBaseSubsidy,
|
||||
|
||||
dagTraversalManager,
|
||||
ghostdagDataStore,
|
||||
acceptanceDataStore,
|
||||
|
||||
@@ -263,7 +263,7 @@ func TestBoundedMergeDepth(t *testing.T) {
|
||||
continue
|
||||
}
|
||||
|
||||
block, _, err := tcSyncer.GetBlock(blocksHash)
|
||||
block, err := tcSyncer.GetBlock(blocksHash)
|
||||
if err != nil {
|
||||
t.Fatalf("GetBlockHeader: %+v", err)
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ type Consensus interface {
|
||||
ValidatePruningPointProof(pruningPointProof *PruningPointProof) error
|
||||
ApplyPruningPointProof(pruningPointProof *PruningPointProof) error
|
||||
|
||||
GetBlock(blockHash *DomainHash) (*DomainBlock, bool, error)
|
||||
GetBlock(blockHash *DomainHash) (*DomainBlock, error)
|
||||
GetBlockEvenIfHeaderOnly(blockHash *DomainHash) (*DomainBlock, error)
|
||||
GetBlockHeader(blockHash *DomainHash) (BlockHeader, error)
|
||||
GetBlockInfo(blockHash *DomainHash) (*BlockInfo, error)
|
||||
|
||||
@@ -7,4 +7,5 @@ type MergeDepthManager interface {
|
||||
CheckBoundedMergeDepth(stagingArea *StagingArea, blockHash *externalapi.DomainHash, isBlockWithTrustedData bool) error
|
||||
NonBoundedMergeDepthViolatingBlues(stagingArea *StagingArea, blockHash, mergeDepthRoot *externalapi.DomainHash) ([]*externalapi.DomainHash, error)
|
||||
VirtualMergeDepthRoot(stagingArea *StagingArea) (*externalapi.DomainHash, error)
|
||||
MergeDepthRoot(stagingArea *StagingArea, blockHash *externalapi.DomainHash, isBlockWithTrustedData bool) (*externalapi.DomainHash, error)
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ func TestValidateAndInsertImportedPruningPoint(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, blockHash := range pruningPointAndItsAnticone {
|
||||
block, _, err := tcSyncer.GetBlock(blockHash)
|
||||
block, err := tcSyncer.GetBlock(blockHash)
|
||||
if err != nil {
|
||||
t.Fatalf("GetBlock: %+v", err)
|
||||
}
|
||||
@@ -268,7 +268,7 @@ func TestValidateAndInsertImportedPruningPoint(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, blocksHash := range missingBlockHashes {
|
||||
block, _, err := tcSyncer.GetBlock(blocksHash)
|
||||
block, err := tcSyncer.GetBlock(blocksHash)
|
||||
if err != nil {
|
||||
t.Fatalf("GetBlock: %+v", err)
|
||||
}
|
||||
@@ -294,7 +294,7 @@ func TestValidateAndInsertImportedPruningPoint(t *testing.T) {
|
||||
}
|
||||
|
||||
tipHash := addBlock(tcSyncer, syncerTips, t)
|
||||
tip, _, err := tcSyncer.GetBlock(tipHash)
|
||||
tip, err := tcSyncer.GetBlock(tipHash)
|
||||
if err != nil {
|
||||
t.Fatalf("GetBlock: %+v", err)
|
||||
}
|
||||
@@ -341,7 +341,7 @@ func TestValidateAndInsertImportedPruningPoint(t *testing.T) {
|
||||
tipHash := consensusConfig.GenesisHash
|
||||
for i := 0; i < numSharedBlocks; i++ {
|
||||
tipHash = addBlock(tcSyncer, []*externalapi.DomainHash{tipHash}, t)
|
||||
block, _, err := tcSyncer.GetBlock(tipHash)
|
||||
block, err := tcSyncer.GetBlock(tipHash)
|
||||
if err != nil {
|
||||
t.Fatalf("GetBlock: %+v", err)
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ func TestCheckBlockIsNotPruned(t *testing.T) {
|
||||
t.Fatalf("AddBlock: %+v", err)
|
||||
}
|
||||
|
||||
beforePruningBlock, _, err := tc.GetBlock(tipHash)
|
||||
beforePruningBlock, err := tc.GetBlock(tipHash)
|
||||
if err != nil {
|
||||
t.Fatalf("beforePruningBlock: %+v", err)
|
||||
}
|
||||
@@ -199,7 +199,7 @@ func TestIsFinalizedTransaction(t *testing.T) {
|
||||
t.Fatalf("Error getting block DAA score : %+v", err)
|
||||
}
|
||||
blockParents := block.Header.DirectParents()
|
||||
parentToSpend, _, err := tc.GetBlock(blockParents[0])
|
||||
parentToSpend, err := tc.GetBlock(blockParents[0])
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting block1: %+v", err)
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ func TestChainedTransactions(t *testing.T) {
|
||||
t.Fatalf("AddBlock: %+v", err)
|
||||
}
|
||||
|
||||
block1, _, err := tc.GetBlock(block1Hash)
|
||||
block1, err := tc.GetBlock(block1Hash)
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting block1: %+v", err)
|
||||
}
|
||||
@@ -97,7 +97,7 @@ func TestChainedTransactions(t *testing.T) {
|
||||
t.Fatalf("unexpected error %+v", err)
|
||||
}
|
||||
|
||||
block2, _, err := tc.GetBlock(block2Hash)
|
||||
block2, err := tc.GetBlock(block2Hash)
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting block2: %+v", err)
|
||||
}
|
||||
@@ -169,10 +169,10 @@ var unOrderedParentsBlock = externalapi.DomainBlock{
|
||||
}),
|
||||
}},
|
||||
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
|
||||
0x7e, 0xe2, 0x10, 0x4e, 0x21, 0x2f, 0x2a, 0xb1,
|
||||
0x7d, 0x22, 0xf5, 0xe8, 0xa0, 0x98, 0xef, 0x53,
|
||||
0x83, 0xae, 0x59, 0x1f, 0x83, 0xf3, 0x78, 0x5d,
|
||||
0x30, 0xae, 0x3e, 0xb3, 0x06, 0x08, 0x6f, 0x79,
|
||||
0x31, 0x33, 0x37, 0x72, 0x5c, 0xde, 0x1c, 0xdf,
|
||||
0xf5, 0x9f, 0xde, 0x16, 0x74, 0xbf, 0x0c, 0x64,
|
||||
0x37, 0x40, 0x49, 0xdf, 0x02, 0x05, 0xca, 0x6d,
|
||||
0x52, 0x23, 0x6f, 0xc2, 0x2b, 0xec, 0xad, 0x42,
|
||||
}),
|
||||
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
|
||||
0x80, 0xf7, 0x00, 0xe3, 0x16, 0x3d, 0x04, 0x95,
|
||||
@@ -202,7 +202,20 @@ var unOrderedParentsBlock = externalapi.DomainBlock{
|
||||
Transactions: []*externalapi.DomainTransaction{
|
||||
{
|
||||
Version: 0,
|
||||
Inputs: nil,
|
||||
Inputs: []*externalapi.DomainTransactionInput{
|
||||
{
|
||||
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{
|
||||
{
|
||||
Value: 0x12a05f200, // 5000000000
|
||||
@@ -433,10 +446,10 @@ var exampleValidBlock = externalapi.DomainBlock{
|
||||
}),
|
||||
}},
|
||||
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
|
||||
0x46, 0xec, 0xf4, 0x5b, 0xe3, 0xba, 0xca, 0x34,
|
||||
0x9d, 0xfe, 0x8a, 0x78, 0xde, 0xaf, 0x05, 0x3b,
|
||||
0x0a, 0xa6, 0xd5, 0x38, 0x97, 0x4d, 0xa5, 0x0f,
|
||||
0xd6, 0xef, 0xb4, 0xd2, 0x66, 0xbc, 0x8d, 0x21,
|
||||
0x86, 0x8b, 0x73, 0xcd, 0x20, 0x51, 0x23, 0x60,
|
||||
0xea, 0x62, 0x99, 0x9b, 0x87, 0xf6, 0xdd, 0x8d,
|
||||
0xa4, 0x0b, 0xd7, 0xcf, 0xc6, 0x32, 0x38, 0xee,
|
||||
0xd9, 0x68, 0x72, 0x1f, 0xa2, 0x51, 0xe4, 0x28,
|
||||
}),
|
||||
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
|
||||
0x8a, 0xb7, 0xd6, 0x73, 0x1b, 0xe6, 0xc5, 0xd3,
|
||||
@@ -461,7 +474,21 @@ var exampleValidBlock = externalapi.DomainBlock{
|
||||
Transactions: []*externalapi.DomainTransaction{
|
||||
{
|
||||
Version: 0,
|
||||
Inputs: nil,
|
||||
Inputs: []*externalapi.DomainTransactionInput{
|
||||
{
|
||||
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{
|
||||
{
|
||||
Value: 0x12a05f200, // 5000000000
|
||||
@@ -724,10 +751,10 @@ var blockWithWrongTxOrder = externalapi.DomainBlock{
|
||||
}),
|
||||
}},
|
||||
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
|
||||
0xd5, 0xd2, 0x32, 0xe4, 0xbe, 0x9c, 0x33, 0xbd,
|
||||
0xf1, 0x0a, 0xd2, 0x9d, 0x0c, 0xbd, 0xe5, 0xae,
|
||||
0xcb, 0x1a, 0xf9, 0x5a, 0x3e, 0xfb, 0xf3, 0xc7,
|
||||
0x2b, 0x4d, 0x10, 0xa6, 0xbd, 0x5f, 0x07, 0xe7,
|
||||
0x7b, 0x25, 0x8b, 0xfa, 0xfb, 0x49, 0xe4, 0x94,
|
||||
0x48, 0x2c, 0xf9, 0x74, 0xdd, 0xad, 0x9d, 0x6f,
|
||||
0x98, 0x8f, 0xfb, 0x01, 0x9d, 0x49, 0x29, 0xbe,
|
||||
0x3c, 0xec, 0x90, 0xfe, 0xa5, 0x0c, 0xaf, 0x6b,
|
||||
}),
|
||||
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
|
||||
0xa0, 0x69, 0x2d, 0x16, 0xb5, 0xd7, 0xe4, 0xf3,
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
@@ -28,7 +28,7 @@ func (c *coinbaseManager) serializeCoinbasePayload(blueScore uint64,
|
||||
binary.LittleEndian.PutUint64(payload[:uint64Len], blueScore)
|
||||
binary.LittleEndian.PutUint64(payload[uint64Len:], subsidy)
|
||||
|
||||
binary.LittleEndian.PutUint16(payload[uint64Len+lengthOfSubsidy:], coinbaseData.ScriptPublicKey.Version)
|
||||
payload[uint64Len+lengthOfSubsidy] = uint8(coinbaseData.ScriptPublicKey.Version)
|
||||
payload[uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey] = uint8(len(coinbaseData.ScriptPublicKey.Script))
|
||||
copy(payload[uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey+lengthOfScriptPubKeyLength:], coinbaseData.ScriptPublicKey.Script)
|
||||
copy(payload[uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey+lengthOfScriptPubKeyLength+scriptLengthOfScriptPubKey:], coinbaseData.ExtraData)
|
||||
@@ -52,7 +52,7 @@ func ModifyCoinbasePayload(payload []byte, coinbaseData *externalapi.DomainCoinb
|
||||
payload = newPayload
|
||||
}
|
||||
|
||||
binary.LittleEndian.PutUint16(payload[uint64Len+lengthOfSubsidy:uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey], coinbaseData.ScriptPublicKey.Version)
|
||||
payload[uint64Len+lengthOfSubsidy] = uint8(coinbaseData.ScriptPublicKey.Version)
|
||||
payload[uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey] = uint8(len(coinbaseData.ScriptPublicKey.Script))
|
||||
copy(payload[uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey+lengthOfScriptPubKeyLength:], coinbaseData.ScriptPublicKey.Script)
|
||||
copy(payload[uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey+lengthOfScriptPubKeyLength+scriptLengthOfScriptPubKey:], coinbaseData.ExtraData)
|
||||
@@ -73,8 +73,7 @@ func (c *coinbaseManager) ExtractCoinbaseDataBlueScoreAndSubsidy(coinbaseTx *ext
|
||||
blueScore = binary.LittleEndian.Uint64(coinbaseTx.Payload[:uint64Len])
|
||||
subsidy = binary.LittleEndian.Uint64(coinbaseTx.Payload[uint64Len:])
|
||||
|
||||
scriptPubKeyVersion := binary.LittleEndian.Uint16(coinbaseTx.Payload[uint64Len+lengthOfSubsidy : uint64Len+lengthOfSubsidy+uint16Len])
|
||||
|
||||
scriptPubKeyVersion := uint16(coinbaseTx.Payload[uint64Len+lengthOfSubsidy])
|
||||
scriptPubKeyScriptLength := coinbaseTx.Payload[uint64Len+lengthOfSubsidy+lengthOfVersionScriptPubKey]
|
||||
|
||||
if scriptPubKeyScriptLength > c.coinbasePayloadScriptPublicKeyMaxLength {
|
||||
|
||||
@@ -40,7 +40,7 @@ func TestUTXOCommitment(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating block B: %+v", err)
|
||||
}
|
||||
blockB, _, err := consensus.GetBlock(blockBHash)
|
||||
blockB, err := consensus.GetBlock(blockBHash)
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting block B: %+v", err)
|
||||
}
|
||||
@@ -73,7 +73,7 @@ func TestUTXOCommitment(t *testing.T) {
|
||||
}
|
||||
|
||||
func checkBlockUTXOCommitment(t *testing.T, consensus testapi.TestConsensus, blockHash *externalapi.DomainHash, blockName string) {
|
||||
block, _, err := consensus.GetBlock(blockHash)
|
||||
block, err := consensus.GetBlock(blockHash)
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting block %s: %+v", blockName, err)
|
||||
}
|
||||
|
||||
@@ -72,8 +72,7 @@ func New(
|
||||
maxBlockParents: maxBlockParents,
|
||||
mergeSetSizeLimit: mergeSetSizeLimit,
|
||||
genesisHash: genesisHash,
|
||||
|
||||
databaseContext: databaseContext,
|
||||
databaseContext: databaseContext,
|
||||
|
||||
ghostdagManager: ghostdagManager,
|
||||
dagTopologyManager: dagTopologyManager,
|
||||
|
||||
@@ -40,7 +40,7 @@ func TestDoubleSpends(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating fundingBlock: %+v", err)
|
||||
}
|
||||
fundingBlock, _, err := consensus.GetBlock(fundingBlockHash)
|
||||
fundingBlock, err := consensus.GetBlock(fundingBlockHash)
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting fundingBlock: %+v", err)
|
||||
}
|
||||
@@ -195,7 +195,7 @@ func TestTransactionAcceptance(t *testing.T) {
|
||||
}
|
||||
}
|
||||
lastBlockInChain := chainTipHash
|
||||
blockC, _, err := testConsensus.GetBlock(blockHashC)
|
||||
blockC, err := testConsensus.GetBlock(blockHashC)
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting blockC: %+v", err)
|
||||
}
|
||||
@@ -269,27 +269,22 @@ func TestTransactionAcceptance(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting acceptance data: %+v", err)
|
||||
}
|
||||
blueChildOfRedBlock, _, err := testConsensus.GetBlock(hashBlueChildOfRedBlock)
|
||||
blueChildOfRedBlock, err := testConsensus.GetBlock(hashBlueChildOfRedBlock)
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting blueChildOfRedBlock: %+v", err)
|
||||
}
|
||||
blockE, _, err := testConsensus.GetBlock(blockHashF)
|
||||
blockE, err := testConsensus.GetBlock(blockHashF)
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting blockE: %+v", err)
|
||||
}
|
||||
redBlock, _, err := testConsensus.GetBlock(redHash)
|
||||
redBlock, err := testConsensus.GetBlock(redHash)
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting redBlock: %+v", err)
|
||||
}
|
||||
_, found, err := testConsensus.GetBlock(blockHashG)
|
||||
_, err = testConsensus.GetBlock(blockHashG)
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting blockG: %+v", err)
|
||||
t.Fatalf("Error getting blockF: %+v", err)
|
||||
}
|
||||
|
||||
if !found {
|
||||
t.Fatalf("block G is missing")
|
||||
}
|
||||
|
||||
updatedDAAScoreVirtualBlock := consensusConfig.GenesisBlock.Header.DAAScore() + 26
|
||||
//We expect the second transaction in the "blue block" (blueChildOfRedBlock) to be accepted because the merge set is ordered topologically
|
||||
//and the red block is ordered topologically before the "blue block" so the input is known in the UTXOSet.
|
||||
|
||||
@@ -205,37 +205,37 @@ func TestBlockWindow(t *testing.T) {
|
||||
{
|
||||
parents: []string{"H", "F"},
|
||||
id: "I",
|
||||
expectedWindow: []string{"F", "C", "H", "D", "B", "G"},
|
||||
expectedWindow: []string{"F", "C", "D", "H", "G", "B"},
|
||||
},
|
||||
{
|
||||
parents: []string{"I"},
|
||||
id: "J",
|
||||
expectedWindow: []string{"I", "F", "C", "H", "D", "B", "G"},
|
||||
expectedWindow: []string{"I", "F", "C", "D", "H", "G", "B"},
|
||||
},
|
||||
{
|
||||
parents: []string{"J"},
|
||||
id: "K",
|
||||
expectedWindow: []string{"J", "I", "F", "C", "H", "D", "B", "G"},
|
||||
expectedWindow: []string{"J", "I", "F", "C", "D", "H", "G", "B"},
|
||||
},
|
||||
{
|
||||
parents: []string{"K"},
|
||||
id: "L",
|
||||
expectedWindow: []string{"K", "J", "I", "F", "C", "H", "D", "B", "G"},
|
||||
expectedWindow: []string{"K", "J", "I", "F", "C", "D", "H", "G", "B"},
|
||||
},
|
||||
{
|
||||
parents: []string{"L"},
|
||||
id: "M",
|
||||
expectedWindow: []string{"L", "K", "J", "I", "F", "C", "H", "D", "B", "G"},
|
||||
expectedWindow: []string{"L", "K", "J", "I", "F", "C", "D", "H", "G", "B"},
|
||||
},
|
||||
{
|
||||
parents: []string{"M"},
|
||||
id: "N",
|
||||
expectedWindow: []string{"M", "L", "K", "J", "I", "F", "C", "H", "D", "B"},
|
||||
expectedWindow: []string{"M", "L", "K", "J", "I", "F", "C", "D", "H", "G"},
|
||||
},
|
||||
{
|
||||
parents: []string{"N"},
|
||||
id: "O",
|
||||
expectedWindow: []string{"N", "M", "L", "K", "J", "I", "F", "C", "H", "D"},
|
||||
expectedWindow: []string{"N", "M", "L", "K", "J", "I", "F", "C", "D", "H"},
|
||||
},
|
||||
},
|
||||
dagconfig.SimnetParams.Name: {
|
||||
|
||||
@@ -132,7 +132,7 @@ func TestDifficulty(t *testing.T) {
|
||||
case dagconfig.TestnetParams.Name:
|
||||
expectedBits = uint32(0x1e7f1441)
|
||||
case dagconfig.DevnetParams.Name:
|
||||
expectedBits = uint32(0x1f4e54ab)
|
||||
expectedBits = uint32(0x207f1441)
|
||||
case dagconfig.MainnetParams.Name:
|
||||
expectedBits = uint32(0x1d02c50f)
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ func TestPruning(t *testing.T) {
|
||||
"dag-for-test-pruning.json": {
|
||||
dagconfig.MainnetParams.Name: "503",
|
||||
dagconfig.TestnetParams.Name: "503",
|
||||
dagconfig.DevnetParams.Name: "502",
|
||||
dagconfig.DevnetParams.Name: "503",
|
||||
dagconfig.SimnetParams.Name: "503",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -768,114 +768,6 @@ func (pm *pruningManager) calculateDiffBetweenPreviousAndCurrentPruningPoints(st
|
||||
return nil, errors.Errorf("previous pruning point doesn't exist")
|
||||
}
|
||||
|
||||
previousPruningHash, err := pm.pruningStore.PruningPointByIndex(pm.databaseContext, stagingArea, pruningPointIndex-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
currentPruningGhostDAG, err := pm.ghostdagDataStore.Get(pm.databaseContext, stagingArea, currentPruningHash, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
previousPruningGhostDAG, err := pm.ghostdagDataStore.Get(pm.databaseContext, stagingArea, previousPruningHash, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
currentPruningCurrentDiffChild := currentPruningHash
|
||||
previousPruningCurrentDiffChild := previousPruningHash
|
||||
// We need to use BlueWork because it's the only thing that's monotonic in the whole DAG
|
||||
// We use the BlueWork to know which point is currently lower on the DAG so we can keep climbing its children,
|
||||
// that way we keep climbing on the lowest point until they both reach the exact same descendant
|
||||
currentPruningCurrentDiffChildBlueWork := currentPruningGhostDAG.BlueWork()
|
||||
previousPruningCurrentDiffChildBlueWork := previousPruningGhostDAG.BlueWork()
|
||||
|
||||
var diffHashesFromPrevious []*externalapi.DomainHash
|
||||
var diffHashesFromCurrent []*externalapi.DomainHash
|
||||
for {
|
||||
// if currentPruningCurrentDiffChildBlueWork > previousPruningCurrentDiffChildBlueWork
|
||||
if currentPruningCurrentDiffChildBlueWork.Cmp(previousPruningCurrentDiffChildBlueWork) == 1 {
|
||||
diffHashesFromPrevious = append(diffHashesFromPrevious, previousPruningCurrentDiffChild)
|
||||
previousPruningCurrentDiffChild, err = pm.utxoDiffStore.UTXODiffChild(pm.databaseContext, stagingArea, previousPruningCurrentDiffChild)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
diffChildGhostDag, err := pm.ghostdagDataStore.Get(pm.databaseContext, stagingArea, previousPruningCurrentDiffChild, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
previousPruningCurrentDiffChildBlueWork = diffChildGhostDag.BlueWork()
|
||||
} else if currentPruningCurrentDiffChild.Equal(previousPruningCurrentDiffChild) {
|
||||
break
|
||||
} else {
|
||||
diffHashesFromCurrent = append(diffHashesFromCurrent, currentPruningCurrentDiffChild)
|
||||
currentPruningCurrentDiffChild, err = pm.utxoDiffStore.UTXODiffChild(pm.databaseContext, stagingArea, currentPruningCurrentDiffChild)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
diffChildGhostDag, err := pm.ghostdagDataStore.Get(pm.databaseContext, stagingArea, currentPruningCurrentDiffChild, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
currentPruningCurrentDiffChildBlueWork = diffChildGhostDag.BlueWork()
|
||||
}
|
||||
}
|
||||
// The order in which we apply the diffs should be from top to bottom, but we traversed from bottom to top
|
||||
// so we apply the diffs in reverse order.
|
||||
oldDiff := utxo.NewMutableUTXODiff()
|
||||
for i := len(diffHashesFromPrevious) - 1; i >= 0; i-- {
|
||||
utxoDiff, err := pm.utxoDiffStore.UTXODiff(pm.databaseContext, stagingArea, diffHashesFromPrevious[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = oldDiff.WithDiffInPlace(utxoDiff)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
newDiff := utxo.NewMutableUTXODiff()
|
||||
for i := len(diffHashesFromCurrent) - 1; i >= 0; i-- {
|
||||
utxoDiff, err := pm.utxoDiffStore.UTXODiff(pm.databaseContext, stagingArea, diffHashesFromCurrent[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = newDiff.WithDiffInPlace(utxoDiff)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return oldDiff.DiffFrom(newDiff.ToImmutable())
|
||||
}
|
||||
|
||||
// This function takes 2 chain blocks (currentPruningHash, previousPruningHash) and finds
|
||||
// the UTXO diff between them by iterating over acceptance data of the chain blocks in between.
|
||||
func (pm *pruningManager) calculateDiffBetweenPreviousAndCurrentPruningPointsUsingAcceptanceData(stagingArea *model.StagingArea, currentPruningHash *externalapi.DomainHash) (externalapi.UTXODiff, error) {
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "pruningManager.calculateDiffBetweenPreviousAndCurrentPruningPoints__UsingAcceptanceData")
|
||||
defer onEnd()
|
||||
if currentPruningHash.Equal(pm.genesisHash) {
|
||||
iter, err := pm.consensusStateManager.RestorePastUTXOSetIterator(stagingArea, currentPruningHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
set := make(map[externalapi.DomainOutpoint]externalapi.UTXOEntry)
|
||||
for ok := iter.First(); ok; ok = iter.Next() {
|
||||
outpoint, entry, err := iter.Get()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
set[*outpoint] = entry
|
||||
}
|
||||
return utxo.NewUTXODiffFromCollections(utxo.NewUTXOCollection(set), utxo.NewUTXOCollection(make(map[externalapi.DomainOutpoint]externalapi.UTXOEntry)))
|
||||
}
|
||||
|
||||
pruningPointIndex, err := pm.pruningStore.CurrentPruningPointIndex(pm.databaseContext, stagingArea)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if pruningPointIndex == 0 {
|
||||
return nil, errors.Errorf("previous pruning point doesn't exist")
|
||||
}
|
||||
|
||||
previousPruningHash, err := pm.pruningStore.PruningPointByIndex(pm.databaseContext, stagingArea, pruningPointIndex-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1001,13 +893,7 @@ func (pm *pruningManager) updatePruningPoint() error {
|
||||
log.Debugf("Restoring the pruning point UTXO set")
|
||||
utxoSetDiff, err := pm.calculateDiffBetweenPreviousAndCurrentPruningPoints(stagingArea, pruningPoint)
|
||||
if err != nil {
|
||||
log.Infof("Calculating pruning points diff through utxo diff children failed %s. Falling back to calculation "+
|
||||
"through acceptance data", err)
|
||||
|
||||
utxoSetDiff, err = pm.calculateDiffBetweenPreviousAndCurrentPruningPointsUsingAcceptanceData(stagingArea, pruningPoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
log.Debugf("Updating the pruning point UTXO set")
|
||||
err = pm.pruningStore.UpdatePruningPointUTXOSet(pm.databaseContext, utxoSetDiff)
|
||||
|
||||
@@ -350,7 +350,6 @@ func (v *transactionValidator) validateTransactionSigOpCounts(tx *externalapi.Do
|
||||
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",
|
||||
|
||||
@@ -23,7 +23,7 @@ func (v *transactionValidator) ValidateTransactionInIsolation(tx *externalapi.Do
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = v.checkCoinbaseInIsolation(tx)
|
||||
err = v.checkCoinbaseLength(tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -114,7 +114,7 @@ func (v *transactionValidator) checkDuplicateTransactionInputs(tx *externalapi.D
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *transactionValidator) checkCoinbaseInIsolation(tx *externalapi.DomainTransaction) error {
|
||||
func (v *transactionValidator) checkCoinbaseLength(tx *externalapi.DomainTransaction) error {
|
||||
if !transactionhelper.IsCoinBase(tx) {
|
||||
return nil
|
||||
}
|
||||
@@ -127,22 +127,6 @@ func (v *transactionValidator) checkCoinbaseInIsolation(tx *externalapi.DomainTr
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ func TestValidateTransactionInIsolationAndPopulateMass(t *testing.T) {
|
||||
subnetworks.SubnetworkIDNative,
|
||||
&txSubnetworkData{subnetworks.SubnetworkIDCoinbase, 0, nil},
|
||||
nil,
|
||||
ruleerrors.ErrCoinbaseWithInputs, 0},
|
||||
nil, 0},
|
||||
{"no inputs coinbase",
|
||||
0,
|
||||
1,
|
||||
|
||||
@@ -2,7 +2,6 @@ package transactionvalidator
|
||||
|
||||
import (
|
||||
"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/util/txmass"
|
||||
)
|
||||
@@ -12,26 +11,22 @@ const sigCacheSize = 10_000
|
||||
// transactionValidator exposes a set of validation classes, after which
|
||||
// it's possible to determine whether either a transaction is valid
|
||||
type transactionValidator struct {
|
||||
blockCoinbaseMaturity uint64
|
||||
databaseContext model.DBReader
|
||||
pastMedianTimeManager model.PastMedianTimeManager
|
||||
ghostdagDataStore model.GHOSTDAGDataStore
|
||||
daaBlocksStore model.DAABlocksStore
|
||||
enableNonNativeSubnetworks bool
|
||||
maxCoinbasePayloadLength uint64
|
||||
ghostdagK externalapi.KType
|
||||
coinbasePayloadScriptPublicKeyMaxLength uint8
|
||||
sigCache *txscript.SigCache
|
||||
sigCacheECDSA *txscript.SigCacheECDSA
|
||||
txMassCalculator *txmass.Calculator
|
||||
blockCoinbaseMaturity uint64
|
||||
databaseContext model.DBReader
|
||||
pastMedianTimeManager model.PastMedianTimeManager
|
||||
ghostdagDataStore model.GHOSTDAGDataStore
|
||||
daaBlocksStore model.DAABlocksStore
|
||||
enableNonNativeSubnetworks bool
|
||||
maxCoinbasePayloadLength uint64
|
||||
sigCache *txscript.SigCache
|
||||
sigCacheECDSA *txscript.SigCacheECDSA
|
||||
txMassCalculator *txmass.Calculator
|
||||
}
|
||||
|
||||
// New instantiates a new TransactionValidator
|
||||
func New(blockCoinbaseMaturity uint64,
|
||||
enableNonNativeSubnetworks bool,
|
||||
maxCoinbasePayloadLength uint64,
|
||||
ghostdagK externalapi.KType,
|
||||
coinbasePayloadScriptPublicKeyMaxLength uint8,
|
||||
databaseContext model.DBReader,
|
||||
pastMedianTimeManager model.PastMedianTimeManager,
|
||||
ghostdagDataStore model.GHOSTDAGDataStore,
|
||||
@@ -39,17 +34,15 @@ func New(blockCoinbaseMaturity uint64,
|
||||
txMassCalculator *txmass.Calculator) model.TransactionValidator {
|
||||
|
||||
return &transactionValidator{
|
||||
blockCoinbaseMaturity: blockCoinbaseMaturity,
|
||||
enableNonNativeSubnetworks: enableNonNativeSubnetworks,
|
||||
maxCoinbasePayloadLength: maxCoinbasePayloadLength,
|
||||
ghostdagK: ghostdagK,
|
||||
coinbasePayloadScriptPublicKeyMaxLength: coinbasePayloadScriptPublicKeyMaxLength,
|
||||
databaseContext: databaseContext,
|
||||
pastMedianTimeManager: pastMedianTimeManager,
|
||||
ghostdagDataStore: ghostdagDataStore,
|
||||
daaBlocksStore: daaBlocksStore,
|
||||
sigCache: txscript.NewSigCache(sigCacheSize),
|
||||
sigCacheECDSA: txscript.NewSigCacheECDSA(sigCacheSize),
|
||||
txMassCalculator: txMassCalculator,
|
||||
blockCoinbaseMaturity: blockCoinbaseMaturity,
|
||||
enableNonNativeSubnetworks: enableNonNativeSubnetworks,
|
||||
maxCoinbasePayloadLength: maxCoinbasePayloadLength,
|
||||
databaseContext: databaseContext,
|
||||
pastMedianTimeManager: pastMedianTimeManager,
|
||||
ghostdagDataStore: ghostdagDataStore,
|
||||
daaBlocksStore: daaBlocksStore,
|
||||
sigCache: txscript.NewSigCache(sigCacheSize),
|
||||
sigCacheECDSA: txscript.NewSigCacheECDSA(sigCacheSize),
|
||||
txMassCalculator: txMassCalculator,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,6 +109,18 @@ func TestValidateTransactionInContextAndPopulateFee(t *testing.T) {
|
||||
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{
|
||||
Value: 100000000, // 1 KAS
|
||||
ScriptPublicKey: scriptPublicKey,
|
||||
@@ -181,6 +193,13 @@ func TestValidateTransactionInContextAndPopulateFee(t *testing.T) {
|
||||
SubnetworkID: subnetworks.SubnetworkIDRegistry,
|
||||
Gas: 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()
|
||||
|
||||
@@ -247,6 +266,13 @@ func TestValidateTransactionInContextAndPopulateFee(t *testing.T) {
|
||||
isValid: false,
|
||||
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 {
|
||||
@@ -318,12 +344,12 @@ func TestSigningTwoInputs(t *testing.T) {
|
||||
t.Fatalf("AddBlock: %+v", err)
|
||||
}
|
||||
|
||||
block2, _, err := tc.GetBlock(block2Hash)
|
||||
block2, err := tc.GetBlock(block2Hash)
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting block2: %+v", err)
|
||||
}
|
||||
|
||||
block3, _, err := tc.GetBlock(block3Hash)
|
||||
block3, err := tc.GetBlock(block3Hash)
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting block3: %+v", err)
|
||||
}
|
||||
@@ -444,12 +470,12 @@ func TestSigningTwoInputsECDSA(t *testing.T) {
|
||||
t.Fatalf("AddBlock: %+v", err)
|
||||
}
|
||||
|
||||
block2, _, err := tc.GetBlock(block2Hash)
|
||||
block2, err := tc.GetBlock(block2Hash)
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting block2: %+v", err)
|
||||
}
|
||||
|
||||
block3, _, err := tc.GetBlock(block3Hash)
|
||||
block3, err := tc.GetBlock(block3Hash)
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting block3: %+v", err)
|
||||
}
|
||||
|
||||
@@ -241,9 +241,6 @@ var (
|
||||
ErrPruningProofEmpty = newRuleError("ErrPruningProofEmpty")
|
||||
ErrWrongCoinbaseSubsidy = newRuleError("ErrWrongCoinbaseSubsidy")
|
||||
ErrWrongBlockVersion = newRuleError("ErrWrongBlockVersion")
|
||||
ErrCoinbaseWithInputs = newRuleError("ErrCoinbaseWithInputs")
|
||||
ErrCoinbaseTooManyOutputs = newRuleError("ErrCoinbaseTooManyOutputs")
|
||||
ErrCoinbaseTooLongScriptPublicKey = newRuleError("ErrCoinbaseTooLongScriptPublicKey")
|
||||
)
|
||||
|
||||
// RuleError identifies a rule violation. It is used to indicate that
|
||||
|
||||
@@ -43,7 +43,7 @@ func TestCheckLockTimeVerifyConditionedByDAAScore(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating blockD: %v", err)
|
||||
}
|
||||
blockD, _, err := testConsensus.GetBlock(blockDHash)
|
||||
blockD, err := testConsensus.GetBlock(blockDHash)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed getting blockD: %v", err)
|
||||
}
|
||||
@@ -150,7 +150,7 @@ func TestCheckLockTimeVerifyConditionedByDAAScoreWithWrongLockTime(t *testing.T)
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating blockD: %v", err)
|
||||
}
|
||||
blockD, _, err := testConsensus.GetBlock(blockDHash)
|
||||
blockD, err := testConsensus.GetBlock(blockDHash)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed getting blockD: %v", err)
|
||||
}
|
||||
@@ -252,7 +252,7 @@ func TestCheckLockTimeVerifyConditionedByAbsoluteTime(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating blockD: %v", err)
|
||||
}
|
||||
blockD, _, err := testConsensus.GetBlock(blockDHash)
|
||||
blockD, err := testConsensus.GetBlock(blockDHash)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed getting blockD: %v", err)
|
||||
}
|
||||
@@ -283,7 +283,7 @@ func TestCheckLockTimeVerifyConditionedByAbsoluteTime(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating blockE: %v", err)
|
||||
}
|
||||
blockE, _, err := testConsensus.GetBlock(blockEHash)
|
||||
blockE, err := testConsensus.GetBlock(blockEHash)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed getting blockE: %v", err)
|
||||
}
|
||||
@@ -380,7 +380,7 @@ func TestCheckLockTimeVerifyConditionedByAbsoluteTimeWithWrongLockTime(t *testin
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating blockD: %v", err)
|
||||
}
|
||||
blockD, _, err := testConsensus.GetBlock(blockDHash)
|
||||
blockD, err := testConsensus.GetBlock(blockDHash)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed getting blockD: %v", err)
|
||||
}
|
||||
@@ -411,7 +411,7 @@ func TestCheckLockTimeVerifyConditionedByAbsoluteTimeWithWrongLockTime(t *testin
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating blockE: %v", err)
|
||||
}
|
||||
blockE, _, err := testConsensus.GetBlock(blockEHash)
|
||||
blockE, err := testConsensus.GetBlock(blockEHash)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed getting blockE: %v", err)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package consensushashing_test
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
|
||||
"testing"
|
||||
|
||||
"github.com/kaspanet/go-secp256k1"
|
||||
@@ -109,73 +108,73 @@ func TestCalculateSignatureHashSchnorr(t *testing.T) {
|
||||
|
||||
// sigHashAll
|
||||
{name: "native-all-0", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||
expectedSignatureHash: "03b7ac6927b2b67100734c3cc313ff8c2e8b3ce3e746d46dd660b706a916b1f5"},
|
||||
expectedSignatureHash: "b363613fe99c8bb1d3712656ec8dfaea621ee6a9a95d851aec5bb59363b03f5e"},
|
||||
{name: "native-all-0-modify-input-1", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifyInput(1), // should change the hash
|
||||
expectedSignatureHash: "a9f563d86c0ef19ec2e4f483901d202e90150580b6123c3d492e26e7965f488c"},
|
||||
expectedSignatureHash: "34ae2989115068fc73a1b2cae023ad79c3cdb5cbe532a46fa91d9181a36990fd"},
|
||||
{name: "native-all-0-modify-output-1", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifyOutput(1), // should change the hash
|
||||
expectedSignatureHash: "aad2b61bd2405dfcf7294fc2be85f325694f02dda22d0af30381cb50d8295e0a"},
|
||||
expectedSignatureHash: "043441346c66e461f9f1dc618ebbfe7fd87f74e363f267bf8b3243a7bfe0c870"},
|
||||
{name: "native-all-0-modify-sequence-1", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifySequence(1), // should change the hash
|
||||
expectedSignatureHash: "0818bd0a3703638d4f01014c92cf866a8903cab36df2fa2506dc0d06b94295e8"},
|
||||
expectedSignatureHash: "de8d3d46bc8c51f51a1b85470f8bf01ee38214901d6d514fd13bafe4efc8aa0f"},
|
||||
{name: "native-all-anyonecanpay-0", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||
expectedSignatureHash: "24821e466e53ff8e5fa93257cb17bb06131a48be4ef282e87f59d2bdc9afebc2"},
|
||||
expectedSignatureHash: "19897764789644c2ac5cd6d83f7a78a1208f3ce6d15e8788f9b9fa6d7c91d8f1"},
|
||||
{name: "native-all-anyonecanpay-0-modify-input-0", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifyInput(0), // should change the hash
|
||||
expectedSignatureHash: "d09cb639f335ee69ac71f2ad43fd9e59052d38a7d0638de4cf989346588a7c38"},
|
||||
expectedSignatureHash: "f1ff39b1b9ce86d2fdfac61a75f3b13e98fe5e0f1057b4ec69245031ecf7be37"},
|
||||
{name: "native-all-anyonecanpay-0-modify-input-1", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifyInput(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "24821e466e53ff8e5fa93257cb17bb06131a48be4ef282e87f59d2bdc9afebc2"},
|
||||
expectedSignatureHash: "19897764789644c2ac5cd6d83f7a78a1208f3ce6d15e8788f9b9fa6d7c91d8f1"},
|
||||
{name: "native-all-anyonecanpay-0-modify-sequence", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifySequence(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "24821e466e53ff8e5fa93257cb17bb06131a48be4ef282e87f59d2bdc9afebc2"},
|
||||
expectedSignatureHash: "19897764789644c2ac5cd6d83f7a78a1208f3ce6d15e8788f9b9fa6d7c91d8f1"},
|
||||
|
||||
// sigHashNone
|
||||
{name: "native-none-0", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||
expectedSignatureHash: "38ce4bc93cf9116d2e377b33ff8449c665b7b5e2f2e65303c543b9afdaa4bbba"},
|
||||
expectedSignatureHash: "7a5b0fef8219bb72ef1912db5335c71c4fdfac873a6096c24b2f0b5c3774349c"},
|
||||
{name: "native-none-0-modify-output-1", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||
modificationFunction: modifyOutput(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "38ce4bc93cf9116d2e377b33ff8449c665b7b5e2f2e65303c543b9afdaa4bbba"},
|
||||
expectedSignatureHash: "7a5b0fef8219bb72ef1912db5335c71c4fdfac873a6096c24b2f0b5c3774349c"},
|
||||
{name: "native-none-0-modify-sequence-0", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||
modificationFunction: modifySequence(0), // should change the hash
|
||||
expectedSignatureHash: "d9efdd5edaa0d3fd0133ee3ab731d8c20e0a1b9f3c0581601ae2075db1109268"},
|
||||
expectedSignatureHash: "852011233473ee1e61a9d0e51fb5ecd65857ceca65ebea4c54b6d557f2006f2a"},
|
||||
{name: "native-none-0-modify-sequence-1", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||
modificationFunction: modifySequence(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "38ce4bc93cf9116d2e377b33ff8449c665b7b5e2f2e65303c543b9afdaa4bbba"},
|
||||
expectedSignatureHash: "7a5b0fef8219bb72ef1912db5335c71c4fdfac873a6096c24b2f0b5c3774349c"},
|
||||
{name: "native-none-anyonecanpay-0", tx: nativeTx, hashType: noneAnyoneCanPay, inputIndex: 0,
|
||||
expectedSignatureHash: "06aa9f4239491e07bb2b6bda6b0657b921aeae51e193d2c5bf9e81439cfeafa0"},
|
||||
expectedSignatureHash: "1624d46e77d09cb09e4a7dcbf419b8c37671bd0274b9dc6aba0668922da83935"},
|
||||
{name: "native-none-anyonecanpay-0-modify-amount-spent", tx: nativeTx, hashType: noneAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifyAmountSpent(0), // should change the hash
|
||||
expectedSignatureHash: "f07f45f3634d3ea8c0f2cb676f56e20993edf9be07a83bf0dfdb3debcf1441bf"},
|
||||
expectedSignatureHash: "235f0766528865a4c478a46b0b3eef6b4760c6a05c792a452c06fab9ad0bd57c"},
|
||||
{name: "native-none-anyonecanpay-0-modify-script-public-key", tx: nativeTx, hashType: noneAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifyScriptPublicKey(0), // should change the hash
|
||||
expectedSignatureHash: "20a525c54dc33b2a61201f05233c086dbe8e06e9515775181ed96550b4f2d714"},
|
||||
expectedSignatureHash: "42b408acc6df78f1b1aef605339233af129b6e656788e8c93712e4954d28583d"},
|
||||
|
||||
// sigHashSingle
|
||||
{name: "native-single-0", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
expectedSignatureHash: "44a0b407ff7b239d447743dd503f7ad23db5b2ee4d25279bd3dffaf6b474e005"},
|
||||
expectedSignatureHash: "c9f7adaa7a22af87195183cf1f10e368429139f16069597d5631a0f522e320a5"},
|
||||
{name: "native-single-0-modify-output-0", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
modificationFunction: modifyOutput(0), // should change the hash
|
||||
expectedSignatureHash: "0fcaca1211f7ea44997717eb84c04c9c807db8b59797bc6800c2ccb135a5271c"},
|
||||
expectedSignatureHash: "af40fbd0ac061c586484c4f266d44007c0715eb0b80d20eb89be65325db05716"},
|
||||
{name: "native-single-0-modify-output-1", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
modificationFunction: modifyOutput(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "44a0b407ff7b239d447743dd503f7ad23db5b2ee4d25279bd3dffaf6b474e005"},
|
||||
expectedSignatureHash: "c9f7adaa7a22af87195183cf1f10e368429139f16069597d5631a0f522e320a5"},
|
||||
{name: "native-single-0-modify-sequence-0", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
modificationFunction: modifySequence(0), // should change the hash
|
||||
expectedSignatureHash: "83796d22879718eee1165d4aace667bb6778075dab579c32c57be945f466a451"},
|
||||
expectedSignatureHash: "c40f48b35fc933d5930c612c420e80bad336388126aaba6073588e31d95aca2c"},
|
||||
{name: "native-single-0-modify-sequence-1", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
modificationFunction: modifySequence(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "44a0b407ff7b239d447743dd503f7ad23db5b2ee4d25279bd3dffaf6b474e005"},
|
||||
expectedSignatureHash: "c9f7adaa7a22af87195183cf1f10e368429139f16069597d5631a0f522e320a5"},
|
||||
{name: "native-single-2-no-corresponding-output", tx: nativeTx, hashType: single, inputIndex: 2,
|
||||
expectedSignatureHash: "022ad967192f39d8d5895d243e025ec14cc7a79708c5e364894d4eff3cecb1b0"},
|
||||
expectedSignatureHash: "145487f676cd1d5f8042b9d042cc63bc0ecdf20563d324fa0b847714eeb94816"},
|
||||
{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: "022ad967192f39d8d5895d243e025ec14cc7a79708c5e364894d4eff3cecb1b0"},
|
||||
expectedSignatureHash: "145487f676cd1d5f8042b9d042cc63bc0ecdf20563d324fa0b847714eeb94816"},
|
||||
{name: "native-single-anyonecanpay-0", tx: nativeTx, hashType: singleAnyoneCanPay, inputIndex: 0,
|
||||
expectedSignatureHash: "43b20aba775050cf9ba8d5e48fc7ed2dc6c071d23f30382aea58b7c59cfb8ed7"},
|
||||
expectedSignatureHash: "4f3f758e1ed9c438dcc241efd31dd07e6bf2e11e900e105eebd4d337391e48fe"},
|
||||
{name: "native-single-anyonecanpay-2-no-corresponding-output", tx: nativeTx, hashType: singleAnyoneCanPay, inputIndex: 2,
|
||||
expectedSignatureHash: "846689131fb08b77f83af1d3901076732ef09d3f8fdff945be89aa4300562e5f"},
|
||||
expectedSignatureHash: "200207998528ab3b58cbdfe578cd079572eb3093e68fb5c728e505b847e91c64"},
|
||||
|
||||
// subnetwork transaction
|
||||
{name: "subnetwork-all-0", tx: subnetworkTx, hashType: all, inputIndex: 0,
|
||||
@@ -231,73 +230,73 @@ func TestCalculateSignatureHashECDSA(t *testing.T) {
|
||||
|
||||
// sigHashAll
|
||||
{name: "native-all-0", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||
expectedSignatureHash: "1d679268414c20ffe952e3c255befd892e60e86ae1657fce8a20225e5dc87d64"},
|
||||
expectedSignatureHash: "6ec7f4949d0c095d78bf41475310fd38eb054f3e7c4240daf91ea888e4eb9a30"},
|
||||
{name: "native-all-0-modify-input-1", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifyInput(1), // should change the hash
|
||||
expectedSignatureHash: "c573469b9ec6551507371d26eaa75417905420577f56d0277c4234a99f2305d7"},
|
||||
expectedSignatureHash: "34fcc1cb538736c473c1778eba4df5f88c3d9f27508b0d842ec2348d097cd103"},
|
||||
{name: "native-all-0-modify-output-1", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifyOutput(1), // should change the hash
|
||||
expectedSignatureHash: "a92450b0662c120db3993b6bb258d06d2bcb983aa591d85f97adf8b7207a5db5"},
|
||||
expectedSignatureHash: "faf02d20d32f0e4536dfb0a86c67f97b394c11a34069bd74a2f7533ea964b10f"},
|
||||
{name: "native-all-0-modify-sequence-1", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifySequence(1), // should change the hash
|
||||
expectedSignatureHash: "c7a7524096499e4401a1592f892bada1afe7f7d276c4f0e691c993e17c03cf7d"},
|
||||
expectedSignatureHash: "25484c5dcc89d21e5b5858847964c8c2938d5090be54b21a590099ce4f792b14"},
|
||||
{name: "native-all-anyonecanpay-0", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||
expectedSignatureHash: "13270aeb5b56d844d064d5d2cf06af7dbd0341fd55069b9af56d5e3c99f2eddd"},
|
||||
expectedSignatureHash: "458a711830a66d592c89845cd6406b525b5f89f4d9ca50abbdbb48dbb5adbb07"},
|
||||
{name: "native-all-anyonecanpay-0-modify-input-0", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifyInput(0), // should change the hash
|
||||
expectedSignatureHash: "981959e8c427ba4a06c3d53abc93514ba179d8cc7e94daeb4f516a0c2c685f86"},
|
||||
expectedSignatureHash: "67157f1984a881c71ea92c9959da1b856383489a8bb0150783cdc4d58bca95ea"},
|
||||
{name: "native-all-anyonecanpay-0-modify-input-1", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifyInput(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "13270aeb5b56d844d064d5d2cf06af7dbd0341fd55069b9af56d5e3c99f2eddd"},
|
||||
expectedSignatureHash: "458a711830a66d592c89845cd6406b525b5f89f4d9ca50abbdbb48dbb5adbb07"},
|
||||
{name: "native-all-anyonecanpay-0-modify-sequence", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifySequence(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "13270aeb5b56d844d064d5d2cf06af7dbd0341fd55069b9af56d5e3c99f2eddd"},
|
||||
expectedSignatureHash: "458a711830a66d592c89845cd6406b525b5f89f4d9ca50abbdbb48dbb5adbb07"},
|
||||
|
||||
// sigHashNone
|
||||
{name: "native-none-0", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||
expectedSignatureHash: "a45955ca970039160bb91b1ea42e070b4ff21598654aad91c562e8b9af922c5f"},
|
||||
expectedSignatureHash: "bf92d39b8381e49d4b2f37a7d2e2d9b4f126b6659cb873b84ae3db8910cd9664"},
|
||||
{name: "native-none-0-modify-output-1", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||
modificationFunction: modifyOutput(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "a45955ca970039160bb91b1ea42e070b4ff21598654aad91c562e8b9af922c5f"},
|
||||
expectedSignatureHash: "bf92d39b8381e49d4b2f37a7d2e2d9b4f126b6659cb873b84ae3db8910cd9664"},
|
||||
{name: "native-none-0-modify-sequence-0", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||
modificationFunction: modifySequence(0), // should change the hash
|
||||
expectedSignatureHash: "e1a430a24d77bc259ae572e1505dd67d3444ba0ffbc7918e06ae7e907e575adb"},
|
||||
expectedSignatureHash: "20550f85a6ac0d4b20ebb0d8df9b1f4ec0ecb3df5adf539c9d6ad9af03f712d6"},
|
||||
{name: "native-none-0-modify-sequence-1", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||
modificationFunction: modifySequence(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "a45955ca970039160bb91b1ea42e070b4ff21598654aad91c562e8b9af922c5f"},
|
||||
expectedSignatureHash: "bf92d39b8381e49d4b2f37a7d2e2d9b4f126b6659cb873b84ae3db8910cd9664"},
|
||||
{name: "native-none-anyonecanpay-0", tx: nativeTx, hashType: noneAnyoneCanPay, inputIndex: 0,
|
||||
expectedSignatureHash: "6bae2a0f1f7b9fd59804f4720a1a918be31b7ec12e184585fa16bda8c7f8c35c"},
|
||||
expectedSignatureHash: "a048ec7a396397e1357b42905f26c51d0ec6c0943298ff4f2b8707ec3e8e1aa0"},
|
||||
{name: "native-none-anyonecanpay-0-modify-amount-spent", tx: nativeTx, hashType: noneAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifyAmountSpent(0), // should change the hash
|
||||
expectedSignatureHash: "6653d3d882d2ffc1c3ff5b7ccf07f7970c5973b824abb5b117803809c5a884c7"},
|
||||
expectedSignatureHash: "66125d23d3dc9711683a6dbc96d4d4411af41e71f92596e9983ea8c5e3a04753"},
|
||||
{name: "native-none-anyonecanpay-0-modify-script-public-key", tx: nativeTx, hashType: noneAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifyScriptPublicKey(0), // should change the hash
|
||||
expectedSignatureHash: "da3cb9094d905de69b3881cf8d4e2d5268bcf029dec5b62a972fcab90e6abde9"},
|
||||
expectedSignatureHash: "0ba5f527f8408b252eb77ea54efe63b831c736fea4bed58fc47c4ceaabf3f6cf"},
|
||||
|
||||
// sigHashSingle
|
||||
{name: "native-single-0", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
expectedSignatureHash: "964d03d8477dd468f3d9933676b5b4a976a68fee1760eae037be4247c36cc207"},
|
||||
expectedSignatureHash: "b21ec5c5e1830f8b9b3cb13bfbd542318a17d89d9844bd64167696ca36374f7f"},
|
||||
{name: "native-single-0-modify-output-0", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
modificationFunction: modifyOutput(0), // should change the hash
|
||||
expectedSignatureHash: "7c51b4a7c6a6e786b1c420c859c2853131d7041b8ba8de72cbcd026b2e0d511b"},
|
||||
expectedSignatureHash: "e15914f6b22979f70162f5c57b3ad7ceff91b8a2356960f66a23dc8e602303fe"},
|
||||
{name: "native-single-0-modify-output-1", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
modificationFunction: modifyOutput(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "964d03d8477dd468f3d9933676b5b4a976a68fee1760eae037be4247c36cc207"},
|
||||
expectedSignatureHash: "b21ec5c5e1830f8b9b3cb13bfbd542318a17d89d9844bd64167696ca36374f7f"},
|
||||
{name: "native-single-0-modify-sequence-0", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
modificationFunction: modifySequence(0), // should change the hash
|
||||
expectedSignatureHash: "d31e5a9e71560d2f66483e7e4e7d41418b66cd22814450848a2d8fa78045d6a0"},
|
||||
expectedSignatureHash: "a09f20428456475bc5fcff07242416d439faa0dec37152e31a8546874f323473"},
|
||||
{name: "native-single-0-modify-sequence-1", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
modificationFunction: modifySequence(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "964d03d8477dd468f3d9933676b5b4a976a68fee1760eae037be4247c36cc207"},
|
||||
expectedSignatureHash: "b21ec5c5e1830f8b9b3cb13bfbd542318a17d89d9844bd64167696ca36374f7f"},
|
||||
{name: "native-single-2-no-corresponding-output", tx: nativeTx, hashType: single, inputIndex: 2,
|
||||
expectedSignatureHash: "667b6b65682a6e1e14aec699a177d22ce1392661828e54dcd97cd83b05233d41"},
|
||||
expectedSignatureHash: "7cc3c80a6250599e47e4ceca66e3670b4fc74a009aba2b7df737bc37e8cb5b79"},
|
||||
{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: "667b6b65682a6e1e14aec699a177d22ce1392661828e54dcd97cd83b05233d41"},
|
||||
expectedSignatureHash: "7cc3c80a6250599e47e4ceca66e3670b4fc74a009aba2b7df737bc37e8cb5b79"},
|
||||
{name: "native-single-anyonecanpay-0", tx: nativeTx, hashType: singleAnyoneCanPay, inputIndex: 0,
|
||||
expectedSignatureHash: "a11c2fbcd4f09bffce9e5fca62323388a2cf9037fd3be66211c7869c067123a2"},
|
||||
expectedSignatureHash: "8040f5ebfc6c5a8285272d5e1956dd3036eaa9a7abec9b18cb1b614a015f2fc7"},
|
||||
{name: "native-single-anyonecanpay-2-no-corresponding-output", tx: nativeTx, hashType: singleAnyoneCanPay, inputIndex: 2,
|
||||
expectedSignatureHash: "00f429dfb9150d7a96aa3f179bcc6f8fbf9bce481f00c6bb97af67e108e5d0ff"},
|
||||
expectedSignatureHash: "5e1ac311544301aa6afa578f18e1d1871ffbc15915e01f25f2375715c3a3147d"},
|
||||
|
||||
// subnetwork transaction
|
||||
{name: "subnetwork-all-0", tx: subnetworkTx, hashType: all, inputIndex: 0,
|
||||
@@ -391,7 +390,7 @@ func generateTxs() (nativeTx, subnetworkTx *externalapi.DomainTransaction, err e
|
||||
Inputs: txIns,
|
||||
Outputs: txOuts,
|
||||
LockTime: 1615462089000,
|
||||
SubnetworkID: subnetworks.SubnetworkIDNative,
|
||||
SubnetworkID: externalapi.DomainSubnetworkID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
|
||||
}
|
||||
subnetworkTx = &externalapi.DomainTransaction{
|
||||
Version: 0,
|
||||
|
||||
@@ -139,19 +139,11 @@ func writeTransactionInput(w io.Writer, ti *externalapi.DomainTransactionInput,
|
||||
|
||||
if encodingFlags&txEncodingExcludeSignatureScript != txEncodingExcludeSignatureScript {
|
||||
err = writeVarBytes(w, ti.SignatureScript)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = w.Write([]byte{ti.SigOpCount})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
err = writeVarBytes(w, []byte{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return binaryserializer.PutUint64(w, ti.Sequence)
|
||||
|
||||
102
domain/consensus/utils/consensushashing/transaction_hash_test.go
Normal file
102
domain/consensus/utils/consensushashing/transaction_hash_test.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package consensushashing
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
|
||||
)
|
||||
|
||||
func TestTransactionHash(t *testing.T) {
|
||||
tx := externalapi.DomainTransaction{0, []*externalapi.DomainTransactionInput{}, []*externalapi.DomainTransactionOutput{}, 0,
|
||||
externalapi.DomainSubnetworkID{}, 0, []byte{}, 0, 0,
|
||||
nil}
|
||||
id := TransactionID(&tx)
|
||||
fmt.Printf("%s\n", id)
|
||||
tx_hash := TransactionHash(&tx)
|
||||
fmt.Printf("%s\n\n", tx_hash)
|
||||
|
||||
inputs := []*externalapi.DomainTransactionInput{&externalapi.DomainTransactionInput{
|
||||
PreviousOutpoint: externalapi.DomainOutpoint{
|
||||
TransactionID: externalapi.DomainTransactionID{},
|
||||
Index: 2,
|
||||
},
|
||||
SignatureScript: []byte{1, 2},
|
||||
Sequence: 7,
|
||||
SigOpCount: 5,
|
||||
UTXOEntry: nil,
|
||||
}}
|
||||
|
||||
tx = externalapi.DomainTransaction{1, inputs, []*externalapi.DomainTransactionOutput{}, 0,
|
||||
externalapi.DomainSubnetworkID{}, 0, []byte{}, 0, 0,
|
||||
nil}
|
||||
id = TransactionID(&tx)
|
||||
fmt.Printf("%s\n", id)
|
||||
tx_hash = TransactionHash(&tx)
|
||||
fmt.Printf("%s\n\n", tx_hash)
|
||||
|
||||
outputs := []*externalapi.DomainTransactionOutput{&externalapi.DomainTransactionOutput{
|
||||
Value: 1564,
|
||||
ScriptPublicKey: &externalapi.ScriptPublicKey{
|
||||
Script: []byte{1, 2, 3, 4, 5},
|
||||
Version: 7,
|
||||
},
|
||||
}}
|
||||
|
||||
tx = externalapi.DomainTransaction{1, inputs, outputs, 0,
|
||||
externalapi.DomainSubnetworkID{}, 0, []byte{}, 0, 0,
|
||||
nil}
|
||||
id = TransactionID(&tx)
|
||||
fmt.Printf("%s\n", id)
|
||||
tx_hash = TransactionHash(&tx)
|
||||
fmt.Printf("%s\n\n", tx_hash)
|
||||
|
||||
tx = externalapi.DomainTransaction{2, inputs, outputs, 54,
|
||||
externalapi.DomainSubnetworkID{}, 3, []byte{}, 4, 7,
|
||||
nil}
|
||||
id = TransactionID(&tx)
|
||||
fmt.Printf("%s\n", id)
|
||||
tx_hash = TransactionHash(&tx)
|
||||
fmt.Printf("%s\n\n", tx_hash)
|
||||
|
||||
transactionId, err := externalapi.NewDomainHashFromString("59b3d6dc6cdc660c389c3fdb5704c48c598d279cdf1bab54182db586a4c95dd5")
|
||||
if err != nil {
|
||||
t.Fatalf("%s", err)
|
||||
}
|
||||
|
||||
inputs = []*externalapi.DomainTransactionInput{&externalapi.DomainTransactionInput{
|
||||
PreviousOutpoint: externalapi.DomainOutpoint{
|
||||
TransactionID: externalapi.DomainTransactionID(*transactionId),
|
||||
Index: 2,
|
||||
},
|
||||
SignatureScript: []byte{1, 2},
|
||||
Sequence: 7,
|
||||
SigOpCount: 5,
|
||||
UTXOEntry: nil,
|
||||
}}
|
||||
|
||||
tx = externalapi.DomainTransaction{2, inputs, outputs, 54,
|
||||
externalapi.DomainSubnetworkID{}, 3, []byte{}, 4, 7,
|
||||
nil}
|
||||
id = TransactionID(&tx)
|
||||
fmt.Printf("%s\n", id)
|
||||
tx_hash = TransactionHash(&tx)
|
||||
fmt.Printf("%s\n\n", tx_hash)
|
||||
|
||||
tx = externalapi.DomainTransaction{2, inputs, outputs, 54,
|
||||
subnetworks.SubnetworkIDCoinbase, 3, []byte{}, 4, 7,
|
||||
nil}
|
||||
id = TransactionID(&tx)
|
||||
fmt.Printf("%s\n", id)
|
||||
tx_hash = TransactionHash(&tx)
|
||||
fmt.Printf("%s\n\n", tx_hash)
|
||||
|
||||
tx = externalapi.DomainTransaction{2, inputs, outputs, 54,
|
||||
subnetworks.SubnetworkIDRegistry, 3, []byte{}, 4, 7,
|
||||
nil}
|
||||
id = TransactionID(&tx)
|
||||
fmt.Printf("%s\n", id)
|
||||
tx_hash = TransactionHash(&tx)
|
||||
fmt.Printf("%s\n\n", tx_hash)
|
||||
}
|
||||
@@ -105,7 +105,7 @@ var devnetGenesisCoinbaseTx = transactionhelper.NewSubnetworkTransaction(0,
|
||||
// devGenesisHash is the hash of the first block in the block DAG for the development
|
||||
// network (genesis block).
|
||||
var devnetGenesisHash = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
|
||||
0xb3, 0x13, 0x87, 0x0a, 0x32, 0xc7, 0x04, 0xbd, 0xf1, 0x21, 0x4a, 0x3b, 0x27, 0x0c, 0xc4, 0x75, 0xd9, 0x42, 0xc2, 0x09, 0x2d, 0x37, 0x9b, 0xc8, 0x70, 0x0a, 0xb0, 0x43, 0x31, 0x9e, 0xf8, 0x46,
|
||||
0x4c, 0x64, 0x16, 0x35, 0xc8, 0x5d, 0xc8, 0x8d, 0x90, 0xbe, 0x2a, 0x42, 0xc1, 0xf6, 0x0f, 0xc4, 0xe9, 0xfc, 0xfc, 0xda, 0xdb, 0x53, 0x0d, 0x51, 0xe3, 0x02, 0x2b, 0x68, 0x65, 0xa6, 0x46, 0x7b,
|
||||
})
|
||||
|
||||
// devnetGenesisMerkleRoot is the hash of the first transaction in the genesis block
|
||||
@@ -127,7 +127,7 @@ var devnetGenesisBlock = externalapi.DomainBlock{
|
||||
&externalapi.DomainHash{},
|
||||
externalapi.NewDomainHashFromByteArray(muhash.EmptyMuHashHash.AsArray()),
|
||||
0x11e9db49828,
|
||||
525264379,
|
||||
0x207fffff,
|
||||
0x48e5e,
|
||||
0,
|
||||
0,
|
||||
|
||||
@@ -297,11 +297,7 @@ var TestnetParams = Params{
|
||||
Net: appmessage.Testnet,
|
||||
RPCPort: "16210",
|
||||
DefaultPort: "16211",
|
||||
DNSSeeds: []string{
|
||||
"testnet-10-dnsseed.kas.pa",
|
||||
// This DNS seeder is run by Tiram
|
||||
"seeder1-testnet.kaspad.net",
|
||||
},
|
||||
DNSSeeds: []string{"testnet-10-dnsseed.kas.pa"},
|
||||
|
||||
// DAG parameters
|
||||
GenesisBlock: &testnetGenesisBlock,
|
||||
|
||||
@@ -2,7 +2,6 @@ package domain
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/pkg/errors"
|
||||
"math"
|
||||
)
|
||||
|
||||
@@ -67,15 +66,11 @@ func syncConsensuses(syncer, syncee externalapi.Consensus) error {
|
||||
}
|
||||
|
||||
for _, blockHash := range pruningPointAndItsAnticone {
|
||||
block, found, err := syncer.GetBlock(blockHash)
|
||||
block, err := syncer.GetBlock(blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !found {
|
||||
return errors.Errorf("block %s is missing", blockHash)
|
||||
}
|
||||
|
||||
blockDAAWindowHashes, err := syncer.BlockDAAWindowHashes(blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -161,14 +156,11 @@ func syncConsensuses(syncer, syncee externalapi.Consensus) error {
|
||||
continue
|
||||
}
|
||||
|
||||
block, found, err := syncer.GetBlock(blocksHash)
|
||||
block, err := syncer.GetBlock(blocksHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !found {
|
||||
return errors.Errorf("block %s is missing", blocksHash)
|
||||
}
|
||||
err = syncee.ValidateAndInsertBlock(block, false)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -339,7 +339,7 @@ func TestOrphanTransactions(t *testing.T) {
|
||||
t.Fatalf("AddBlock: %v", err)
|
||||
}
|
||||
|
||||
blockParentsTransactions, _, err := tc.GetBlock(blockParentsTransactionsHash)
|
||||
blockParentsTransactions, err := tc.GetBlock(blockParentsTransactionsHash)
|
||||
if err != nil {
|
||||
t.Fatalf("GetBlock: %v", err)
|
||||
}
|
||||
@@ -648,7 +648,7 @@ func TestModifyBlockTemplate(t *testing.T) {
|
||||
t.Fatalf("AddBlock: %v", err)
|
||||
}
|
||||
|
||||
blockParentsTransactions, _, err := tc.GetBlock(blockParentsTransactionsHash)
|
||||
blockParentsTransactions, err := tc.GetBlock(blockParentsTransactionsHash)
|
||||
if err != nil {
|
||||
t.Fatalf("GetBlock: %v", err)
|
||||
}
|
||||
@@ -924,7 +924,7 @@ func createParentAndChildrenTransactions(tc testapi.TestConsensus) (txParent *ex
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "AddBlock: ")
|
||||
}
|
||||
fundingBlockForParent, _, err := tc.GetBlock(fundingBlockHashForParent)
|
||||
fundingBlockForParent, err := tc.GetBlock(fundingBlockHashForParent)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "GetBlock: ")
|
||||
}
|
||||
@@ -949,7 +949,7 @@ func createChildAndParentTxsAndAddParentToConsensus(tc testapi.TestConsensus) (*
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "AddBlock: ")
|
||||
}
|
||||
ParentBlock, _, err := tc.GetBlock(ParentBlockHash)
|
||||
ParentBlock, err := tc.GetBlock(ParentBlockHash)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetBlock: ")
|
||||
}
|
||||
|
||||
3
go.mod
3
go.mod
@@ -7,7 +7,6 @@ require (
|
||||
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd
|
||||
github.com/btcsuite/winsvc v1.0.0
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/gofrs/flock v0.8.1
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/jessevdk/go-flags v1.4.0
|
||||
github.com/jrick/logrotate v1.0.0
|
||||
@@ -20,7 +19,7 @@ require (
|
||||
golang.org/x/exp v0.0.0-20220414153411-bcd21879b8fd
|
||||
golang.org/x/term v0.0.0-20210503060354-a79de5458b56
|
||||
google.golang.org/grpc v1.38.0
|
||||
google.golang.org/protobuf v1.28.1
|
||||
google.golang.org/protobuf v1.27.1
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
12
go.sum
12
go.sum
@@ -26,8 +26,6 @@ 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/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/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/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
@@ -120,6 +118,8 @@ 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-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-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/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
@@ -155,6 +155,8 @@ 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.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0=
|
||||
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-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
@@ -165,10 +167,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.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 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
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=
|
||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
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/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
|
||||
@@ -2,12 +2,8 @@ package grpcserver
|
||||
|
||||
import (
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/infrastructure/logger"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
routerpkg "github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
|
||||
@@ -29,9 +25,6 @@ func (c *gRPCConnection) connectionLoops() error {
|
||||
return err
|
||||
}
|
||||
|
||||
var blockDelayOnce sync.Once
|
||||
var blockDelay = 0
|
||||
|
||||
func (c *gRPCConnection) sendLoop() error {
|
||||
outgoingRoute := c.router.OutgoingRoute()
|
||||
for c.IsConnected() {
|
||||
@@ -43,20 +36,6 @@ func (c *gRPCConnection) sendLoop() error {
|
||||
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.Tracef("outgoing '%s' message to %s: %s", message.Command(), c, logger.NewLogClosure(func() string {
|
||||
return spew.Sdump(message)
|
||||
|
||||
@@ -35,7 +35,7 @@ func (x *KaspadMessage_GetConnectedPeerInfoResponse) fromAppMessage(message *app
|
||||
TimeOffset: info.TimeOffset,
|
||||
UserAgent: info.UserAgent,
|
||||
AdvertisedProtocolVersion: info.AdvertisedProtocolVersion,
|
||||
TimeConnected: info.TimeConnected,
|
||||
TimeConnected: info.TimeOffset,
|
||||
IsIbdPeer: info.IsIBDPeer,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ func (c *RPCClient) connect() error {
|
||||
remoteVersion := getInfoResponse.ServerVersion
|
||||
|
||||
if localVersion != remoteVersion {
|
||||
log.Warnf("version mismatch, client: %s, server: %s - expected responses and requests may deviate", localVersion, remoteVersion)
|
||||
return errors.Errorf("Server version mismatch, expect: %s, got: %s", localVersion, remoteVersion)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -105,16 +105,7 @@ func mineBlocks(consensusConfig *consensus.Config, rpcClient *rpc.Client, blockC
|
||||
func mineOrFetchBlock(blockData JSONBlock, mdb *miningDB, testConsensus testapi.TestConsensus) (*externalapi.DomainBlock, error) {
|
||||
hash := mdb.hashByID(blockData.ID)
|
||||
if mdb.hashByID(blockData.ID) != nil {
|
||||
block, found, err := testConsensus.GetBlock(hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !found {
|
||||
return nil, errors.Errorf("block %s is missing", hash)
|
||||
}
|
||||
|
||||
return block, nil
|
||||
return testConsensus.GetBlock(hash)
|
||||
}
|
||||
|
||||
parentHashes := make([]*externalapi.DomainHash, len(blockData.Parents))
|
||||
|
||||
@@ -44,7 +44,7 @@ func TestGenerateFastPruningIBDTest(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
tip, _, err := tc.GetBlock(tipHash)
|
||||
tip, err := tc.GetBlock(tipHash)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ func TestGetHashrateString(t *testing.T) {
|
||||
var results = map[string]string{
|
||||
dagconfig.MainnetParams.Name: "1.53 GH/s",
|
||||
dagconfig.TestnetParams.Name: "131.07 KH/s",
|
||||
dagconfig.DevnetParams.Name: "830 H/s",
|
||||
dagconfig.DevnetParams.Name: "2 H/s",
|
||||
dagconfig.SimnetParams.Name: "2.00 KH/s",
|
||||
}
|
||||
testutils.ForAllNets(t, false, func(t *testing.T, consensusConfig *consensus.Config) {
|
||||
|
||||
@@ -11,7 +11,7 @@ const validCharacters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrs
|
||||
const (
|
||||
appMajor uint = 0
|
||||
appMinor uint = 12
|
||||
appPatch uint = 10
|
||||
appPatch uint = 5
|
||||
)
|
||||
|
||||
// appBuild is defined as a variable so it can be overridden during the build
|
||||
|
||||
Reference in New Issue
Block a user