Merge PR #2167: Load Ledger Device at Runtime

This commit is contained in:
Christopher Goes 2018-08-28 14:55:25 +02:00 committed by GitHub
commit 6a7d700543
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 23 deletions

View File

@ -83,5 +83,7 @@ BUG FIXES
* SDK
* \#1988 Make us compile on OpenBSD (disable ledger) [#1988] (https://github.com/cosmos/cosmos-sdk/issues/1988)
* \#2105 Fix DB Iterator leak, which may leak a go routine.
* [ledger] \#2064 Fix inability to sign and send transactions via the LCD by
loading a Ledger device at runtime.
* Tendermint

View File

@ -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, which implies a CGO dependency,
// 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
}
}

View File

@ -1,24 +1,27 @@
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. Its allows a method to avoid CGO
// dependencies when Ledger support is potentially not enabled.
discoverLedgerFn func() (LedgerSECP256K1, error)
// DerivationPath represents a Ledger derivation path.
DerivationPath []uint32
@ -47,18 +50,17 @@ 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
}
return nil, fmt.Errorf("failed to create PrivKeyLedgerSecp256k1: %v", err)
if discoverLedger == nil {
return nil, errors.New("no Ledger discovery function defined")
}
pkl := &PrivKeyLedgerSecp256k1{Path: path, ledger: ledgerDevice}
device, err := discoverLedger()
if err != nil {
return nil, errors.Wrap(err, "failed to create PrivKeyLedgerSecp256k1")
}
pkl := &PrivKeyLedgerSecp256k1{Path: path, ledger: device}
// cache the pubkey for later use
pubKey, err := pkl.getPubKey()
if err != nil {
return nil, err