From fc20f757ecb0761de17c189de4380a0feea405e0 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 27 Aug 2018 18:42:03 -0400 Subject: [PATCH] Load ledger device at runtime --- crypto/ledger.go | 17 ++++++++++------- crypto/ledger_secp256k1.go | 31 ++++++++++++++++++------------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/crypto/ledger.go b/crypto/ledger.go index 9d446202f7..5489810bca 100644 --- a/crypto/ledger.go +++ b/crypto/ledger.go @@ -6,13 +6,16 @@ import ( ledger "github.com/zondax/ledger-goclient" ) -// If ledger support (build tag) has been enabled, automically attempt to load -// and set the ledger device, ledgerDevice, if it has not already been set. +// If ledger support (build tag) has been enabled, set the DiscoverLedger +// function which is responsible for loading the Ledger device at runtime or +// returning an error. func init() { - device, err := ledger.FindLedger() - if err != nil { - ledgerDeviceErr = err - } else { - ledgerDevice = device + DiscoverLedger = func() (LedgerSECP256K1, error) { + device, err := ledger.FindLedger() + if err != nil { + return nil, err + } + + return device, nil } } diff --git a/crypto/ledger_secp256k1.go b/crypto/ledger_secp256k1.go index 8cb175d4f5..5f6bcb1ad7 100644 --- a/crypto/ledger_secp256k1.go +++ b/crypto/ledger_secp256k1.go @@ -1,24 +1,26 @@ package crypto import ( - "errors" "fmt" + "github.com/pkg/errors" + secp256k1 "github.com/btcsuite/btcd/btcec" tmcrypto "github.com/tendermint/tendermint/crypto" tmsecp256k1 "github.com/tendermint/tendermint/crypto/secp256k1" ) var ( - ledgerDevice LedgerSECP256K1 - ledgerDeviceErr error - - // ErrMissingLedgerDevice is used to reflect that a ledger device load has - // not been attempted. - ErrMissingLedgerDevice = errors.New("missing ledger device") + // DiscoverLedger defines a function to be invoked at runtime for discovering + // a connected Ledger device. + DiscoverLedger DiscoverLedgerFn ) type ( + // DiscoverLedgerFn defines a Ledger discovery function that returns a + // connected device or an error upon failure. + DiscoverLedgerFn func() (LedgerSECP256K1, error) + // DerivationPath represents a Ledger derivation path. DerivationPath []uint32 @@ -47,18 +49,21 @@ type ( // CONTRACT: The ledger device, ledgerDevice, must be loaded and set prior to // any creation of a PrivKeyLedgerSecp256k1. func NewPrivKeyLedgerSecp256k1(path DerivationPath) (tmcrypto.PrivKey, error) { - if ledgerDevice == nil { - err := ErrMissingLedgerDevice - if ledgerDeviceErr != nil { - err = ledgerDeviceErr + var ledgerDevice LedgerSECP256K1 + + if DiscoverLedger != nil { + device, err := DiscoverLedger() + if err != nil { + return nil, errors.Wrap(err, "failed to create PrivKeyLedgerSecp256k1") } - return nil, fmt.Errorf("failed to create PrivKeyLedgerSecp256k1: %v", err) + ledgerDevice = device + } else { + return nil, errors.New("no ledger discovery function defined") } pkl := &PrivKeyLedgerSecp256k1{Path: path, ledger: ledgerDevice} - // cache the pubkey for later use pubKey, err := pkl.getPubKey() if err != nil { return nil, err