mirror of
https://github.com/kaspanet/kaspad.git
synced 2026-02-21 03:03:08 +00:00
Compare commits
18 Commits
fix-Remove
...
v0.12.16-r
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
387fbf0451 | ||
|
|
265d76a393 | ||
|
|
057cc85c8c | ||
|
|
0534413213 | ||
|
|
0428502c44 | ||
|
|
c3ef43795b | ||
|
|
9e3b89c357 | ||
|
|
f62a174985 | ||
|
|
0d66fa8cd8 | ||
|
|
eabbdad738 | ||
|
|
c28eaa6998 | ||
|
|
ee2a848412 | ||
|
|
524a654886 | ||
|
|
629faa8436 | ||
|
|
91e6c6b74b | ||
|
|
0819244ba1 | ||
|
|
a0149cd8d0 | ||
|
|
5a3b8a0066 |
@@ -1,3 +1,25 @@
|
||||
Kaspad v0.12.16 - 2023-12-25
|
||||
===========================
|
||||
|
||||
* Adapt wallet UTXO selection to dust patch (#2254)
|
||||
|
||||
Kaspad v0.12.15 - 2023-12-16
|
||||
===========================
|
||||
|
||||
* Update ECDSA address test to use a valid public key (#2202)
|
||||
* Fix off by small amounts in sent amount kaspa (#2220)
|
||||
* Use removeRedeemers correctly by (#2235)
|
||||
* Fix windows asset building by increasing go version (#2245)
|
||||
* Added a mainnet dnsseeder (#2247)
|
||||
* Fix extract atomic swap data pushes (#2203)
|
||||
* Adapt kaspawallet to support testnet 11 (#2211)
|
||||
* Fix type detection in RemoveInvalidTransactions (#2252)
|
||||
|
||||
Kaspad v0.12.14 - 2023-09-26
|
||||
===========================
|
||||
|
||||
* Anti-spam measurements against dust attack (#2223)
|
||||
|
||||
Kaspad v0.12.13 - 2023-03-06
|
||||
===========================
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/kaspanet/kaspad/infrastructure/config"
|
||||
"github.com/pkg/errors"
|
||||
"os"
|
||||
|
||||
"github.com/jessevdk/go-flags"
|
||||
)
|
||||
@@ -22,6 +21,8 @@ const (
|
||||
newAddressSubCmd = "new-address"
|
||||
dumpUnencryptedDataSubCmd = "dump-unencrypted-data"
|
||||
startDaemonSubCmd = "start-daemon"
|
||||
versionSubCmd = "version"
|
||||
getDaemonVersionSubCmd = "get-daemon-version"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -30,6 +31,7 @@ const (
|
||||
)
|
||||
|
||||
type configFlags struct {
|
||||
ShowVersion bool `short:"V" long:"version" description:"Display version information and exit"`
|
||||
config.NetworkFlags
|
||||
}
|
||||
|
||||
@@ -129,6 +131,13 @@ type dumpUnencryptedDataConfig struct {
|
||||
config.NetworkFlags
|
||||
}
|
||||
|
||||
type versionConfig struct {
|
||||
}
|
||||
|
||||
type getDaemonVersionConfig struct {
|
||||
DaemonAddress string `long:"daemonaddress" short:"d" description:"Wallet daemon server to connect to"`
|
||||
}
|
||||
|
||||
func parseCommandLine() (subCommand string, config interface{}) {
|
||||
cfg := &configFlags{}
|
||||
parser := flags.NewParser(cfg, flags.PrintErrors|flags.HelpFlag)
|
||||
@@ -185,6 +194,9 @@ func parseCommandLine() (subCommand string, config interface{}) {
|
||||
Listen: defaultListen,
|
||||
}
|
||||
parser.AddCommand(startDaemonSubCmd, "Start the wallet daemon", "Start the wallet daemon", startDaemonConf)
|
||||
parser.AddCommand(versionSubCmd, "Get the wallet version", "Get the wallet version", &versionConfig{})
|
||||
getDaemonVersionConf := &getDaemonVersionConfig{DaemonAddress: defaultListen}
|
||||
parser.AddCommand(getDaemonVersionSubCmd, "Get the wallet daemon version", "Get the wallet daemon version", getDaemonVersionConf)
|
||||
|
||||
_, err := parser.Parse()
|
||||
if err != nil {
|
||||
@@ -290,6 +302,9 @@ func parseCommandLine() (subCommand string, config interface{}) {
|
||||
printErrorAndExit(err)
|
||||
}
|
||||
config = startDaemonConf
|
||||
case versionSubCmd:
|
||||
case getDaemonVersionSubCmd:
|
||||
config = getDaemonVersionConf
|
||||
}
|
||||
|
||||
return parser.Command.Active.Name, config
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc v3.21.12
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.12.3
|
||||
// source: kaspawalletd.proto
|
||||
|
||||
package pb
|
||||
@@ -1242,6 +1242,91 @@ func (x *SignResponse) GetSignedTransactions() [][]byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
type GetVersionRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *GetVersionRequest) Reset() {
|
||||
*x = GetVersionRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_kaspawalletd_proto_msgTypes[23]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetVersionRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetVersionRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetVersionRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_kaspawalletd_proto_msgTypes[23]
|
||||
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 GetVersionRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetVersionRequest) Descriptor() ([]byte, []int) {
|
||||
return file_kaspawalletd_proto_rawDescGZIP(), []int{23}
|
||||
}
|
||||
|
||||
type GetVersionResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`
|
||||
}
|
||||
|
||||
func (x *GetVersionResponse) Reset() {
|
||||
*x = GetVersionResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_kaspawalletd_proto_msgTypes[24]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetVersionResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetVersionResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetVersionResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_kaspawalletd_proto_msgTypes[24]
|
||||
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 GetVersionResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetVersionResponse) Descriptor() ([]byte, []int) {
|
||||
return file_kaspawalletd_proto_rawDescGZIP(), []int{24}
|
||||
}
|
||||
|
||||
func (x *GetVersionResponse) GetVersion() string {
|
||||
if x != nil {
|
||||
return x.Version
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_kaspawalletd_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_kaspawalletd_proto_rawDesc = []byte{
|
||||
@@ -1371,62 +1456,72 @@ var file_kaspawalletd_proto_rawDesc = []byte{
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72,
|
||||
0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c,
|
||||
0x52, 0x12, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x73, 0x32, 0xb3, 0x06, 0x0a, 0x0c, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61,
|
||||
0x6c, 0x6c, 0x65, 0x74, 0x64, 0x12, 0x51, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61,
|
||||
0x6e, 0x63, 0x65, 0x12, 0x1f, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65,
|
||||
0x74, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c,
|
||||
0x65, 0x74, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7e, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x45,
|
||||
0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x70, 0x65, 0x6e, 0x64, 0x61, 0x62, 0x6c, 0x65,
|
||||
0x55, 0x54, 0x58, 0x4f, 0x73, 0x12, 0x2e, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c,
|
||||
0x6c, 0x65, 0x74, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
|
||||
0x53, 0x70, 0x65, 0x6e, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x55, 0x54, 0x58, 0x4f, 0x73, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c,
|
||||
0x6c, 0x65, 0x74, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
|
||||
0x53, 0x70, 0x65, 0x6e, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x55, 0x54, 0x58, 0x4f, 0x73, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x81, 0x01, 0x0a, 0x1a, 0x43, 0x72, 0x65,
|
||||
0x69, 0x6f, 0x6e, 0x73, 0x22, 0x13, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2e, 0x0a, 0x12, 0x47, 0x65, 0x74,
|
||||
0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x32, 0x86, 0x07, 0x0a, 0x0c, 0x6b, 0x61,
|
||||
0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x12, 0x51, 0x0a, 0x0a, 0x47, 0x65,
|
||||
0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x1f, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61,
|
||||
0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e,
|
||||
0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6b, 0x61, 0x73, 0x70,
|
||||
0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61,
|
||||
0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7e, 0x0a,
|
||||
0x19, 0x47, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x70, 0x65, 0x6e,
|
||||
0x64, 0x61, 0x62, 0x6c, 0x65, 0x55, 0x54, 0x58, 0x4f, 0x73, 0x12, 0x2e, 0x2e, 0x6b, 0x61, 0x73,
|
||||
0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x74,
|
||||
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x70, 0x65, 0x6e, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x55, 0x54,
|
||||
0x58, 0x4f, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x6b, 0x61, 0x73,
|
||||
0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x74,
|
||||
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x70, 0x65, 0x6e, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x55, 0x54,
|
||||
0x58, 0x4f, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x81, 0x01,
|
||||
0x0a, 0x1a, 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, 0x73, 0x12, 0x2f, 0x2e, 0x6b,
|
||||
0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 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, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e,
|
||||
0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 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, 0x73, 0x12, 0x2f, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77,
|
||||
0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 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,
|
||||
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61,
|
||||
0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 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, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x0d,
|
||||
0x53, 0x68, 0x6f, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x22, 0x2e,
|
||||
0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x53, 0x68, 0x6f,
|
||||
0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x23, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64,
|
||||
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, 0x51, 0x0a, 0x0a, 0x4e, 0x65, 0x77, 0x41,
|
||||
0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1f, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61,
|
||||
0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77,
|
||||
0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73,
|
||||
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x08, 0x53,
|
||||
0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x1d, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77,
|
||||
0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61,
|
||||
0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x09, 0x42, 0x72, 0x6f, 0x61,
|
||||
0x64, 0x63, 0x61, 0x73, 0x74, 0x12, 0x1e, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c,
|
||||
0x6c, 0x65, 0x74, 0x64, 0x2e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c,
|
||||
0x6c, 0x65, 0x74, 0x64, 0x2e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3f, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64,
|
||||
0x12, 0x19, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e,
|
||||
0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6b, 0x61,
|
||||
0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3f, 0x0a, 0x04, 0x53, 0x69, 0x67,
|
||||
0x6e, 0x12, 0x19, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64,
|
||||
0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6b,
|
||||
0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x53, 0x69, 0x67, 0x6e,
|
||||
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,
|
||||
0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x00, 0x12, 0x5a, 0x0a, 0x0d, 0x53, 0x68, 0x6f, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
|
||||
0x65, 0x73, 0x12, 0x22, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74,
|
||||
0x64, 0x2e, 0x53, 0x68, 0x6f, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61,
|
||||
0x6c, 0x6c, 0x65, 0x74, 0x64, 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, 0x51, 0x0a,
|
||||
0x0a, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1f, 0x2e, 0x6b, 0x61,
|
||||
0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x64,
|
||||
0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6b,
|
||||
0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x4e, 0x65, 0x77, 0x41,
|
||||
0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
|
||||
0x12, 0x4b, 0x0a, 0x08, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x1d, 0x2e, 0x6b,
|
||||
0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x53, 0x68, 0x75, 0x74,
|
||||
0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6b, 0x61,
|
||||
0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64,
|
||||
0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a,
|
||||
0x09, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x12, 0x1e, 0x2e, 0x6b, 0x61, 0x73,
|
||||
0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63,
|
||||
0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6b, 0x61, 0x73,
|
||||
0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63,
|
||||
0x61, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3f, 0x0a,
|
||||
0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x19, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c,
|
||||
0x6c, 0x65, 0x74, 0x64, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x1a, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e,
|
||||
0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3f,
|
||||
0x0a, 0x04, 0x53, 0x69, 0x67, 0x6e, 0x12, 0x19, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61,
|
||||
0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x1a, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64,
|
||||
0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
|
||||
0x51, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x2e,
|
||||
0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x47, 0x65, 0x74,
|
||||
0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20,
|
||||
0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x47, 0x65,
|
||||
0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 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 (
|
||||
@@ -1441,7 +1536,7 @@ func file_kaspawalletd_proto_rawDescGZIP() []byte {
|
||||
return file_kaspawalletd_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_kaspawalletd_proto_msgTypes = make([]protoimpl.MessageInfo, 23)
|
||||
var file_kaspawalletd_proto_msgTypes = make([]protoimpl.MessageInfo, 25)
|
||||
var file_kaspawalletd_proto_goTypes = []interface{}{
|
||||
(*GetBalanceRequest)(nil), // 0: kaspawalletd.GetBalanceRequest
|
||||
(*GetBalanceResponse)(nil), // 1: kaspawalletd.GetBalanceResponse
|
||||
@@ -1466,6 +1561,8 @@ var file_kaspawalletd_proto_goTypes = []interface{}{
|
||||
(*SendResponse)(nil), // 20: kaspawalletd.SendResponse
|
||||
(*SignRequest)(nil), // 21: kaspawalletd.SignRequest
|
||||
(*SignResponse)(nil), // 22: kaspawalletd.SignResponse
|
||||
(*GetVersionRequest)(nil), // 23: kaspawalletd.GetVersionRequest
|
||||
(*GetVersionResponse)(nil), // 24: kaspawalletd.GetVersionResponse
|
||||
}
|
||||
var file_kaspawalletd_proto_depIdxs = []int32{
|
||||
2, // 0: kaspawalletd.GetBalanceResponse.addressBalances:type_name -> kaspawalletd.AddressBalances
|
||||
@@ -1482,17 +1579,19 @@ var file_kaspawalletd_proto_depIdxs = []int32{
|
||||
9, // 11: kaspawalletd.kaspawalletd.Broadcast:input_type -> kaspawalletd.BroadcastRequest
|
||||
19, // 12: kaspawalletd.kaspawalletd.Send:input_type -> kaspawalletd.SendRequest
|
||||
21, // 13: kaspawalletd.kaspawalletd.Sign:input_type -> kaspawalletd.SignRequest
|
||||
1, // 14: kaspawalletd.kaspawalletd.GetBalance:output_type -> kaspawalletd.GetBalanceResponse
|
||||
18, // 15: kaspawalletd.kaspawalletd.GetExternalSpendableUTXOs:output_type -> kaspawalletd.GetExternalSpendableUTXOsResponse
|
||||
4, // 16: kaspawalletd.kaspawalletd.CreateUnsignedTransactions:output_type -> kaspawalletd.CreateUnsignedTransactionsResponse
|
||||
6, // 17: kaspawalletd.kaspawalletd.ShowAddresses:output_type -> kaspawalletd.ShowAddressesResponse
|
||||
8, // 18: kaspawalletd.kaspawalletd.NewAddress:output_type -> kaspawalletd.NewAddressResponse
|
||||
12, // 19: kaspawalletd.kaspawalletd.Shutdown:output_type -> kaspawalletd.ShutdownResponse
|
||||
10, // 20: kaspawalletd.kaspawalletd.Broadcast:output_type -> kaspawalletd.BroadcastResponse
|
||||
20, // 21: kaspawalletd.kaspawalletd.Send:output_type -> kaspawalletd.SendResponse
|
||||
22, // 22: kaspawalletd.kaspawalletd.Sign:output_type -> kaspawalletd.SignResponse
|
||||
14, // [14:23] is the sub-list for method output_type
|
||||
5, // [5:14] is the sub-list for method input_type
|
||||
23, // 14: kaspawalletd.kaspawalletd.GetVersion:input_type -> kaspawalletd.GetVersionRequest
|
||||
1, // 15: kaspawalletd.kaspawalletd.GetBalance:output_type -> kaspawalletd.GetBalanceResponse
|
||||
18, // 16: kaspawalletd.kaspawalletd.GetExternalSpendableUTXOs:output_type -> kaspawalletd.GetExternalSpendableUTXOsResponse
|
||||
4, // 17: kaspawalletd.kaspawalletd.CreateUnsignedTransactions:output_type -> kaspawalletd.CreateUnsignedTransactionsResponse
|
||||
6, // 18: kaspawalletd.kaspawalletd.ShowAddresses:output_type -> kaspawalletd.ShowAddressesResponse
|
||||
8, // 19: kaspawalletd.kaspawalletd.NewAddress:output_type -> kaspawalletd.NewAddressResponse
|
||||
12, // 20: kaspawalletd.kaspawalletd.Shutdown:output_type -> kaspawalletd.ShutdownResponse
|
||||
10, // 21: kaspawalletd.kaspawalletd.Broadcast:output_type -> kaspawalletd.BroadcastResponse
|
||||
20, // 22: kaspawalletd.kaspawalletd.Send:output_type -> kaspawalletd.SendResponse
|
||||
22, // 23: kaspawalletd.kaspawalletd.Sign:output_type -> kaspawalletd.SignResponse
|
||||
24, // 24: kaspawalletd.kaspawalletd.GetVersion:output_type -> kaspawalletd.GetVersionResponse
|
||||
15, // [15:25] is the sub-list for method output_type
|
||||
5, // [5:15] is the sub-list for method input_type
|
||||
5, // [5:5] is the sub-list for extension type_name
|
||||
5, // [5:5] is the sub-list for extension extendee
|
||||
0, // [0:5] is the sub-list for field type_name
|
||||
@@ -1780,6 +1879,30 @@ func file_kaspawalletd_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_kaspawalletd_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetVersionRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_kaspawalletd_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetVersionResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
@@ -1787,7 +1910,7 @@ func file_kaspawalletd_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_kaspawalletd_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 23,
|
||||
NumMessages: 25,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
||||
@@ -15,6 +15,7 @@ service kaspawalletd {
|
||||
rpc Send(SendRequest) returns (SendResponse) {}
|
||||
// Since SignRequest contains a password - this command should only be used on a trusted or secure connection
|
||||
rpc Sign(SignRequest) returns (SignResponse) {}
|
||||
rpc GetVersion(GetVersionRequest) returns (GetVersionResponse) {}
|
||||
}
|
||||
|
||||
message GetBalanceRequest {
|
||||
@@ -127,3 +128,10 @@ message SignRequest{
|
||||
message SignResponse{
|
||||
repeated bytes signedTransactions = 1;
|
||||
}
|
||||
|
||||
message GetVersionRequest{
|
||||
}
|
||||
|
||||
message GetVersionResponse{
|
||||
string version = 1;
|
||||
}
|
||||
@@ -1,4 +1,8 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.2.0
|
||||
// - protoc v3.12.3
|
||||
// source: kaspawalletd.proto
|
||||
|
||||
package pb
|
||||
|
||||
@@ -29,6 +33,7 @@ type KaspawalletdClient interface {
|
||||
Send(ctx context.Context, in *SendRequest, opts ...grpc.CallOption) (*SendResponse, error)
|
||||
// Since SignRequest contains a password - this command should only be used on a trusted or secure connection
|
||||
Sign(ctx context.Context, in *SignRequest, opts ...grpc.CallOption) (*SignResponse, error)
|
||||
GetVersion(ctx context.Context, in *GetVersionRequest, opts ...grpc.CallOption) (*GetVersionResponse, error)
|
||||
}
|
||||
|
||||
type kaspawalletdClient struct {
|
||||
@@ -120,6 +125,15 @@ func (c *kaspawalletdClient) Sign(ctx context.Context, in *SignRequest, opts ...
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *kaspawalletdClient) GetVersion(ctx context.Context, in *GetVersionRequest, opts ...grpc.CallOption) (*GetVersionResponse, error) {
|
||||
out := new(GetVersionResponse)
|
||||
err := c.cc.Invoke(ctx, "/kaspawalletd.kaspawalletd/GetVersion", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// KaspawalletdServer is the server API for Kaspawalletd service.
|
||||
// All implementations must embed UnimplementedKaspawalletdServer
|
||||
// for forward compatibility
|
||||
@@ -135,6 +149,7 @@ type KaspawalletdServer interface {
|
||||
Send(context.Context, *SendRequest) (*SendResponse, error)
|
||||
// Since SignRequest contains a password - this command should only be used on a trusted or secure connection
|
||||
Sign(context.Context, *SignRequest) (*SignResponse, error)
|
||||
GetVersion(context.Context, *GetVersionRequest) (*GetVersionResponse, error)
|
||||
mustEmbedUnimplementedKaspawalletdServer()
|
||||
}
|
||||
|
||||
@@ -169,6 +184,9 @@ func (UnimplementedKaspawalletdServer) Send(context.Context, *SendRequest) (*Sen
|
||||
func (UnimplementedKaspawalletdServer) Sign(context.Context, *SignRequest) (*SignResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Sign not implemented")
|
||||
}
|
||||
func (UnimplementedKaspawalletdServer) GetVersion(context.Context, *GetVersionRequest) (*GetVersionResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetVersion not implemented")
|
||||
}
|
||||
func (UnimplementedKaspawalletdServer) mustEmbedUnimplementedKaspawalletdServer() {}
|
||||
|
||||
// UnsafeKaspawalletdServer may be embedded to opt out of forward compatibility for this service.
|
||||
@@ -344,6 +362,24 @@ func _Kaspawalletd_Sign_Handler(srv interface{}, ctx context.Context, dec func(i
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Kaspawalletd_GetVersion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetVersionRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(KaspawalletdServer).GetVersion(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/kaspawalletd.kaspawalletd/GetVersion",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(KaspawalletdServer).GetVersion(ctx, req.(*GetVersionRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// Kaspawalletd_ServiceDesc is the grpc.ServiceDesc for Kaspawalletd service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
@@ -387,6 +423,10 @@ var Kaspawalletd_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "Sign",
|
||||
Handler: _Kaspawalletd_Sign_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetVersion",
|
||||
Handler: _Kaspawalletd_GetVersion_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "kaspawalletd.proto",
|
||||
|
||||
@@ -2,6 +2,7 @@ package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet"
|
||||
@@ -14,13 +15,15 @@ func (s *server) GetBalance(_ context.Context, _ *pb.GetBalanceRequest) (*pb.Get
|
||||
s.lock.RLock()
|
||||
defer s.lock.RUnlock()
|
||||
|
||||
if !s.isSynced() {
|
||||
return nil, errors.Errorf("wallet daemon is not synced yet, %s", s.formatSyncStateReport())
|
||||
}
|
||||
|
||||
dagInfo, err := s.rpcClient.GetBlockDAGInfo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
daaScore := dagInfo.VirtualDAAScore
|
||||
maturity := s.params.BlockCoinbaseMaturity
|
||||
|
||||
balancesMap := make(balancesMapType, 0)
|
||||
for _, entry := range s.utxosSortedByAmount {
|
||||
amount := entry.UTXOEntry.Amount()
|
||||
@@ -30,7 +33,7 @@ func (s *server) GetBalance(_ context.Context, _ *pb.GetBalanceRequest) (*pb.Get
|
||||
balances = new(balancesType)
|
||||
balancesMap[address] = balances
|
||||
}
|
||||
if isUTXOSpendable(entry, daaScore, maturity) {
|
||||
if s.isUTXOSpendable(entry, daaScore) {
|
||||
balances.available += amount
|
||||
} else {
|
||||
balances.pending += amount
|
||||
@@ -55,6 +58,8 @@ func (s *server) GetBalance(_ context.Context, _ *pb.GetBalanceRequest) (*pb.Get
|
||||
pending += balances.pending
|
||||
}
|
||||
|
||||
log.Infof("GetBalance request scanned %d UTXOs overall over %d addresses", len(s.utxosSortedByAmount), len(balancesMap))
|
||||
|
||||
return &pb.GetBalanceResponse{
|
||||
Available: available,
|
||||
Pending: pending,
|
||||
@@ -62,9 +67,9 @@ func (s *server) GetBalance(_ context.Context, _ *pb.GetBalanceRequest) (*pb.Get
|
||||
}, nil
|
||||
}
|
||||
|
||||
func isUTXOSpendable(entry *walletUTXO, virtualDAAScore uint64, coinbaseMaturity uint64) bool {
|
||||
func (s *server) isUTXOSpendable(entry *walletUTXO, virtualDAAScore uint64) bool {
|
||||
if !entry.UTXOEntry.IsCoinbase() {
|
||||
return true
|
||||
}
|
||||
return entry.UTXOEntry.BlockDAAScore()+coinbaseMaturity < virtualDAAScore
|
||||
return entry.UTXOEntry.BlockDAAScore()+s.coinbaseMaturity < virtualDAAScore
|
||||
}
|
||||
|
||||
@@ -54,11 +54,7 @@ func (s *server) broadcast(transactions [][]byte, isDomain bool) ([]string, erro
|
||||
}
|
||||
}
|
||||
|
||||
err = s.refreshUTXOs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.forceSync()
|
||||
return txIDs, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -3,14 +3,12 @@ package server
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
||||
"github.com/kaspanet/kaspad/util"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
// TODO: Implement a better fee estimation mechanism
|
||||
@@ -35,7 +33,6 @@ func (s *server) createUnsignedTransactions(address string, amount uint64, isSen
|
||||
if !s.isSynced() {
|
||||
return nil, errors.Errorf("wallet daemon is not synced yet, %s", s.formatSyncStateReport())
|
||||
}
|
||||
|
||||
// make sure address string is correct before proceeding to a
|
||||
// potentially long UTXO refreshment operation
|
||||
toAddress, err := util.DecodeAddress(address, s.params.Prefix)
|
||||
@@ -43,16 +40,11 @@ func (s *server) createUnsignedTransactions(address string, amount uint64, isSen
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = s.refreshUTXOs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var fromAddresses []*walletAddress
|
||||
for _, from := range fromAddressesString {
|
||||
fromAddress, exists := s.addressSet[from]
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("Specified from address %s does not exists", from)
|
||||
return nil, fmt.Errorf("specified from address %s does not exists", from)
|
||||
}
|
||||
fromAddresses = append(fromAddresses, fromAddress)
|
||||
}
|
||||
@@ -106,19 +98,14 @@ func (s *server) selectUTXOs(spendAmount uint64, isSendAll bool, feePerInput uin
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
|
||||
coinbaseMaturity := s.params.BlockCoinbaseMaturity
|
||||
if dagInfo.NetworkName == "kaspa-testnet-11" {
|
||||
coinbaseMaturity = 1000
|
||||
}
|
||||
|
||||
for _, utxo := range s.utxosSortedByAmount {
|
||||
if (fromAddresses != nil && !slices.Contains(fromAddresses, utxo.address)) ||
|
||||
!isUTXOSpendable(utxo, dagInfo.VirtualDAAScore, coinbaseMaturity) {
|
||||
if (fromAddresses != nil && !walletAddressesContain(fromAddresses, utxo.address)) ||
|
||||
!s.isUTXOSpendable(utxo, dagInfo.VirtualDAAScore) {
|
||||
continue
|
||||
}
|
||||
|
||||
if broadcastTime, ok := s.usedOutpoints[*utxo.Outpoint]; ok {
|
||||
if time.Since(broadcastTime) > time.Minute {
|
||||
if s.usedOutpointHasExpired(broadcastTime) {
|
||||
delete(s.usedOutpoints, *utxo.Outpoint)
|
||||
} else {
|
||||
continue
|
||||
@@ -135,7 +122,11 @@ func (s *server) selectUTXOs(spendAmount uint64, isSendAll bool, feePerInput uin
|
||||
|
||||
fee := feePerInput * uint64(len(selectedUTXOs))
|
||||
totalSpend := spendAmount + fee
|
||||
if !isSendAll && totalValue >= totalSpend {
|
||||
// Two break cases (if not send all):
|
||||
// 1. totalValue == totalSpend, so there's no change needed -> number of outputs = 1, so a single input is sufficient
|
||||
// 2. totalValue > totalSpend, so there will be change and 2 outputs, therefor in order to not struggle with new dust
|
||||
// rules we try and find at least 2 inputs (even though the next one is not necessary in terms of spend value)
|
||||
if !isSendAll && (totalValue == totalSpend || (totalValue > totalSpend && len(selectedUTXOs) > 1)) {
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -156,3 +147,13 @@ func (s *server) selectUTXOs(spendAmount uint64, isSendAll bool, feePerInput uin
|
||||
|
||||
return selectedUTXOs, totalReceived, totalValue - totalSpend, nil
|
||||
}
|
||||
|
||||
func walletAddressesContain(addresses []*walletAddress, contain *walletAddress) bool {
|
||||
for _, address := range addresses {
|
||||
if *address == *contain {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -5,8 +5,11 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/kaspanet/kaspad/version"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
|
||||
"github.com/kaspanet/kaspad/util/txmass"
|
||||
@@ -27,17 +30,22 @@ import (
|
||||
type server struct {
|
||||
pb.UnimplementedKaspawalletdServer
|
||||
|
||||
rpcClient *rpcclient.RPCClient
|
||||
params *dagconfig.Params
|
||||
rpcClient *rpcclient.RPCClient // RPC client for ongoing user requests
|
||||
backgroundRPCClient *rpcclient.RPCClient // RPC client dedicated for address and UTXO background fetching
|
||||
params *dagconfig.Params
|
||||
coinbaseMaturity uint64 // Is different from default if we use testnet-11
|
||||
|
||||
lock sync.RWMutex
|
||||
utxosSortedByAmount []*walletUTXO
|
||||
nextSyncStartIndex uint32
|
||||
keysFile *keys.File
|
||||
shutdown chan struct{}
|
||||
addressSet walletAddressSet
|
||||
txMassCalculator *txmass.Calculator
|
||||
usedOutpoints map[externalapi.DomainOutpoint]time.Time
|
||||
lock sync.RWMutex
|
||||
utxosSortedByAmount []*walletUTXO
|
||||
nextSyncStartIndex uint32
|
||||
keysFile *keys.File
|
||||
shutdown chan struct{}
|
||||
forceSyncChan chan struct{}
|
||||
startTimeOfLastCompletedRefresh time.Time
|
||||
addressSet walletAddressSet
|
||||
txMassCalculator *txmass.Calculator
|
||||
usedOutpoints map[externalapi.DomainOutpoint]time.Time
|
||||
firstSyncDone atomic.Bool
|
||||
|
||||
isLogFinalProgressLineShown bool
|
||||
maxUsedAddressesForLog uint32
|
||||
@@ -59,6 +67,7 @@ func Start(params *dagconfig.Params, listen, rpcServer string, keysFilePath stri
|
||||
profiling.Start(profile, log)
|
||||
}
|
||||
|
||||
log.Infof("Version %s", version.Version())
|
||||
listener, err := net.Listen("tcp", listen)
|
||||
if err != nil {
|
||||
return (errors.Wrapf(err, "Error listening to TCP on %s", listen))
|
||||
@@ -70,6 +79,10 @@ func Start(params *dagconfig.Params, listen, rpcServer string, keysFilePath stri
|
||||
if err != nil {
|
||||
return (errors.Wrapf(err, "Error connecting to RPC server %s", rpcServer))
|
||||
}
|
||||
backgroundRPCClient, err := connectToRPC(params, rpcServer, timeout)
|
||||
if err != nil {
|
||||
return (errors.Wrapf(err, "Error making a second connection to RPC server %s", rpcServer))
|
||||
}
|
||||
|
||||
log.Infof("Connected, reading keys file %s...", keysFilePath)
|
||||
keysFile, err := keys.ReadKeysFile(params, keysFilePath)
|
||||
@@ -82,13 +95,26 @@ func Start(params *dagconfig.Params, listen, rpcServer string, keysFilePath stri
|
||||
return err
|
||||
}
|
||||
|
||||
dagInfo, err := rpcClient.GetBlockDAGInfo()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
coinbaseMaturity := params.BlockCoinbaseMaturity
|
||||
if dagInfo.NetworkName == "kaspa-testnet-11" {
|
||||
coinbaseMaturity = 1000
|
||||
}
|
||||
|
||||
serverInstance := &server{
|
||||
rpcClient: rpcClient,
|
||||
backgroundRPCClient: backgroundRPCClient,
|
||||
params: params,
|
||||
coinbaseMaturity: coinbaseMaturity,
|
||||
utxosSortedByAmount: []*walletUTXO{},
|
||||
nextSyncStartIndex: 0,
|
||||
keysFile: keysFile,
|
||||
shutdown: make(chan struct{}),
|
||||
forceSyncChan: make(chan struct{}),
|
||||
addressSet: make(walletAddressSet),
|
||||
txMassCalculator: txmass.NewCalculator(params.MassPerTxByte, params.MassPerScriptPubKeyByte, params.MassPerSigOp),
|
||||
usedOutpoints: map[externalapi.DomainOutpoint]time.Time{},
|
||||
@@ -98,8 +124,8 @@ func Start(params *dagconfig.Params, listen, rpcServer string, keysFilePath stri
|
||||
}
|
||||
|
||||
log.Infof("Read, syncing the wallet...")
|
||||
spawn("serverInstance.sync", func() {
|
||||
err := serverInstance.sync()
|
||||
spawn("serverInstance.syncLoop", func() {
|
||||
err := serverInstance.syncLoop()
|
||||
if err != nil {
|
||||
printErrorAndExit(errors.Wrap(err, "error syncing the wallet"))
|
||||
}
|
||||
|
||||
@@ -264,7 +264,7 @@ func (s *server) moreUTXOsForMergeTransaction(alreadySelectedUTXOs []*libkaspawa
|
||||
if _, ok := alreadySelectedUTXOsMap[*utxo.Outpoint]; ok {
|
||||
continue
|
||||
}
|
||||
if !isUTXOSpendable(utxo, dagInfo.VirtualDAAScore, s.params.BlockCoinbaseMaturity) {
|
||||
if !s.isUTXOSpendable(utxo, dagInfo.VirtualDAAScore) {
|
||||
continue
|
||||
}
|
||||
additionalUTXOs = append(additionalUTXOs, &libkaspawallet.UTXO{
|
||||
|
||||
@@ -23,7 +23,7 @@ func (was walletAddressSet) strings() []string {
|
||||
return addresses
|
||||
}
|
||||
|
||||
func (s *server) sync() error {
|
||||
func (s *server) syncLoop() error {
|
||||
ticker := time.NewTicker(time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
@@ -32,29 +32,39 @@ func (s *server) sync() error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = s.refreshExistingUTXOsWithLock()
|
||||
err = s.refreshUTXOs()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for range ticker.C {
|
||||
err = s.collectFarAddresses()
|
||||
if err != nil {
|
||||
return err
|
||||
s.firstSyncDone.Store(true)
|
||||
log.Infof("Wallet is synced and ready for operation")
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
case <-s.forceSyncChan:
|
||||
}
|
||||
|
||||
err = s.collectRecentAddresses()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = s.refreshExistingUTXOsWithLock()
|
||||
err := s.sync()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
func (s *server) sync() error {
|
||||
err := s.collectFarAddresses()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = s.collectRecentAddresses()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.refreshUTXOs()
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -158,7 +168,7 @@ func (s *server) collectAddresses(start, end uint32) error {
|
||||
return err
|
||||
}
|
||||
|
||||
getBalancesByAddressesResponse, err := s.rpcClient.GetBalancesByAddresses(addressSet.strings())
|
||||
getBalancesByAddressesResponse, err := s.backgroundRPCClient.GetBalancesByAddresses(addressSet.strings())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -208,15 +218,17 @@ func (s *server) updateAddressesAndLastUsedIndexes(requestedAddressSet walletAdd
|
||||
return s.keysFile.SetLastUsedInternalIndex(lastUsedInternalIndex)
|
||||
}
|
||||
|
||||
func (s *server) refreshExistingUTXOsWithLock() error {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
return s.refreshUTXOs()
|
||||
func (s *server) usedOutpointHasExpired(outpointBroadcastTime time.Time) bool {
|
||||
// If the node returns a UTXO we previously attempted to spend and enough time has passed, we assume
|
||||
// that the network rejected or lost the previous transaction and allow a reuse. We set this time
|
||||
// interval to a minute.
|
||||
// We also verify that a full refresh UTXO operation started after this time point and has already
|
||||
// completed, in order to make sure that indeed this state reflects a state obtained following the required wait time.
|
||||
return s.startTimeOfLastCompletedRefresh.After(outpointBroadcastTime.Add(time.Minute))
|
||||
}
|
||||
|
||||
// updateUTXOSet clears the current UTXO set, and re-fills it with the given entries
|
||||
func (s *server) updateUTXOSet(entries []*appmessage.UTXOsByAddressesEntry, mempoolEntries []*appmessage.MempoolEntryByAddress) error {
|
||||
func (s *server) updateUTXOSet(entries []*appmessage.UTXOsByAddressesEntry, mempoolEntries []*appmessage.MempoolEntryByAddress, refreshStart time.Time) error {
|
||||
utxos := make([]*walletUTXO, 0, len(entries))
|
||||
|
||||
exclude := make(map[appmessage.RPCOutpoint]struct{})
|
||||
@@ -243,6 +255,7 @@ func (s *server) updateUTXOSet(entries []*appmessage.UTXOsByAddressesEntry, memp
|
||||
return err
|
||||
}
|
||||
|
||||
// No need to lock for reading since the only writer of this set is on `syncLoop` on the same goroutine.
|
||||
address, ok := s.addressSet[entry.Address]
|
||||
if !ok {
|
||||
return errors.Errorf("Got result from address %s even though it wasn't requested", entry.Address)
|
||||
@@ -256,32 +269,56 @@ func (s *server) updateUTXOSet(entries []*appmessage.UTXOsByAddressesEntry, memp
|
||||
|
||||
sort.Slice(utxos, func(i, j int) bool { return utxos[i].UTXOEntry.Amount() > utxos[j].UTXOEntry.Amount() })
|
||||
|
||||
s.lock.Lock()
|
||||
s.startTimeOfLastCompletedRefresh = refreshStart
|
||||
s.utxosSortedByAmount = utxos
|
||||
|
||||
// Cleanup expired used outpoints to avoid a memory leak
|
||||
for outpoint, broadcastTime := range s.usedOutpoints {
|
||||
if s.usedOutpointHasExpired(broadcastTime) {
|
||||
delete(s.usedOutpoints, outpoint)
|
||||
}
|
||||
}
|
||||
s.lock.Unlock()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *server) refreshUTXOs() error {
|
||||
refreshStart := time.Now()
|
||||
|
||||
// No need to lock for reading since the only writer of this set is on `syncLoop` on the same goroutine.
|
||||
addresses := s.addressSet.strings()
|
||||
// It's important to check the mempool before calling `GetUTXOsByAddresses`:
|
||||
// If we would do it the other way around an output can be spent in the mempool
|
||||
// and not in consensus, and between the calls its spending transaction will be
|
||||
// added to consensus and removed from the mempool, so `getUTXOsByAddressesResponse`
|
||||
// will include an obsolete output.
|
||||
mempoolEntriesByAddresses, err := s.rpcClient.GetMempoolEntriesByAddresses(s.addressSet.strings(), true, true)
|
||||
mempoolEntriesByAddresses, err := s.backgroundRPCClient.GetMempoolEntriesByAddresses(addresses, true, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
getUTXOsByAddressesResponse, err := s.rpcClient.GetUTXOsByAddresses(s.addressSet.strings())
|
||||
getUTXOsByAddressesResponse, err := s.backgroundRPCClient.GetUTXOsByAddresses(addresses)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.updateUTXOSet(getUTXOsByAddressesResponse.Entries, mempoolEntriesByAddresses.Entries)
|
||||
return s.updateUTXOSet(getUTXOsByAddressesResponse.Entries, mempoolEntriesByAddresses.Entries, refreshStart)
|
||||
}
|
||||
|
||||
func (s *server) forceSync() {
|
||||
// Technically if two callers check the `if` simultaneously they will both spawn a
|
||||
// goroutine, but we don't care about the small redundancy in such a rare case.
|
||||
if len(s.forceSyncChan) == 0 {
|
||||
go func() {
|
||||
s.forceSyncChan <- struct{}{}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *server) isSynced() bool {
|
||||
return s.nextSyncStartIndex > s.maxUsedIndex()
|
||||
return s.nextSyncStartIndex > s.maxUsedIndex() && s.firstSyncDone.Load()
|
||||
}
|
||||
|
||||
func (s *server) formatSyncStateReport() string {
|
||||
@@ -291,8 +328,11 @@ func (s *server) formatSyncStateReport() string {
|
||||
maxUsedIndex = s.nextSyncStartIndex
|
||||
}
|
||||
|
||||
return fmt.Sprintf("scanned %d out of %d addresses (%.2f%%)",
|
||||
s.nextSyncStartIndex, maxUsedIndex, float64(s.nextSyncStartIndex)*100.0/float64(maxUsedIndex))
|
||||
if s.nextSyncStartIndex < s.maxUsedIndex() {
|
||||
return fmt.Sprintf("scanned %d out of %d addresses (%.2f%%)",
|
||||
s.nextSyncStartIndex, maxUsedIndex, float64(s.nextSyncStartIndex)*100.0/float64(maxUsedIndex))
|
||||
}
|
||||
return "loading the wallet UTXO set"
|
||||
}
|
||||
|
||||
func (s *server) updateSyncingProgressLog(currProcessedAddresses, currMaxUsedAddresses uint32) {
|
||||
@@ -311,7 +351,7 @@ func (s *server) updateSyncingProgressLog(currProcessedAddresses, currMaxUsedAdd
|
||||
|
||||
if s.maxProcessedAddressesForLog >= s.maxUsedAddressesForLog {
|
||||
if !s.isLogFinalProgressLineShown {
|
||||
log.Infof("Wallet is synced, ready for queries")
|
||||
log.Infof("Finished scanning recent addresses")
|
||||
s.isLogFinalProgressLineShown = true
|
||||
}
|
||||
} else {
|
||||
|
||||
16
cmd/kaspawallet/daemon/server/version.go
Normal file
16
cmd/kaspawallet/daemon/server/version.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
|
||||
"github.com/kaspanet/kaspad/version"
|
||||
)
|
||||
|
||||
func (s *server) GetVersion(_ context.Context, _ *pb.GetVersionRequest) (*pb.GetVersionResponse, error) {
|
||||
s.lock.RLock()
|
||||
defer s.lock.RUnlock()
|
||||
|
||||
return &pb.GetVersionResponse{
|
||||
Version: version.Version(),
|
||||
}, nil
|
||||
}
|
||||
26
cmd/kaspawallet/get_daemon_version.go
Normal file
26
cmd/kaspawallet/get_daemon_version.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/client"
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
|
||||
)
|
||||
|
||||
func getDaemonVersion(conf *getDaemonVersionConfig) 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.GetVersion(ctx, &pb.GetVersionRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(response.Version)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
package main
|
||||
|
||||
import "github.com/pkg/errors"
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
subCmd, config := parseCommandLine()
|
||||
|
||||
var err error
|
||||
switch subCmd {
|
||||
case createSubCmd:
|
||||
@@ -31,6 +32,10 @@ func main() {
|
||||
err = startDaemon(config.(*startDaemonConfig))
|
||||
case sweepSubCmd:
|
||||
err = sweep(config.(*sweepConfig))
|
||||
case versionSubCmd:
|
||||
showVersion()
|
||||
case getDaemonVersionSubCmd:
|
||||
err = getDaemonVersion(config.(*getDaemonVersionConfig))
|
||||
default:
|
||||
err = errors.Errorf("Unknown sub-command '%s'\n", subCmd)
|
||||
}
|
||||
|
||||
@@ -75,23 +75,29 @@ func send(conf *sendConfig) error {
|
||||
signedTransactions[i] = signedTransaction
|
||||
}
|
||||
|
||||
if len(signedTransactions) > 1 {
|
||||
fmt.Printf("Broadcasting %d transactions\n", len(signedTransactions))
|
||||
}
|
||||
|
||||
fmt.Printf("Broadcasting %d transaction(s)\n", len(signedTransactions))
|
||||
// Since we waited for user input when getting the password, which could take unbound amount of time -
|
||||
// create a new context for broadcast, to reset the timeout.
|
||||
broadcastCtx, broadcastCancel := context.WithTimeout(context.Background(), daemonTimeout)
|
||||
defer broadcastCancel()
|
||||
|
||||
response, err := daemonClient.Broadcast(broadcastCtx, &pb.BroadcastRequest{Transactions: signedTransactions})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Transactions were sent successfully")
|
||||
fmt.Println("Transaction ID(s): ")
|
||||
for _, txID := range response.TxIDs {
|
||||
fmt.Printf("\t%s\n", txID)
|
||||
const chunkSize = 100 // To avoid sending a message bigger than the gRPC max message size, we split it to chunks
|
||||
for offset := 0; offset < len(signedTransactions); offset += chunkSize {
|
||||
end := len(signedTransactions)
|
||||
if offset+chunkSize <= len(signedTransactions) {
|
||||
end = offset + chunkSize
|
||||
}
|
||||
|
||||
chunk := signedTransactions[offset:end]
|
||||
response, err := daemonClient.Broadcast(broadcastCtx, &pb.BroadcastRequest{Transactions: chunk})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("Broadcasted %d transaction(s) (broadcasted %.2f%% of the transactions so far)\n", len(chunk), 100*float64(end)/float64(len(signedTransactions)))
|
||||
fmt.Println("Broadcasted Transaction ID(s): ")
|
||||
for _, txID := range response.TxIDs {
|
||||
fmt.Printf("\t%s\n", txID)
|
||||
}
|
||||
}
|
||||
|
||||
if conf.Verbose {
|
||||
|
||||
15
cmd/kaspawallet/version.go
Normal file
15
cmd/kaspawallet/version.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/kaspanet/kaspad/version"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func showVersion() {
|
||||
appName := filepath.Base(os.Args[0])
|
||||
appName = strings.TrimSuffix(appName, filepath.Ext(appName))
|
||||
fmt.Println(appName, "version", version.Version())
|
||||
}
|
||||
@@ -131,11 +131,12 @@ func (bb *blockBuilder) validateTransactions(stagingArea *model.StagingArea,
|
||||
for _, transaction := range transactions {
|
||||
err := bb.validateTransaction(stagingArea, transaction)
|
||||
if err != nil {
|
||||
if !errors.As(err, &ruleerrors.RuleError{}) {
|
||||
ruleError := ruleerrors.RuleError{}
|
||||
if !errors.As(err, &ruleError) {
|
||||
return err
|
||||
}
|
||||
invalidTransactions = append(invalidTransactions,
|
||||
ruleerrors.InvalidTransaction{Transaction: transaction, Error: err})
|
||||
ruleerrors.InvalidTransaction{Transaction: transaction, Error: &ruleError})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -315,7 +315,7 @@ func NewErrMissingParents(missingParentHashes []*externalapi.DomainHash) error {
|
||||
// InvalidTransaction is a struct containing an invalid transaction, and the error explaining why it's invalid.
|
||||
type InvalidTransaction struct {
|
||||
Transaction *externalapi.DomainTransaction
|
||||
Error error
|
||||
Error *RuleError
|
||||
}
|
||||
|
||||
func (invalid InvalidTransaction) String() string {
|
||||
|
||||
@@ -3,9 +3,10 @@ package ruleerrors
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||
"testing"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
)
|
||||
|
||||
@@ -49,7 +50,7 @@ func TestNewErrMissingTxOut(t *testing.T) {
|
||||
func TestNewErrInvalidTransactionsInNewBlock(t *testing.T) {
|
||||
tx := &externalapi.DomainTransaction{Fee: 1337}
|
||||
txID := consensushashing.TransactionID(tx)
|
||||
outer := NewErrInvalidTransactionsInNewBlock([]InvalidTransaction{{tx, ErrNoTxInputs}})
|
||||
outer := NewErrInvalidTransactionsInNewBlock([]InvalidTransaction{{tx, &ErrNoTxInputs}})
|
||||
//TODO: Implement Stringer for `DomainTransaction`
|
||||
expectedOuterErr := fmt.Sprintf("ErrInvalidTransactionsInNewBlock: [(%s: ErrNoTxInputs)]", txID)
|
||||
inner := &ErrInvalidTransactionsInNewBlock{}
|
||||
@@ -60,7 +61,7 @@ func TestNewErrInvalidTransactionsInNewBlock(t *testing.T) {
|
||||
if len(inner.InvalidTransactions) != 1 {
|
||||
t.Fatalf("TestNewErrInvalidTransactionsInNewBlock: Expected len(inner.MissingOutpoints) 1, found: %d", len(inner.InvalidTransactions))
|
||||
}
|
||||
if inner.InvalidTransactions[0].Error != ErrNoTxInputs {
|
||||
if *inner.InvalidTransactions[0].Error != ErrNoTxInputs {
|
||||
t.Fatalf("TestNewErrInvalidTransactionsInNewBlock: Expected ErrNoTxInputs. found: %v", inner.InvalidTransactions[0].Error)
|
||||
}
|
||||
if inner.InvalidTransactions[0].Transaction.Fee != 1337 {
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package mempool
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
||||
"sync"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensusreference"
|
||||
|
||||
@@ -209,17 +211,7 @@ func (mp *mempool) RemoveInvalidTransactions(err *ruleerrors.ErrInvalidTransacti
|
||||
defer mp.mtx.Unlock()
|
||||
|
||||
for _, tx := range err.InvalidTransactions {
|
||||
ruleErr, success := tx.Error.(ruleerrors.RuleError)
|
||||
if !success {
|
||||
continue
|
||||
}
|
||||
|
||||
inner := ruleErr.Unwrap()
|
||||
removeRedeemers := true
|
||||
if _, ok := inner.(ruleerrors.ErrMissingTxOut); ok {
|
||||
removeRedeemers = false
|
||||
}
|
||||
|
||||
removeRedeemers := !errors.As(tx.Error, &ruleerrors.ErrMissingTxOut{})
|
||||
err := mp.removeTransaction(consensushashing.TransactionID(tx.Transaction), removeRedeemers)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -11,7 +11,7 @@ const validCharacters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrs
|
||||
const (
|
||||
appMajor uint = 0
|
||||
appMinor uint = 12
|
||||
appPatch uint = 15
|
||||
appPatch uint = 16
|
||||
)
|
||||
|
||||
// appBuild is defined as a variable so it can be overridden during the build
|
||||
|
||||
Reference in New Issue
Block a user