Compare commits

..

1 Commits

Author SHA1 Message Date
msutton
242513c5a2 Transaction hashing outputs to be used as reference for rust imp 2022-09-06 14:42:40 +03:00
69 changed files with 432 additions and 664 deletions

View File

@@ -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.

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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))

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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) {

View File

@@ -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(),

View File

@@ -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

View File

@@ -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
===========================

View File

@@ -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

View File

@@ -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

View File

@@ -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
}

View File

@@ -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

View File

@@ -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`")

View File

@@ -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,

View File

@@ -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

View File

@@ -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{

View File

@@ -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 {

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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() {

View File

@@ -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)
}

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -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,

View File

@@ -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)
}

View File

@@ -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)

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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,

View File

@@ -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)
}
}
})
}

View File

@@ -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 {

View File

@@ -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)
}

View File

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

View File

@@ -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.

View File

@@ -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: {

View File

@@ -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)
}

View File

@@ -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",
},
}

View File

@@ -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)

View File

@@ -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",

View File

@@ -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
}

View File

@@ -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,

View File

@@ -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,
}
}

View File

@@ -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)
}

View File

@@ -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

View File

@@ -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)
}

View File

@@ -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,

View File

@@ -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)

View 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)
}

View File

@@ -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,

View File

@@ -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,

View File

@@ -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

View File

@@ -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
View File

@@ -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
View File

@@ -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=

View File

@@ -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)

View File

@@ -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,
}
}

View File

@@ -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

View File

@@ -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))

View File

@@ -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)
}

View File

@@ -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) {

View File

@@ -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