Bootstrap unspent outpoints for rescan requests.

This commit is contained in:
Josh Rickmar 2014-03-21 14:08:54 -05:00
parent bb4cba51cd
commit dd3813d811
3 changed files with 96 additions and 24 deletions

66
cmds.go
View file

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

View file

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

View file

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