Bootstrap unspent outpoints for rescan requests.
This commit is contained in:
parent
bb4cba51cd
commit
dd3813d811
3 changed files with 96 additions and 24 deletions
66
cmds.go
66
cmds.go
|
@ -611,7 +611,8 @@ func (cmd *RecoverAddressesCmd) UnmarshalJSON(b []byte) error {
|
|||
type RescanCmd struct {
|
||||
id interface{}
|
||||
BeginBlock int32
|
||||
Addresses map[string]struct{}
|
||||
Addresses []string
|
||||
OutPoints []*btcwire.OutPoint
|
||||
EndBlock int64 // TODO: switch this and btcdb.AllShas to int32
|
||||
}
|
||||
|
||||
|
@ -621,8 +622,8 @@ var _ btcjson.Cmd = &RescanCmd{}
|
|||
// NewRescanCmd creates a new RescanCmd, parsing the optional
|
||||
// arguments optArgs which may either be empty or a single upper
|
||||
// block height.
|
||||
func NewRescanCmd(id interface{}, begin int32, addresses map[string]struct{},
|
||||
optArgs ...int64) (*RescanCmd, error) {
|
||||
func NewRescanCmd(id interface{}, begin int32, addresses []string,
|
||||
outpoints []*btcwire.OutPoint, optArgs ...int64) (*RescanCmd, error) {
|
||||
|
||||
// Optional parameters set to their defaults.
|
||||
end := btcdb.AllShas
|
||||
|
@ -638,6 +639,7 @@ func NewRescanCmd(id interface{}, begin int32, addresses map[string]struct{},
|
|||
id: id,
|
||||
BeginBlock: begin,
|
||||
Addresses: addresses,
|
||||
OutPoints: outpoints,
|
||||
EndBlock: end,
|
||||
}, nil
|
||||
}
|
||||
|
@ -646,7 +648,7 @@ func NewRescanCmd(id interface{}, begin int32, addresses map[string]struct{},
|
|||
// the btcjson.Cmd interface. This is used when registering the custom
|
||||
// command with the btcjson parser.
|
||||
func parseRescanCmd(r *btcjson.RawCmd) (btcjson.Cmd, error) {
|
||||
if len(r.Params) < 2 {
|
||||
if len(r.Params) < 3 {
|
||||
return nil, btcjson.ErrWrongNumberOfParams
|
||||
}
|
||||
|
||||
|
@ -654,16 +656,47 @@ func parseRescanCmd(r *btcjson.RawCmd) (btcjson.Cmd, error) {
|
|||
if !ok {
|
||||
return nil, errors.New("first parameter must be a number")
|
||||
}
|
||||
iaddrs, ok := r.Params[1].(map[string]interface{})
|
||||
|
||||
iaddrs, ok := r.Params[1].([]interface{})
|
||||
if !ok {
|
||||
return nil, errors.New("second parameter must be a JSON object")
|
||||
return nil, errors.New("second parameter must be a JSON array")
|
||||
}
|
||||
addresses := make(map[string]struct{}, len(iaddrs))
|
||||
for addr := range iaddrs {
|
||||
addresses[addr] = struct{}{}
|
||||
addresses := make([]string, 0, len(iaddrs))
|
||||
for _, addr := range iaddrs {
|
||||
addrStr, ok := addr.(string)
|
||||
if !ok {
|
||||
return nil, errors.New("address is not a string")
|
||||
}
|
||||
addresses = append(addresses, addrStr)
|
||||
}
|
||||
params := make([]int64, len(r.Params[2:]))
|
||||
for i, val := range r.Params[2:] {
|
||||
|
||||
ops, ok := r.Params[2].([]interface{})
|
||||
if !ok {
|
||||
return nil, errors.New("third parameter must be a JSON array")
|
||||
}
|
||||
outpoints := make([]*btcwire.OutPoint, 0, len(ops))
|
||||
for i := range ops {
|
||||
op, ok := ops[i].(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, errors.New("outpoint is not a JSON object")
|
||||
}
|
||||
txHashHexStr, ok := op["hash"].(string)
|
||||
if !ok {
|
||||
return nil, errors.New("outpoint hash is not a string")
|
||||
}
|
||||
txHash, err := btcwire.NewShaHashFromStr(txHashHexStr)
|
||||
if err != nil {
|
||||
return nil, errors.New("outpoint hash is not a valid hex string")
|
||||
}
|
||||
index, ok := op["index"].(float64)
|
||||
if !ok {
|
||||
return nil, errors.New("outpoint index is not a number")
|
||||
}
|
||||
outpoints = append(outpoints, btcwire.NewOutPoint(txHash, uint32(index)))
|
||||
}
|
||||
|
||||
params := make([]int64, len(r.Params[3:]))
|
||||
for i, val := range r.Params[3:] {
|
||||
fval, ok := val.(float64)
|
||||
if !ok {
|
||||
return nil, errors.New("optional parameters must " +
|
||||
|
@ -672,7 +705,7 @@ func parseRescanCmd(r *btcjson.RawCmd) (btcjson.Cmd, error) {
|
|||
params[i] = int64(fval)
|
||||
}
|
||||
|
||||
return NewRescanCmd(r.Id, int32(begin), addresses, params...)
|
||||
return NewRescanCmd(r.Id, int32(begin), addresses, outpoints, params...)
|
||||
}
|
||||
|
||||
// Id satisifies the Cmd interface by returning the ID of the command.
|
||||
|
@ -692,6 +725,14 @@ func (cmd *RescanCmd) Method() string {
|
|||
|
||||
// MarshalJSON returns the JSON encoding of cmd. Part of the Cmd interface.
|
||||
func (cmd *RescanCmd) MarshalJSON() ([]byte, error) {
|
||||
ops := make([]interface{}, 0, len(cmd.OutPoints))
|
||||
for _, op := range cmd.OutPoints {
|
||||
ops = append(ops, map[string]interface{}{
|
||||
"hash": op.Hash.String(),
|
||||
"index": float64(op.Index),
|
||||
})
|
||||
}
|
||||
|
||||
// Fill a RawCmd and marshal.
|
||||
raw := btcjson.RawCmd{
|
||||
Jsonrpc: "1.0",
|
||||
|
@ -700,6 +741,7 @@ func (cmd *RescanCmd) MarshalJSON() ([]byte, error) {
|
|||
Params: []interface{}{
|
||||
cmd.BeginBlock,
|
||||
cmd.Addresses,
|
||||
ops,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
48
cmds_test.go
48
cmds_test.go
|
@ -211,19 +211,34 @@ var cmdtests = []struct {
|
|||
{
|
||||
name: "rescan no optargs",
|
||||
f: func() (btcjson.Cmd, error) {
|
||||
addrs := map[string]struct{}{
|
||||
"17XhEvq9Nahdj7Xe1nv6oRe1tEmaHUuynH": {},
|
||||
addrs := []string{"17XhEvq9Nahdj7Xe1nv6oRe1tEmaHUuynH"}
|
||||
ops := []*btcwire.OutPoint{
|
||||
&btcwire.OutPoint{
|
||||
Hash: [...]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
30, 31},
|
||||
Index: 1,
|
||||
},
|
||||
}
|
||||
return NewRescanCmd(
|
||||
float64(1),
|
||||
270000,
|
||||
addrs)
|
||||
addrs,
|
||||
ops)
|
||||
},
|
||||
result: &RescanCmd{
|
||||
id: float64(1),
|
||||
BeginBlock: 270000,
|
||||
Addresses: map[string]struct{}{
|
||||
"17XhEvq9Nahdj7Xe1nv6oRe1tEmaHUuynH": {},
|
||||
Addresses: []string{"17XhEvq9Nahdj7Xe1nv6oRe1tEmaHUuynH"},
|
||||
OutPoints: []*btcwire.OutPoint{
|
||||
&btcwire.OutPoint{
|
||||
Hash: [...]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
30, 31},
|
||||
Index: 1,
|
||||
},
|
||||
},
|
||||
EndBlock: btcdb.AllShas,
|
||||
},
|
||||
|
@ -231,20 +246,35 @@ var cmdtests = []struct {
|
|||
{
|
||||
name: "rescan one optarg",
|
||||
f: func() (btcjson.Cmd, error) {
|
||||
addrs := map[string]struct{}{
|
||||
"17XhEvq9Nahdj7Xe1nv6oRe1tEmaHUuynH": {},
|
||||
addrs := []string{"17XhEvq9Nahdj7Xe1nv6oRe1tEmaHUuynH"}
|
||||
ops := []*btcwire.OutPoint{
|
||||
&btcwire.OutPoint{
|
||||
Hash: [...]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
30, 31},
|
||||
Index: 1,
|
||||
},
|
||||
}
|
||||
return NewRescanCmd(
|
||||
float64(1),
|
||||
270000,
|
||||
addrs,
|
||||
ops,
|
||||
280000)
|
||||
},
|
||||
result: &RescanCmd{
|
||||
id: float64(1),
|
||||
BeginBlock: 270000,
|
||||
Addresses: map[string]struct{}{
|
||||
"17XhEvq9Nahdj7Xe1nv6oRe1tEmaHUuynH": {},
|
||||
Addresses: []string{"17XhEvq9Nahdj7Xe1nv6oRe1tEmaHUuynH"},
|
||||
OutPoints: []*btcwire.OutPoint{
|
||||
&btcwire.OutPoint{
|
||||
Hash: [...]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
30, 31},
|
||||
Index: 1,
|
||||
},
|
||||
},
|
||||
EndBlock: 280000,
|
||||
},
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
|
||||
github.com/conformal/btcws/cmds.go init 100.00% (16/16)
|
||||
github.com/conformal/btcws/notifications.go init 100.00% (10/10)
|
||||
github.com/conformal/btcws/cmds.go RescanCmd.MarshalJSON 100.00% (7/7)
|
||||
github.com/conformal/btcws/notifications.go RedeemingTxNtfn.MarshalJSON 100.00% (6/6)
|
||||
github.com/conformal/btcws/notifications.go RecvTxNtfn.MarshalJSON 100.00% (6/6)
|
||||
github.com/conformal/btcws/cmds.go ListAddressTransactionsCmd.MarshalJSON 100.00% (4/4)
|
||||
github.com/conformal/btcws/cmds.go ListAllTransactionsCmd.MarshalJSON 100.00% (4/4)
|
||||
github.com/conformal/btcws/cmds.go RescanCmd.MarshalJSON 100.00% (4/4)
|
||||
github.com/conformal/btcws/cmds.go WalletIsLockedCmd.MarshalJSON 100.00% (4/4)
|
||||
github.com/conformal/btcws/cmds.go GetUnconfirmedBalanceCmd.MarshalJSON 100.00% (4/4)
|
||||
github.com/conformal/btcws/cmds.go GetAddressBalanceCmd.MarshalJSON 100.00% (4/4)
|
||||
|
@ -92,11 +92,11 @@ github.com/conformal/btcws/cmds.go NewRescanCmd 83.33% (5/6)
|
|||
github.com/conformal/btcws/cmds.go NewWalletIsLockedCmd 83.33% (5/6)
|
||||
github.com/conformal/btcws/cmds.go NewListAllTransactionsCmd 83.33% (5/6)
|
||||
github.com/conformal/btcws/cmds.go NewGetAddressBalanceCmd 83.33% (5/6)
|
||||
github.com/conformal/btcws/cmds.go parseRescanCmd 77.78% (14/18)
|
||||
github.com/conformal/btcws/cmds.go parseListAddressTransactionsCmd 76.47% (13/17)
|
||||
github.com/conformal/btcws/cmds.go parseNotifyNewTXsCmd 75.00% (9/12)
|
||||
github.com/conformal/btcws/cmds.go parseGetUnconfirmedBalanceCmd 75.00% (6/8)
|
||||
github.com/conformal/btcws/cmds.go parseWalletIsLockedCmd 75.00% (6/8)
|
||||
github.com/conformal/btcws/cmds.go parseRescanCmd 74.36% (29/39)
|
||||
github.com/conformal/btcws/cmds.go NotifyNewTXsCmd.UnmarshalJSON 72.73% (8/11)
|
||||
github.com/conformal/btcws/notifications.go RedeemingTxNtfn.UnmarshalJSON 72.73% (8/11)
|
||||
github.com/conformal/btcws/cmds.go CreateEncryptedWalletCmd.UnmarshalJSON 72.73% (8/11)
|
||||
|
@ -183,5 +183,5 @@ github.com/conformal/btcws/notifications.go AllVerboseTxNtfn.SetId 0.00% (0
|
|||
github.com/conformal/btcws/notifications.go TxNtfn.SetId 0.00% (0/0)
|
||||
github.com/conformal/btcws/notifications.go RedeemingTxNtfn.SetId 0.00% (0/0)
|
||||
github.com/conformal/btcws/notifications.go AllTxNtfn.SetId 0.00% (0/0)
|
||||
github.com/conformal/btcws ---------------------------------------- 66.67% (534/801)
|
||||
github.com/conformal/btcws ---------------------------------------- 66.91% (552/825)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue