Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rpc: Add default config options to settings. #1981

Merged
merged 1 commit into from
Dec 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions client/asset/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,3 +271,32 @@ nextasset:
delete(tokens, assetID)
}
}

// WalletDef gets the registered WalletDefinition for the asset and
// wallet type.
func WalletDef(assetID uint32, walletType string) (*WalletDefinition, error) {
token := TokenInfo(assetID)
if token != nil {
return token.Definition, nil
}
winfo, err := Info(assetID)
if err != nil {
return nil, fmt.Errorf("Info error: %w", err)
}
if walletType == "" {
if len(winfo.AvailableWallets) <= winfo.LegacyWalletIndex {
return nil, fmt.Errorf("legacy wallet index out of range")
}
return winfo.AvailableWallets[winfo.LegacyWalletIndex], nil
}
var wd *WalletDefinition
for _, def := range winfo.AvailableWallets {
if def.Type == walletType {
wd = def
}
}
if wd == nil {
return nil, fmt.Errorf("could not find wallet definition for asset %s, type %q", dex.BipIDSymbol(assetID), walletType)
}
return wd, nil
}
21 changes: 19 additions & 2 deletions client/cmd/dexcctl/simnet-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ BCH_ON=$?
~/dextest/eth/harness-ctl/alpha attach --exec 'eth.blockNumber' > /dev/null
ETH_ON=$?

~/dextest/doge/harness-ctl/alpha getblockchaininfo > /dev/null
DOGE_ON=$?

~/dextest/zec/harness-ctl/alpha getblockchaininfo > /dev/null
ZEC_ON=$?

set -e

echo initializing
Expand All @@ -41,8 +47,19 @@ if [ $BCH_ON -eq 0 ]; then
fi

if [ $ETH_ON -eq 0 ]; then
echo configuring Eth wallet
./dexcctl -p abc -p "" --simnet newwallet 60 geth
echo configuring Eth and dextt.eth wallets
./dexcctl -p abc -p "" --simnet newwallet 60 rpc "" "{\"providers\":\"${HOME}/dextest/eth/alpha/node/geth.ipc\"}"
./dexcctl -p abc -p "" --simnet newwallet 60000 rpc
fi

if [ $DOGE_ON -eq 0 ]; then
echo configuring doge wallet
./dexcctl -p abc -p "" --simnet newwallet 3 dogecoindRPC ~/dextest/doge/alpha/alpha.conf
fi

if [ $ZEC_ON -eq 0 ]; then
echo configuring zcash wallet
./dexcctl -p abc -p "" --simnet newwallet 133 zcashdRPC ~/dextest/zec/alpha/alpha.conf
fi

echo checking if we have an account already
Expand Down
53 changes: 12 additions & 41 deletions client/core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -2376,9 +2376,9 @@ func (c *Core) createWalletOrToken(crypter encrypt.Crypter, walletPW []byte, for
}

