Skip to content

Commit

Permalink
client/eth: implement Exists
Browse files Browse the repository at this point in the history
Exists works by trying to load the keystore and checking for > 1
wallets. Remove unused "appdir" setting from custom config. Just use
CreateWalletParams.DataDir.
  • Loading branch information
buck54321 authored and chappjc committed Dec 9, 2021
1 parent 6c947e0 commit 90716b9
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 11 deletions.
1 change: 0 additions & 1 deletion client/asset/eth/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (

// Config holds the parameters needed to initialize an ETH wallet.
type Config struct {
AppDir string `ini:"appdir"`
NodeListenAddr string `ini:"nodelistenaddr"`
GasFee float64 `ini:"gasfee"`
}
Expand Down
21 changes: 13 additions & 8 deletions client/asset/eth/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/decred/dcrd/hdkeychain/v3"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
Expand All @@ -44,6 +45,8 @@ const (
defaultGasFee = 82 // gwei
defaultGasFeeLimit = 200 // gwei
defaultSendGasLimit = 21_000

walletTypeGeth = "geth"
)

var (
Expand All @@ -61,20 +64,14 @@ var (
"wallet. Units: gwei / gas",
DefaultValue: defaultGasFeeLimit,
},
{
Key: "appdir",
DisplayName: "DCR Dex Ethereum directory location.",
Description: "Location of the ethereum client data. This SHOULD NOT be a directory used by other ethereum applications. The default is recommended.",
DefaultValue: defaultAppDir,
},
}
// WalletInfo defines some general information about a Ethereum wallet.
WalletInfo = &asset.WalletInfo{
Name: "Ethereum",
UnitInfo: dexeth.UnitInfo,
AvailableWallets: []*asset.WalletDefinition{
{
Type: "geth",
Type: walletTypeGeth,
Tab: "Internal",
Description: "Use the built-in DEX wallet with snap sync",
ConfigOpts: configOpts,
Expand Down Expand Up @@ -125,7 +122,12 @@ func (d *Driver) Info() *asset.WalletInfo {

// Exists checks the existence of the wallet.
func (d *Driver) Exists(walletType, dataDir string, settings map[string]string, net dex.Network) (bool, error) {
return false, errors.New("unimplemented")
if walletType != walletTypeGeth {
return false, fmt.Errorf("wallet type %q unrecognized", walletType)
}
keyStoreDir := filepath.Join(getWalletDir(dataDir, net), "keystore")
ks := keystore.NewKeyStore(keyStoreDir, keystore.LightScryptN, keystore.LightScryptP)
return len(ks.Wallets()) > 0, nil
}

func (d *Driver) Create(params *asset.CreateWalletParams) error {
Expand Down Expand Up @@ -195,6 +197,9 @@ func (*ExchangeWallet) Info() *asset.WalletInfo {
// CreateWallet creates a new internal ETH wallet and stores the private key
// derived from the wallet seed.
func CreateWallet(createWalletParams *asset.CreateWalletParams) error {
if createWalletParams.Type != walletTypeGeth {
return fmt.Errorf("wallet type %q unrecognized", createWalletParams.Type)
}
walletDir := getWalletDir(createWalletParams.DataDir, createWalletParams.Net)
node, err := prepareNode(&nodeConfig{
net: createWalletParams.Net,
Expand Down
46 changes: 46 additions & 0 deletions client/asset/eth/eth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"fmt"
"math/big"
"math/rand"
"os"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -1742,6 +1743,51 @@ func TestSwapConfirmation(t *testing.T) {
checkResult(false, 1, true)
}

func TestDriverExists(t *testing.T) {
drv := &Driver{}
tmpDir, _ := os.MkdirTemp("", "")
defer os.RemoveAll(tmpDir)

settings := map[string]string{}

// no wallet
exists, err := drv.Exists(walletTypeGeth, tmpDir, settings, dex.Simnet)
if err != nil {
t.Fatalf("Exists error for no geth wallet: %v", err)
}
if exists {
t.Fatalf("Uninitiated wallet exists")
}

// Create the wallet.
err = CreateWallet(&asset.CreateWalletParams{
Type: walletTypeGeth,
Seed: encode.RandomBytes(32),
Pass: encode.RandomBytes(32),
Settings: settings,
DataDir: tmpDir,
Net: dex.Simnet,
Logger: tLogger,
})
if err != nil {
t.Fatalf("CreateWallet error: %v", err)
}

// exists
exists, err = drv.Exists(walletTypeGeth, tmpDir, settings, dex.Simnet)
if err != nil {
t.Fatalf("Exists error for existent geth wallet: %v", err)
}
if !exists {
t.Fatalf("Initiated wallet doesn't exist")
}

// Wrong wallet type
if _, err := drv.Exists("not-geth", tmpDir, settings, dex.Simnet); err == nil {
t.Fatalf("no error for unknown wallet type")
}
}

func TestLocktimeExpired(t *testing.T) {
var secretHash [32]byte
copy(secretHash[:], encode.RandomBytes(32))
Expand Down
7 changes: 6 additions & 1 deletion client/asset/eth/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,12 @@ func SetSimnetGenesis(sng string) {

// prepareNode sets up a geth node, but does not start it.
func prepareNode(cfg *nodeConfig) (*node.Node, error) {
stackConf := &node.Config{DataDir: cfg.appDir}
stackConf := &node.Config{
DataDir: cfg.appDir,
// KeyStoreDir is set the same as the geth default, but we rely on this
// location for Exists, so protect against future geth changes.
KeyStoreDir: filepath.Join(cfg.appDir, "keystore"),
}

stackConf.Logger = &ethLogger{dl: cfg.logger}

Expand Down
2 changes: 1 addition & 1 deletion client/asset/eth/nodeclient_harness_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,12 +217,12 @@ func TestMain(m *testing.M) {

func setupWallet(walletDir, seed, listenAddress string) error {
settings := map[string]string{
"appdir": walletDir,
"nodelistenaddr": listenAddress,
}
seedB, _ := hex.DecodeString(seed)
walletPass, _ := hex.DecodeString(pw)
createWalletParams := asset.CreateWalletParams{
Type: walletTypeGeth,
Seed: seedB,
Pass: walletPass,
Settings: settings,
Expand Down

0 comments on commit 90716b9

Please sign in to comment.