Skip to content
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
22 changes: 11 additions & 11 deletions docs/ledger-simulator.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ It uses the `@zondax/zemu` js library to:

- Download the docker image for the simulator (if needed)
- Set the ledger seed to the default or the user-given one
- Execute the docker container for the simulator by passing to it the avalanche app binary `app_s.elf` (ledger nano s device). That starts the simulated avalanche app.
- Execute the docker container for the simulator by passing to it the avalanche app binary `app_s2.elf` (ledger nano s+ device). That starts the simulated avalanche app.
- Create a rpc entry point to the simulated avalanche app so as the golang client ledger library can connect to the simulator (instead of a real device)
- Previous steps can take some time. Once the app and rpc entry is ready, it prints a custom msg `SIMULATED LEDGER DEV READY` as a means to communicate
with the test code (or the user) that the simulator can start receiving requests (eg connect to it, ask for addresses, etc).
Expand Down Expand Up @@ -73,19 +73,19 @@ the simulator, if not, the test is expected to operate agains a real device.

## Ledger device status for avalanche-cli tests interaction

Latest avalanche ledger app downloadable version `v0.7.2` (and also latest ledger live official version `v0.7.0`) can not interact with tests
as it does not support avalanche-cli local network id 1337.
The tests use the Avalanche Ledger app version `v1.3.7`, available as `app_s2.elf` binary (Nano S+ device).

For that, currently the tests operate against a modified version of `v0.7.2`, available as `app_s.elf` binary.
This binary must be built from source from the [ledger-avalanche](https://github.com/ava-labs/ledger-avalanche) repository:

For a real ledger device to be used with the tests, it should be loaded with a supporting version, currently available on dev branch of ledger-avalanche.

It is expected for next downloadable version to:

- support network id 1337
- provide elf binary downloads
```bash
cd /path/to/ledger-avalanche
git checkout v1.3.7
git submodule update --init --recursive
make
cp app/output/app_s2.elf /path/to/avalanche-cli/tests/e2e/ledgerSim/app_s2.elf
```

With that elements provided, CLI e2e could start downloading latest ledger app and using it on CI.
For a real ledger device to be used with the tests, it should be loaded with v1.3.7 or a compatible version.

## How to execute the test script

Expand Down
36 changes: 24 additions & 12 deletions pkg/keychain/keychain.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,19 +243,25 @@ func getLedgerIndices(ledgerDevice ledger.Ledger, addressesStr []string) ([]uint
}
// maps the indices of addresses to their corresponding ledger indices
indexMap := map[int]uint32{}
// Build list of indices to query
indicesToQuery := make([]uint32, numLedgerIndicesToSearch)
for i := uint32(0); i < numLedgerIndicesToSearch; i++ {
indicesToQuery[i] = i
}
// Get all public keys at once using PubKeys (which caches GetExtPubKey)
pubKeys, err := ledgerDevice.PubKeys(indicesToQuery)
if err != nil {
return []uint32{}, err
}
// for all ledger indices to search for, find if the ledger address belongs to the input
// addresses and, if so, add the index pair to indexMap, breaking the loop if
// all addresses were found
for ledgerIndex := uint32(0); ledgerIndex < numLedgerIndicesToSearch; ledgerIndex++ {
pubKey, err := ledgerDevice.PubKey(ledgerIndex)
if err != nil {
return []uint32{}, err
}
for ledgerIndex, pubKey := range pubKeys {
ledgerAddress := pubKey.Address()
for addressesIndex, addr := range addresses {
if addr == ledgerAddress {
ux.Logger.PrintToUser(" Found index %d for address %s", ledgerIndex, addressesStr[addressesIndex])
indexMap[addressesIndex] = ledgerIndex
indexMap[addressesIndex] = uint32(ledgerIndex)
}
}
if len(indexMap) == len(addresses) {
Expand All @@ -278,13 +284,19 @@ func getLedgerIndices(ledgerDevice ledger.Ledger, addressesStr []string) ([]uint
func searchForFundedLedgerIndices(network models.Network, ledgerDevice ledger.Ledger, amount uint64) ([]uint32, error) {
ux.Logger.PrintToUser("Looking for ledger indices to pay for %.9f AVAX...", float64(amount)/float64(units.Avax))
pClient := platformvm.NewClient(network.Endpoint)
// Build list of indices to query
indicesToQuery := make([]uint32, numLedgerIndicesToSearchForBalance)
for i := uint32(0); i < numLedgerIndicesToSearchForBalance; i++ {
indicesToQuery[i] = i
}
// Get all public keys at once using PubKeys (which caches GetExtPubKey)
pubKeys, err := ledgerDevice.PubKeys(indicesToQuery)
if err != nil {
return []uint32{}, err
}
totalBalance := uint64(0)
ledgerIndices := []uint32{}
for ledgerIndex := uint32(0); ledgerIndex < numLedgerIndicesToSearchForBalance; ledgerIndex++ {
pubKey, err := ledgerDevice.PubKey(ledgerIndex)
if err != nil {
return []uint32{}, err
}
for ledgerIndex, pubKey := range pubKeys {
ledgerAddress := pubKey.Address()
ctx, cancel := utils.GetAPIContext()
resp, err := pClient.GetBalance(ctx, []ids.ShortID{ledgerAddress})
Expand All @@ -295,7 +307,7 @@ func searchForFundedLedgerIndices(network models.Network, ledgerDevice ledger.Le
if resp.Balance > 0 {
ux.Logger.PrintToUser(" Found index %d with %.9f AVAX", ledgerIndex, float64(resp.Balance)/float64(units.Avax))
totalBalance += uint64(resp.Balance)
ledgerIndices = append(ledgerIndices, ledgerIndex)
ledgerIndices = append(ledgerIndices, uint32(ledgerIndex))
}
if totalBalance >= amount {
break
Expand Down
Binary file removed tests/e2e/ledgerSim/app_s.elf
Binary file not shown.
Binary file added tests/e2e/ledgerSim/app_s2.elf
Binary file not shown.
7 changes: 4 additions & 3 deletions tests/e2e/ledgerSim/launchAndApproveTxs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const rl = createInterface({

const Resolve = require('path').resolve

const appPath = Resolve('app_s.elf')
const appPath = Resolve('app_s2.elf')
const waitTimeout = 60000;
const waitUntilClose = 1000;
const grpcPort = 3002;
Expand All @@ -29,16 +29,17 @@ const options = {
...DEFAULT_START_OPTIONS,
custom: `-s "${appSeed}"`,
startDelay: 300000,
model: "nanosp",
}

async function main() {
const sim = new Zemu(appPath, {}, "127.0.0.1", transportPort, speculosApiPort);
const sim = new Zemu(appPath);

await Zemu.checkAndPullImage();
await Zemu.stopAllEmuContainers();

await sim.start(options)

sim.startGRPCServer("localhost", grpcPort);

await sim.waitForText("Avalanche", waitTimeout, true);
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/ledgerSim/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"dependencies": {
"@zondax/zemu": "0.36.0"
"@zondax/zemu": "0.55.3"
}
}
Loading
Loading