func (c *Core) createWallet(crypter encrypt.Crypter, walletPW []byte, assetID uint32, form *WalletForm) (*db.Wallet, error) {
walletDef, err := walletDefinition(assetID, form.Type)
walletDef, err := asset.WalletDef(assetID, form.Type)
if err != nil {
return nil, err
return nil, newError(assetSupportErr, "asset.WalletDef error: %w", err)
}

// Sometimes core will insert data into the Settings map to communicate
Expand Down Expand Up @@ -2798,9 +2798,9 @@ func (c *Core) RecoverWallet(assetID uint32, appPW []byte, force bool) error {
if !isRecoverer {
return errors.New("wallet is not a recoverer")
}
walletDef, err := walletDefinition(assetID, oldWallet.walletType)
walletDef, err := asset.WalletDef(assetID, oldWallet.walletType)
if err != nil {
return err
return newError(assetSupportErr, "asset.WalletDef error: %w", err)
}
// Unseeded wallets shouldn't implement the Recoverer interface. This
// is just an additional check for safety.
Expand Down Expand Up @@ -3016,9 +3016,9 @@ func (c *Core) ReconfigureWallet(appPW, newWalletPW []byte, form *WalletForm) er

assetID := form.AssetID

walletDef, err := walletDefinition(assetID, form.Type)
walletDef, err := asset.WalletDef(assetID, form.Type)
if err != nil {
return err
return newError(assetSupportErr, "asset.WalletDef error: %w", err)
}
if walletDef.Seeded && newWalletPW != nil {
return newError(passwordErr, "cannot set a password on a built-in(seeded) wallet")
Expand All @@ -3034,9 +3034,9 @@ func (c *Core) ReconfigureWallet(appPW, newWalletPW []byte, form *WalletForm) er
return fmt.Errorf(walletDisabledErrStr, strings.ToUpper(unbip(assetID)))
}

oldDef, err := walletDefinition(assetID, oldWallet.walletType)
oldDef, err := asset.WalletDef(assetID, oldWallet.walletType)
if err != nil {
return fmt.Errorf("failed to locate old wallet definition: %v", err)
return newError(assetSupportErr, "old wallet asset.WalletDef error: %w", err)
}
oldDepositAddr := oldWallet.currentDepositAddress()

Expand Down Expand Up @@ -3338,9 +3338,9 @@ func (c *Core) SetWalletPassword(appPW []byte, assetID uint32, newPW []byte) err

// setWalletPassword updates the (encrypted) password for the wallet.
func (c *Core) setWalletPassword(wallet *xcWallet, newPW []byte, crypter encrypt.Crypter) error {
walletDef, err := walletDefinition(wallet.AssetID, wallet.walletType)
walletDef, err := asset.WalletDef(wallet.AssetID, wallet.walletType)
if err != nil {
return err
return newError(assetSupportErr, "asset.WalletDef error: %w", err)
}
if walletDef.Seeded || asset.TokenInfo(wallet.AssetID) != nil {
return newError(passwordErr, "cannot set a password on a seeded or token wallet")
Expand Down Expand Up @@ -3436,9 +3436,9 @@ func (c *Core) NewDepositAddress(assetID uint32) (string, error) {
// asset.WalletInfo.DefaultConfigPath. If settings are not found, an empty map
// is returned.
func (c *Core) AutoWalletConfig(assetID uint32, walletType string) (map[string]string, error) {
walletDef, err := walletDefinition(assetID, walletType)
walletDef, err := asset.WalletDef(assetID, walletType)
if err != nil {
return nil, err
return nil, newError(assetSupportErr, "asset.WalletDef error: %w", err)
}

if walletDef.DefaultConfigPath == "" {
Expand Down Expand Up @@ -8682,35 +8682,6 @@ func parseCert(host string, certI interface{}, net dex.Network) ([]byte, error)
return nil, fmt.Errorf("not a valid certificate type %T", certI)
}

// walletDefinition gets the registered WalletDefinition for the asset and
// wallet type.
func walletDefinition(assetID uint32, walletType string) (*asset.WalletDefinition, error) {
token := asset.TokenInfo(assetID)
if token != nil {
return token.Definition, nil
}
winfo, err := asset.Info(assetID)
if err != nil {
return nil, newError(assetSupportErr, "asset.Info error: %w", err)
}
if walletType == "" {
if len(winfo.AvailableWallets) <= winfo.LegacyWalletIndex {
return nil, fmt.Errorf("legacy wallet index out of range")
}
return winfo.AvailableWallets[winfo.LegacyWalletIndex], nil
}
var walletDef *asset.WalletDefinition
for _, def := range winfo.AvailableWallets {
if def.Type == walletType {
walletDef = def
}
}
if walletDef == nil {
return nil, fmt.Errorf("could not find wallet definition for asset %s, type %q", unbip(assetID), walletType)
}
return walletDef, nil
}

// WalletLogFilePath returns the path to the wallet's log file.
func (c *Core) WalletLogFilePath(assetID uint32) (string, error) {
wallet, exists := c.wallet(assetID)
Expand Down
17 changes: 17 additions & 0 deletions client/rpcserver/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"strings"
"time"

"decred.org/dcrdex/client/asset"
"decred.org/dcrdex/client/core"
"decred.org/dcrdex/dex"
"decred.org/dcrdex/dex/encode"
Expand Down Expand Up @@ -192,6 +193,22 @@ func handleNewWallet(s *RPCServer, params *RawParams) *msgjson.ResponsePayload {
resErr := msgjson.NewError(msgjson.RPCWalletExistsError, errMsg)
return createResponse(newWalletRoute, nil, resErr)
}

walletDef, err := asset.WalletDef(form.assetID, form.walletType)
if err != nil {
errMsg := fmt.Sprintf("error creating %s wallet: unable to get wallet definition: %v",
dex.BipIDSymbol(form.assetID), err)
resErr := msgjson.NewError(msgjson.RPCWalletDefinitionError, errMsg)
return createResponse(newWalletRoute, nil, resErr)
}

// Apply default config options if they exist.
for _, opt := range walletDef.ConfigOpts {
if _, has := form.config[opt.Key]; !has && opt.DefaultValue != nil {
form.config[opt.Key] = fmt.Sprintf("%v", opt.DefaultValue)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fmt.Sprintf("%v", ...) should do the trick for all the types we give in DefaultValue, but in our other uses of this field (WalletConfigForm.map) we consider the other flags like isdateand repeatable. I don't feel like we need to replicate all that at this time though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To clarify, nothing to change unless another reviewer sees an issue related to this.

}
}

// Wallet does not exist yet. Try to create it.
err = s.core.CreateWallet(form.appPass, form.walletPass, &core.WalletForm{
Type: form.walletType,
Expand Down
64 changes: 63 additions & 1 deletion client/rpcserver/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ import (
"github.com/davecgh/go-spew/spew"
)

func init() {
asset.Register(tUTXOAssetA.ID, &tDriver{
decodedCoinID: tUTXOAssetA.Symbol,
winfo: tWalletInfo,
})
}

func verifyResponse(payload *msgjson.ResponsePayload, res interface{}, wantErrCode int) error {
if wantErrCode != -1 {
if payload.Error == nil {
Expand All @@ -40,7 +47,49 @@ func verifyResponse(payload *msgjson.ResponsePayload, res interface{}, wantErrCo
return nil
}

var wsServer = websocket.New(&TCore{}, dex.StdOutLogger("TEST", dex.LevelTrace))
var (
wsServer = websocket.New(&TCore{}, dex.StdOutLogger("TEST", dex.LevelTrace))
tUTXOAssetA = &dex.Asset{
ID: 42,
Symbol: "dcr",
Version: 0, // match the stubbed (*TXCWallet).Info result
SwapSize: 251,
SwapSizeBase: 85,
RedeemSize: 200,
MaxFeeRate: 10,
SwapConf: 1,
}
tWalletInfo = &asset.WalletInfo{
Version: 0,
SupportedVersions: []uint32{0},
UnitInfo: dex.UnitInfo{
Conventional: dex.Denomination{
ConversionFactor: 1e8,
},
},
AvailableWallets: []*asset.WalletDefinition{{
Type: "rpc",
}},
}
)

type tDriver struct {
wallet asset.Wallet
decodedCoinID string
winfo *asset.WalletInfo
}

func (drv *tDriver) Open(cfg *asset.WalletConfig, logger dex.Logger, net dex.Network) (asset.Wallet, error) {
return drv.wallet, nil
}

func (drv *tDriver) DecodeCoinID(coinID []byte) (string, error) {
return drv.decodedCoinID, nil
}

func (drv *tDriver) Info() *asset.WalletInfo {
return drv.winfo
}

type Dummy struct {
Status string
Expand Down Expand Up @@ -277,6 +326,15 @@ func TestHandleNewWallet(t *testing.T) {
`{"field": value"}`,
},
}
badWalletDefParams := &RawParams{
PWArgs: []encode.PassBytes{pw, pw},
Args: []string{
"45",
"rpc",
"username=tacotime",
`{"field":"value"}`,
},
}
tests := []struct {
name string
params *RawParams
Expand Down Expand Up @@ -307,6 +365,10 @@ func TestHandleNewWallet(t *testing.T) {
name: "bad JSON error",
params: badJSONParams,
wantErrCode: msgjson.RPCArgumentsError,
}, {
name: "bad config opts error, unknown coin",
params: badWalletDefParams,
wantErrCode: msgjson.RPCWalletDefinitionError,
}, {
name: "bad params",
params: &RawParams{},
Expand Down
1 change: 1 addition & 0 deletions dex/msgjson/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ const (
RPCWalletPeersError // 68
RPCNotificationsError // 69
RPCPostBondError // 70
RPCWalletDefinitionError // 71
)

// Routes are destinations for a "payload" of data. The type of data being
Expand Down
Loading