Compare commits

..

9 Commits

Author SHA1 Message Date
Ori Newman
227ef392ba Update version 2021-12-11 20:55:25 +02:00
Ori Newman
f3d76d6565 Ignore header mass in devnet and testnet (#1879) 2021-12-11 20:36:58 +02:00
Ori Newman
df573bba63 Remove unused args from CalcSubsidy (#1877) 2021-12-11 20:16:23 +02:00
Ori Newman
2a97b7c9bb ExpectedHeaderPruningPoint fix (#1876)
* ExpectedHeaderPruningPoint fix

* Fix off by one error when iterating lowHash's selected chain
2021-12-11 19:26:35 +02:00
Svarog
70900c571b Changes to libkaspawallet to support Kaspaper (#1878)
* Add NewFileFromMnemonics

* Export InternalKeychain and ExternalKeychain

* Rename NewFileFromMnemonics -> NewFileFromMnemonic

* NewFileFromMnemonic: change also argument name

* Use libkaspawallet.ExternalKeychain instead of externalKeychain
2021-12-11 17:52:21 +02:00
Constantine Bytensky
7292438e4a kaspawallet: show-address →new-address + show-addresses (#1870)
* Rename show-address to new-address

* New proto: ShowAdresses

* kaspawallet: added show-addresses command

Co-authored-by: Constantine Bitensky <cbitensky1@gmail.com>
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-12-07 00:49:06 +02:00
Ori Newman
dced1a9376 Fix numThreads using getAEAD instead of decryptMnemonic (#1859)
* Fix num threads using getAEAD instead of decryptMnemonic

* Use d.NumThread to init bruteforce for num threads in getAEAD

Co-authored-by: Ori Newman <>
2021-12-06 23:56:00 +02:00
Ori Newman
32e8e539ac Apply ResolveVirtual diffs to the UTXO index (#1868)
* Apply ResolveVirtual diffs to the UTXO index

* Add comments

Co-authored-by: Ori Newman <>
2021-12-05 13:22:48 +02:00
Ori Newman
11103a36d3 Get rid of genesis's UTXO dump (#1867)
* Get rid of genesis's UTXO dump

* Allow known orphans when AllowSubmitBlockWhenNotSynced=true

* gofmt

* Avoid IBD without changing the pruning point when only genesis is available

* Add DisallowDirectBlocksOnTopOfGenesis=true for mainnet

* Remove any mention to nobanning to let stability tests run

* Rename ifGenesisSetUtxoSet to loadUTXODataForGenesis

Co-authored-by: Ori Newman <>
2021-12-05 12:46:41 +02:00
60 changed files with 796 additions and 450 deletions

View File

@@ -152,6 +152,7 @@ func setupRPC(
utxoIndex,
shutDownChan,
)
protocolManager.SetOnVirtualChange(rpcManager.NotifyVirtualChange)
protocolManager.SetOnBlockAddedToDAGHandler(rpcManager.NotifyBlockAddedToDAG)
protocolManager.SetOnPruningPointUTXOSetOverrideHandler(rpcManager.NotifyPruningPointUTXOSetOverride)

View File

@@ -18,7 +18,7 @@ import (
// relays newly unorphaned transactions and possibly rebroadcast
// manually added transactions when not in IBD.
func (f *FlowContext) OnNewBlock(block *externalapi.DomainBlock,
blockInsertionResult *externalapi.BlockInsertionResult) error {
virtualChangeSet *externalapi.VirtualChangeSet) error {
hash := consensushashing.BlockHash(block)
log.Debugf("OnNewBlock start for block %s", hash)
@@ -32,10 +32,10 @@ func (f *FlowContext) OnNewBlock(block *externalapi.DomainBlock,
log.Debugf("OnNewBlock: block %s unorphaned %d blocks", hash, len(unorphaningResults))
newBlocks := []*externalapi.DomainBlock{block}
newBlockInsertionResults := []*externalapi.BlockInsertionResult{blockInsertionResult}
newVirtualChangeSets := []*externalapi.VirtualChangeSet{virtualChangeSet}
for _, unorphaningResult := range unorphaningResults {
newBlocks = append(newBlocks, unorphaningResult.block)
newBlockInsertionResults = append(newBlockInsertionResults, unorphaningResult.blockInsertionResult)
newVirtualChangeSets = append(newVirtualChangeSets, unorphaningResult.virtualChangeSet)
}
allAcceptedTransactions := make([]*externalapi.DomainTransaction, 0)
@@ -49,8 +49,8 @@ func (f *FlowContext) OnNewBlock(block *externalapi.DomainBlock,
if f.onBlockAddedToDAGHandler != nil {
log.Debugf("OnNewBlock: calling f.onBlockAddedToDAGHandler for block %s", hash)
blockInsertionResult = newBlockInsertionResults[i]
err := f.onBlockAddedToDAGHandler(newBlock, blockInsertionResult)
virtualChangeSet = newVirtualChangeSets[i]
err := f.onBlockAddedToDAGHandler(newBlock, virtualChangeSet)
if err != nil {
return err
}
@@ -60,6 +60,15 @@ func (f *FlowContext) OnNewBlock(block *externalapi.DomainBlock,
return f.broadcastTransactionsAfterBlockAdded(newBlocks, allAcceptedTransactions)
}
// OnVirtualChange calls the handler function whenever the virtual block changes.
func (f *FlowContext) OnVirtualChange(virtualChangeSet *externalapi.VirtualChangeSet) error {
if f.onVirtualChangeHandler != nil && virtualChangeSet != nil {
return f.onVirtualChangeHandler(virtualChangeSet)
}
return nil
}
// OnPruningPointUTXOSetOverride calls the handler function whenever the UTXO set
// resets due to pruning point change via IBD.
func (f *FlowContext) OnPruningPointUTXOSetOverride() error {
@@ -110,14 +119,14 @@ func (f *FlowContext) AddBlock(block *externalapi.DomainBlock) error {
return protocolerrors.Errorf(false, "cannot add header only block")
}
blockInsertionResult, err := f.Domain().Consensus().ValidateAndInsertBlock(block, true)
virtualChangeSet, err := f.Domain().Consensus().ValidateAndInsertBlock(block, true)
if err != nil {
if errors.As(err, &ruleerrors.RuleError{}) {
log.Warnf("Validation failed for block %s: %s", consensushashing.BlockHash(block), err)
}
return err
}
err = f.OnNewBlock(block, blockInsertionResult)
err = f.OnNewBlock(block, virtualChangeSet)
if err != nil {
return err
}

View File

@@ -22,7 +22,10 @@ import (
// OnBlockAddedToDAGHandler is a handler function that's triggered
// when a block is added to the DAG
type OnBlockAddedToDAGHandler func(block *externalapi.DomainBlock, blockInsertionResult *externalapi.BlockInsertionResult) error
type OnBlockAddedToDAGHandler func(block *externalapi.DomainBlock, virtualChangeSet *externalapi.VirtualChangeSet) error
// OnVirtualChangeHandler is a handler function that's triggered when the virtual changes
type OnVirtualChangeHandler func(virtualChangeSet *externalapi.VirtualChangeSet) error
// OnPruningPointUTXOSetOverrideHandler is a handle function that's triggered whenever the UTXO set
// resets due to pruning point change via IBD.
@@ -43,6 +46,7 @@ type FlowContext struct {
timeStarted int64
onVirtualChangeHandler OnVirtualChangeHandler
onBlockAddedToDAGHandler OnBlockAddedToDAGHandler
onPruningPointUTXOSetOverrideHandler OnPruningPointUTXOSetOverrideHandler
onTransactionAddedToMempoolHandler OnTransactionAddedToMempoolHandler
@@ -100,6 +104,11 @@ func (f *FlowContext) ShutdownChan() <-chan struct{} {
return f.shutdownChan
}
// SetOnVirtualChangeHandler sets the onVirtualChangeHandler handler
func (f *FlowContext) SetOnVirtualChangeHandler(onVirtualChangeHandler OnVirtualChangeHandler) {
f.onVirtualChangeHandler = onVirtualChangeHandler
}
// SetOnBlockAddedToDAGHandler sets the onBlockAddedToDAG handler
func (f *FlowContext) SetOnBlockAddedToDAGHandler(onBlockAddedToDAGHandler OnBlockAddedToDAGHandler) {
f.onBlockAddedToDAGHandler = onBlockAddedToDAGHandler

View File

@@ -17,8 +17,8 @@ const maxOrphans = 600
// UnorphaningResult is the result of unorphaning a block
type UnorphaningResult struct {
block *externalapi.DomainBlock
blockInsertionResult *externalapi.BlockInsertionResult
block *externalapi.DomainBlock
virtualChangeSet *externalapi.VirtualChangeSet
}
// AddOrphan adds the block to the orphan set
@@ -90,14 +90,14 @@ func (f *FlowContext) UnorphanBlocks(rootBlock *externalapi.DomainBlock) ([]*Uno
}
}
if canBeUnorphaned {
blockInsertionResult, unorphaningSucceeded, err := f.unorphanBlock(orphanHash)
virtualChangeSet, unorphaningSucceeded, err := f.unorphanBlock(orphanHash)
if err != nil {
return nil, err
}
if unorphaningSucceeded {
unorphaningResults = append(unorphaningResults, &UnorphaningResult{
block: orphanBlock,
blockInsertionResult: blockInsertionResult,
block: orphanBlock,
virtualChangeSet: virtualChangeSet,
})
processQueue = f.addChildOrphansToProcessQueue(&orphanHash, processQueue)
}
@@ -143,14 +143,14 @@ func (f *FlowContext) findChildOrphansOfBlock(blockHash *externalapi.DomainHash)
return childOrphans
}
func (f *FlowContext) unorphanBlock(orphanHash externalapi.DomainHash) (*externalapi.BlockInsertionResult, bool, error) {
func (f *FlowContext) unorphanBlock(orphanHash externalapi.DomainHash) (*externalapi.VirtualChangeSet, bool, error) {
orphanBlock, ok := f.orphans[orphanHash]
if !ok {
return nil, false, errors.Errorf("attempted to unorphan a non-orphan block %s", orphanHash)
}
delete(f.orphans, orphanHash)
blockInsertionResult, err := f.domain.Consensus().ValidateAndInsertBlock(orphanBlock, true)
virtualChangeSet, err := f.domain.Consensus().ValidateAndInsertBlock(orphanBlock, true)
if err != nil {
if errors.As(err, &ruleerrors.RuleError{}) {
log.Warnf("Validation failed for orphan block %s: %s", orphanHash, err)
@@ -160,7 +160,7 @@ func (f *FlowContext) unorphanBlock(orphanHash externalapi.DomainHash) (*externa
}
log.Infof("Unorphaned block %s", orphanHash)
return blockInsertionResult, true, nil
return virtualChangeSet, true, nil
}
// GetOrphanRoots returns the roots of the missing ancestors DAG of the given orphan

View File

@@ -25,6 +25,10 @@ func (f *FlowContext) ShouldMine() (bool, error) {
return false, err
}
if virtualSelectedParent.Equal(f.Config().NetParams().GenesisHash) {
return false, nil
}
virtualSelectedParentHeader, err := f.domain.Consensus().GetBlockHeader(virtualSelectedParent)
if err != nil {
return false, err

View File

@@ -23,7 +23,8 @@ var orphanResolutionRange uint32 = 5
type RelayInvsContext interface {
Domain() domain.Domain
Config() *config.Config
OnNewBlock(block *externalapi.DomainBlock, blockInsertionResult *externalapi.BlockInsertionResult) error
OnNewBlock(block *externalapi.DomainBlock, virtualChangeSet *externalapi.VirtualChangeSet) error
OnVirtualChange(virtualChangeSet *externalapi.VirtualChangeSet) error
OnPruningPointUTXOSetOverride() error
SharedRequestedBlocks() *SharedRequestedBlocks
Broadcast(message appmessage.Message) error
@@ -81,7 +82,18 @@ func (flow *handleRelayInvsFlow) start() error {
continue
}
isGenesisVirtualSelectedParent, err := flow.isGenesisVirtualSelectedParent()
if err != nil {
return err
}
if flow.IsOrphan(inv.Hash) {
if flow.Config().NetParams().DisallowDirectBlocksOnTopOfGenesis && !flow.Config().AllowSubmitBlockWhenNotSynced && isGenesisVirtualSelectedParent {
log.Infof("Cannot process orphan %s for a node with only the genesis block. The node needs to IBD "+
"to the recent pruning point before normal operation can resume.", inv.Hash)
continue
}
log.Debugf("Block %s is a known orphan. Requesting its missing ancestors", inv.Hash)
err := flow.AddOrphanRootsToQueue(inv.Hash)
if err != nil {
@@ -111,8 +123,13 @@ func (flow *handleRelayInvsFlow) start() error {
return err
}
if flow.Config().NetParams().DisallowDirectBlocksOnTopOfGenesis && !flow.Config().AllowSubmitBlockWhenNotSynced && !flow.Config().Devnet && flow.isChildOfGenesis(block) {
log.Infof("Cannot process %s because it's a direct child of genesis.", consensushashing.BlockHash(block))
continue
}
log.Debugf("Processing block %s", inv.Hash)
missingParents, blockInsertionResult, err := flow.processBlock(block)
missingParents, virtualChangeSet, err := flow.processBlock(block)
if err != nil {
if errors.Is(err, ruleerrors.ErrPrunedBlock) {
log.Infof("Ignoring pruned block %s", inv.Hash)
@@ -140,7 +157,7 @@ func (flow *handleRelayInvsFlow) start() error {
return err
}
log.Infof("Accepted block %s via relay", inv.Hash)
err = flow.OnNewBlock(block, blockInsertionResult)
err = flow.OnNewBlock(block, virtualChangeSet)
if err != nil {
return err
}
@@ -227,9 +244,9 @@ func (flow *handleRelayInvsFlow) readMsgBlock() (msgBlock *appmessage.MsgBlock,
}
}
func (flow *handleRelayInvsFlow) processBlock(block *externalapi.DomainBlock) ([]*externalapi.DomainHash, *externalapi.BlockInsertionResult, error) {
func (flow *handleRelayInvsFlow) processBlock(block *externalapi.DomainBlock) ([]*externalapi.DomainHash, *externalapi.VirtualChangeSet, error) {
blockHash := consensushashing.BlockHash(block)
blockInsertionResult, err := flow.Domain().Consensus().ValidateAndInsertBlock(block, true)
virtualChangeSet, err := flow.Domain().Consensus().ValidateAndInsertBlock(block, true)
if err != nil {
if !errors.As(err, &ruleerrors.RuleError{}) {
return nil, nil, errors.Wrapf(err, "failed to process block %s", blockHash)
@@ -242,7 +259,7 @@ func (flow *handleRelayInvsFlow) processBlock(block *externalapi.DomainBlock) ([
log.Warnf("Rejected block %s from %s: %s", blockHash, flow.peer, err)
return nil, nil, protocolerrors.Wrapf(true, err, "got invalid block %s from relay", blockHash)
}
return nil, blockInsertionResult, nil
return nil, virtualChangeSet, nil
}
func (flow *handleRelayInvsFlow) relayBlock(block *externalapi.DomainBlock) error {
@@ -265,6 +282,19 @@ func (flow *handleRelayInvsFlow) processOrphan(block *externalapi.DomainBlock) e
return err
}
if isBlockInOrphanResolutionRange {
if flow.Config().NetParams().DisallowDirectBlocksOnTopOfGenesis && !flow.Config().AllowSubmitBlockWhenNotSynced {
isGenesisVirtualSelectedParent, err := flow.isGenesisVirtualSelectedParent()
if err != nil {
return err
}
if isGenesisVirtualSelectedParent {
log.Infof("Cannot process orphan %s for a node with only the genesis block. The node needs to IBD "+
"to the recent pruning point before normal operation can resume.", blockHash)
return nil
}
}
log.Debugf("Block %s is within orphan resolution range. "+
"Adding it to the orphan set", blockHash)
flow.AddOrphan(block)
@@ -278,6 +308,20 @@ func (flow *handleRelayInvsFlow) processOrphan(block *externalapi.DomainBlock) e
return flow.runIBDIfNotRunning(block)
}
func (flow *handleRelayInvsFlow) isGenesisVirtualSelectedParent() (bool, error) {
virtualSelectedParent, err := flow.Domain().Consensus().GetVirtualSelectedParent()
if err != nil {
return false, err
}
return virtualSelectedParent.Equal(flow.Config().NetParams().GenesisHash), nil
}
func (flow *handleRelayInvsFlow) isChildOfGenesis(block *externalapi.DomainBlock) bool {
parents := block.Header.DirectParents()
return len(parents) == 1 && parents[0].Equal(flow.Config().NetParams().GenesisHash)
}
// isBlockInOrphanResolutionRange finds out whether the given blockHash should be
// retrieved via the unorphaning mechanism or via IBD. This method sends a
// getBlockLocator request to the peer with a limit of orphanResolutionRange.

View File

@@ -55,6 +55,19 @@ func (flow *handleRelayInvsFlow) runIBDIfNotRunning(block *externalapi.DomainBlo
return err
}
} else {
if flow.Config().NetParams().DisallowDirectBlocksOnTopOfGenesis && !flow.Config().AllowSubmitBlockWhenNotSynced {
isGenesisVirtualSelectedParent, err := flow.isGenesisVirtualSelectedParent()
if err != nil {
return err
}
if isGenesisVirtualSelectedParent {
log.Infof("Cannot IBD to %s because it won't change the pruning point. The node needs to IBD "+
"to the recent pruning point before normal operation can resume.", highHash)
return nil
}
}
err = flow.syncPruningPointFutureHeaders(flow.Domain().Consensus(), highestSharedBlockHash, highHash)
if err != nil {
return err
@@ -458,7 +471,7 @@ func (flow *handleRelayInvsFlow) syncMissingBlockBodies(highHash *externalapi.Do
return err
}
blockInsertionResult, err := flow.Domain().Consensus().ValidateAndInsertBlock(block, false)
virtualChangeSet, 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)
@@ -466,14 +479,36 @@ func (flow *handleRelayInvsFlow) syncMissingBlockBodies(highHash *externalapi.Do
}
return protocolerrors.ConvertToBanningProtocolErrorIfRuleError(err, "invalid block %s", blockHash)
}
err = flow.OnNewBlock(block, blockInsertionResult)
err = flow.OnNewBlock(block, virtualChangeSet)
if err != nil {
return err
}
}
}
return flow.Domain().Consensus().ResolveVirtual()
return flow.resolveVirtual()
}
func (flow *handleRelayInvsFlow) resolveVirtual() error {
for i := 0; ; i++ {
if i%10 == 0 {
log.Infof("Resolving virtual. This may take some time...")
}
virtualChangeSet, isCompletelyResolved, err := flow.Domain().Consensus().ResolveVirtual()
if err != nil {
return err
}
err = flow.OnVirtualChange(virtualChangeSet)
if err != nil {
return err
}
if isCompletelyResolved {
log.Infof("Resolved virtual")
return nil
}
}
}
// dequeueIncomingMessageAndSkipInvs is a convenience method to be used during

View File

@@ -84,6 +84,11 @@ func (m *Manager) runFlows(flows []*flow, peer *peerpkg.Peer, errChan <-chan err
return <-errChan
}
// SetOnVirtualChange sets the onVirtualChangeHandler handler
func (m *Manager) SetOnVirtualChange(onVirtualChangeHandler flowcontext.OnVirtualChangeHandler) {
m.context.SetOnVirtualChangeHandler(onVirtualChangeHandler)
}
// SetOnBlockAddedToDAGHandler sets the onBlockAddedToDAG handler
func (m *Manager) SetOnBlockAddedToDAGHandler(onBlockAddedToDAGHandler flowcontext.OnBlockAddedToDAGHandler) {
m.context.SetOnBlockAddedToDAGHandler(onBlockAddedToDAGHandler)

View File

@@ -48,12 +48,31 @@ func NewManager(
}
// NotifyBlockAddedToDAG notifies the manager that a block has been added to the DAG
func (m *Manager) NotifyBlockAddedToDAG(block *externalapi.DomainBlock, blockInsertionResult *externalapi.BlockInsertionResult) error {
func (m *Manager) NotifyBlockAddedToDAG(block *externalapi.DomainBlock, virtualChangeSet *externalapi.VirtualChangeSet) error {
onEnd := logger.LogAndMeasureExecutionTime(log, "RPCManager.NotifyBlockAddedToDAG")
defer onEnd()
err := m.NotifyVirtualChange(virtualChangeSet)
if err != nil {
return err
}
rpcBlock := appmessage.DomainBlockToRPCBlock(block)
err = m.context.PopulateBlockWithVerboseData(rpcBlock, block.Header, block, false)
if err != nil {
return err
}
blockAddedNotification := appmessage.NewBlockAddedNotificationMessage(rpcBlock)
return m.context.NotificationManager.NotifyBlockAdded(blockAddedNotification)
}
// NotifyVirtualChange notifies the manager that the virtual block has been changed.
func (m *Manager) NotifyVirtualChange(virtualChangeSet *externalapi.VirtualChangeSet) error {
onEnd := logger.LogAndMeasureExecutionTime(log, "RPCManager.NotifyBlockAddedToDAG")
defer onEnd()
if m.context.Config.UTXOIndex {
err := m.notifyUTXOsChanged(blockInsertionResult)
err := m.notifyUTXOsChanged(virtualChangeSet)
if err != nil {
return err
}
@@ -69,18 +88,12 @@ func (m *Manager) NotifyBlockAddedToDAG(block *externalapi.DomainBlock, blockIns
return err
}
err = m.notifyVirtualSelectedParentChainChanged(blockInsertionResult)
err = m.notifyVirtualSelectedParentChainChanged(virtualChangeSet)
if err != nil {
return err
}
rpcBlock := appmessage.DomainBlockToRPCBlock(block)
err = m.context.PopulateBlockWithVerboseData(rpcBlock, block.Header, block, false)
if err != nil {
return err
}
blockAddedNotification := appmessage.NewBlockAddedNotificationMessage(rpcBlock)
return m.context.NotificationManager.NotifyBlockAdded(blockAddedNotification)
return nil
}
// NotifyPruningPointUTXOSetOverride notifies the manager whenever the UTXO index
@@ -117,11 +130,11 @@ func (m *Manager) NotifyFinalityConflictResolved(finalityBlockHash string) error
return m.context.NotificationManager.NotifyFinalityConflictResolved(notification)
}
func (m *Manager) notifyUTXOsChanged(blockInsertionResult *externalapi.BlockInsertionResult) error {
func (m *Manager) notifyUTXOsChanged(virtualChangeSet *externalapi.VirtualChangeSet) error {
onEnd := logger.LogAndMeasureExecutionTime(log, "RPCManager.NotifyUTXOsChanged")
defer onEnd()
utxoIndexChanges, err := m.context.UTXOIndex.Update(blockInsertionResult)
utxoIndexChanges, err := m.context.UTXOIndex.Update(virtualChangeSet)
if err != nil {
return err
}
@@ -171,12 +184,12 @@ func (m *Manager) notifyVirtualDaaScoreChanged() error {
return m.context.NotificationManager.NotifyVirtualDaaScoreChanged(notification)
}
func (m *Manager) notifyVirtualSelectedParentChainChanged(blockInsertionResult *externalapi.BlockInsertionResult) error {
func (m *Manager) notifyVirtualSelectedParentChainChanged(virtualChangeSet *externalapi.VirtualChangeSet) error {
onEnd := logger.LogAndMeasureExecutionTime(log, "RPCManager.NotifyVirtualSelectedParentChainChanged")
defer onEnd()
notification, err := m.context.ConvertVirtualSelectedParentChainChangesToChainChangedNotificationMessage(
blockInsertionResult.VirtualSelectedParentChainChanges)
virtualChangeSet.VirtualSelectedParentChainChanges)
if err != nil {
return err
}

View File

@@ -1,3 +1,19 @@
Kaspad v0.11.7 - 2021-12-11
===========================
Breaking changes:
* kaspawallet: show-address →new-address + show-addresses (#1870)
Bug fixes:
* Fix numThreads using getAEAD instead of decryptMnemonic (#1859)
* Apply ResolveVirtual diffs to the UTXO index (#1868)
Non-breaking changes:
* Ignore header mass in devnet and testnet (#1879)
* Remove unused args from CalcSubsidy (#1877)
* ExpectedHeaderPruningPoint fix (#1876)
* Changes to libkaspawallet to support Kaspaper (#1878)
* Get rid of genesis's UTXO dump (#1867)
Kaspad v0.11.2 - 2021-11-11
===========================
Bug fixes:

View File

@@ -15,7 +15,8 @@ const (
createUnsignedTransactionSubCmd = "create-unsigned-transaction"
signSubCmd = "sign"
broadcastSubCmd = "broadcast"
showAddressSubCmd = "show-address"
showAddressesSubCmd = "show-addresses"
newAddressSubCmd = "new-address"
dumpUnencryptedDataSubCmd = "dump-unencrypted-data"
startDaemonSubCmd = "start-daemon"
)
@@ -75,7 +76,12 @@ type broadcastConfig struct {
config.NetworkFlags
}
type showAddressConfig struct {
type showAddressesConfig struct {
DaemonAddress string `long:"daemonaddress" short:"d" description:"Wallet daemon server to connect to (default: localhost:8082)"`
config.NetworkFlags
}
type newAddressConfig struct {
DaemonAddress string `long:"daemonaddress" short:"d" description:"Wallet daemon server to connect to (default: localhost:8082)"`
config.NetworkFlags
}
@@ -123,9 +129,13 @@ func parseCommandLine() (subCommand string, config interface{}) {
parser.AddCommand(broadcastSubCmd, "Broadcast the given transaction",
"Broadcast the given transaction", broadcastConf)
showAddressConf := &showAddressConfig{DaemonAddress: defaultListen}
parser.AddCommand(showAddressSubCmd, "Shows the public address of the current wallet",
"Shows the public address of the current wallet", showAddressConf)
showAddressesConf := &showAddressesConfig{DaemonAddress: defaultListen}
parser.AddCommand(showAddressesSubCmd, "Shows all generated public addresses of the current wallet",
"Shows all generated public addresses of the current wallet", showAddressesConf)
newAddressConf := &newAddressConfig{DaemonAddress: defaultListen}
parser.AddCommand(newAddressSubCmd, "Generates new public address of the current wallet and shows it",
"Generates new public address of the current wallet and shows it", newAddressConf)
dumpUnencryptedDataConf := &dumpUnencryptedDataConfig{}
parser.AddCommand(dumpUnencryptedDataSubCmd, "Prints the unencrypted wallet data",
@@ -193,13 +203,20 @@ func parseCommandLine() (subCommand string, config interface{}) {
printErrorAndExit(err)
}
config = broadcastConf
case showAddressSubCmd:
combineNetworkFlags(&showAddressConf.NetworkFlags, &cfg.NetworkFlags)
err := showAddressConf.ResolveNetwork(parser)
case showAddressesSubCmd:
combineNetworkFlags(&showAddressesConf.NetworkFlags, &cfg.NetworkFlags)
err := showAddressesConf.ResolveNetwork(parser)
if err != nil {
printErrorAndExit(err)
}
config = showAddressConf
config = showAddressesConf
case newAddressSubCmd:
combineNetworkFlags(&newAddressConf.NetworkFlags, &cfg.NetworkFlags)
err := newAddressConf.ResolveNetwork(parser)
if err != nil {
printErrorAndExit(err)
}
config = newAddressConf
case dumpUnencryptedDataSubCmd:
combineNetworkFlags(&dumpUnencryptedDataConf.NetworkFlags, &cfg.NetworkFlags)
err := dumpUnencryptedDataConf.ResolveNetwork(parser)

View File

@@ -1,13 +1,12 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc-gen-go v1.27.1
// 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"
@@ -21,10 +20,6 @@ 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
@@ -220,14 +215,14 @@ func (x *CreateUnsignedTransactionResponse) GetUnsignedTransaction() []byte {
return nil
}
type GetReceiveAddressRequest struct {
type ShowAddressesRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *GetReceiveAddressRequest) Reset() {
*x = GetReceiveAddressRequest{}
func (x *ShowAddressesRequest) Reset() {
*x = ShowAddressesRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_kaspawalletd_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -235,13 +230,13 @@ func (x *GetReceiveAddressRequest) Reset() {
}
}
func (x *GetReceiveAddressRequest) String() string {
func (x *ShowAddressesRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetReceiveAddressRequest) ProtoMessage() {}
func (*ShowAddressesRequest) ProtoMessage() {}
func (x *GetReceiveAddressRequest) ProtoReflect() protoreflect.Message {
func (x *ShowAddressesRequest) ProtoReflect() protoreflect.Message {
mi := &file_kaspawalletd_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -253,21 +248,21 @@ func (x *GetReceiveAddressRequest) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
// Deprecated: Use GetReceiveAddressRequest.ProtoReflect.Descriptor instead.
func (*GetReceiveAddressRequest) Descriptor() ([]byte, []int) {
// Deprecated: Use ShowAddressesRequest.ProtoReflect.Descriptor instead.
func (*ShowAddressesRequest) Descriptor() ([]byte, []int) {
return file_kaspawalletd_proto_rawDescGZIP(), []int{4}
}
type GetReceiveAddressResponse struct {
type ShowAddressesResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
Address []string `protobuf:"bytes,1,rep,name=address,proto3" json:"address,omitempty"`
}
func (x *GetReceiveAddressResponse) Reset() {
*x = GetReceiveAddressResponse{}
func (x *ShowAddressesResponse) Reset() {
*x = ShowAddressesResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_kaspawalletd_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -275,13 +270,13 @@ func (x *GetReceiveAddressResponse) Reset() {
}
}
func (x *GetReceiveAddressResponse) String() string {
func (x *ShowAddressesResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetReceiveAddressResponse) ProtoMessage() {}
func (*ShowAddressesResponse) ProtoMessage() {}
func (x *GetReceiveAddressResponse) ProtoReflect() protoreflect.Message {
func (x *ShowAddressesResponse) ProtoReflect() protoreflect.Message {
mi := &file_kaspawalletd_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -293,12 +288,97 @@ func (x *GetReceiveAddressResponse) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
// Deprecated: Use GetReceiveAddressResponse.ProtoReflect.Descriptor instead.
func (*GetReceiveAddressResponse) Descriptor() ([]byte, []int) {
// Deprecated: Use ShowAddressesResponse.ProtoReflect.Descriptor instead.
func (*ShowAddressesResponse) Descriptor() ([]byte, []int) {
return file_kaspawalletd_proto_rawDescGZIP(), []int{5}
}
func (x *GetReceiveAddressResponse) GetAddress() string {
func (x *ShowAddressesResponse) GetAddress() []string {
if x != nil {
return x.Address
}
return nil
}
type NewAddressRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *NewAddressRequest) Reset() {
*x = NewAddressRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_kaspawalletd_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *NewAddressRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*NewAddressRequest) ProtoMessage() {}
func (x *NewAddressRequest) ProtoReflect() protoreflect.Message {
mi := &file_kaspawalletd_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use NewAddressRequest.ProtoReflect.Descriptor instead.
func (*NewAddressRequest) Descriptor() ([]byte, []int) {
return file_kaspawalletd_proto_rawDescGZIP(), []int{6}
}
type NewAddressResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
}
func (x *NewAddressResponse) Reset() {
*x = NewAddressResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_kaspawalletd_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *NewAddressResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*NewAddressResponse) ProtoMessage() {}
func (x *NewAddressResponse) ProtoReflect() protoreflect.Message {
mi := &file_kaspawalletd_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use NewAddressResponse.ProtoReflect.Descriptor instead.
func (*NewAddressResponse) Descriptor() ([]byte, []int) {
return file_kaspawalletd_proto_rawDescGZIP(), []int{7}
}
func (x *NewAddressResponse) GetAddress() string {
if x != nil {
return x.Address
}
@@ -316,7 +396,7 @@ type BroadcastRequest struct {
func (x *BroadcastRequest) Reset() {
*x = BroadcastRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_kaspawalletd_proto_msgTypes[6]
mi := &file_kaspawalletd_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -329,7 +409,7 @@ func (x *BroadcastRequest) String() string {
func (*BroadcastRequest) ProtoMessage() {}
func (x *BroadcastRequest) ProtoReflect() protoreflect.Message {
mi := &file_kaspawalletd_proto_msgTypes[6]
mi := &file_kaspawalletd_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -342,7 +422,7 @@ func (x *BroadcastRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use BroadcastRequest.ProtoReflect.Descriptor instead.
func (*BroadcastRequest) Descriptor() ([]byte, []int) {
return file_kaspawalletd_proto_rawDescGZIP(), []int{6}
return file_kaspawalletd_proto_rawDescGZIP(), []int{8}
}
func (x *BroadcastRequest) GetTransaction() []byte {
@@ -363,7 +443,7 @@ type BroadcastResponse struct {
func (x *BroadcastResponse) Reset() {
*x = BroadcastResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_kaspawalletd_proto_msgTypes[7]
mi := &file_kaspawalletd_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -376,7 +456,7 @@ func (x *BroadcastResponse) String() string {
func (*BroadcastResponse) ProtoMessage() {}
func (x *BroadcastResponse) ProtoReflect() protoreflect.Message {
mi := &file_kaspawalletd_proto_msgTypes[7]
mi := &file_kaspawalletd_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -389,7 +469,7 @@ func (x *BroadcastResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use BroadcastResponse.ProtoReflect.Descriptor instead.
func (*BroadcastResponse) Descriptor() ([]byte, []int) {
return file_kaspawalletd_proto_rawDescGZIP(), []int{7}
return file_kaspawalletd_proto_rawDescGZIP(), []int{9}
}
func (x *BroadcastResponse) GetTxID() string {
@@ -408,7 +488,7 @@ type ShutdownRequest struct {
func (x *ShutdownRequest) Reset() {
*x = ShutdownRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_kaspawalletd_proto_msgTypes[8]
mi := &file_kaspawalletd_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -421,7 +501,7 @@ func (x *ShutdownRequest) String() string {
func (*ShutdownRequest) ProtoMessage() {}
func (x *ShutdownRequest) ProtoReflect() protoreflect.Message {
mi := &file_kaspawalletd_proto_msgTypes[8]
mi := &file_kaspawalletd_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -434,7 +514,7 @@ func (x *ShutdownRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use ShutdownRequest.ProtoReflect.Descriptor instead.
func (*ShutdownRequest) Descriptor() ([]byte, []int) {
return file_kaspawalletd_proto_rawDescGZIP(), []int{8}
return file_kaspawalletd_proto_rawDescGZIP(), []int{10}
}
type ShutdownResponse struct {
@@ -446,7 +526,7 @@ type ShutdownResponse struct {
func (x *ShutdownResponse) Reset() {
*x = ShutdownResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_kaspawalletd_proto_msgTypes[9]
mi := &file_kaspawalletd_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -459,7 +539,7 @@ func (x *ShutdownResponse) String() string {
func (*ShutdownResponse) ProtoMessage() {}
func (x *ShutdownResponse) ProtoReflect() protoreflect.Message {
mi := &file_kaspawalletd_proto_msgTypes[9]
mi := &file_kaspawalletd_proto_msgTypes[11]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -472,7 +552,7 @@ func (x *ShutdownResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use ShutdownResponse.ProtoReflect.Descriptor instead.
func (*ShutdownResponse) Descriptor() ([]byte, []int) {
return file_kaspawalletd_proto_rawDescGZIP(), []int{9}
return file_kaspawalletd_proto_rawDescGZIP(), []int{11}
}
var File_kaspawalletd_proto protoreflect.FileDescriptor
@@ -496,47 +576,53 @@ var file_kaspawalletd_proto_rawDesc = []byte{
0x73, 0x65, 0x12, 0x30, 0x0a, 0x13, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72,
0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x13, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x22, 0x1a, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69,
0x76, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x22, 0x35, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x41, 0x64,
0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a,
0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x34, 0x0a, 0x10, 0x42, 0x72, 0x6f, 0x61, 0x64,
0x63, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x74,
0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
0x52, 0x0b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x27, 0x0a,
0x11, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x04, 0x74, 0x78, 0x49, 0x44, 0x22, 0x11, 0x0a, 0x0f, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f,
0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x12, 0x0a, 0x10, 0x53, 0x68, 0x75,
0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xe4, 0x02,
0x0a, 0x0c, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x12, 0x37,
0x0a, 0x0a, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x2e, 0x47,
0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x13, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x64, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, 0x74,
0x65, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x6e, 0x73,
0x74, 0x69, 0x6f, 0x6e, 0x22, 0x16, 0x0a, 0x14, 0x53, 0x68, 0x6f, 0x77, 0x41, 0x64, 0x64, 0x72,
0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x31, 0x0a, 0x15,
0x53, 0x68, 0x6f, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22,
0x13, 0x0a, 0x11, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x22, 0x2e, 0x0a, 0x12, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65,
0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64,
0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64,
0x72, 0x65, 0x73, 0x73, 0x22, 0x34, 0x0a, 0x10, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73,
0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x72, 0x61, 0x6e,
0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x74,
0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x27, 0x0a, 0x11, 0x42, 0x72,
0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x12, 0x0a, 0x04, 0x74, 0x78, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74,
0x78, 0x49, 0x44, 0x22, 0x11, 0x0a, 0x0f, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x12, 0x0a, 0x10, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f,
0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x91, 0x03, 0x0a, 0x0c, 0x6b,
0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x12, 0x37, 0x0a, 0x0a, 0x47,
0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x2e, 0x47, 0x65, 0x74, 0x42,
0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e,
0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x00, 0x12, 0x64, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x6e,
0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x12, 0x21, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e,
0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x6e, 0x73,
0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a,
0x11, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65,
0x73, 0x73, 0x12, 0x19, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x41,
0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e,
0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73,
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x08, 0x53,
0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x10, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f,
0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x53, 0x68, 0x75, 0x74,
0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x34,
0x0a, 0x09, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x12, 0x11, 0x2e, 0x42, 0x72,
0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12,
0x2e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x00, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
0x6f, 0x6d, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x6e, 0x65, 0x74, 0x2f, 0x6b, 0x61, 0x73, 0x70,
0x61, 0x64, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c,
0x65, 0x74, 0x2f, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0d, 0x53, 0x68,
0x6f, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x15, 0x2e, 0x53, 0x68,
0x6f, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x16, 0x2e, 0x53, 0x68, 0x6f, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x0a,
0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x2e, 0x4e, 0x65, 0x77,
0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13,
0x2e, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x08, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77,
0x6e, 0x12, 0x10, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x34, 0x0a, 0x09, 0x42, 0x72, 0x6f, 0x61,
0x64, 0x63, 0x61, 0x73, 0x74, 0x12, 0x11, 0x2e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73,
0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x42, 0x72, 0x6f, 0x61, 0x64,
0x63, 0x61, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x36,
0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x61, 0x73,
0x70, 0x61, 0x6e, 0x65, 0x74, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x2f, 0x63, 0x6d, 0x64,
0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2f, 0x64, 0x61, 0x65,
0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -551,35 +637,39 @@ func file_kaspawalletd_proto_rawDescGZIP() []byte {
return file_kaspawalletd_proto_rawDescData
}
var file_kaspawalletd_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
var file_kaspawalletd_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
var file_kaspawalletd_proto_goTypes = []interface{}{
(*GetBalanceRequest)(nil), // 0: GetBalanceRequest
(*GetBalanceResponse)(nil), // 1: GetBalanceResponse
(*CreateUnsignedTransactionRequest)(nil), // 2: CreateUnsignedTransactionRequest
(*CreateUnsignedTransactionResponse)(nil), // 3: CreateUnsignedTransactionResponse
(*GetReceiveAddressRequest)(nil), // 4: GetReceiveAddressRequest
(*GetReceiveAddressResponse)(nil), // 5: GetReceiveAddressResponse
(*BroadcastRequest)(nil), // 6: BroadcastRequest
(*BroadcastResponse)(nil), // 7: BroadcastResponse
(*ShutdownRequest)(nil), // 8: ShutdownRequest
(*ShutdownResponse)(nil), // 9: ShutdownResponse
(*ShowAddressesRequest)(nil), // 4: ShowAddressesRequest
(*ShowAddressesResponse)(nil), // 5: ShowAddressesResponse
(*NewAddressRequest)(nil), // 6: NewAddressRequest
(*NewAddressResponse)(nil), // 7: NewAddressResponse
(*BroadcastRequest)(nil), // 8: BroadcastRequest
(*BroadcastResponse)(nil), // 9: BroadcastResponse
(*ShutdownRequest)(nil), // 10: ShutdownRequest
(*ShutdownResponse)(nil), // 11: ShutdownResponse
}
var file_kaspawalletd_proto_depIdxs = []int32{
0, // 0: kaspawalletd.GetBalance:input_type -> GetBalanceRequest
2, // 1: kaspawalletd.CreateUnsignedTransaction:input_type -> CreateUnsignedTransactionRequest
4, // 2: kaspawalletd.GetReceiveAddress:input_type -> GetReceiveAddressRequest
8, // 3: kaspawalletd.Shutdown:input_type -> ShutdownRequest
6, // 4: kaspawalletd.Broadcast:input_type -> BroadcastRequest
1, // 5: kaspawalletd.GetBalance:output_type -> GetBalanceResponse
3, // 6: kaspawalletd.CreateUnsignedTransaction:output_type -> CreateUnsignedTransactionResponse
5, // 7: kaspawalletd.GetReceiveAddress:output_type -> GetReceiveAddressResponse
9, // 8: kaspawalletd.Shutdown:output_type -> ShutdownResponse
7, // 9: kaspawalletd.Broadcast:output_type -> BroadcastResponse
5, // [5:10] is the sub-list for method output_type
0, // [0:5] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
0, // 0: kaspawalletd.GetBalance:input_type -> GetBalanceRequest
2, // 1: kaspawalletd.CreateUnsignedTransaction:input_type -> CreateUnsignedTransactionRequest
4, // 2: kaspawalletd.ShowAddresses:input_type -> ShowAddressesRequest
6, // 3: kaspawalletd.NewAddress:input_type -> NewAddressRequest
10, // 4: kaspawalletd.Shutdown:input_type -> ShutdownRequest
8, // 5: kaspawalletd.Broadcast:input_type -> BroadcastRequest
1, // 6: kaspawalletd.GetBalance:output_type -> GetBalanceResponse
3, // 7: kaspawalletd.CreateUnsignedTransaction:output_type -> CreateUnsignedTransactionResponse
5, // 8: kaspawalletd.ShowAddresses:output_type -> ShowAddressesResponse
7, // 9: kaspawalletd.NewAddress:output_type -> NewAddressResponse
11, // 10: kaspawalletd.Shutdown:output_type -> ShutdownResponse
9, // 11: kaspawalletd.Broadcast:output_type -> BroadcastResponse
6, // [6:12] is the sub-list for method output_type
0, // [0:6] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_kaspawalletd_proto_init() }
@@ -637,7 +727,7 @@ func file_kaspawalletd_proto_init() {
}
}
file_kaspawalletd_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetReceiveAddressRequest); i {
switch v := v.(*ShowAddressesRequest); i {
case 0:
return &v.state
case 1:
@@ -649,7 +739,7 @@ func file_kaspawalletd_proto_init() {
}
}
file_kaspawalletd_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetReceiveAddressResponse); i {
switch v := v.(*ShowAddressesResponse); i {
case 0:
return &v.state
case 1:
@@ -661,7 +751,7 @@ func file_kaspawalletd_proto_init() {
}
}
file_kaspawalletd_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BroadcastRequest); i {
switch v := v.(*NewAddressRequest); i {
case 0:
return &v.state
case 1:
@@ -673,7 +763,7 @@ func file_kaspawalletd_proto_init() {
}
}
file_kaspawalletd_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BroadcastResponse); i {
switch v := v.(*NewAddressResponse); i {
case 0:
return &v.state
case 1:
@@ -685,7 +775,7 @@ func file_kaspawalletd_proto_init() {
}
}
file_kaspawalletd_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ShutdownRequest); i {
switch v := v.(*BroadcastRequest); i {
case 0:
return &v.state
case 1:
@@ -697,6 +787,30 @@ func file_kaspawalletd_proto_init() {
}
}
file_kaspawalletd_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BroadcastResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_kaspawalletd_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ShutdownRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_kaspawalletd_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ShutdownResponse); i {
case 0:
return &v.state
@@ -715,7 +829,7 @@ func file_kaspawalletd_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_kaspawalletd_proto_rawDesc,
NumEnums: 0,
NumMessages: 10,
NumMessages: 12,
NumExtensions: 0,
NumServices: 1,
},

View File

@@ -5,7 +5,8 @@ option go_package = "github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb";
service kaspawalletd {
rpc GetBalance (GetBalanceRequest) returns (GetBalanceResponse) {}
rpc CreateUnsignedTransaction (CreateUnsignedTransactionRequest) returns (CreateUnsignedTransactionResponse) {}
rpc GetReceiveAddress (GetReceiveAddressRequest) returns (GetReceiveAddressResponse) {}
rpc ShowAddresses (ShowAddressesRequest) returns (ShowAddressesResponse) {}
rpc NewAddress (NewAddressRequest) returns (NewAddressResponse) {}
rpc Shutdown (ShutdownRequest) returns (ShutdownResponse) {}
rpc Broadcast (BroadcastRequest) returns (BroadcastResponse) {}
}
@@ -27,10 +28,17 @@ message CreateUnsignedTransactionResponse {
bytes unsignedTransaction = 1;
}
message GetReceiveAddressRequest {
message ShowAddressesRequest {
}
message GetReceiveAddressResponse {
message ShowAddressesResponse {
repeated string address = 1;
}
message NewAddressRequest {
}
message NewAddressResponse {
string address = 1;
}

View File

@@ -11,7 +11,8 @@ import (
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion6
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// KaspawalletdClient is the client API for Kaspawalletd service.
//
@@ -19,7 +20,8 @@ const _ = grpc.SupportPackageIsVersion6
type KaspawalletdClient interface {
GetBalance(ctx context.Context, in *GetBalanceRequest, opts ...grpc.CallOption) (*GetBalanceResponse, error)
CreateUnsignedTransaction(ctx context.Context, in *CreateUnsignedTransactionRequest, opts ...grpc.CallOption) (*CreateUnsignedTransactionResponse, error)
GetReceiveAddress(ctx context.Context, in *GetReceiveAddressRequest, opts ...grpc.CallOption) (*GetReceiveAddressResponse, error)
ShowAddresses(ctx context.Context, in *ShowAddressesRequest, opts ...grpc.CallOption) (*ShowAddressesResponse, error)
NewAddress(ctx context.Context, in *NewAddressRequest, opts ...grpc.CallOption) (*NewAddressResponse, error)
Shutdown(ctx context.Context, in *ShutdownRequest, opts ...grpc.CallOption) (*ShutdownResponse, error)
Broadcast(ctx context.Context, in *BroadcastRequest, opts ...grpc.CallOption) (*BroadcastResponse, error)
}
@@ -50,9 +52,18 @@ func (c *kaspawalletdClient) CreateUnsignedTransaction(ctx context.Context, in *
return out, nil
}
func (c *kaspawalletdClient) GetReceiveAddress(ctx context.Context, in *GetReceiveAddressRequest, opts ...grpc.CallOption) (*GetReceiveAddressResponse, error) {
out := new(GetReceiveAddressResponse)
err := c.cc.Invoke(ctx, "/kaspawalletd/GetReceiveAddress", in, out, opts...)
func (c *kaspawalletdClient) ShowAddresses(ctx context.Context, in *ShowAddressesRequest, opts ...grpc.CallOption) (*ShowAddressesResponse, error) {
out := new(ShowAddressesResponse)
err := c.cc.Invoke(ctx, "/kaspawalletd/ShowAddresses", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *kaspawalletdClient) NewAddress(ctx context.Context, in *NewAddressRequest, opts ...grpc.CallOption) (*NewAddressResponse, error) {
out := new(NewAddressResponse)
err := c.cc.Invoke(ctx, "/kaspawalletd/NewAddress", in, out, opts...)
if err != nil {
return nil, err
}
@@ -83,7 +94,8 @@ func (c *kaspawalletdClient) Broadcast(ctx context.Context, in *BroadcastRequest
type KaspawalletdServer interface {
GetBalance(context.Context, *GetBalanceRequest) (*GetBalanceResponse, error)
CreateUnsignedTransaction(context.Context, *CreateUnsignedTransactionRequest) (*CreateUnsignedTransactionResponse, error)
GetReceiveAddress(context.Context, *GetReceiveAddressRequest) (*GetReceiveAddressResponse, error)
ShowAddresses(context.Context, *ShowAddressesRequest) (*ShowAddressesResponse, error)
NewAddress(context.Context, *NewAddressRequest) (*NewAddressResponse, error)
Shutdown(context.Context, *ShutdownRequest) (*ShutdownResponse, error)
Broadcast(context.Context, *BroadcastRequest) (*BroadcastResponse, error)
mustEmbedUnimplementedKaspawalletdServer()
@@ -93,25 +105,35 @@ 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) CreateUnsignedTransaction(context.Context, *CreateUnsignedTransactionRequest) (*CreateUnsignedTransactionResponse, error) {
func (UnimplementedKaspawalletdServer) CreateUnsignedTransaction(context.Context, *CreateUnsignedTransactionRequest) (*CreateUnsignedTransactionResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateUnsignedTransaction not implemented")
}
func (*UnimplementedKaspawalletdServer) GetReceiveAddress(context.Context, *GetReceiveAddressRequest) (*GetReceiveAddressResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetReceiveAddress not implemented")
func (UnimplementedKaspawalletdServer) ShowAddresses(context.Context, *ShowAddressesRequest) (*ShowAddressesResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ShowAddresses not implemented")
}
func (*UnimplementedKaspawalletdServer) Shutdown(context.Context, *ShutdownRequest) (*ShutdownResponse, 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) {
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) mustEmbedUnimplementedKaspawalletdServer() {}
func (UnimplementedKaspawalletdServer) mustEmbedUnimplementedKaspawalletdServer() {}
func RegisterKaspawalletdServer(s *grpc.Server, srv KaspawalletdServer) {
s.RegisterService(&_Kaspawalletd_serviceDesc, srv)
// 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 _Kaspawalletd_GetBalance_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
@@ -150,20 +172,38 @@ func _Kaspawalletd_CreateUnsignedTransaction_Handler(srv interface{}, ctx contex
return interceptor(ctx, in, info, handler)
}
func _Kaspawalletd_GetReceiveAddress_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetReceiveAddressRequest)
func _Kaspawalletd_ShowAddresses_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ShowAddressesRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(KaspawalletdServer).GetReceiveAddress(ctx, in)
return srv.(KaspawalletdServer).ShowAddresses(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/kaspawalletd/GetReceiveAddress",
FullMethod: "/kaspawalletd/ShowAddresses",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(KaspawalletdServer).GetReceiveAddress(ctx, req.(*GetReceiveAddressRequest))
return srv.(KaspawalletdServer).ShowAddresses(ctx, req.(*ShowAddressesRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Kaspawalletd_NewAddress_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(NewAddressRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(KaspawalletdServer).NewAddress(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/kaspawalletd/NewAddress",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(KaspawalletdServer).NewAddress(ctx, req.(*NewAddressRequest))
}
return interceptor(ctx, in, info, handler)
}
@@ -204,7 +244,10 @@ func _Kaspawalletd_Broadcast_Handler(srv interface{}, ctx context.Context, dec f
return interceptor(ctx, in, info, handler)
}
var _Kaspawalletd_serviceDesc = grpc.ServiceDesc{
// 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{
ServiceName: "kaspawalletd",
HandlerType: (*KaspawalletdServer)(nil),
Methods: []grpc.MethodDesc{
@@ -217,8 +260,12 @@ var _Kaspawalletd_serviceDesc = grpc.ServiceDesc{
Handler: _Kaspawalletd_CreateUnsignedTransaction_Handler,
},
{
MethodName: "GetReceiveAddress",
Handler: _Kaspawalletd_GetReceiveAddress_Handler,
MethodName: "ShowAddresses",
Handler: _Kaspawalletd_ShowAddresses_Handler,
},
{
MethodName: "NewAddress",
Handler: _Kaspawalletd_NewAddress_Handler,
},
{
MethodName: "Shutdown",

View File

@@ -3,6 +3,7 @@ package server
import (
"context"
"fmt"
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet"
"github.com/kaspanet/kaspad/util"
@@ -23,13 +24,39 @@ func (s *server) changeAddress() (util.Address, error) {
walletAddr := &walletAddress{
index: s.keysFile.LastUsedInternalIndex(),
cosignerIndex: s.keysFile.CosignerIndex,
keyChain: internalKeychain,
keyChain: libkaspawallet.InternalKeychain,
}
path := s.walletAddressPath(walletAddr)
return libkaspawallet.Address(s.params, s.keysFile.ExtendedPublicKeys, s.keysFile.MinimumSignatures, path, s.keysFile.ECDSA)
}
func (s *server) GetReceiveAddress(_ context.Context, request *pb.GetReceiveAddressRequest) (*pb.GetReceiveAddressResponse, error) {
func (s *server) ShowAddresses(_ context.Context, request *pb.ShowAddressesRequest) (*pb.ShowAddressesResponse, error) {
s.lock.Lock()
defer s.lock.Unlock()
if !s.isSynced() {
return nil, errors.New("server is not synced")
}
addresses := make([]string, 0)
for i := uint32(1); i <= s.keysFile.LastUsedExternalIndex(); i++ {
walletAddr := &walletAddress{
index: i,
cosignerIndex: s.keysFile.CosignerIndex,
keyChain: libkaspawallet.ExternalKeychain,
}
path := s.walletAddressPath(walletAddr)
address, err := libkaspawallet.Address(s.params, s.keysFile.ExtendedPublicKeys, s.keysFile.MinimumSignatures, path, s.keysFile.ECDSA)
if err != nil {
return nil, err
}
addresses = append(addresses, address.String())
}
return &pb.ShowAddressesResponse{Address: addresses}, nil
}
func (s *server) NewAddress(_ context.Context, request *pb.NewAddressRequest) (*pb.NewAddressResponse, error) {
s.lock.Lock()
defer s.lock.Unlock()
@@ -50,7 +77,7 @@ func (s *server) GetReceiveAddress(_ context.Context, request *pb.GetReceiveAddr
walletAddr := &walletAddress{
index: s.keysFile.LastUsedExternalIndex(),
cosignerIndex: s.keysFile.CosignerIndex,
keyChain: externalKeychain,
keyChain: libkaspawallet.ExternalKeychain,
}
path := s.walletAddressPath(walletAddr)
address, err := libkaspawallet.Address(s.params, s.keysFile.ExtendedPublicKeys, s.keysFile.MinimumSignatures, path, s.keysFile.ECDSA)
@@ -58,7 +85,7 @@ func (s *server) GetReceiveAddress(_ context.Context, request *pb.GetReceiveAddr
return nil, err
}
return &pb.GetReceiveAddressResponse{Address: address.String()}, nil
return &pb.NewAddressResponse{Address: address.String()}, nil
}
func (s *server) walletAddressString(wAddr *walletAddress) (string, error) {

View File

@@ -1,20 +1,16 @@
package server
import (
"time"
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/pkg/errors"
"time"
)
const (
// externalKeychain is the key chain that is used to create receive addresses
externalKeychain = 0
// internalKeychain is used to create change addresses
internalKeychain = 1
)
var keyChains = []uint8{externalKeychain, internalKeychain}
var keyChains = []uint8{libkaspawallet.ExternalKeychain, libkaspawallet.InternalKeychain}
type walletAddressSet map[string]*walletAddress
@@ -180,7 +176,7 @@ func (s *server) updateLastUsedIndexes(addressSet walletAddressSet,
continue
}
if walletAddress.keyChain == externalKeychain {
if walletAddress.keyChain == libkaspawallet.ExternalKeychain {
if walletAddress.index > lastUsedExternalIndex {
lastUsedExternalIndex = walletAddress.index
}

View File

@@ -6,12 +6,13 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
"github.com/kaspanet/kaspad/cmd/kaspawallet/utils"
"os"
"path/filepath"
"runtime"
"strings"
"github.com/kaspanet/kaspad/cmd/kaspawallet/utils"
"github.com/kaspanet/kaspad/domain/dagconfig"
"github.com/kaspanet/kaspad/util"
"github.com/pkg/errors"
@@ -89,6 +90,23 @@ func (d *File) toJSON() *keysFileJSON {
}
}
// NewFileFromMnemonic generates a new File from the given mnemonic string
func NewFileFromMnemonic(params *dagconfig.Params, mnemonic string, password string) (*File, error) {
encryptedMnemonics, extendedPublicKeys, err :=
encryptedMnemonicExtendedPublicKeyPairs(params, []string{mnemonic}, password, false)
if err != nil {
return nil, err
}
return &File{
Version: LastVersion,
NumThreads: defaultNumThreads,
EncryptedMnemonics: encryptedMnemonics,
ExtendedPublicKeys: extendedPublicKeys,
MinimumSignatures: 1,
ECDSA: false,
}, nil
}
func (d *File) fromJSON(fileJSON *keysFileJSON) error {
d.Version = fileJSON.Version
d.NumThreads = fileJSON.NumThreads
@@ -314,11 +332,7 @@ func (d *File) numThreads(password []byte) (uint8, error) {
return defaultNumThreads, nil
}
if d.NumThreads != 0 {
return d.NumThreads, nil
}
numThreads, err := d.detectNumThreads(password, d.EncryptedMnemonics[0].salt)
numThreads, err := d.detectNumThreads(password, d.EncryptedMnemonics[0])
if err != nil {
return 0, err
}
@@ -332,30 +346,33 @@ func (d *File) numThreads(password []byte) (uint8, error) {
return numThreads, nil
}
func (d *File) detectNumThreads(password, salt []byte) (uint8, error) {
numCPU := uint8(runtime.NumCPU())
_, err := getAEAD(numCPU, password, salt)
func (d *File) detectNumThreads(password []byte, encryptedMnemonic *EncryptedMnemonic) (uint8, error) {
firstGuessNumThreads := d.NumThreads
if d.NumThreads == 0 {
firstGuessNumThreads = uint8(runtime.NumCPU())
}
_, err := decryptMnemonic(firstGuessNumThreads, encryptedMnemonic, password)
if err != nil {
if !strings.Contains(err.Error(), "message authentication failed") {
return 0, err
}
} else {
return numCPU, nil
return firstGuessNumThreads, nil
}
for i := uint8(1); ; i++ {
if i == numCPU {
for numThreadsGuess := uint8(1); ; numThreadsGuess++ {
if numThreadsGuess == firstGuessNumThreads {
continue
}
_, err := getAEAD(i, password, salt)
_, err := decryptMnemonic(numThreadsGuess, encryptedMnemonic, password)
if err != nil {
const maxTries = 32
if i > maxTries || !strings.Contains(err.Error(), "message authentication failed") {
if numThreadsGuess == maxTries || !strings.Contains(err.Error(), "message authentication failed") {
return 0, err
}
} else {
return i, nil
return numThreadsGuess, nil
}
}
}

View File

@@ -0,0 +1,8 @@
package libkaspawallet
const (
// ExternalKeychain is the key chain that is used to create receive addresses
ExternalKeychain = 0
// InternalKeychain is used to create change addresses
InternalKeychain = 1
)

View File

@@ -163,7 +163,7 @@ func TestMultisig(t *testing.T) {
t.Fatalf("Expected extractedSignedTxOneStep and extractedSignedTxStep2 IDs to be equal")
}
_, insertionResult, err := tc.AddBlock([]*externalapi.DomainHash{block1Hash}, nil, []*externalapi.DomainTransaction{extractedSignedTxStep2})
_, virtualChangeSet, err := tc.AddBlock([]*externalapi.DomainHash{block1Hash}, nil, []*externalapi.DomainTransaction{extractedSignedTxStep2})
if err != nil {
t.Fatalf("AddBlock: %+v", err)
}
@@ -172,7 +172,7 @@ func TestMultisig(t *testing.T) {
TransactionID: *consensushashing.TransactionID(extractedSignedTxStep2),
Index: 0,
}
if !insertionResult.VirtualUTXODiff.ToAdd().Contains(addedUTXO) {
if !virtualChangeSet.VirtualUTXODiff.ToAdd().Contains(addedUTXO) {
t.Fatalf("Transaction wasn't accepted in the DAG")
}
})
@@ -294,7 +294,7 @@ func TestP2PK(t *testing.T) {
t.Fatalf("ExtractTransaction: %+v", err)
}
_, insertionResult, err := tc.AddBlock([]*externalapi.DomainHash{block1Hash}, nil, []*externalapi.DomainTransaction{tx})
_, virtualChangeSet, err := tc.AddBlock([]*externalapi.DomainHash{block1Hash}, nil, []*externalapi.DomainTransaction{tx})
if err != nil {
t.Fatalf("AddBlock: %+v", err)
}
@@ -303,7 +303,7 @@ func TestP2PK(t *testing.T) {
TransactionID: *consensushashing.TransactionID(tx),
Index: 0,
}
if !insertionResult.VirtualUTXODiff.ToAdd().Contains(addedUTXO) {
if !virtualChangeSet.VirtualUTXODiff.ToAdd().Contains(addedUTXO) {
t.Fatalf("Transaction wasn't accepted in the DAG")
}
})

View File

@@ -19,8 +19,10 @@ func main() {
err = sign(config.(*signConfig))
case broadcastSubCmd:
err = broadcast(config.(*broadcastConfig))
case showAddressSubCmd:
err = showAddress(config.(*showAddressConfig))
case showAddressesSubCmd:
err = showAddresses(config.(*showAddressesConfig))
case newAddressSubCmd:
err = newAddress(config.(*newAddressConfig))
case dumpUnencryptedDataSubCmd:
err = dumpUnencryptedData(config.(*dumpUnencryptedDataConfig))
case startDaemonSubCmd:

View File

@@ -7,7 +7,7 @@ import (
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
)
func showAddress(conf *showAddressConfig) error {
func newAddress(conf *newAddressConfig) error {
daemonClient, tearDown, err := client.Connect(conf.DaemonAddress)
if err != nil {
return err
@@ -17,11 +17,11 @@ func showAddress(conf *showAddressConfig) error {
ctx, cancel := context.WithTimeout(context.Background(), daemonTimeout)
defer cancel()
response, err := daemonClient.GetReceiveAddress(ctx, &pb.GetReceiveAddressRequest{})
response, err := daemonClient.NewAddress(ctx, &pb.NewAddressRequest{})
if err != nil {
return err
}
fmt.Printf("Address:\n%s\n", response.Address)
fmt.Printf("New address:\n%s\n", response.Address)
return nil
}

View File

@@ -0,0 +1,30 @@
package main
import (
"context"
"fmt"
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/client"
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
)
func showAddresses(conf *showAddressesConfig) error {
daemonClient, tearDown, err := client.Connect(conf.DaemonAddress)
if err != nil {
return err
}
defer tearDown()
ctx, cancel := context.WithTimeout(context.Background(), daemonTimeout)
defer cancel()
response, err := daemonClient.ShowAddresses(ctx, &pb.ShowAddressesRequest{})
if err != nil {
return err
}
fmt.Printf("Addresses (%d):\n", len(response.Address))
for _, address := range response.Address {
fmt.Println(address)
}
return nil
}

View File

@@ -56,7 +56,7 @@ type consensus struct {
daaBlocksStore model.DAABlocksStore
}
func (s *consensus) ValidateAndInsertBlockWithTrustedData(block *externalapi.BlockWithTrustedData, validateUTXO bool) (*externalapi.BlockInsertionResult, error) {
func (s *consensus) ValidateAndInsertBlockWithTrustedData(block *externalapi.BlockWithTrustedData, validateUTXO bool) (*externalapi.VirtualChangeSet, error) {
s.lock.Lock()
defer s.lock.Unlock()
@@ -164,7 +164,7 @@ func (s *consensus) BuildBlock(coinbaseData *externalapi.DomainCoinbaseData,
// ValidateAndInsertBlock validates the given block and, if valid, applies it
// to the current state
func (s *consensus) ValidateAndInsertBlock(block *externalapi.DomainBlock, shouldValidateAgainstUTXO bool) (*externalapi.BlockInsertionResult, error) {
func (s *consensus) ValidateAndInsertBlock(block *externalapi.DomainBlock, shouldValidateAgainstUTXO bool) (*externalapi.VirtualChangeSet, error) {
s.lock.Lock()
defer s.lock.Unlock()
@@ -720,30 +720,13 @@ func (s *consensus) PopulateMass(transaction *externalapi.DomainTransaction) {
s.transactionValidator.PopulateMass(transaction)
}
func (s *consensus) ResolveVirtual() error {
func (s *consensus) ResolveVirtual() (*externalapi.VirtualChangeSet, bool, error) {
s.lock.Lock()
defer s.lock.Unlock()
// In order to prevent a situation that the consensus lock is held for too much time, we
// release the lock each time resolve 100 blocks.
for i := 0; ; i++ {
if i%10 == 0 {
log.Infof("Resolving virtual. This may take some time...")
}
var isCompletelyResolved bool
var err error
func() {
s.lock.Lock()
defer s.lock.Unlock()
isCompletelyResolved, err = s.consensusStateManager.ResolveVirtual(100)
}()
if err != nil {
return err
}
if isCompletelyResolved {
log.Infof("Resolved virtual")
return nil
}
}
return s.consensusStateManager.ResolveVirtual(100)
}
func (s *consensus) BuildPruningPointProof() (*externalapi.PruningPointProof, error) {

View File

@@ -307,6 +307,7 @@ func (f *factory) NewConsensus(config *Config, db infrastructuredatabase.Databas
config.MaxBlockParents,
config.TimestampDeviationTolerance,
config.TargetTimePerBlock,
config.IgnoreHeaderMass,
dbManager,
difficultyManager,
@@ -588,7 +589,7 @@ func dagStores(config *Config,
ghostdagDataStores[i] = ghostdagdatastore.New(prefixBucket, ghostdagDataCacheSize, preallocateCaches)
} else {
blockRelationStores[i] = blockrelationstore.New(prefixBucket, 200, false)
reachabilityDataStores[i] = reachabilitydatastore.New(prefixBucket, 86400, false)
reachabilityDataStores[i] = reachabilitydatastore.New(prefixBucket, pruningWindowSizePlusFinalityDepthForCache, false)
ghostdagDataStores[i] = ghostdagdatastore.New(prefixBucket, 200, false)
}
}

View File

@@ -4,8 +4,8 @@ package externalapi
type Consensus interface {
Init(skipAddingGenesis bool) error
BuildBlock(coinbaseData *DomainCoinbaseData, transactions []*DomainTransaction) (*DomainBlock, error)
ValidateAndInsertBlock(block *DomainBlock, shouldValidateAgainstUTXO bool) (*BlockInsertionResult, error)
ValidateAndInsertBlockWithTrustedData(block *BlockWithTrustedData, validateUTXO bool) (*BlockInsertionResult, error)
ValidateAndInsertBlock(block *DomainBlock, shouldValidateAgainstUTXO bool) (*VirtualChangeSet, error)
ValidateAndInsertBlockWithTrustedData(block *BlockWithTrustedData, validateUTXO bool) (*VirtualChangeSet, error)
ValidateTransactionAndPopulateWithConsensusData(transaction *DomainTransaction) error
ImportPruningPoints(pruningPoints []BlockHeader) error
BuildPruningPointProof() (*PruningPointProof, error)
@@ -46,5 +46,5 @@ type Consensus interface {
Anticone(blockHash *DomainHash) ([]*DomainHash, error)
EstimateNetworkHashesPerSecond(startHash *DomainHash, windowSize int) (uint64, error)
PopulateMass(transaction *DomainTransaction)
ResolveVirtual() error
ResolveVirtual() (*VirtualChangeSet, bool, error)
}

View File

@@ -1,7 +1,7 @@
package externalapi
// BlockInsertionResult is auxiliary data returned from ValidateAndInsertBlock
type BlockInsertionResult struct {
// VirtualChangeSet is auxiliary data returned from ValidateAndInsertBlock and ResolveVirtual
type VirtualChangeSet struct {
VirtualSelectedParentChainChanges *SelectedChainPath
VirtualUTXODiff UTXODiff
VirtualParents []*DomainHash

View File

@@ -4,7 +4,7 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
// BlockProcessor is responsible for processing incoming blocks
type BlockProcessor interface {
ValidateAndInsertBlock(block *externalapi.DomainBlock, shouldValidateAgainstUTXO bool) (*externalapi.BlockInsertionResult, error)
ValidateAndInsertBlock(block *externalapi.DomainBlock, shouldValidateAgainstUTXO bool) (*externalapi.VirtualChangeSet, error)
ValidateAndInsertImportedPruningPoint(newPruningPoint *externalapi.DomainHash) error
ValidateAndInsertBlockWithTrustedData(block *externalapi.BlockWithTrustedData, validateUTXO bool) (*externalapi.BlockInsertionResult, error)
ValidateAndInsertBlockWithTrustedData(block *externalapi.BlockWithTrustedData, validateUTXO bool) (*externalapi.VirtualChangeSet, error)
}

View File

@@ -6,7 +6,7 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
// coinbase transactions
type CoinbaseManager interface {
ExpectedCoinbaseTransaction(stagingArea *StagingArea, blockHash *externalapi.DomainHash,
coinbaseData *externalapi.DomainCoinbaseData, blockPruningPoint *externalapi.DomainHash) (*externalapi.DomainTransaction, error)
CalcBlockSubsidy(stagingArea *StagingArea, blockHash *externalapi.DomainHash, blockPruningPoint *externalapi.DomainHash) (uint64, error)
coinbaseData *externalapi.DomainCoinbaseData) (*externalapi.DomainTransaction, error)
CalcBlockSubsidy(blockHash *externalapi.DomainHash) (uint64, error)
ExtractCoinbaseDataBlueScoreAndSubsidy(coinbaseTx *externalapi.DomainTransaction) (blueScore uint64, coinbaseData *externalapi.DomainCoinbaseData, subsidy uint64, err error)
}

View File

@@ -13,5 +13,5 @@ type ConsensusStateManager interface {
GetVirtualSelectedParentChainFromBlock(stagingArea *StagingArea, blockHash *externalapi.DomainHash) (*externalapi.SelectedChainPath, error)
RecoverUTXOIfRequired() error
ReverseUTXODiffs(tipHash *externalapi.DomainHash, reversalData *UTXODiffReversalData) error
ResolveVirtual(maxBlocksToResolve uint64) (bool, error)
ResolveVirtual(maxBlocksToResolve uint64) (*externalapi.VirtualChangeSet, bool, error)
}

View File

@@ -8,7 +8,7 @@ type DAGTraversalManager interface {
LowestChainBlockAboveOrEqualToBlueScore(stagingArea *StagingArea, highHash *externalapi.DomainHash, blueScore uint64) (*externalapi.DomainHash, error)
// SelectedChildIterator should return a BlockIterator that iterates
// from lowHash (exclusive) to highHash (inclusive) over highHash's selected parent chain
SelectedChildIterator(stagingArea *StagingArea, highHash, lowHash *externalapi.DomainHash) (BlockIterator, error)
SelectedChildIterator(stagingArea *StagingArea, highHash, lowHash *externalapi.DomainHash, includeLowHash bool) (BlockIterator, error)
SelectedChild(stagingArea *StagingArea, highHash, lowHash *externalapi.DomainHash) (*externalapi.DomainHash, error)
AnticoneFromBlocks(stagingArea *StagingArea, tips []*externalapi.DomainHash, blockHash *externalapi.DomainHash) ([]*externalapi.DomainHash, error)
AnticoneFromVirtualPOV(stagingArea *StagingArea, blockHash *externalapi.DomainHash) ([]*externalapi.DomainHash, error)

View File

@@ -41,12 +41,12 @@ type TestConsensus interface {
// AddBlock builds a block with given information, solves it, and adds to the DAG.
// Returns the hash of the added block
AddBlock(parentHashes []*externalapi.DomainHash, coinbaseData *externalapi.DomainCoinbaseData,
transactions []*externalapi.DomainTransaction) (*externalapi.DomainHash, *externalapi.BlockInsertionResult, error)
transactions []*externalapi.DomainTransaction) (*externalapi.DomainHash, *externalapi.VirtualChangeSet, error)
AddUTXOInvalidHeader(parentHashes []*externalapi.DomainHash) (*externalapi.DomainHash, *externalapi.BlockInsertionResult, error)
AddUTXOInvalidHeader(parentHashes []*externalapi.DomainHash) (*externalapi.DomainHash, *externalapi.VirtualChangeSet, error)
AddUTXOInvalidBlock(parentHashes []*externalapi.DomainHash) (*externalapi.DomainHash,
*externalapi.BlockInsertionResult, error)
*externalapi.VirtualChangeSet, error)
MineJSON(r io.Reader, blockType MineJSONBlockType) (tips []*externalapi.DomainHash, err error)

View File

@@ -107,7 +107,7 @@ func (bb *blockBuilder) buildBlock(stagingArea *model.StagingArea, coinbaseData
if err != nil {
return nil, err
}
coinbase, err := bb.newBlockCoinbaseTransaction(stagingArea, coinbaseData, newBlockPruningPoint)
coinbase, err := bb.newBlockCoinbaseTransaction(stagingArea, coinbaseData)
if err != nil {
return nil, err
}
@@ -175,9 +175,9 @@ func (bb *blockBuilder) validateTransaction(
}
func (bb *blockBuilder) newBlockCoinbaseTransaction(stagingArea *model.StagingArea,
coinbaseData *externalapi.DomainCoinbaseData, blockPruningPoint *externalapi.DomainHash) (*externalapi.DomainTransaction, error) {
coinbaseData *externalapi.DomainCoinbaseData) (*externalapi.DomainTransaction, error) {
return bb.coinbaseManager.ExpectedCoinbaseTransaction(stagingArea, model.VirtualBlockHash, coinbaseData, blockPruningPoint)
return bb.coinbaseManager.ExpectedCoinbaseTransaction(stagingArea, model.VirtualBlockHash, coinbaseData)
}
func (bb *blockBuilder) buildHeader(stagingArea *model.StagingArea, transactions []*externalapi.DomainTransaction,

View File

@@ -200,11 +200,7 @@ func (bb *testBlockBuilder) buildBlockWithParents(stagingArea *model.StagingArea
bb.acceptanceDataStore.Stage(stagingArea, tempBlockHash, acceptanceData)
pruningPoint, err := bb.newBlockPruningPoint(stagingArea, tempBlockHash)
if err != nil {
return nil, nil, err
}
coinbase, err := bb.coinbaseManager.ExpectedCoinbaseTransaction(stagingArea, tempBlockHash, coinbaseData, pruningPoint)
coinbase, err := bb.coinbaseManager.ExpectedCoinbaseTransaction(stagingArea, tempBlockHash, coinbaseData)
if err != nil {
return nil, nil, err
}

View File

@@ -143,7 +143,7 @@ func New(
// ValidateAndInsertBlock validates the given block and, if valid, applies it
// to the current state
func (bp *blockProcessor) ValidateAndInsertBlock(block *externalapi.DomainBlock, shouldValidateAgainstUTXO bool) (*externalapi.BlockInsertionResult, error) {
func (bp *blockProcessor) ValidateAndInsertBlock(block *externalapi.DomainBlock, shouldValidateAgainstUTXO bool) (*externalapi.VirtualChangeSet, error) {
onEnd := logger.LogAndMeasureExecutionTime(log, "ValidateAndInsertBlock")
defer onEnd()
@@ -159,7 +159,7 @@ func (bp *blockProcessor) ValidateAndInsertImportedPruningPoint(newPruningPoint
return bp.validateAndInsertImportedPruningPoint(stagingArea, newPruningPoint)
}
func (bp *blockProcessor) ValidateAndInsertBlockWithTrustedData(block *externalapi.BlockWithTrustedData, shouldValidateAgainstUTXO bool) (*externalapi.BlockInsertionResult, error) {
func (bp *blockProcessor) ValidateAndInsertBlockWithTrustedData(block *externalapi.BlockWithTrustedData, shouldValidateAgainstUTXO bool) (*externalapi.VirtualChangeSet, error) {
onEnd := logger.LogAndMeasureExecutionTime(log, "ValidateAndInsertBlockWithTrustedData")
defer onEnd()

View File

@@ -1,32 +1,22 @@
package blockprocessor
import (
"bytes"
"compress/gzip"
"github.com/kaspanet/go-muhash"
// we need to embed the utxoset of mainnet genesis here
_ "embed"
"fmt"
"github.com/kaspanet/kaspad/domain/consensus/utils/multiset"
"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
"github.com/kaspanet/kaspad/infrastructure/db/database"
"github.com/kaspanet/kaspad/util/difficulty"
"github.com/kaspanet/kaspad/util/staging"
"io"
"sync"
"github.com/kaspanet/kaspad/domain/consensus/model"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
"github.com/kaspanet/kaspad/domain/consensus/utils/multiset"
"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
"github.com/kaspanet/kaspad/infrastructure/db/database"
"github.com/kaspanet/kaspad/infrastructure/logger"
"github.com/kaspanet/kaspad/util/difficulty"
"github.com/kaspanet/kaspad/util/staging"
"github.com/pkg/errors"
)
//go:embed resources/utxos.gz
var utxoDumpFile []byte
func (bp *blockProcessor) setBlockStatusAfterBlockValidation(
stagingArea *model.StagingArea, block *externalapi.DomainBlock, isPruningPoint bool) error {
@@ -87,7 +77,7 @@ func (bp *blockProcessor) updateVirtualAcceptanceDataAfterImportingPruningPoint(
}
func (bp *blockProcessor) validateAndInsertBlock(stagingArea *model.StagingArea, block *externalapi.DomainBlock,
isPruningPoint bool, shouldValidateAgainstUTXO bool, isBlockWithTrustedData bool) (*externalapi.BlockInsertionResult, error) {
isPruningPoint bool, shouldValidateAgainstUTXO bool, isBlockWithTrustedData bool) (*externalapi.VirtualChangeSet, error) {
blockHash := consensushashing.HeaderHash(block.Header)
err := bp.validateBlock(stagingArea, block, isBlockWithTrustedData)
@@ -139,11 +129,7 @@ func (bp *blockProcessor) validateAndInsertBlock(stagingArea *model.StagingArea,
}
}
err = bp.ifGenesisSetUtxoSet(block)
if err != nil {
return nil, err
}
bp.loadUTXODataForGenesis(stagingArea, block)
var selectedParentChainChanges *externalapi.SelectedChainPath
var virtualUTXODiff externalapi.UTXODiff
var reversalData *model.UTXODiffReversalData
@@ -224,98 +210,32 @@ func (bp *blockProcessor) validateAndInsertBlock(stagingArea *model.StagingArea,
bp.blockLogger.LogBlock(block)
return &externalapi.BlockInsertionResult{
return &externalapi.VirtualChangeSet{
VirtualSelectedParentChainChanges: selectedParentChainChanges,
VirtualUTXODiff: virtualUTXODiff,
VirtualParents: virtualParents,
}, nil
}
var mainnetGenesisUTXOSet externalapi.UTXODiff
var mainnetGenesisMultiSet model.Multiset
var mainnetGenesisOnce sync.Once
var mainnetGenesisErr error
func deserializeMainnetUTXOSet() (externalapi.UTXODiff, model.Multiset, error) {
mainnetGenesisOnce.Do(func() {
toAdd := make(map[externalapi.DomainOutpoint]externalapi.UTXOEntry)
mainnetGenesisMultiSet = multiset.New()
file, err := gzip.NewReader(bytes.NewReader(utxoDumpFile))
if err != nil {
mainnetGenesisErr = err
return
}
for i := 0; ; i++ {
size := make([]byte, 1)
_, err = io.ReadFull(file, size)
if errors.Is(err, io.EOF) {
break
}
if err != nil {
mainnetGenesisErr = err
return
}
serializedUTXO := make([]byte, size[0])
_, err = io.ReadFull(file, serializedUTXO)
if err != nil {
mainnetGenesisErr = err
return
}
mainnetGenesisMultiSet.Add(serializedUTXO)
entry, outpoint, err := utxo.DeserializeUTXO(serializedUTXO)
if err != nil {
mainnetGenesisErr = err
return
}
toAdd[*outpoint] = entry
}
mainnetGenesisUTXOSet, mainnetGenesisErr = utxo.NewUTXODiffFromCollections(utxo.NewUTXOCollection(toAdd), utxo.NewUTXOCollection(make(map[externalapi.DomainOutpoint]externalapi.UTXOEntry)))
})
return mainnetGenesisUTXOSet, mainnetGenesisMultiSet, mainnetGenesisErr
}
func (bp *blockProcessor) ifGenesisSetUtxoSet(block *externalapi.DomainBlock) error {
func (bp *blockProcessor) loadUTXODataForGenesis(stagingArea *model.StagingArea, block *externalapi.DomainBlock) {
isGenesis := len(block.Header.DirectParents()) == 0
if !isGenesis {
return nil
return
}
blockHash := consensushashing.BlockHash(block)
if !block.Header.UTXOCommitment().Equal(externalapi.NewDomainHashFromByteArray(muhash.EmptyMuHashHash.AsArray())) {
log.Infof("Loading checkpoint UTXO set")
diff, utxoSetMultiset, err := deserializeMainnetUTXOSet()
if err != nil {
return err
}
log.Infof("Finished loading checkpoint UTXO set")
utxoSetHash := utxoSetMultiset.Hash()
if !utxoSetHash.Equal(block.Header.UTXOCommitment()) {
return errors.New("Invalid UTXO set dump")
}
area := model.NewStagingArea()
bp.consensusStateStore.StageVirtualUTXODiff(area, diff)
bp.utxoDiffStore.Stage(area, blockHash, diff, nil)
// commit the multiset of genesis
bp.multisetStore.Stage(area, blockHash, utxoSetMultiset)
err = staging.CommitAllChanges(bp.databaseContext, area)
if err != nil {
return err
}
} else {
// if it's genesis but has an empty muhash then commit an empty multiset and an empty diff
area := model.NewStagingArea()
bp.consensusStateStore.StageVirtualUTXODiff(area, utxo.NewUTXODiff())
bp.utxoDiffStore.Stage(area, blockHash, utxo.NewUTXODiff(), nil)
bp.multisetStore.Stage(area, blockHash, multiset.New())
err := staging.CommitAllChanges(bp.databaseContext, area)
if err != nil {
return err
}
}
return nil
// Note: The applied UTXO set and multiset do not satisfy the UTXO commitment
// of Mainnet's genesis. This is why any block that will be built on top of genesis
// will have a wrong UTXO commitment as well, and will not be able to get to a consensus
// with the rest of the network.
// This is why getting direct blocks on top of genesis is forbidden, and the only way to
// get a newer state for a node with genesis only is by requesting a proof for a recent
// pruning point.
// The actual UTXO set that fits Mainnet's genesis' UTXO commitment was removed from the codebase in order
// to make reduce the consensus initialization time and the compiled binary size, but can be still
// found here for anyone to verify: https://github.com/kaspanet/kaspad/blob/dbf18d8052f000ba0079be9e79b2d6f5a98b74ca/domain/consensus/processes/blockprocessor/resources/utxos.gz
bp.consensusStateStore.StageVirtualUTXODiff(stagingArea, utxo.NewUTXODiff())
bp.utxoDiffStore.Stage(stagingArea, blockHash, utxo.NewUTXODiff(), nil)
bp.multisetStore.Stage(stagingArea, blockHash, multiset.New())
}
func isHeaderOnlyBlock(block *externalapi.DomainBlock) bool {

View File

@@ -8,7 +8,7 @@ import (
)
func (bp *blockProcessor) validateAndInsertBlockWithTrustedData(stagingArea *model.StagingArea,
block *externalapi.BlockWithTrustedData, validateUTXO bool) (*externalapi.BlockInsertionResult, error) {
block *externalapi.BlockWithTrustedData, validateUTXO bool) (*externalapi.VirtualChangeSet, error) {
blockHash := consensushashing.BlockHash(block.Block)
for i, daaBlock := range block.DAAWindow {

View File

@@ -533,12 +533,7 @@ func TestGetPruningPointUTXOs(t *testing.T) {
}
}
const mainnetUTXOSize = 1232643
expected := len(outputs) + 1
if consensusConfig.Name == "kaspa-mainnet" {
expected += mainnetUTXOSize
}
// Make sure the length of the UTXOs is exactly spendingTransaction.Outputs + 1 coinbase
// output (includingBlock's coinbase)
if len(allOutpointAndUTXOEntryPairs) != expected {

View File

@@ -178,7 +178,7 @@ func (v *blockValidator) checkCoinbaseSubsidy(
return err
}
expectedSubsidy, err := v.coinbaseManager.CalcBlockSubsidy(stagingArea, blockHash, block.Header.PruningPoint())
expectedSubsidy, err := v.coinbaseManager.CalcBlockSubsidy(blockHash)
if err != nil {
return err
}

View File

@@ -220,7 +220,9 @@ func (v *blockValidator) validateGasLimit(block *externalapi.DomainBlock) error
func (v *blockValidator) checkBlockMass(block *externalapi.DomainBlock) error {
mass := uint64(0)
mass += v.headerEstimatedSerializedSize(block.Header)
if !v.ignoreHeaderMass {
mass += v.headerEstimatedSerializedSize(block.Header)
}
for _, transaction := range block.Transactions {
v.transactionValidator.PopulateMass(transaction)

View File

@@ -22,6 +22,7 @@ type blockValidator struct {
maxBlockParents externalapi.KType
timestampDeviationTolerance int
targetTimePerBlock time.Duration
ignoreHeaderMass bool
databaseContext model.DBReader
difficultyManager model.DifficultyManager
@@ -58,6 +59,7 @@ func New(powMax *big.Int,
maxBlockParents externalapi.KType,
timestampDeviationTolerance int,
targetTimePerBlock time.Duration,
ignoreHeaderMass bool,
databaseContext model.DBReader,
@@ -94,6 +96,7 @@ func New(powMax *big.Int,
maxBlockMass: maxBlockMass,
mergeSetSizeLimit: mergeSetSizeLimit,
maxBlockParents: maxBlockParents,
ignoreHeaderMass: ignoreHeaderMass,
timestampDeviationTolerance: timestampDeviationTolerance,
targetTimePerBlock: targetTimePerBlock,

View File

@@ -36,7 +36,7 @@ type coinbaseManager struct {
}
func (c *coinbaseManager) ExpectedCoinbaseTransaction(stagingArea *model.StagingArea, blockHash *externalapi.DomainHash,
coinbaseData *externalapi.DomainCoinbaseData, blockPruningPoint *externalapi.DomainHash) (*externalapi.DomainTransaction, error) {
coinbaseData *externalapi.DomainCoinbaseData) (*externalapi.DomainTransaction, error) {
ghostdagData, err := c.ghostdagDataStore.Get(c.databaseContext, stagingArea, blockHash, true)
if !database.IsNotFoundError(err) && err != nil {
@@ -84,7 +84,7 @@ func (c *coinbaseManager) ExpectedCoinbaseTransaction(stagingArea *model.Staging
txOuts = append(txOuts, txOut)
}
subsidy, err := c.CalcBlockSubsidy(stagingArea, blockHash, blockPruningPoint)
subsidy, err := c.CalcBlockSubsidy(blockHash)
if err != nil {
return nil, err
}
@@ -184,9 +184,7 @@ func acceptanceDataFromArrayToMap(acceptanceData externalapi.AcceptanceData) map
// has the expected value.
//
// Further details: https://hashdag.medium.com/kaspa-launch-plan-9a63f4d754a6
func (c *coinbaseManager) CalcBlockSubsidy(stagingArea *model.StagingArea,
blockHash *externalapi.DomainHash, blockPruningPoint *externalapi.DomainHash) (uint64, error) {
func (c *coinbaseManager) CalcBlockSubsidy(blockHash *externalapi.DomainHash) (uint64, error) {
if blockHash.Equal(c.genesisHash) {
return c.subsidyGenesisReward, nil
}

View File

@@ -22,12 +22,12 @@ func TestVirtualDiff(t *testing.T) {
defer teardown(false)
// Add block A over the genesis
blockAHash, blockInsertionResult, err := tc.AddBlock([]*externalapi.DomainHash{consensusConfig.GenesisHash}, nil, nil)
blockAHash, virtualChangeSet, err := tc.AddBlock([]*externalapi.DomainHash{consensusConfig.GenesisHash}, nil, nil)
if err != nil {
t.Fatalf("Error adding block A: %+v", err)
}
virtualUTXODiff := blockInsertionResult.VirtualUTXODiff
virtualUTXODiff := virtualChangeSet.VirtualUTXODiff
if virtualUTXODiff.ToRemove().Len() != 0 {
t.Fatalf("Unexpected length %d for virtualUTXODiff.ToRemove()", virtualUTXODiff.ToRemove().Len())
}
@@ -37,7 +37,7 @@ func TestVirtualDiff(t *testing.T) {
t.Fatalf("Unexpected length %d for virtualUTXODiff.ToAdd()", virtualUTXODiff.ToAdd().Len())
}
blockBHash, blockInsertionResult, err := tc.AddBlock([]*externalapi.DomainHash{blockAHash}, nil, nil)
blockBHash, virtualChangeSet, err := tc.AddBlock([]*externalapi.DomainHash{blockAHash}, nil, nil)
if err != nil {
t.Fatalf("Error adding block A: %+v", err)
}
@@ -47,7 +47,7 @@ func TestVirtualDiff(t *testing.T) {
t.Fatalf("Block: %+v", err)
}
virtualUTXODiff = blockInsertionResult.VirtualUTXODiff
virtualUTXODiff = virtualChangeSet.VirtualUTXODiff
if virtualUTXODiff.ToRemove().Len() != 0 {
t.Fatalf("Unexpected length %d for virtualUTXODiff.ToRemove()", virtualUTXODiff.ToRemove().Len())
}

View File

@@ -19,11 +19,11 @@ func TestCalculateChainPath(t *testing.T) {
defer teardown(false)
// Add block A over the genesis
blockAHash, blockAInsertionResult, err := consensus.AddBlock([]*externalapi.DomainHash{consensusConfig.GenesisHash}, nil, nil)
blockAHash, blockAVirtualChangeSet, err := consensus.AddBlock([]*externalapi.DomainHash{consensusConfig.GenesisHash}, nil, nil)
if err != nil {
t.Fatalf("Error adding block A: %+v", err)
}
blockASelectedParentChainChanges := blockAInsertionResult.VirtualSelectedParentChainChanges
blockASelectedParentChainChanges := blockAVirtualChangeSet.VirtualSelectedParentChainChanges
// Make sure that the removed slice is empty
if len(blockASelectedParentChainChanges.Removed) > 0 {
@@ -59,11 +59,11 @@ func TestCalculateChainPath(t *testing.T) {
// Add block C over the block that isn't the current virtual's selected parent
// We expect this to cause a reorg
blockCHash, blockCInsertionResult, err := consensus.AddBlock([]*externalapi.DomainHash{notVirtualSelectedParent}, nil, nil)
blockCHash, blockCVirtualChangeSet, err := consensus.AddBlock([]*externalapi.DomainHash{notVirtualSelectedParent}, nil, nil)
if err != nil {
t.Fatalf("Error adding block C: %+v", err)
}
blockCSelectedParentChainChanges := blockCInsertionResult.VirtualSelectedParentChainChanges
blockCSelectedParentChainChanges := blockCVirtualChangeSet.VirtualSelectedParentChainChanges
// Make sure that the removed slice contains only the block that was previously
// the selected parent
@@ -92,11 +92,11 @@ func TestCalculateChainPath(t *testing.T) {
}
// Add block D over the genesis
_, blockDInsertionResult, err := consensus.AddBlock([]*externalapi.DomainHash{consensusConfig.GenesisHash}, nil, nil)
_, blockDVirtualChangeSet, err := consensus.AddBlock([]*externalapi.DomainHash{consensusConfig.GenesisHash}, nil, nil)
if err != nil {
t.Fatalf("Error adding block D: %+v", err)
}
blockDSelectedParentChainChanges := blockDInsertionResult.VirtualSelectedParentChainChanges
blockDSelectedParentChainChanges := blockDVirtualChangeSet.VirtualSelectedParentChainChanges
// Make sure that both the added and the removed slices are empty
if len(blockDSelectedParentChainChanges.Added) > 0 {

View File

@@ -8,14 +8,14 @@ import (
"sort"
)
func (csm *consensusStateManager) ResolveVirtual(maxBlocksToResolve uint64) (bool, error) {
func (csm *consensusStateManager) ResolveVirtual(maxBlocksToResolve uint64) (*externalapi.VirtualChangeSet, bool, error) {
onEnd := logger.LogAndMeasureExecutionTime(log, "csm.ResolveVirtual")
defer onEnd()
readStagingArea := model.NewStagingArea()
tips, err := csm.consensusStateStore.Tips(readStagingArea, csm.databaseContext)
if err != nil {
return false, err
return nil, false, err
}
var sortErr error
@@ -29,7 +29,7 @@ func (csm *consensusStateManager) ResolveVirtual(maxBlocksToResolve uint64) (boo
return selectedParent.Equal(tips[i])
})
if sortErr != nil {
return false, sortErr
return nil, false, sortErr
}
var selectedTip *externalapi.DomainHash
@@ -39,7 +39,7 @@ func (csm *consensusStateManager) ResolveVirtual(maxBlocksToResolve uint64) (boo
resolveStagingArea := model.NewStagingArea()
unverifiedBlocks, err := csm.getUnverifiedChainBlocks(resolveStagingArea, tip)
if err != nil {
return false, err
return nil, false, err
}
resolveTip := tip
@@ -51,7 +51,7 @@ func (csm *consensusStateManager) ResolveVirtual(maxBlocksToResolve uint64) (boo
blockStatus, reversalData, err := csm.resolveBlockStatus(resolveStagingArea, resolveTip, true)
if err != nil {
return false, err
return nil, false, err
}
if blockStatus == externalapi.StatusUTXOValid {
@@ -60,13 +60,13 @@ func (csm *consensusStateManager) ResolveVirtual(maxBlocksToResolve uint64) (boo
err = staging.CommitAllChanges(csm.databaseContext, resolveStagingArea)
if err != nil {
return false, err
return nil, false, err
}
if reversalData != nil {
err = csm.ReverseUTXODiffs(resolveTip, reversalData)
if err != nil {
return false, err
return nil, false, err
}
}
break
@@ -75,19 +75,39 @@ func (csm *consensusStateManager) ResolveVirtual(maxBlocksToResolve uint64) (boo
if selectedTip == nil {
log.Warnf("Non of the DAG tips are valid")
return true, nil
return nil, true, nil
}
oldVirtualGHOSTDAGData, err := csm.ghostdagDataStore.Get(csm.databaseContext, readStagingArea, model.VirtualBlockHash, false)
if err != nil {
return nil, false, err
}
updateVirtualStagingArea := model.NewStagingArea()
_, err = csm.updateVirtualWithParents(updateVirtualStagingArea, []*externalapi.DomainHash{selectedTip})
virtualUTXODiff, err := csm.updateVirtualWithParents(updateVirtualStagingArea, []*externalapi.DomainHash{selectedTip})
if err != nil {
return false, err
return nil, false, err
}
err = staging.CommitAllChanges(csm.databaseContext, updateVirtualStagingArea)
if err != nil {
return false, err
return nil, false, err
}
return isCompletelyResolved, nil
selectedParentChainChanges, err := csm.dagTraversalManager.
CalculateChainPath(readStagingArea, oldVirtualGHOSTDAGData.SelectedParent(), selectedTip)
if err != nil {
return nil, false, err
}
virtualParents, err := csm.dagTopologyManager.Parents(readStagingArea, model.VirtualBlockHash)
if err != nil {
return nil, false, err
}
return &externalapi.VirtualChangeSet{
VirtualSelectedParentChainChanges: selectedParentChainChanges,
VirtualUTXODiff: virtualUTXODiff,
VirtualParents: virtualParents,
}, isCompletelyResolved, nil
}

View File

@@ -117,6 +117,10 @@ func (csm *consensusStateManager) validateUTXOCommitment(
log.Tracef("validateUTXOCommitment start for block %s", blockHash)
defer log.Tracef("validateUTXOCommitment end for block %s", blockHash)
if blockHash.Equal(csm.genesisHash) {
return nil
}
multisetHash := multiset.Hash()
if !block.Header.UTXOCommitment().Equal(multisetHash) {
return errors.Wrapf(ruleerrors.ErrBadUTXOCommitment, "block %s UTXO commitment is invalid - block "+
@@ -162,12 +166,8 @@ func (csm *consensusStateManager) validateCoinbaseTransaction(stagingArea *model
}
log.Tracef("Calculating the expected coinbase transaction for the given coinbase data and block %s", blockHash)
header, err := csm.blockHeaderStore.BlockHeader(csm.databaseContext, stagingArea, blockHash)
if err != nil {
return err
}
expectedCoinbaseTransaction, err :=
csm.coinbaseManager.ExpectedCoinbaseTransaction(stagingArea, blockHash, coinbaseData, header.PruningPoint())
csm.coinbaseManager.ExpectedCoinbaseTransaction(stagingArea, blockHash, coinbaseData)
if err != nil {
return err
}

View File

@@ -9,6 +9,7 @@ import (
type selectedChildIterator struct {
dagTraversalManager model.DAGTraversalManager
includeLowHash bool
highHash, lowHash *externalapi.DomainHash
current *externalapi.DomainHash
err error
@@ -21,6 +22,10 @@ func (s *selectedChildIterator) First() bool {
panic("Tried using a closed SelectedChildIterator")
}
s.current = s.lowHash
if s.includeLowHash {
return true
}
return s.Next()
}
@@ -67,7 +72,9 @@ func (s *selectedChildIterator) Close() error {
// SelectedChildIterator returns a BlockIterator that iterates from lowHash (exclusive) to highHash (inclusive) over
// highHash's selected parent chain
func (dtm *dagTraversalManager) SelectedChildIterator(stagingArea *model.StagingArea, highHash, lowHash *externalapi.DomainHash) (model.BlockIterator, error) {
func (dtm *dagTraversalManager) SelectedChildIterator(stagingArea *model.StagingArea,
highHash, lowHash *externalapi.DomainHash, includeLowHash bool) (model.BlockIterator, error) {
isLowHashInSelectedParentChainOfHighHash, err := dtm.dagTopologyManager.IsInSelectedParentChainOf(
stagingArea, lowHash, highHash)
if err != nil {
@@ -79,6 +86,7 @@ func (dtm *dagTraversalManager) SelectedChildIterator(stagingArea *model.Staging
}
return &selectedChildIterator{
dagTraversalManager: dtm,
includeLowHash: includeLowHash,
highHash: highHash,
lowHash: lowHash,
current: lowHash,

View File

@@ -40,12 +40,12 @@ func TestBlockWindow(t *testing.T) {
{
parents: []string{"C", "D"},
id: "E",
expectedWindow: []string{"D", "C", "B"},
expectedWindow: []string{"C", "D", "B"},
},
{
parents: []string{"C", "D"},
id: "F",
expectedWindow: []string{"D", "C", "B"},
expectedWindow: []string{"C", "D", "B"},
},
{
parents: []string{"A"},
@@ -60,38 +60,38 @@ func TestBlockWindow(t *testing.T) {
{
parents: []string{"H", "F"},
id: "I",
expectedWindow: []string{"F", "D", "H", "C", "G", "B"},
expectedWindow: []string{"F", "C", "H", "D", "B", "G"},
},
{
parents: []string{"I"},
id: "J",
expectedWindow: []string{"I", "F", "D", "H", "C", "G", "B"},
expectedWindow: []string{"I", "F", "C", "H", "D", "B", "G"},
},
//
{
parents: []string{"J"},
id: "K",
expectedWindow: []string{"J", "I", "F", "D", "H", "C", "G", "B"},
expectedWindow: []string{"J", "I", "F", "C", "H", "D", "B", "G"},
},
{
parents: []string{"K"},
id: "L",
expectedWindow: []string{"K", "J", "I", "F", "D", "H", "C", "G", "B"},
expectedWindow: []string{"K", "J", "I", "F", "C", "H", "D", "B", "G"},
},
{
parents: []string{"L"},
id: "M",
expectedWindow: []string{"L", "K", "J", "I", "F", "D", "H", "C", "G", "B"},
expectedWindow: []string{"L", "K", "J", "I", "F", "C", "H", "D", "B", "G"},
},
{
parents: []string{"M"},
id: "N",
expectedWindow: []string{"M", "L", "K", "J", "I", "F", "D", "H", "C", "G"},
expectedWindow: []string{"M", "L", "K", "J", "I", "F", "C", "H", "D", "B"},
},
{
parents: []string{"N"},
id: "O",
expectedWindow: []string{"N", "M", "L", "K", "J", "I", "F", "D", "H", "C"},
expectedWindow: []string{"N", "M", "L", "K", "J", "I", "F", "C", "H", "D"},
},
},
dagconfig.TestnetParams.Name: {

View File

@@ -219,7 +219,7 @@ func (pm *pruningManager) nextPruningPointAndCandidateByBlockHash(stagingArea *m
// We iterate until the selected parent of the given block, in order to allow a situation where the given block hash
// belongs to the virtual. This shouldn't change anything since the max blue score difference between a block and its
// selected parent is K, and K << pm.pruningDepth.
iterator, err := pm.dagTraversalManager.SelectedChildIterator(stagingArea, ghostdagData.SelectedParent(), lowHash)
iterator, err := pm.dagTraversalManager.SelectedChildIterator(stagingArea, ghostdagData.SelectedParent(), lowHash, true)
if err != nil {
return nil, nil, err
}
@@ -1051,7 +1051,19 @@ func (pm *pruningManager) ExpectedHeaderPruningPoint(stagingArea *model.StagingA
}
nextOrCurrentPruningPoint := selectedParentHeader.PruningPoint()
if pm.finalityScore(ghostdagData.BlueScore()) > pm.finalityScore(selectedParentPruningPointHeader.BlueScore()+pm.pruningDepth) {
pruningPoint, err := pm.pruningStore.PruningPoint(pm.databaseContext, stagingArea)
if err != nil {
return nil, err
}
// If the block doesn't have the pruning in its selected chain we know for sure that it can't trigger a pruning point
// change (we check the selected parent to take care of the case where the block is the virtual which doesn't have reachability data).
hasPruningPointInItsSelectedChain, err := pm.dagTopologyManager.IsInSelectedParentChainOf(stagingArea, pruningPoint, ghostdagData.SelectedParent())
if err != nil {
return nil, err
}
if hasPruningPointInItsSelectedChain && pm.finalityScore(ghostdagData.BlueScore()) > pm.finalityScore(selectedParentPruningPointHeader.BlueScore()+pm.pruningDepth) {
var suggestedLowHash *externalapi.DomainHash
hasReachabilityData, err := pm.reachabilityDataStore.HasReachabilityData(pm.databaseContext, stagingArea, selectedParentHeader.PruningPoint())
if err != nil {

View File

@@ -46,7 +46,7 @@ func (sm *syncManager) antiPastHashesBetween(stagingArea *model.StagingArea, low
// Collect all hashes by concatenating the merge-sets of all blocks between highHash and lowHash
blockHashes := []*externalapi.DomainHash{}
iterator, err := sm.dagTraversalManager.SelectedChildIterator(stagingArea, highHash, lowHash)
iterator, err := sm.dagTraversalManager.SelectedChildIterator(stagingArea, highHash, lowHash, false)
if err != nil {
return nil, nil, err
}
@@ -121,7 +121,7 @@ func (sm *syncManager) missingBlockBodyHashes(stagingArea *model.StagingArea, hi
return nil, err
}
selectedChildIterator, err := sm.dagTraversalManager.SelectedChildIterator(stagingArea, highHash, pruningPoint)
selectedChildIterator, err := sm.dagTraversalManager.SelectedChildIterator(stagingArea, highHash, pruningPoint, false)
if err != nil {
return nil, err
}

View File

@@ -366,7 +366,7 @@ func TestSigningTwoInputs(t *testing.T) {
input.SignatureScript = signatureScript
}
_, insertionResult, err := tc.AddBlock([]*externalapi.DomainHash{block3Hash}, nil, []*externalapi.DomainTransaction{tx})
_, virtualChangeSet, err := tc.AddBlock([]*externalapi.DomainHash{block3Hash}, nil, []*externalapi.DomainTransaction{tx})
if err != nil {
t.Fatalf("AddBlock: %+v", err)
}
@@ -375,7 +375,7 @@ func TestSigningTwoInputs(t *testing.T) {
TransactionID: *consensushashing.TransactionID(tx),
Index: 0,
}
if !insertionResult.VirtualUTXODiff.ToAdd().Contains(txOutpoint) {
if !virtualChangeSet.VirtualUTXODiff.ToAdd().Contains(txOutpoint) {
t.Fatalf("tx was not accepted by the DAG")
}
})
@@ -492,7 +492,7 @@ func TestSigningTwoInputsECDSA(t *testing.T) {
input.SignatureScript = signatureScript
}
_, insertionResult, err := tc.AddBlock([]*externalapi.DomainHash{block3Hash}, nil, []*externalapi.DomainTransaction{tx})
_, virtualChangeSet, err := tc.AddBlock([]*externalapi.DomainHash{block3Hash}, nil, []*externalapi.DomainTransaction{tx})
if err != nil {
t.Fatalf("AddBlock: %+v", err)
}
@@ -501,7 +501,7 @@ func TestSigningTwoInputsECDSA(t *testing.T) {
TransactionID: *consensushashing.TransactionID(tx),
Index: 0,
}
if !insertionResult.VirtualUTXODiff.ToAdd().Contains(txOutpoint) {
if !virtualChangeSet.VirtualUTXODiff.ToAdd().Contains(txOutpoint) {
t.Fatalf("tx was not accepted by the DAG")
}
})

View File

@@ -46,7 +46,7 @@ func (tc *testConsensus) BuildBlockWithParents(parentHashes []*externalapi.Domai
}
func (tc *testConsensus) AddBlock(parentHashes []*externalapi.DomainHash, coinbaseData *externalapi.DomainCoinbaseData,
transactions []*externalapi.DomainTransaction) (*externalapi.DomainHash, *externalapi.BlockInsertionResult, error) {
transactions []*externalapi.DomainTransaction) (*externalapi.DomainHash, *externalapi.VirtualChangeSet, error) {
// Require write lock because BuildBlockWithParents stages temporary data
tc.lock.Lock()
@@ -57,16 +57,16 @@ func (tc *testConsensus) AddBlock(parentHashes []*externalapi.DomainHash, coinba
return nil, nil, err
}
blockInsertionResult, err := tc.blockProcessor.ValidateAndInsertBlock(block, true)
virtualChangeSet, err := tc.blockProcessor.ValidateAndInsertBlock(block, true)
if err != nil {
return nil, nil, err
}
return consensushashing.BlockHash(block), blockInsertionResult, nil
return consensushashing.BlockHash(block), virtualChangeSet, nil
}
func (tc *testConsensus) AddUTXOInvalidHeader(parentHashes []*externalapi.DomainHash) (*externalapi.DomainHash,
*externalapi.BlockInsertionResult, error) {
*externalapi.VirtualChangeSet, error) {
// Require write lock because BuildBlockWithParents stages temporary data
tc.lock.Lock()
@@ -77,7 +77,7 @@ func (tc *testConsensus) AddUTXOInvalidHeader(parentHashes []*externalapi.Domain
return nil, nil, err
}
blockInsertionResult, err := tc.blockProcessor.ValidateAndInsertBlock(&externalapi.DomainBlock{
virtualChangeSet, err := tc.blockProcessor.ValidateAndInsertBlock(&externalapi.DomainBlock{
Header: header,
Transactions: nil,
}, true)
@@ -85,11 +85,11 @@ func (tc *testConsensus) AddUTXOInvalidHeader(parentHashes []*externalapi.Domain
return nil, nil, err
}
return consensushashing.HeaderHash(header), blockInsertionResult, nil
return consensushashing.HeaderHash(header), virtualChangeSet, nil
}
func (tc *testConsensus) AddUTXOInvalidBlock(parentHashes []*externalapi.DomainHash) (*externalapi.DomainHash,
*externalapi.BlockInsertionResult, error) {
*externalapi.VirtualChangeSet, error) {
// Require write lock because BuildBlockWithParents stages temporary data
tc.lock.Lock()
@@ -100,12 +100,12 @@ func (tc *testConsensus) AddUTXOInvalidBlock(parentHashes []*externalapi.DomainH
return nil, nil, err
}
blockInsertionResult, err := tc.blockProcessor.ValidateAndInsertBlock(block, true)
virtualChangeSet, err := tc.blockProcessor.ValidateAndInsertBlock(block, true)
if err != nil {
return nil, nil, err
}
return consensushashing.BlockHash(block), blockInsertionResult, nil
return consensushashing.BlockHash(block), virtualChangeSet, nil
}
func (tc *testConsensus) MineJSON(r io.Reader, blockType testapi.MineJSONBlockType) (tips []*externalapi.DomainHash, err error) {

View File

@@ -313,7 +313,7 @@ func TestCheckLockTimeVerifyConditionedByAbsoluteTime(t *testing.T) {
for i := int64(0); ; i++ {
tipBlock, err := testConsensus.BuildBlock(&emptyCoinbase, nil)
if err != nil {
t.Fatalf("Error creating tip using BuildBlock: %v", err)
t.Fatalf("Error creating tip using BuildBlock: %+v", err)
}
blockHeader := tipBlock.Header.ToMutable()
blockHeader.SetTimeInMilliseconds(timeStampBlockE + i*1000)

View File

@@ -186,6 +186,10 @@ type Params struct {
FixedSubsidySwitchPruningPointInterval uint64
FixedSubsidySwitchHashRateThreshold *big.Int
DisallowDirectBlocksOnTopOfGenesis bool
IgnoreHeaderMass bool
}
// NormalizeRPCServerAddress returns addr with the current network default
@@ -272,16 +276,17 @@ var MainnetParams = Params{
PruningProofM: defaultPruningProofM,
FixedSubsidySwitchPruningPointInterval: defaultFixedSubsidySwitchPruningPointInterval,
FixedSubsidySwitchHashRateThreshold: big.NewInt(150_000_000_000),
DisallowDirectBlocksOnTopOfGenesis: true,
}
// TestnetParams defines the network parameters for the test Kaspa network.
var TestnetParams = Params{
K: defaultGHOSTDAGK,
Name: "kaspa-testnet-6",
Name: "kaspa-testnet-7",
Net: appmessage.Testnet,
RPCPort: "16210",
DefaultPort: "16211",
DNSSeeds: []string{"testnet-6-dnsseed.daglabs-dev.com"},
DNSSeeds: []string{"testnet-7-dnsseed.daglabs-dev.com"},
// DAG parameters
GenesisBlock: &testnetGenesisBlock,
@@ -334,6 +339,7 @@ var TestnetParams = Params{
PruningProofM: defaultPruningProofM,
FixedSubsidySwitchPruningPointInterval: defaultFixedSubsidySwitchPruningPointInterval,
FixedSubsidySwitchHashRateThreshold: big.NewInt(150_000_000_000),
IgnoreHeaderMass: true,
}
// SimnetParams defines the network parameters for the simulation test Kaspa
@@ -462,6 +468,7 @@ var DevnetParams = Params{
PruningProofM: defaultPruningProofM,
FixedSubsidySwitchPruningPointInterval: defaultFixedSubsidySwitchPruningPointInterval,
FixedSubsidySwitchHashRateThreshold: big.NewInt(150_000_000_000),
IgnoreHeaderMass: true,
}
var (

View File

@@ -94,25 +94,25 @@ func (ui *UTXOIndex) isSynced() (bool, error) {
}
// Update updates the UTXO index with the given DAG selected parent chain changes
func (ui *UTXOIndex) Update(blockInsertionResult *externalapi.BlockInsertionResult) (*UTXOChanges, error) {
func (ui *UTXOIndex) Update(virtualChangeSet *externalapi.VirtualChangeSet) (*UTXOChanges, error) {
onEnd := logger.LogAndMeasureExecutionTime(log, "UTXOIndex.Update")
defer onEnd()
ui.mutex.Lock()
defer ui.mutex.Unlock()
log.Tracef("Updating UTXO index with VirtualUTXODiff: %+v", blockInsertionResult.VirtualUTXODiff)
err := ui.removeUTXOs(blockInsertionResult.VirtualUTXODiff.ToRemove())
log.Tracef("Updating UTXO index with VirtualUTXODiff: %+v", virtualChangeSet.VirtualUTXODiff)
err := ui.removeUTXOs(virtualChangeSet.VirtualUTXODiff.ToRemove())
if err != nil {
return nil, err
}
err = ui.addUTXOs(blockInsertionResult.VirtualUTXODiff.ToAdd())
err = ui.addUTXOs(virtualChangeSet.VirtualUTXODiff.ToAdd())
if err != nil {
return nil, err
}
ui.store.updateVirtualParents(blockInsertionResult.VirtualParents)
ui.store.updateVirtualParents(virtualChangeSet.VirtualParents)
added, removed, _ := ui.store.stagedData()
utxoIndexChanges := &UTXOChanges{

View File

@@ -85,8 +85,8 @@
; Maximum number of inbound and outbound peers.
; maxinpeers=125
; Disable banning of misbehaving peers.
; nobanning=1
; Enable banning of misbehaving peers.
; enablebanning=1
; Maximum allowed ban score before disconnecting and banning misbehaving peers.
; banthreshold=100

View File

@@ -1,7 +1,7 @@
#!/bin/bash
rm -rf /tmp/kaspad-temp
kaspad --devnet --nobanning --appdir=/tmp/kaspad-temp --profile=6061 --loglevel=debug &
kaspad --devnet --appdir=/tmp/kaspad-temp --profile=6061 --loglevel=debug &
KASPAD_PID=$!
KASPAD_KILLED=0
function killKaspadIfNotKilled() {

View File

@@ -1,7 +1,7 @@
#!/bin/bash
rm -rf /tmp/kaspad-temp
kaspad --devnet --nobanning --appdir=/tmp/kaspad-temp --profile=6061 &
kaspad --devnet --appdir=/tmp/kaspad-temp --profile=6061 &
KASPAD_PID=$!
sleep 1

View File

@@ -1,2 +1 @@
--devnet
--devnet --nobanning
--devnet

View File

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