Compare commits

..

No commits in common. "master" and "v0.22.113" have entirely different histories.

23 changed files with 356 additions and 879 deletions

View file

@ -176,13 +176,12 @@ func NewGetAccountCmd(address string) *GetAccountCmd {
// GetAccountAddressCmd defines the getaccountaddress JSON-RPC command.
type GetAccountAddressCmd struct {
Account *string `jsonrpcdefault:"\"default\""`
AddressType *string `jsonrpcdefault:"\"legacy\""`
Account string
}
// NewGetAccountAddressCmd returns a new instance which can be used to issue a
// getaccountaddress JSON-RPC command.
func NewGetAccountAddressCmd(account *string) *GetAccountAddressCmd {
func NewGetAccountAddressCmd(account string) *GetAccountAddressCmd {
return &GetAccountAddressCmd{
Account: account,
}
@ -190,13 +189,12 @@ func NewGetAccountAddressCmd(account *string) *GetAccountAddressCmd {
// GetAddressesByAccountCmd defines the getaddressesbyaccount JSON-RPC command.
type GetAddressesByAccountCmd struct {
Account *string `jsonrpcdefault:"\"default\""`
AddressType *string `jsonrpcdefault:"\"*\""`
Account string
}
// NewGetAddressesByAccountCmd returns a new instance which can be used to issue
// a getaddressesbyaccount JSON-RPC command.
func NewGetAddressesByAccountCmd(account *string) *GetAddressesByAccountCmd {
func NewGetAddressesByAccountCmd(account string) *GetAddressesByAccountCmd {
return &GetAddressesByAccountCmd{
Account: account,
}
@ -217,9 +215,8 @@ func NewGetAddressInfoCmd(address string) *GetAddressInfoCmd {
// GetBalanceCmd defines the getbalance JSON-RPC command.
type GetBalanceCmd struct {
Account *string `jsonrpcdefault:"\"default\""`
MinConf *int `jsonrpcdefault:"1"`
AddressType *string `jsonrpcdefault:"\"*\""`
Account *string
MinConf *int `jsonrpcdefault:"1"`
}
// NewGetBalanceCmd returns a new instance which can be used to issue a
@ -245,8 +242,8 @@ func NewGetBalancesCmd() *GetBalancesCmd {
// GetNewAddressCmd defines the getnewaddress JSON-RPC command.
type GetNewAddressCmd struct {
Account *string `jsonrpcdefault:"\"default\""`
AddressType *string `jsonrpcdefault:"\"legacy\""`
Account *string
AddressType *string // must be one of legacy / p2pkh or p2sh-p2wkh / p2sh-segwit, or p2wkh / bech32
}
// NewGetNewAddressCmd returns a new instance which can be used to issue a
@ -262,8 +259,7 @@ func NewGetNewAddressCmd(account *string) *GetNewAddressCmd {
// GetRawChangeAddressCmd defines the getrawchangeaddress JSON-RPC command.
type GetRawChangeAddressCmd struct {
Account *string `jsonrpcdefault:"\"default\""`
AddressType *string `jsonrpcdefault:"\"legacy\""`
Account *string
}
// NewGetRawChangeAddressCmd returns a new instance which can be used to issue a
@ -279,8 +275,8 @@ func NewGetRawChangeAddressCmd(account *string) *GetRawChangeAddressCmd {
// GetReceivedByAccountCmd defines the getreceivedbyaccount JSON-RPC command.
type GetReceivedByAccountCmd struct {
Account *string `jsonrpcdefault:"\"default\""`
MinConf *int `jsonrpcdefault:"1"`
Account string
MinConf *int `jsonrpcdefault:"1"`
}
// NewGetReceivedByAccountCmd returns a new instance which can be used to issue
@ -288,7 +284,7 @@ type GetReceivedByAccountCmd struct {
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewGetReceivedByAccountCmd(account *string, minConf *int) *GetReceivedByAccountCmd {
func NewGetReceivedByAccountCmd(account string, minConf *int) *GetReceivedByAccountCmd {
return &GetReceivedByAccountCmd{
Account: account,
MinConf: minConf,
@ -411,8 +407,7 @@ func NewKeyPoolRefillCmd(newSize *uint) *KeyPoolRefillCmd {
// ListAccountsCmd defines the listaccounts JSON-RPC command.
type ListAccountsCmd struct {
MinConf *int `jsonrpcdefault:"1"`
AddressType *string `jsonrpcdefault:"\"*\""`
MinConf *int `jsonrpcdefault:"1"`
}
// NewListAccountsCmd returns a new instance which can be used to issue a
@ -506,10 +501,10 @@ func NewListSinceBlockCmd(blockHash *string, targetConfirms *int, includeWatchOn
// ListTransactionsCmd defines the listtransactions JSON-RPC command.
type ListTransactionsCmd struct {
Account *string `jsonrpcdefault:"\"default\""`
Count *int `jsonrpcdefault:"10"`
From *int `jsonrpcdefault:"0"`
IncludeWatchOnly *bool `jsonrpcdefault:"false"`
Account *string
Count *int `jsonrpcdefault:"10"`
From *int `jsonrpcdefault:"0"`
IncludeWatchOnly *bool `jsonrpcdefault:"false"`
}
// NewListTransactionsCmd returns a new instance which can be used to issue a
@ -567,7 +562,6 @@ type SendFromCmd struct {
ToAddress string
Amount float64 // In BTC
MinConf *int `jsonrpcdefault:"1"`
AddressType *string `jsonrpcdefault:"\"*\""`
Comment *string
CommentTo *string
}
@ -577,15 +571,12 @@ type SendFromCmd struct {
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewSendFromCmd(fromAccount, toAddress string, amount float64,
minConf *int, addrType *string, comment, commentTo *string) *SendFromCmd {
func NewSendFromCmd(fromAccount, toAddress string, amount float64, minConf *int, comment, commentTo *string) *SendFromCmd {
return &SendFromCmd{
FromAccount: fromAccount,
ToAddress: toAddress,
Amount: amount,
MinConf: minConf,
AddressType: addrType,
Comment: comment,
CommentTo: commentTo,
}
@ -596,7 +587,6 @@ type SendManyCmd struct {
FromAccount string
Amounts map[string]float64 `jsonrpcusage:"{\"address\":amount,...}"` // In BTC
MinConf *int `jsonrpcdefault:"1"`
AddressType *string `jsonrpcdefault:"\"*\""`
Comment *string
}
@ -605,24 +595,21 @@ type SendManyCmd struct {
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewSendManyCmd(fromAccount string, amounts map[string]float64,
minConf *int, addrType *string, comment *string) *SendManyCmd {
func NewSendManyCmd(fromAccount string, amounts map[string]float64, minConf *int, comment *string) *SendManyCmd {
return &SendManyCmd{
FromAccount: fromAccount,
Amounts: amounts,
MinConf: minConf,
AddressType: addrType,
Comment: comment,
}
}
// SendToAddressCmd defines the sendtoaddress JSON-RPC command.
type SendToAddressCmd struct {
Address string
Amount float64
AddressType *string `jsonrpcdefault:"\"*\""`
Comment *string
CommentTo *string
Address string
Amount float64
Comment *string
CommentTo *string
}
// NewSendToAddressCmd returns a new instance which can be used to issue a
@ -630,14 +617,12 @@ type SendToAddressCmd struct {
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewSendToAddressCmd(address string, amount float64, addrType *string,
comment, commentTo *string) *SendToAddressCmd {
func NewSendToAddressCmd(address string, amount float64, comment, commentTo *string) *SendToAddressCmd {
return &SendToAddressCmd{
Address: address,
Amount: amount,
AddressType: addrType,
Comment: comment,
CommentTo: commentTo,
Address: address,
Amount: amount,
Comment: comment,
CommentTo: commentTo,
}
}
@ -977,8 +962,8 @@ func NewImportMultiCmd(requests []ImportMultiRequest, options *ImportMultiOption
// RescanBlockchainCmd defines the RescanBlockchain JSON-RPC command.
type RescanBlockchainCmd struct {
StartHeight *int32 `jsonrpcdefault:"0"`
StopHeight *int32
StartHeight *int64 `jsonrpcdefault:"0"`
StopHeight *int64 `jsonrpcdefault:"0"`
}
// NewRescanBlockchainCmd returns a new instance which can be used to issue
@ -986,7 +971,7 @@ type RescanBlockchainCmd struct {
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewRescanBlockchainCmd(startHeight *int32, stopHeight *int32) *RescanBlockchainCmd {
func NewRescanBlockchainCmd(startHeight *int64, stopHeight *int64) *RescanBlockchainCmd {
return &RescanBlockchainCmd{
StartHeight: startHeight,
StopHeight: stopHeight,

View file

@ -287,12 +287,11 @@ func TestWalletSvrCmds(t *testing.T) {
return btcjson.NewCmd("getaccountaddress", "acct")
},
staticCmd: func() interface{} {
return btcjson.NewGetAccountAddressCmd(btcjson.String("acct"))
return btcjson.NewGetAccountAddressCmd("acct")
},
marshalled: `{"jsonrpc":"1.0","method":"getaccountaddress","params":["acct"],"id":1}`,
unmarshalled: &btcjson.GetAccountAddressCmd{
Account: btcjson.String("acct"),
AddressType: btcjson.String("legacy"),
Account: "acct",
},
},
{
@ -301,12 +300,11 @@ func TestWalletSvrCmds(t *testing.T) {
return btcjson.NewCmd("getaddressesbyaccount", "acct")
},
staticCmd: func() interface{} {
return btcjson.NewGetAddressesByAccountCmd(btcjson.String("acct"))
return btcjson.NewGetAddressesByAccountCmd("acct")
},
marshalled: `{"jsonrpc":"1.0","method":"getaddressesbyaccount","params":["acct"],"id":1}`,
unmarshalled: &btcjson.GetAddressesByAccountCmd{
Account: btcjson.String("acct"),
AddressType: btcjson.String("*"),
Account: "acct",
},
},
{
@ -332,9 +330,8 @@ func TestWalletSvrCmds(t *testing.T) {
},
marshalled: `{"jsonrpc":"1.0","method":"getbalance","params":[],"id":1}`,
unmarshalled: &btcjson.GetBalanceCmd{
Account: btcjson.String("default"),
MinConf: btcjson.Int(1),
AddressType: btcjson.String("*"),
Account: nil,
MinConf: btcjson.Int(1),
},
},
{
@ -347,9 +344,8 @@ func TestWalletSvrCmds(t *testing.T) {
},
marshalled: `{"jsonrpc":"1.0","method":"getbalance","params":["acct"],"id":1}`,
unmarshalled: &btcjson.GetBalanceCmd{
Account: btcjson.String("acct"),
MinConf: btcjson.Int(1),
AddressType: btcjson.String("*"),
Account: btcjson.String("acct"),
MinConf: btcjson.Int(1),
},
},
{
@ -362,9 +358,8 @@ func TestWalletSvrCmds(t *testing.T) {
},
marshalled: `{"jsonrpc":"1.0","method":"getbalance","params":["acct",6],"id":1}`,
unmarshalled: &btcjson.GetBalanceCmd{
Account: btcjson.String("acct"),
MinConf: btcjson.Int(6),
AddressType: btcjson.String("*"),
Account: btcjson.String("acct"),
MinConf: btcjson.Int(6),
},
},
{
@ -388,8 +383,7 @@ func TestWalletSvrCmds(t *testing.T) {
},
marshalled: `{"jsonrpc":"1.0","method":"getnewaddress","params":[],"id":1}`,
unmarshalled: &btcjson.GetNewAddressCmd{
Account: btcjson.String("default"),
AddressType: btcjson.String("legacy"),
Account: nil,
},
},
{
@ -402,8 +396,7 @@ func TestWalletSvrCmds(t *testing.T) {
},
marshalled: `{"jsonrpc":"1.0","method":"getnewaddress","params":["acct"],"id":1}`,
unmarshalled: &btcjson.GetNewAddressCmd{
Account: btcjson.String("acct"),
AddressType: btcjson.String("legacy"),
Account: btcjson.String("acct"),
},
},
{
@ -416,8 +409,7 @@ func TestWalletSvrCmds(t *testing.T) {
},
marshalled: `{"jsonrpc":"1.0","method":"getrawchangeaddress","params":[],"id":1}`,
unmarshalled: &btcjson.GetRawChangeAddressCmd{
Account: btcjson.String("default"),
AddressType: btcjson.String("legacy"),
Account: nil,
},
},
{
@ -430,8 +422,7 @@ func TestWalletSvrCmds(t *testing.T) {
},
marshalled: `{"jsonrpc":"1.0","method":"getrawchangeaddress","params":["acct"],"id":1}`,
unmarshalled: &btcjson.GetRawChangeAddressCmd{
Account: btcjson.String("acct"),
AddressType: btcjson.String("legacy"),
Account: btcjson.String("acct"),
},
},
{
@ -440,11 +431,11 @@ func TestWalletSvrCmds(t *testing.T) {
return btcjson.NewCmd("getreceivedbyaccount", "acct")
},
staticCmd: func() interface{} {
return btcjson.NewGetReceivedByAccountCmd(btcjson.String("acct"), nil)
return btcjson.NewGetReceivedByAccountCmd("acct", nil)
},
marshalled: `{"jsonrpc":"1.0","method":"getreceivedbyaccount","params":["acct"],"id":1}`,
unmarshalled: &btcjson.GetReceivedByAccountCmd{
Account: btcjson.String("acct"),
Account: "acct",
MinConf: btcjson.Int(1),
},
},
@ -454,11 +445,11 @@ func TestWalletSvrCmds(t *testing.T) {
return btcjson.NewCmd("getreceivedbyaccount", "acct", 6)
},
staticCmd: func() interface{} {
return btcjson.NewGetReceivedByAccountCmd(btcjson.String("acct"), btcjson.Int(6))
return btcjson.NewGetReceivedByAccountCmd("acct", btcjson.Int(6))
},
marshalled: `{"jsonrpc":"1.0","method":"getreceivedbyaccount","params":["acct",6],"id":1}`,
unmarshalled: &btcjson.GetReceivedByAccountCmd{
Account: btcjson.String("acct"),
Account: "acct",
MinConf: btcjson.Int(6),
},
},
@ -610,8 +601,7 @@ func TestWalletSvrCmds(t *testing.T) {
},
marshalled: `{"jsonrpc":"1.0","method":"listaccounts","params":[],"id":1}`,
unmarshalled: &btcjson.ListAccountsCmd{
MinConf: btcjson.Int(1),
AddressType: btcjson.String("*"),
MinConf: btcjson.Int(1),
},
},
{
@ -624,8 +614,7 @@ func TestWalletSvrCmds(t *testing.T) {
},
marshalled: `{"jsonrpc":"1.0","method":"listaccounts","params":[6],"id":1}`,
unmarshalled: &btcjson.ListAccountsCmd{
MinConf: btcjson.Int(6),
AddressType: btcjson.String("*"),
MinConf: btcjson.Int(6),
},
},
{
@ -855,7 +844,7 @@ func TestWalletSvrCmds(t *testing.T) {
},
marshalled: `{"jsonrpc":"1.0","method":"listtransactions","params":[],"id":1}`,
unmarshalled: &btcjson.ListTransactionsCmd{
Account: btcjson.String("default"),
Account: nil,
Count: btcjson.Int(10),
From: btcjson.Int(0),
IncludeWatchOnly: btcjson.Bool(false),
@ -1013,7 +1002,7 @@ func TestWalletSvrCmds(t *testing.T) {
return btcjson.NewCmd("sendfrom", "from", "1Address", 0.5)
},
staticCmd: func() interface{} {
return btcjson.NewSendFromCmd("from", "1Address", 0.5, nil, nil, nil, nil)
return btcjson.NewSendFromCmd("from", "1Address", 0.5, nil, nil, nil)
},
marshalled: `{"jsonrpc":"1.0","method":"sendfrom","params":["from","1Address",0.5],"id":1}`,
unmarshalled: &btcjson.SendFromCmd{
@ -1021,7 +1010,6 @@ func TestWalletSvrCmds(t *testing.T) {
ToAddress: "1Address",
Amount: 0.5,
MinConf: btcjson.Int(1),
AddressType: btcjson.String("*"),
Comment: nil,
CommentTo: nil,
},
@ -1032,7 +1020,7 @@ func TestWalletSvrCmds(t *testing.T) {
return btcjson.NewCmd("sendfrom", "from", "1Address", 0.5, 6)
},
staticCmd: func() interface{} {
return btcjson.NewSendFromCmd("from", "1Address", 0.5, btcjson.Int(6), nil, nil, nil)
return btcjson.NewSendFromCmd("from", "1Address", 0.5, btcjson.Int(6), nil, nil)
},
marshalled: `{"jsonrpc":"1.0","method":"sendfrom","params":["from","1Address",0.5,6],"id":1}`,
unmarshalled: &btcjson.SendFromCmd{
@ -1040,7 +1028,6 @@ func TestWalletSvrCmds(t *testing.T) {
ToAddress: "1Address",
Amount: 0.5,
MinConf: btcjson.Int(6),
AddressType: btcjson.String("*"),
Comment: nil,
CommentTo: nil,
},
@ -1048,59 +1035,37 @@ func TestWalletSvrCmds(t *testing.T) {
{
name: "sendfrom optional2",
newCmd: func() (interface{}, error) {
return btcjson.NewCmd("sendfrom", "from", "1Address", 0.5, 6, "legacy")
return btcjson.NewCmd("sendfrom", "from", "1Address", 0.5, 6, "comment")
},
staticCmd: func() interface{} {
return btcjson.NewSendFromCmd("from", "1Address", 0.5, btcjson.Int(6), btcjson.String("legacy"),
nil, nil)
return btcjson.NewSendFromCmd("from", "1Address", 0.5, btcjson.Int(6),
btcjson.String("comment"), nil)
},
marshalled: `{"jsonrpc":"1.0","method":"sendfrom","params":["from","1Address",0.5,6,"legacy"],"id":1}`,
marshalled: `{"jsonrpc":"1.0","method":"sendfrom","params":["from","1Address",0.5,6,"comment"],"id":1}`,
unmarshalled: &btcjson.SendFromCmd{
FromAccount: "from",
ToAddress: "1Address",
Amount: 0.5,
MinConf: btcjson.Int(6),
AddressType: btcjson.String("legacy"),
Comment: nil,
Comment: btcjson.String("comment"),
CommentTo: nil,
},
},
{
name: "sendfrom optional3",
newCmd: func() (interface{}, error) {
return btcjson.NewCmd("sendfrom", "from", "1Address", 0.5, 6, "legacy", "comment")
return btcjson.NewCmd("sendfrom", "from", "1Address", 0.5, 6, "comment", "commentto")
},
staticCmd: func() interface{} {
return btcjson.NewSendFromCmd("from", "1Address", 0.5, btcjson.Int(6), btcjson.String("legacy"),
btcjson.String("comment"), nil)
},
marshalled: `{"jsonrpc":"1.0","method":"sendfrom","params":["from","1Address",0.5,6,"legacy","comment"],"id":1}`,
unmarshalled: &btcjson.SendFromCmd{
FromAccount: "from",
ToAddress: "1Address",
Amount: 0.5,
MinConf: btcjson.Int(6),
AddressType: btcjson.String("legacy"),
Comment: btcjson.String("comment"),
CommentTo: nil,
},
},
{
name: "sendfrom optional4",
newCmd: func() (interface{}, error) {
return btcjson.NewCmd("sendfrom", "from", "1Address", 0.5, 6, "legacy", "comment", "commentto")
},
staticCmd: func() interface{} {
return btcjson.NewSendFromCmd("from", "1Address", 0.5, btcjson.Int(6), btcjson.String("legacy"),
return btcjson.NewSendFromCmd("from", "1Address", 0.5, btcjson.Int(6),
btcjson.String("comment"), btcjson.String("commentto"))
},
marshalled: `{"jsonrpc":"1.0","method":"sendfrom","params":["from","1Address",0.5,6,"legacy","comment","commentto"],"id":1}`,
marshalled: `{"jsonrpc":"1.0","method":"sendfrom","params":["from","1Address",0.5,6,"comment","commentto"],"id":1}`,
unmarshalled: &btcjson.SendFromCmd{
FromAccount: "from",
ToAddress: "1Address",
Amount: 0.5,
MinConf: btcjson.Int(6),
AddressType: btcjson.String("legacy"),
Comment: btcjson.String("comment"),
CommentTo: btcjson.String("commentto"),
},
@ -1112,14 +1077,13 @@ func TestWalletSvrCmds(t *testing.T) {
},
staticCmd: func() interface{} {
amounts := map[string]float64{"1Address": 0.5}
return btcjson.NewSendManyCmd("from", amounts, nil, nil, nil)
return btcjson.NewSendManyCmd("from", amounts, nil, nil)
},
marshalled: `{"jsonrpc":"1.0","method":"sendmany","params":["from",{"1Address":0.5}],"id":1}`,
unmarshalled: &btcjson.SendManyCmd{
FromAccount: "from",
Amounts: map[string]float64{"1Address": 0.5},
MinConf: btcjson.Int(1),
AddressType: btcjson.String("*"),
Comment: nil,
},
},
@ -1130,50 +1094,30 @@ func TestWalletSvrCmds(t *testing.T) {
},
staticCmd: func() interface{} {
amounts := map[string]float64{"1Address": 0.5}
return btcjson.NewSendManyCmd("from", amounts, btcjson.Int(6), nil, nil)
return btcjson.NewSendManyCmd("from", amounts, btcjson.Int(6), nil)
},
marshalled: `{"jsonrpc":"1.0","method":"sendmany","params":["from",{"1Address":0.5},6],"id":1}`,
unmarshalled: &btcjson.SendManyCmd{
FromAccount: "from",
Amounts: map[string]float64{"1Address": 0.5},
MinConf: btcjson.Int(6),
AddressType: btcjson.String("*"),
Comment: nil,
},
},
{
name: "sendmany optional2",
newCmd: func() (interface{}, error) {
return btcjson.NewCmd("sendmany", "from", `{"1Address":0.5}`, 6, "legacy")
return btcjson.NewCmd("sendmany", "from", `{"1Address":0.5}`, 6, "comment")
},
staticCmd: func() interface{} {
amounts := map[string]float64{"1Address": 0.5}
return btcjson.NewSendManyCmd("from", amounts, btcjson.Int(6), btcjson.String("legacy"), nil)
return btcjson.NewSendManyCmd("from", amounts, btcjson.Int(6), btcjson.String("comment"))
},
marshalled: `{"jsonrpc":"1.0","method":"sendmany","params":["from",{"1Address":0.5},6,"legacy"],"id":1}`,
marshalled: `{"jsonrpc":"1.0","method":"sendmany","params":["from",{"1Address":0.5},6,"comment"],"id":1}`,
unmarshalled: &btcjson.SendManyCmd{
FromAccount: "from",
Amounts: map[string]float64{"1Address": 0.5},
MinConf: btcjson.Int(6),
AddressType: btcjson.String("legacy"),
Comment: nil,
},
},
{
name: "sendmany optional3",
newCmd: func() (interface{}, error) {
return btcjson.NewCmd("sendmany", "from", `{"1Address":0.5}`, 6, "legacy", "comment")
},
staticCmd: func() interface{} {
amounts := map[string]float64{"1Address": 0.5}
return btcjson.NewSendManyCmd("from", amounts, btcjson.Int(6), btcjson.String("legacy"), btcjson.String("comment"))
},
marshalled: `{"jsonrpc":"1.0","method":"sendmany","params":["from",{"1Address":0.5},6,"legacy","comment"],"id":1}`,
unmarshalled: &btcjson.SendManyCmd{
FromAccount: "from",
Amounts: map[string]float64{"1Address": 0.5},
MinConf: btcjson.Int(6),
AddressType: btcjson.String("legacy"),
Comment: btcjson.String("comment"),
},
},
@ -1183,50 +1127,31 @@ func TestWalletSvrCmds(t *testing.T) {
return btcjson.NewCmd("sendtoaddress", "1Address", 0.5)
},
staticCmd: func() interface{} {
return btcjson.NewSendToAddressCmd("1Address", 0.5, nil, nil, nil)
return btcjson.NewSendToAddressCmd("1Address", 0.5, nil, nil)
},
marshalled: `{"jsonrpc":"1.0","method":"sendtoaddress","params":["1Address",0.5],"id":1}`,
unmarshalled: &btcjson.SendToAddressCmd{
Address: "1Address",
Amount: 0.5,
AddressType: btcjson.String("*"),
Comment: nil,
CommentTo: nil,
Address: "1Address",
Amount: 0.5,
Comment: nil,
CommentTo: nil,
},
},
{
name: "sendtoaddress optional1",
newCmd: func() (interface{}, error) {
return btcjson.NewCmd("sendtoaddress", "1Address", 0.5, "legacy")
return btcjson.NewCmd("sendtoaddress", "1Address", 0.5, "comment", "commentto")
},
staticCmd: func() interface{} {
return btcjson.NewSendToAddressCmd("1Address", 0.5, btcjson.String("legacy"), nil, nil)
},
marshalled: `{"jsonrpc":"1.0","method":"sendtoaddress","params":["1Address",0.5,"legacy"],"id":1}`,
unmarshalled: &btcjson.SendToAddressCmd{
Address: "1Address",
Amount: 0.5,
AddressType: btcjson.String("legacy"),
Comment: nil,
CommentTo: nil,
},
},
{
name: "sendtoaddress optional2",
newCmd: func() (interface{}, error) {
return btcjson.NewCmd("sendtoaddress", "1Address", 0.5, "legacy", "comment", "commentto")
},
staticCmd: func() interface{} {
return btcjson.NewSendToAddressCmd("1Address", 0.5, btcjson.String("legacy"), btcjson.String("comment"),
return btcjson.NewSendToAddressCmd("1Address", 0.5, btcjson.String("comment"),
btcjson.String("commentto"))
},
marshalled: `{"jsonrpc":"1.0","method":"sendtoaddress","params":["1Address",0.5,"legacy","comment","commentto"],"id":1}`,
marshalled: `{"jsonrpc":"1.0","method":"sendtoaddress","params":["1Address",0.5,"comment","commentto"],"id":1}`,
unmarshalled: &btcjson.SendToAddressCmd{
Address: "1Address",
Amount: 0.5,
AddressType: btcjson.String("legacy"),
Comment: btcjson.String("comment"),
CommentTo: btcjson.String("commentto"),
Address: "1Address",
Amount: 0.5,
Comment: btcjson.String("comment"),
CommentTo: btcjson.String("commentto"),
},
},
{

View file

@ -174,7 +174,6 @@ type GetTransactionResult struct {
TimeReceived int64 `json:"timereceived"`
Details []GetTransactionDetailsResult `json:"details"`
Hex string `json:"hex"`
Generated bool `json:"generated"`
}
type ScanningOrFalse struct {
@ -289,6 +288,7 @@ type ListReceivedByAccountResult struct {
// ListReceivedByAddressResult models the data from the listreceivedbyaddress
// command.
type ListReceivedByAddressResult struct {
Account string `json:"account"`
Address string `json:"address"`
Amount float64 `json:"amount"`
Confirmations uint64 `json:"confirmations"`
@ -319,8 +319,8 @@ type ListUnspentResult struct {
// RescanBlockchainResult models the data returned from the rescanblockchain command.
type RescanBlockchainResult struct {
StartHeight int32 `json:"start_height"`
StoptHeight int32 `json:"stop_height"`
StartHeight int64 `json:"start_height"`
StoptHeight int64 `json:"stop_height"`
}
// SignRawTransactionError models the data that contains script verification

View file

@ -40,7 +40,7 @@ func NewExportWatchingWalletCmd(account *string, download *bool) *ExportWatching
// GetUnconfirmedBalanceCmd defines the getunconfirmedbalance JSON-RPC command.
type GetUnconfirmedBalanceCmd struct {
Account *string `jsonrpcdefault:"\"default\""`
Account *string
}
// NewGetUnconfirmedBalanceCmd returns a new instance which can be used to issue
@ -58,7 +58,7 @@ func NewGetUnconfirmedBalanceCmd(account *string) *GetUnconfirmedBalanceCmd {
// command.
type ListAddressTransactionsCmd struct {
Addresses []string
Account *string `jsonrpcdefault:"\"default\""`
Account *string
}
// NewListAddressTransactionsCmd returns a new instance which can be used to
@ -75,7 +75,7 @@ func NewListAddressTransactionsCmd(addresses []string, account *string) *ListAdd
// ListAllTransactionsCmd defines the listalltransactions JSON-RPC command.
type ListAllTransactionsCmd struct {
Account *string `jsonrpcdefault:"\"default\""`
Account *string
}
// NewListAllTransactionsCmd returns a new instance which can be used to issue a

View file

@ -71,7 +71,7 @@ func TestWalletSvrWsCmds(t *testing.T) {
{
name: "exportwatchingwallet optional2",
newCmd: func() (interface{}, error) {
return btcjson.NewCmd("exportwatchingwallet", btcjson.String("acct"), true)
return btcjson.NewCmd("exportwatchingwallet", "acct", true)
},
staticCmd: func() interface{} {
return btcjson.NewExportWatchingWalletCmd(btcjson.String("acct"),
@ -93,7 +93,7 @@ func TestWalletSvrWsCmds(t *testing.T) {
},
marshalled: `{"jsonrpc":"1.0","method":"getunconfirmedbalance","params":[],"id":1}`,
unmarshalled: &btcjson.GetUnconfirmedBalanceCmd{
Account: btcjson.String("default"),
Account: nil,
},
},
{
@ -120,7 +120,7 @@ func TestWalletSvrWsCmds(t *testing.T) {
marshalled: `{"jsonrpc":"1.0","method":"listaddresstransactions","params":[["1Address"]],"id":1}`,
unmarshalled: &btcjson.ListAddressTransactionsCmd{
Addresses: []string{"1Address"},
Account: btcjson.String("default"),
Account: nil,
},
},
{
@ -148,7 +148,7 @@ func TestWalletSvrWsCmds(t *testing.T) {
},
marshalled: `{"jsonrpc":"1.0","method":"listalltransactions","params":[],"id":1}`,
unmarshalled: &btcjson.ListAllTransactionsCmd{
Account: btcjson.String("default"),
Account: nil,
},
},
{

View file

@ -4,7 +4,9 @@ import (
"bytes"
"fmt"
"path/filepath"
"runtime"
"sort"
"sync"
"github.com/pkg/errors"
@ -247,17 +249,17 @@ func (ct *ClaimTrie) AppendBlock(temporary bool) error {
names = append(names, expirations...)
names = removeDuplicates(names)
for _, name := range names {
nhns := ct.makeNameHashNext(names, false, nil)
for nhn := range nhns {
hash, next := ct.nodeManager.Hash(name)
ct.merkleTrie.Update(name, hash, true)
if next <= 0 {
ct.merkleTrie.Update(nhn.Name, nhn.Hash, true)
if nhn.Next <= 0 {
continue
}
newName := normalization.NormalizeIfNecessary(name, next)
newName := normalization.NormalizeIfNecessary(nhn.Name, nhn.Next)
updateNames = append(updateNames, newName)
updateHeights = append(updateHeights, next)
updateHeights = append(updateHeights, nhn.Next)
}
if !temporary && len(updateNames) > 0 {
err = ct.temporalRepo.SetNodesAt(updateNames, updateHeights)
@ -354,29 +356,22 @@ func (ct *ClaimTrie) ResetHeight(height int32) error {
}
func (ct *ClaimTrie) runFullTrieRebuild(names [][]byte, interrupt <-chan struct{}) {
var nhns chan NameHashNext
if names == nil {
node.Log("Building the entire claim trie in RAM...")
ct.claimLogger = newClaimProgressLogger("Processed", node.GetLogger())
ct.nodeManager.IterateNames(func(name []byte) bool {
if interruptRequested(interrupt) {
return false
}
clone := make([]byte, len(name))
copy(clone, name)
hash, _ := ct.nodeManager.Hash(clone)
ct.merkleTrie.Update(clone, hash, false)
ct.claimLogger.LogName(name)
return true
})
nhns = ct.makeNameHashNext(nil, true, interrupt)
} else {
for _, name := range names {
hash, _ := ct.nodeManager.Hash(name)
ct.merkleTrie.Update(name, hash, false)
}
ct.claimLogger = nil
nhns = ct.makeNameHashNext(names, false, interrupt)
}
for nhn := range nhns {
ct.merkleTrie.Update(nhn.Name, nhn.Hash, false)
if ct.claimLogger != nil {
ct.claimLogger.LogName(nhn.Name)
}
}
}
// MerkleHash returns the Merkle Hash of the claimTrie.
@ -442,6 +437,12 @@ func (ct *ClaimTrie) FlushToDisk() {
}
}
type NameHashNext struct {
Name []byte
Hash *chainhash.Hash
Next int32
}
func interruptRequested(interrupted <-chan struct{}) bool {
select {
case <-interrupted: // should never block on nil
@ -451,3 +452,53 @@ func interruptRequested(interrupted <-chan struct{}) bool {
return false
}
func (ct *ClaimTrie) makeNameHashNext(names [][]byte, all bool, interrupt <-chan struct{}) chan NameHashNext {
inputs := make(chan []byte, 512)
outputs := make(chan NameHashNext, 512)
var wg sync.WaitGroup
hashComputationWorker := func() {
for name := range inputs {
hash, next := ct.nodeManager.Hash(name)
outputs <- NameHashNext{name, hash, next}
}
wg.Done()
}
threads := int(0.8 * float32(runtime.GOMAXPROCS(0)))
if threads < 1 {
threads = 1
}
for threads > 0 {
threads--
wg.Add(1)
go hashComputationWorker()
}
go func() {
if all {
ct.nodeManager.IterateNames(func(name []byte) bool {
if interruptRequested(interrupt) {
return false
}
clone := make([]byte, len(name))
copy(clone, name) // iteration name buffer is reused on future loops
inputs <- clone
return true
})
} else {
for _, name := range names {
if interruptRequested(interrupt) {
break
}
inputs <- name
}
}
close(inputs)
}()
go func() {
wg.Wait()
close(outputs)
}()
return outputs
}

View file

@ -1,85 +0,0 @@
package node
import (
"container/list"
"github.com/lbryio/lbcd/claimtrie/change"
)
type cacheLeaf struct {
node *Node
element *list.Element
changes []change.Change
height int32
}
type Cache struct {
nodes map[string]*cacheLeaf
order *list.List
limit int
}
func (nc *Cache) insert(name []byte, n *Node, height int32) {
key := string(name)
existing := nc.nodes[key]
if existing != nil {
existing.node = n
existing.height = height
existing.changes = nil
nc.order.MoveToFront(existing.element)
return
}
for nc.order.Len() >= nc.limit {
// TODO: maybe ensure that we don't remove nodes that have a lot of changes?
delete(nc.nodes, nc.order.Back().Value.(string))
nc.order.Remove(nc.order.Back())
}
element := nc.order.PushFront(key)
nc.nodes[key] = &cacheLeaf{node: n, element: element, height: height}
}
func (nc *Cache) fetch(name []byte, height int32) (*Node, []change.Change, int32) {
key := string(name)
existing := nc.nodes[key]
if existing != nil && existing.height <= height {
nc.order.MoveToFront(existing.element)
return existing.node, existing.changes, existing.height
}
return nil, nil, -1
}
func (nc *Cache) addChanges(changes []change.Change, height int32) {
for _, c := range changes {
key := string(c.Name)
existing := nc.nodes[key]
if existing != nil && existing.height <= height {
existing.changes = append(existing.changes, c)
}
}
}
func (nc *Cache) drop(names [][]byte) {
for _, name := range names {
key := string(name)
existing := nc.nodes[key]
if existing != nil {
// we can't roll it backwards because we don't know its previous height value; just toast it
delete(nc.nodes, key)
nc.order.Remove(existing.element)
}
}
}
func (nc *Cache) clear() {
nc.nodes = map[string]*cacheLeaf{}
nc.order = list.New()
// we'll let the GC sort out the remains...
}
func NewCache(limit int) *Cache {
return &Cache{limit: limit, nodes: map[string]*cacheLeaf{}, order: list.New()}
}

View file

@ -21,7 +21,6 @@ type Manager interface {
IterateNames(predicate func(name []byte) bool)
Hash(name []byte) (*chainhash.Hash, int32)
Flush() error
ClearCache()
}
type BaseManager struct {
@ -31,62 +30,31 @@ type BaseManager struct {
changes []change.Change
tempChanges map[string][]change.Change
cache *Cache
}
func NewBaseManager(repo Repo) (*BaseManager, error) {
nm := &BaseManager{
repo: repo,
cache: NewCache(10000), // TODO: how many should we cache?
repo: repo,
}
return nm, nil
}
func (nm *BaseManager) ClearCache() {
nm.cache.clear()
}
func (nm *BaseManager) NodeAt(height int32, name []byte) (*Node, error) {
n, changes, oldHeight := nm.cache.fetch(name, height)
if n == nil {
changes, err := nm.repo.LoadChanges(name)
if err != nil {
return nil, errors.Wrap(err, "in load changes")
}
changes, err := nm.repo.LoadChanges(name)
if err != nil {
return nil, errors.Wrap(err, "in load changes")
}
if nm.tempChanges != nil { // making an assumption that we only ever have tempChanges for a single block
changes = append(changes, nm.tempChanges[string(name)]...)
}
if nm.tempChanges != nil { // making an assumption that we only ever have tempChanges for a single block
changes = append(changes, nm.tempChanges[string(name)]...)
}
n, err = nm.newNodeFromChanges(changes, height)
if err != nil {
return nil, errors.Wrap(err, "in new node")
}
// TODO: how can we tell what needs to be cached?
if nm.tempChanges == nil && height == nm.height && n != nil && (len(changes) > 4 || len(name) < 12) {
nm.cache.insert(name, n, height)
}
} else {
if nm.tempChanges != nil { // making an assumption that we only ever have tempChanges for a single block
changes = append(changes, nm.tempChanges[string(name)]...)
n = n.Clone()
} else if height != nm.height {
n = n.Clone()
}
updated, err := nm.updateFromChanges(n, changes, height)
if err != nil {
return nil, errors.Wrap(err, "in update from changes")
}
if !updated {
n.AdjustTo(oldHeight, height, name)
}
if nm.tempChanges == nil && height == nm.height {
nm.cache.insert(name, n, height)
}
n, err := nm.newNodeFromChanges(changes, height)
if err != nil {
return nil, errors.Wrap(err, "in new node")
}
return n, nil
@ -98,13 +66,17 @@ func (nm *BaseManager) node(name []byte) (*Node, error) {
return nm.NodeAt(nm.height, name)
}
func (nm *BaseManager) updateFromChanges(n *Node, changes []change.Change, height int32) (bool, error) {
// newNodeFromChanges returns a new Node constructed from the changes.
// The changes must preserve their order received.
func (nm *BaseManager) newNodeFromChanges(changes []change.Change, height int32) (*Node, error) {
count := len(changes)
if count == 0 {
return false, nil
if len(changes) == 0 {
return nil, nil
}
n := New()
previous := changes[0].Height
count := len(changes)
for i, chg := range changes {
if chg.Height < previous {
@ -123,37 +95,15 @@ func (nm *BaseManager) updateFromChanges(n *Node, changes []change.Change, heigh
delay := nm.getDelayForName(n, chg)
err := n.ApplyChange(chg, delay)
if err != nil {
return false, errors.Wrap(err, "in apply change")
return nil, errors.Wrap(err, "in apply change")
}
}
if count <= 0 {
// we applied no changes, which means we shouldn't exist if we had all the changes
// or might mean nothing significant if we are applying a partial changeset
return false, nil
}
lastChange := changes[count-1]
n.AdjustTo(lastChange.Height, height, lastChange.Name)
return true, nil
}
// newNodeFromChanges returns a new Node constructed from the changes.
// The changes must preserve their order received.
func (nm *BaseManager) newNodeFromChanges(changes []change.Change, height int32) (*Node, error) {
if len(changes) == 0 {
return nil, nil
}
n := New()
updated, err := nm.updateFromChanges(n, changes, height)
if err != nil {
return nil, errors.Wrap(err, "in update from changes")
}
if updated {
return n, nil
}
return nil, nil
lastChange := changes[count-1]
return n.AdjustTo(lastChange.Height, height, lastChange.Name), nil
}
func (nm *BaseManager) AppendChange(chg change.Change) {
@ -270,7 +220,6 @@ func (nm *BaseManager) IncrementHeightTo(height int32, temporary bool) ([][]byte
}
if !temporary {
nm.cache.addChanges(nm.changes, height)
if err := nm.repo.AppendChanges(nm.changes); err != nil { // destroys names
return nil, errors.Wrap(err, "in append changes")
}
@ -306,8 +255,6 @@ func (nm *BaseManager) DecrementHeightTo(affectedNames [][]byte, height int32) (
return affectedNames, errors.Wrap(err, "in drop changes")
}
}
nm.cache.drop(affectedNames)
}
nm.height = height

View file

@ -110,7 +110,7 @@ func (n *Node) ApplyChange(chg change.Change, delay int32) error {
}
// AdjustTo activates claims and computes takeovers until it reaches the specified height.
func (n *Node) AdjustTo(height, maxHeight int32, name []byte) {
func (n *Node) AdjustTo(height, maxHeight int32, name []byte) *Node {
changed := n.handleExpiredAndActivated(height) > 0
n.updateTakeoverHeight(height, name, changed)
if maxHeight > height {
@ -120,6 +120,7 @@ func (n *Node) AdjustTo(height, maxHeight int32, name []byte) {
height = h
}
}
return n
}
func (n *Node) updateTakeoverHeight(height int32, name []byte, refindBest bool) {
@ -339,28 +340,3 @@ func (n *Node) SortClaimsByBid() {
return OutPointLess(n.Claims[j].OutPoint, n.Claims[i].OutPoint)
})
}
func (n *Node) Clone() *Node {
clone := New()
if n.SupportSums != nil {
clone.SupportSums = map[string]int64{}
for key, value := range n.SupportSums {
clone.SupportSums[key] = value
}
}
clone.Supports = make(ClaimList, len(n.Supports))
for i, support := range n.Supports {
clone.Supports[i] = &Claim{}
*clone.Supports[i] = *support
}
clone.Claims = make(ClaimList, len(n.Claims))
for i, claim := range n.Claims {
clone.Claims[i] = &Claim{}
*clone.Claims[i] = *claim
}
clone.TakenOverAt = n.TakenOverAt
if n.BestClaim != nil {
clone.BestClaim = clone.Claims.find(byID(n.BestClaim.ClaimID))
}
return clone
}

View file

@ -34,7 +34,6 @@ func (nm *NormalizingManager) IncrementHeightTo(height int32, temporary bool) ([
func (nm *NormalizingManager) DecrementHeightTo(affectedNames [][]byte, height int32) ([][]byte, error) {
if nm.normalizedAt > height {
nm.normalizedAt = -1
nm.ClearCache()
}
return nm.Manager.DecrementHeightTo(affectedNames, height)
}
@ -111,7 +110,5 @@ func (nm *NormalizingManager) addNormalizationForkChangesIfNecessary(height int3
return true
}
nm.Manager.ClearCache()
nm.Manager.IterateNames(predicate)
}

View file

@ -111,8 +111,6 @@ type config struct {
SigNet bool `long:"signet" description:"Connect to signet (default RPC server: localhost:49245)"`
Wallet bool `long:"wallet" description:"Connect to wallet RPC server instead (default: localhost:9244, testnet: localhost:19244, regtest: localhost:29244)"`
ShowVersion bool `short:"V" long:"version" description:"Display version information and exit"`
Timed bool `short:"t" long:"timed" description:"Display RPC response time"`
Quiet bool `short:"q" long:"quiet" description:"Do not output results to stdout"`
}
// normalizeAddress returns addr with the passed default port appended if

View file

@ -9,7 +9,6 @@ import (
"os"
"path/filepath"
"strings"
"time"
"github.com/lbryio/lbcd/btcjson"
)
@ -134,8 +133,6 @@ func main() {
os.Exit(1)
}
started := time.Now()
// Send the JSON-RPC request to the server using the user-specified
// connection configuration.
result, err := sendPostRequest(marshalledJSON, cfg)
@ -144,16 +141,6 @@ func main() {
os.Exit(1)
}
if cfg.Timed {
elapsed := time.Since(started)
defer fmt.Fprintf(os.Stderr, "%s\n", elapsed)
}
var output io.Writer = os.Stdout
if cfg.Quiet {
output = io.Discard
}
// Choose how to display the result based on its type.
strResult := string(result)
if strings.HasPrefix(strResult, "{") || strings.HasPrefix(strResult, "[") {
@ -163,7 +150,7 @@ func main() {
err)
os.Exit(1)
}
fmt.Fprintln(output, dst.String())
fmt.Println(dst.String())
} else if strings.HasPrefix(strResult, `"`) {
var str string
@ -172,9 +159,9 @@ func main() {
err)
os.Exit(1)
}
fmt.Fprintln(output, str)
fmt.Println(str)
} else if strResult != "null" {
fmt.Fprintln(output, strResult)
fmt.Println(strResult)
}
}

View file

@ -1,42 +0,0 @@
#! /bin/bash
read -r -d '' help << EOM
$0 - helper script for displaying miner of a mined block.
Options:
-h Display this message.
--height Specify blockheight.
--hash Specify blockhash.
EOM
while getopts ":h-:" optchar; do
case "${optchar}" in
-)
case "${OPTARG}" in
hash)
blockhash="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
;;
height)
blockheight="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
blockhash=$(lbcctl getblockhash ${blockheight})
;;
*) echo "Unknown long option --${OPTARG}" >&2; exit -2 ;;
esac
;;
h) printf "${help}\n\n"; exit 2;;
*) echo "Unknown option -${OPTARG}" >&2; exit -2;;
esac
done
block=$(lbcctl getblock $blockhash)
blockheight=$(lbcctl getblock $blockhash | jq -r .height)
coinbase_txid=$(echo ${block} | jq -r '.tx[0]')
coinbase_raw=$(lbcctl getrawtransaction ${coinbase_txid} 1)
coinbase=$(echo ${coinbase_raw} | jq '.vin[0].coinbase')
miner=$(echo ${coinbase} | grep -o '2f.*2f' | xxd -r -p | strings)
echo ${blockheight}: ${blockhash}: ${miner}

View file

@ -1,21 +1,15 @@
# lbcdbloknotify
# lbcd Websockets Example
This bridge program subscribes to lbcd's notifications over websockets using the rpcclient package.
Users can specify supported actions upon receiving this notifications.
This example shows how to use the rpcclient package to connect to a btcd RPC
server using TLS-secured websockets, register for block connected and block
disconnected notifications, and get the current block count.
## Building(or Running) the Program
## Running the Example
Clone the lbcd package:
The first step is to clone the lbcd package:
```bash
$ git clone github.com/lbryio/lbcd
$ cd lbcd/rpcclient/examples
# build the program
$ go build .
# or directly run it (build implicitly behind the scene)
$ go run .
```
Display available options:
@ -35,31 +29,18 @@ $ go run . -h
Stratum server (default "lbrypool.net:3334")
-stratumpass string
Stratum server password (default "password")
-quiet
Do not print periodic logs
```
Running the program:
Start the program:
```bash
# Send stratum mining.update_block mesage upon receving block connected notifiations.
$ go run . -rpcuser <RPC USERNAME> -rpcpass <RPC PASSWD> --notls -stratum <STRATUM SERVER> -stratumpass <STRATUM PASSWD>
$ go run . -stratumpass <STRATUM PASSWD> -rpcuser <RPC USERNAME> -rpcpass <RPC PASSWD>
2022/01/10 23:16:21 Current block count: 1093112
2022/01/10 23:16:21 NotifyBlocks: Registration Complete
2022/01/10 23:16:21 Block count: 1093112
...
# Execute a custome command (with blockhash) upon receving block connected notifiations.
$ go run . -rpcuser <RPC USERNAME> -rpcpass <RPC PASSWD> --notls -run "echo %s"
```
## Notes
* Stratum TCP connection is persisted with auto-reconnect. (retry backoff increases from 1s to 60s maximum)
* Stratum update_block jobs on previous notifications are canceled when a new notification arrives.
Usually, the jobs are so short and completed immediately. However, if the Stratum connection is broken, this
prevents the bridge from accumulating stale jobs.
## License
This example is licensed under the [copyfree](http://copyfree.org) ISC License.

View file

@ -1,20 +0,0 @@
package main
import (
"github.com/lbryio/lbcd/wire"
"github.com/lbryio/lbcutil"
)
type eventBlockConected struct {
height int32
header *wire.BlockHeader
txns []*lbcutil.Tx
}
type adapter struct {
*bridge
}
func (a *adapter) onFilteredBlockConnected(height int32, header *wire.BlockHeader, txns []*lbcutil.Tx) {
a.eventCh <- &eventBlockConected{height, header, txns}
}

View file

@ -1,172 +0,0 @@
package main
import (
"context"
"errors"
"fmt"
"log"
"net"
"os"
"os/exec"
"strings"
"sync"
"syscall"
"time"
)
type bridge struct {
ctx context.Context
prevJobContext context.Context
prevJobCancel context.CancelFunc
eventCh chan interface{}
errorc chan error
wg sync.WaitGroup
stratum *stratumClient
customCmd string
}
func newBridge(stratumServer, stratumPass, coinid string) *bridge {
s := &bridge{
ctx: context.Background(),
eventCh: make(chan interface{}),
errorc: make(chan error),
}
if len(stratumServer) > 0 {
s.stratum = newStratumClient(stratumServer, stratumPass, coinid)
}
return s
}
func (b *bridge) start() {
if b.stratum != nil {
backoff := time.Second
for {
err := b.stratum.dial()
if err == nil {
break
}
log.Printf("WARN: stratum.dial() error: %s, retry in %s", err, backoff)
time.Sleep(backoff)
if backoff < 60*time.Second {
backoff += time.Second
}
}
}
for e := range b.eventCh {
switch e := e.(type) {
case *eventBlockConected:
b.handleFilteredBlockConnected(e)
default:
b.errorc <- fmt.Errorf("unknown event type: %T", e)
return
}
}
}
func (b *bridge) handleFilteredBlockConnected(e *eventBlockConected) {
if !*quiet {
log.Printf("Block connected: %s (%d) %v", e.header.BlockHash(), e.height, e.header.Timestamp)
}
hash := e.header.BlockHash().String()
height := e.height
// Cancel jobs on previous block. It's safe if they are already done.
if b.prevJobContext != nil {
select {
case <-b.prevJobContext.Done():
log.Printf("prev one canceled")
default:
b.prevJobCancel()
}
}
// Wait until all previous jobs are done or canceled.
b.wg.Wait()
// Create and save cancelable subcontext for new jobs.
ctx, cancel := context.WithCancel(b.ctx)
b.prevJobContext, b.prevJobCancel = ctx, cancel
if len(b.customCmd) > 0 {
go b.execCustomCommand(ctx, hash, height)
}
// Send stratum update block message
if b.stratum != nil {
go b.stratumUpdateBlock(ctx, hash, height)
}
}
func (s *bridge) stratumUpdateBlock(ctx context.Context, hash string, height int32) {
s.wg.Add(1)
defer s.wg.Done()
backoff := time.Second
retry := func(err error) {
if backoff < 60*time.Second {
backoff += time.Second
}
log.Printf("WARN: stratum.send() on block %d error: %s", height, err)
time.Sleep(backoff)
s.stratum.dial()
}
msg := stratumUpdateBlockMsg(*stratumPass, *coinid, hash)
for {
switch err := s.stratum.send(ctx, msg); {
case err == nil:
return
case errors.Is(err, context.Canceled):
log.Printf("INFO: stratum.send() on block %d: %s.", height, err)
return
case errors.Is(err, syscall.EPIPE):
errClose := s.stratum.conn.Close()
if errClose != nil {
log.Printf("WARN: stratum.conn.Close() on block %d: %s.", height, errClose)
}
retry(err)
case errors.Is(err, net.ErrClosed):
retry(err)
default:
retry(err)
}
}
}
func (s *bridge) execCustomCommand(ctx context.Context, hash string, height int32) {
s.wg.Add(1)
defer s.wg.Done()
cmd := strings.ReplaceAll(s.customCmd, "%s", hash)
err := doExecCustomCommand(ctx, cmd)
if err != nil {
log.Printf("ERROR: execCustomCommand on block %s(%d): %s", hash, height, err)
}
}
func doExecCustomCommand(ctx context.Context, cmd string) error {
strs := strings.Split(cmd, " ")
path, err := exec.LookPath(strs[0])
if errors.Is(err, exec.ErrDot) {
err = nil
}
if err != nil {
return err
}
c := exec.CommandContext(ctx, path, strs[1:]...)
c.Stdout = os.Stdout
return c.Run()
}

View file

@ -1,53 +0,0 @@
package main
import (
"io/ioutil"
"log"
"path/filepath"
"github.com/lbryio/lbcd/rpcclient"
)
func newLbcdClient(server, user, pass string, notls bool, adpt adapter) *rpcclient.Client {
ntfnHandlers := rpcclient.NotificationHandlers{
OnFilteredBlockConnected: adpt.onFilteredBlockConnected,
}
// Config lbcd RPC client with websockets.
connCfg := &rpcclient.ConnConfig{
Host: server,
Endpoint: "ws",
User: user,
Pass: pass,
DisableTLS: true,
}
if !notls {
cert, err := ioutil.ReadFile(filepath.Join(lbcdHomeDir, "rpc.cert"))
if err != nil {
log.Fatalf("can't read lbcd certificate: %s", err)
}
connCfg.Certificates = cert
connCfg.DisableTLS = false
}
client, err := rpcclient.New(connCfg, &ntfnHandlers)
if err != nil {
log.Fatalf("can't create rpc client: %s", err)
}
// Register for block connect and disconnect notifications.
if err = client.NotifyBlocks(); err != nil {
log.Fatalf("can't register block notification: %s", err)
}
// Get the current block count.
blockCount, err := client.GetBlockCount()
if err != nil {
log.Fatalf("can't get block count: %s", err)
}
log.Printf("Current block count: %d", blockCount)
return client
}

View file

@ -1,63 +1,133 @@
// Copyright (c) 2014-2017 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package main
import (
"errors"
"flag"
"fmt"
"io/ioutil"
"log"
"net"
"os"
"os/exec"
"path/filepath"
"strings"
"github.com/lbryio/lbcd/rpcclient"
"github.com/lbryio/lbcd/wire"
"github.com/lbryio/lbcutil"
)
var (
lbcdHomeDir = lbcutil.AppDataDir("lbcd", false)
defaultCert = filepath.Join(lbcdHomeDir, "rpc.cert")
)
var (
coinid = flag.String("coinid", "1425", "Coin ID")
stratumServer = flag.String("stratum", "", "Stratum server")
stratumPass = flag.String("stratumpass", "", "Stratum server password")
rpcserver = flag.String("rpcserver", "localhost:9245", "LBCD RPC server")
rpcuser = flag.String("rpcuser", "rpcuser", "LBCD RPC username")
rpcpass = flag.String("rpcpass", "rpcpass", "LBCD RPC password")
rpccert = flag.String("rpccert", defaultCert, "LBCD RPC certificate")
notls = flag.Bool("notls", false, "Connect to LBCD with TLS disabled")
run = flag.String("run", "", "Run custom shell command")
quiet = flag.Bool("quiet", false, "Do not print logs")
coinid = flag.String("coinid", "1425", "Coin ID")
stratum = flag.String("stratum", "", "Stratum server")
stratumPass = flag.String("stratumpass", "", "Stratum server password")
rpcserver = flag.String("rpcserver", "localhost:9245", "LBCD RPC server")
rpcuser = flag.String("rpcuser", "rpcuser", "LBCD RPC username")
rpcpass = flag.String("rpcpass", "rpcpass", "LBCD RPC password")
notls = flag.Bool("notls", false, "Connect to LBCD with TLS disabled")
run = flag.String("run", "", "Run custom shell command")
)
func onFilteredBlockConnected(height int32, header *wire.BlockHeader, txns []*lbcutil.Tx) {
blockHash := header.BlockHash().String()
log.Printf("Block connected: %v (%d) %v", blockHash, height, header.Timestamp)
if cmd := *run; len(cmd) != 0 {
cmd = strings.ReplaceAll(cmd, "%s", blockHash)
err := execCustomCommand(cmd)
if err != nil {
log.Printf("ERROR: execCustomCommand: %s", err)
}
}
if len(*stratum) > 0 && len(*stratumPass) > 0 {
err := stratumUpdateBlock(*stratum, *stratumPass, *coinid, blockHash)
if err != nil {
log.Printf("ERROR: stratumUpdateBlock: %s", err)
}
}
}
func execCustomCommand(cmd string) error {
strs := strings.Split(cmd, " ")
path, err := exec.LookPath(strs[0])
if errors.Is(err, exec.ErrDot) {
err = nil
}
if err != nil {
return err
}
c := exec.Command(path, strs[1:]...)
c.Stdout = os.Stdout
return c.Run()
}
func stratumUpdateBlock(stratum, stratumPass, coinid, blockHash string) error {
addr, err := net.ResolveTCPAddr("tcp", stratum)
if err != nil {
return fmt.Errorf("can't resolve addr: %w", err)
}
conn, err := net.DialTCP("tcp", nil, addr)
if err != nil {
return fmt.Errorf("can't dial tcp: %w", err)
}
defer conn.Close()
msg := fmt.Sprintf(`{"id":1,"method":"mining.update_block","params":[%q,%s,%q]}`,
stratumPass, coinid, blockHash)
_, err = conn.Write([]byte(msg))
if err != nil {
return fmt.Errorf("can't write message: %w", err)
}
return nil
}
func main() {
flag.Parse()
// Setup notification handler
b := newBridge(*stratumServer, *stratumPass, *coinid)
if len(*run) > 0 {
// Check if ccommand exists.
strs := strings.Split(*run, " ")
cmd := strs[0]
_, err := exec.LookPath(cmd)
if err != nil {
log.Fatalf("ERROR: %s not found: %s", cmd, err)
}
b.customCmd = *run
ntfnHandlers := rpcclient.NotificationHandlers{
OnFilteredBlockConnected: onFilteredBlockConnected,
}
// Start the eventt handler.
go b.start()
// Connect to local lbcd RPC server using websockets.
lbcdHomeDir := lbcutil.AppDataDir("lbcd", false)
certs, err := ioutil.ReadFile(filepath.Join(lbcdHomeDir, "rpc.cert"))
if err != nil {
log.Fatalf("can't read lbcd certificate: %s", err)
}
connCfg := &rpcclient.ConnConfig{
Host: *rpcserver,
Endpoint: "ws",
User: *rpcuser,
Pass: *rpcpass,
Certificates: certs,
DisableTLS: *notls,
}
client, err := rpcclient.New(connCfg, &ntfnHandlers)
if err != nil {
log.Fatalf("can't create rpc client: %s", err)
}
// Adaptater receives lbcd notifications, and emit events.
adpt := adapter{b}
// Register for block connect and disconnect notifications.
if err = client.NotifyBlocks(); err != nil {
log.Fatalf("can't register block notification: %s", err)
}
log.Printf("NotifyBlocks: Registration Complete")
client := newLbcdClient(*rpcserver, *rpcuser, *rpcpass, *notls, adpt)
go func() {
err := <-b.errorc
log.Fatalf("ERROR: %s", err)
client.Shutdown()
}()
// Get the current block count.
blockCount, err := client.GetBlockCount()
if err != nil {
log.Fatalf("can't get block count: %s", err)
}
log.Printf("Block count: %d", blockCount)
// Wait until the client either shuts down gracefully (or the user
// terminates the process with Ctrl+C).

View file

@ -1,56 +0,0 @@
package main
import (
"context"
"fmt"
"net"
)
type stratumClient struct {
server string
passwd string
coinid string
conn *net.TCPConn
}
func newStratumClient(server, passwd, coinid string) *stratumClient {
return &stratumClient{
server: server,
}
}
func (c *stratumClient) dial() error {
addr, err := net.ResolveTCPAddr("tcp", c.server)
if err != nil {
return fmt.Errorf("resolve tcp addr: %w", err)
}
conn, err := net.DialTCP("tcp", nil, addr)
if err != nil {
return fmt.Errorf("dial tcp: %w", err)
}
c.conn = conn
return nil
}
func (c *stratumClient) send(ctx context.Context, msg string) error {
select {
case <-ctx.Done():
return ctx.Err()
default:
}
_, err := c.conn.Write([]byte(msg))
return err
}
func stratumUpdateBlockMsg(stratumPass, coinid, blockHash string) string {
return fmt.Sprintf(`{"id":1,"method":"mining.update_block","params":[%q,%s,%q]}`,
stratumPass, coinid, blockHash)
}

View file

@ -774,8 +774,7 @@ func (c *Client) handleSendPostMessage(jReq *jsonRequest) {
tries := 10
for i := 0; tries == 0 || i < tries; i++ {
bodyReader := bytes.NewReader(jReq.marshalledJSON)
var httpReq *http.Request
httpReq, err = http.NewRequest("POST", url, bodyReader)
httpReq, err := http.NewRequest("POST", url, bodyReader)
if err != nil {
jReq.responseChan <- &Response{result: nil, err: err}
return
@ -787,8 +786,7 @@ func (c *Client) handleSendPostMessage(jReq *jsonRequest) {
}
// Configure basic access authorization.
var user, pass string
user, pass, err = c.config.getAuth()
user, pass, err := c.config.getAuth()
if err != nil {
jReq.responseChan <- &Response{result: nil, err: err}
return

View file

@ -536,10 +536,9 @@ func (r FutureSendToAddressResult) Receive() (*chainhash.Hash, error) {
// returned instance.
//
// See SendToAddress for the blocking version and more details.
func (c *Client) SendToAddressAsync(address btcutil.Address, amount btcutil.Amount,
addrType *string) FutureSendToAddressResult {
func (c *Client) SendToAddressAsync(address btcutil.Address, amount btcutil.Amount) FutureSendToAddressResult {
addr := address.EncodeAddress()
cmd := btcjson.NewSendToAddressCmd(addr, amount.ToBTC(), addrType, nil, nil)
cmd := btcjson.NewSendToAddressCmd(addr, amount.ToBTC(), nil, nil)
return c.SendCmd(cmd)
}
@ -551,9 +550,8 @@ func (c *Client) SendToAddressAsync(address btcutil.Address, amount btcutil.Amou
//
// NOTE: This function requires to the wallet to be unlocked. See the
// WalletPassphrase function for more details.
func (c *Client) SendToAddress(address btcutil.Address, amount btcutil.Amount,
addrType *string) (*chainhash.Hash, error) {
return c.SendToAddressAsync(address, amount, addrType).Receive()
func (c *Client) SendToAddress(address btcutil.Address, amount btcutil.Amount) (*chainhash.Hash, error) {
return c.SendToAddressAsync(address, amount).Receive()
}
// SendToAddressCommentAsync returns an instance of a type that can be used to
@ -562,12 +560,12 @@ func (c *Client) SendToAddress(address btcutil.Address, amount btcutil.Amount,
//
// See SendToAddressComment for the blocking version and more details.
func (c *Client) SendToAddressCommentAsync(address btcutil.Address,
amount btcutil.Amount, addrType *string, comment string,
amount btcutil.Amount, comment,
commentTo string) FutureSendToAddressResult {
addr := address.EncodeAddress()
cmd := btcjson.NewSendToAddressCmd(addr, amount.ToBTC(), addrType,
&comment, &commentTo)
cmd := btcjson.NewSendToAddressCmd(addr, amount.ToBTC(), &comment,
&commentTo)
return c.SendCmd(cmd)
}
@ -583,10 +581,9 @@ func (c *Client) SendToAddressCommentAsync(address btcutil.Address,
//
// NOTE: This function requires to the wallet to be unlocked. See the
// WalletPassphrase function for more details.
func (c *Client) SendToAddressComment(address btcutil.Address, amount btcutil.Amount,
addrType *string, comment, commentTo string) (*chainhash.Hash, error) {
return c.SendToAddressCommentAsync(address, amount, addrType,
comment, commentTo).Receive()
func (c *Client) SendToAddressComment(address btcutil.Address, amount btcutil.Amount, comment, commentTo string) (*chainhash.Hash, error) {
return c.SendToAddressCommentAsync(address, amount, comment,
commentTo).Receive()
}
// FutureSendFromResult is a future promise to deliver the result of a
@ -618,11 +615,10 @@ func (r FutureSendFromResult) Receive() (*chainhash.Hash, error) {
// returned instance.
//
// See SendFrom for the blocking version and more details.
func (c *Client) SendFromAsync(fromAccount string, toAddress btcutil.Address,
amount btcutil.Amount, addrType *string) FutureSendFromResult {
func (c *Client) SendFromAsync(fromAccount string, toAddress btcutil.Address, amount btcutil.Amount) FutureSendFromResult {
addr := toAddress.EncodeAddress()
cmd := btcjson.NewSendFromCmd(fromAccount, addr, amount.ToBTC(), nil,
addrType, nil, nil)
nil, nil)
return c.SendCmd(cmd)
}
@ -634,8 +630,8 @@ func (c *Client) SendFromAsync(fromAccount string, toAddress btcutil.Address,
//
// NOTE: This function requires to the wallet to be unlocked. See the
// WalletPassphrase function for more details.
func (c *Client) SendFrom(fromAccount string, toAddress btcutil.Address, amount btcutil.Amount, addrType *string) (*chainhash.Hash, error) {
return c.SendFromAsync(fromAccount, toAddress, amount, addrType).Receive()
func (c *Client) SendFrom(fromAccount string, toAddress btcutil.Address, amount btcutil.Amount) (*chainhash.Hash, error) {
return c.SendFromAsync(fromAccount, toAddress, amount).Receive()
}
// SendFromMinConfAsync returns an instance of a type that can be used to get
@ -643,12 +639,10 @@ func (c *Client) SendFrom(fromAccount string, toAddress btcutil.Address, amount
// the returned instance.
//
// See SendFromMinConf for the blocking version and more details.
func (c *Client) SendFromMinConfAsync(fromAccount string,
toAddress btcutil.Address, amount btcutil.Amount,
minConfirms int, addrType *string) FutureSendFromResult {
func (c *Client) SendFromMinConfAsync(fromAccount string, toAddress btcutil.Address, amount btcutil.Amount, minConfirms int) FutureSendFromResult {
addr := toAddress.EncodeAddress()
cmd := btcjson.NewSendFromCmd(fromAccount, addr, amount.ToBTC(),
&minConfirms, addrType, nil, nil)
&minConfirms, nil, nil)
return c.SendCmd(cmd)
}
@ -661,10 +655,9 @@ func (c *Client) SendFromMinConfAsync(fromAccount string,
//
// NOTE: This function requires to the wallet to be unlocked. See the
// WalletPassphrase function for more details.
func (c *Client) SendFromMinConf(fromAccount string, toAddress btcutil.Address,
amount btcutil.Amount, minConfirms int, addrType *string) (*chainhash.Hash, error) {
func (c *Client) SendFromMinConf(fromAccount string, toAddress btcutil.Address, amount btcutil.Amount, minConfirms int) (*chainhash.Hash, error) {
return c.SendFromMinConfAsync(fromAccount, toAddress, amount,
minConfirms, addrType).Receive()
minConfirms).Receive()
}
// SendFromCommentAsync returns an instance of a type that can be used to get
@ -674,11 +667,11 @@ func (c *Client) SendFromMinConf(fromAccount string, toAddress btcutil.Address,
// See SendFromComment for the blocking version and more details.
func (c *Client) SendFromCommentAsync(fromAccount string,
toAddress btcutil.Address, amount btcutil.Amount, minConfirms int,
addrType *string, comment, commentTo string) FutureSendFromResult {
comment, commentTo string) FutureSendFromResult {
addr := toAddress.EncodeAddress()
cmd := btcjson.NewSendFromCmd(fromAccount, addr, amount.ToBTC(),
&minConfirms, addrType, &comment, &commentTo)
&minConfirms, &comment, &commentTo)
return c.SendCmd(cmd)
}
@ -694,11 +687,11 @@ func (c *Client) SendFromCommentAsync(fromAccount string,
// NOTE: This function requires to the wallet to be unlocked. See the
// WalletPassphrase function for more details.
func (c *Client) SendFromComment(fromAccount string, toAddress btcutil.Address,
amount btcutil.Amount, minConfirms int, addrType *string,
amount btcutil.Amount, minConfirms int,
comment, commentTo string) (*chainhash.Hash, error) {
return c.SendFromCommentAsync(fromAccount, toAddress, amount,
minConfirms, addrType, comment, commentTo).Receive()
minConfirms, comment, commentTo).Receive()
}
// FutureSendManyResult is a future promise to deliver the result of a
@ -735,7 +728,7 @@ func (c *Client) SendManyAsync(fromAccount string, amounts map[btcutil.Address]b
for addr, amount := range amounts {
convertedAmounts[addr.EncodeAddress()] = amount.ToBTC()
}
cmd := btcjson.NewSendManyCmd(fromAccount, convertedAmounts, nil, nil, nil)
cmd := btcjson.NewSendManyCmd(fromAccount, convertedAmounts, nil, nil)
return c.SendCmd(cmd)
}
@ -758,14 +751,14 @@ func (c *Client) SendMany(fromAccount string, amounts map[btcutil.Address]btcuti
// See SendManyMinConf for the blocking version and more details.
func (c *Client) SendManyMinConfAsync(fromAccount string,
amounts map[btcutil.Address]btcutil.Amount,
minConfirms int, addrType *string) FutureSendManyResult {
minConfirms int) FutureSendManyResult {
convertedAmounts := make(map[string]float64, len(amounts))
for addr, amount := range amounts {
convertedAmounts[addr.EncodeAddress()] = amount.ToBTC()
}
cmd := btcjson.NewSendManyCmd(fromAccount, convertedAmounts,
&minConfirms, nil, addrType)
&minConfirms, nil)
return c.SendCmd(cmd)
}
@ -780,10 +773,9 @@ func (c *Client) SendManyMinConfAsync(fromAccount string,
// WalletPassphrase function for more details.
func (c *Client) SendManyMinConf(fromAccount string,
amounts map[btcutil.Address]btcutil.Amount,
minConfirms int, addrType *string) (*chainhash.Hash, error) {
minConfirms int) (*chainhash.Hash, error) {
return c.SendManyMinConfAsync(fromAccount, amounts, minConfirms,
addrType).Receive()
return c.SendManyMinConfAsync(fromAccount, amounts, minConfirms).Receive()
}
// SendManyCommentAsync returns an instance of a type that can be used to get
@ -793,14 +785,14 @@ func (c *Client) SendManyMinConf(fromAccount string,
// See SendManyComment for the blocking version and more details.
func (c *Client) SendManyCommentAsync(fromAccount string,
amounts map[btcutil.Address]btcutil.Amount, minConfirms int,
addrType *string, comment string) FutureSendManyResult {
comment string) FutureSendManyResult {
convertedAmounts := make(map[string]float64, len(amounts))
for addr, amount := range amounts {
convertedAmounts[addr.EncodeAddress()] = amount.ToBTC()
}
cmd := btcjson.NewSendManyCmd(fromAccount, convertedAmounts,
&minConfirms, &comment, addrType)
&minConfirms, &comment)
return c.SendCmd(cmd)
}
@ -816,10 +808,10 @@ func (c *Client) SendManyCommentAsync(fromAccount string,
// WalletPassphrase function for more details.
func (c *Client) SendManyComment(fromAccount string,
amounts map[btcutil.Address]btcutil.Amount, minConfirms int,
addrType *string, comment string) (*chainhash.Hash, error) {
comment string) (*chainhash.Hash, error) {
return c.SendManyCommentAsync(fromAccount, amounts, minConfirms,
addrType, comment).Receive()
comment).Receive()
}
// *************************
@ -1143,8 +1135,8 @@ func (r FutureGetRawChangeAddressResult) Receive() (btcutil.Address, error) {
// function on the returned instance.
//
// See GetRawChangeAddress for the blocking version and more details.
func (c *Client) GetRawChangeAddressAsync(account *string) FutureGetRawChangeAddressResult {
cmd := btcjson.NewGetRawChangeAddressCmd(account)
func (c *Client) GetRawChangeAddressAsync(account string) FutureGetRawChangeAddressResult {
cmd := btcjson.NewGetRawChangeAddressCmd(&account)
result := FutureGetRawChangeAddressResult{
network: c.chainParams,
responseChannel: c.SendCmd(cmd),
@ -1155,7 +1147,7 @@ func (c *Client) GetRawChangeAddressAsync(account *string) FutureGetRawChangeAdd
// GetRawChangeAddress returns a new address for receiving change that will be
// associated with the provided account. Note that this is only for raw
// transactions and NOT for normal use.
func (c *Client) GetRawChangeAddress(account *string) (btcutil.Address, error) {
func (c *Client) GetRawChangeAddress(account string) (btcutil.Address, error) {
return c.GetRawChangeAddressAsync(account).Receive()
}
@ -1234,7 +1226,7 @@ func (r FutureGetAccountAddressResult) Receive() (btcutil.Address, error) {
// the returned instance.
//
// See GetAccountAddress for the blocking version and more details.
func (c *Client) GetAccountAddressAsync(account *string) FutureGetAccountAddressResult {
func (c *Client) GetAccountAddressAsync(account string) FutureGetAccountAddressResult {
cmd := btcjson.NewGetAccountAddressCmd(account)
result := FutureGetAccountAddressResult{
network: c.chainParams,
@ -1245,7 +1237,7 @@ func (c *Client) GetAccountAddressAsync(account *string) FutureGetAccountAddress
// GetAccountAddress returns the current Bitcoin address for receiving payments
// to the specified account.
func (c *Client) GetAccountAddress(account *string) (btcutil.Address, error) {
func (c *Client) GetAccountAddress(account string) (btcutil.Address, error) {
return c.GetAccountAddressAsync(account).Receive()
}
@ -1325,7 +1317,7 @@ func (r FutureGetAddressesByAccountResult) Receive() ([]btcutil.Address, error)
// function on the returned instance.
//
// See GetAddressesByAccount for the blocking version and more details.
func (c *Client) GetAddressesByAccountAsync(account *string) FutureGetAddressesByAccountResult {
func (c *Client) GetAddressesByAccountAsync(account string) FutureGetAddressesByAccountResult {
cmd := btcjson.NewGetAddressesByAccountCmd(account)
result := FutureGetAddressesByAccountResult{
network: c.chainParams,
@ -1336,7 +1328,7 @@ func (c *Client) GetAddressesByAccountAsync(account *string) FutureGetAddressesB
// GetAddressesByAccount returns the list of addresses associated with the
// passed account.
func (c *Client) GetAddressesByAccount(account *string) ([]btcutil.Address, error) {
func (c *Client) GetAddressesByAccount(account string) ([]btcutil.Address, error) {
return c.GetAddressesByAccountAsync(account).Receive()
}
@ -1717,7 +1709,7 @@ func (r FutureGetReceivedByAccountResult) Receive() (btcutil.Amount, error) {
// function on the returned instance.
//
// See GetReceivedByAccount for the blocking version and more details.
func (c *Client) GetReceivedByAccountAsync(account *string) FutureGetReceivedByAccountResult {
func (c *Client) GetReceivedByAccountAsync(account string) FutureGetReceivedByAccountResult {
cmd := btcjson.NewGetReceivedByAccountCmd(account, nil)
return c.SendCmd(cmd)
}
@ -1727,7 +1719,7 @@ func (c *Client) GetReceivedByAccountAsync(account *string) FutureGetReceivedByA
//
// See GetReceivedByAccountMinConf to override the minimum number of
// confirmations.
func (c *Client) GetReceivedByAccount(account *string) (btcutil.Amount, error) {
func (c *Client) GetReceivedByAccount(account string) (btcutil.Amount, error) {
return c.GetReceivedByAccountAsync(account).Receive()
}
@ -1736,8 +1728,8 @@ func (c *Client) GetReceivedByAccount(account *string) (btcutil.Amount, error) {
// function on the returned instance.
//
// See GetReceivedByAccountMinConf for the blocking version and more details.
func (c *Client) GetReceivedByAccountMinConfAsync(account *string, minConfirms *int) FutureGetReceivedByAccountResult {
cmd := btcjson.NewGetReceivedByAccountCmd(account, minConfirms)
func (c *Client) GetReceivedByAccountMinConfAsync(account string, minConfirms int) FutureGetReceivedByAccountResult {
cmd := btcjson.NewGetReceivedByAccountCmd(account, &minConfirms)
return c.SendCmd(cmd)
}
@ -1746,7 +1738,7 @@ func (c *Client) GetReceivedByAccountMinConfAsync(account *string, minConfirms *
// confirmations.
//
// See GetReceivedByAccount to use the default minimum number of confirmations.
func (c *Client) GetReceivedByAccountMinConf(account *string, minConfirms *int) (btcutil.Amount, error) {
func (c *Client) GetReceivedByAccountMinConf(account string, minConfirms int) (btcutil.Amount, error) {
return c.GetReceivedByAccountMinConfAsync(account, minConfirms).Receive()
}
@ -2062,14 +2054,14 @@ func (r FutureRescanBlockchainResult) Receive() (*btcjson.RescanBlockchainResult
// returned instance.
//
// See RescanBlockchain for the blocking version and more details.
func (c *Client) RescanBlockchainAsync(startHeight *int32, stopHeight *int32) FutureRescanBlockchainResult {
func (c *Client) RescanBlockchainAsync(startHeight *int64, stopHeight *int64) FutureRescanBlockchainResult {
cmd := btcjson.NewRescanBlockchainCmd(startHeight, stopHeight)
return c.SendCmd(cmd)
}
// RescanBlockchain rescans the local blockchain for wallet related
// transactions from the startHeight to the the inclusive stopHeight.
func (c *Client) RescanBlockchain(startHeight *int32, stopHeight *int32) (*btcjson.RescanBlockchainResult, error) {
func (c *Client) RescanBlockchain(startHeight *int64, stopHeight *int64) (*btcjson.RescanBlockchainResult, error) {
return c.RescanBlockchainAsync(startHeight, stopHeight).Receive()
}

View file

@ -2368,6 +2368,7 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld
if useCoinbaseValue {
reply.CoinbaseAux = gbtCoinbaseAux
reply.CoinbaseValue = &msgBlock.Transactions[0].TxOut[0].Value
} else {
// Ensure the template has a valid payment address associated
// with it when a full coinbase is requested.
@ -2400,9 +2401,6 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld
reply.CoinbaseTxn = &resultTx
}
// Return coinbasevalue anyway as lbrycrd and bitcoind do.
reply.CoinbaseValue = &msgBlock.Transactions[0].TxOut[0].Value
return &reply, nil
}

View file

@ -206,7 +206,7 @@ func StripClaimScriptPrefix(script []byte) []byte {
return script[cs.Size:]
}
const illegalChars = "=&#:$%?/;\\\b\n\t\r\x00"
const illegalChars = "=&#:*$%?/;\\\b\n\t\r\x00"
func AllClaimsAreSane(script []byte, enforceSoftFork bool) error {
cs, err := ExtractClaimScript(script)