reach-sh / reach-lang

Reach: The Safest and Smartest DApp Programming Language
https://www.reach.sh
Apache License 2.0
583 stars 167 forks source link

Algorand sandbox update #559

Closed robdmoore closed 2 years ago

robdmoore commented 2 years ago

Hi,

Firstly, just wanted to say I'm super impressed with the sandbox container that you have published for Algorand.

I have an automated test that went from taking 37s to taking 7s after switching from Algorand sandbox with devnet configuration (which also isn't in a published docker container so painful to set up with docker compose) to the reach container.

I realise that Reach has a specific use of the sandbox for Reach purposes rather than general sandbox use, but I was wondering if the reach algorand sandbox docker container can be updated to a later version of Algorand Sandbox. The current one (3.0.1 from September) is unfortunately fairly out of date and doesn't run the latest versions of TEAL. I assume keeping it up to date is beneficial anyway to give better confidence that reach running locally has similar behaviour to reach running against the real thing.

If there is no capacity to look at that I'm happy to have a crack at it, although disclaimer I'm not a Go expert and don't have a solid handle on what to look for to check if upgrading it in fact breaks reach local development so may need a little guidance.

Side-note: I've noticed running some goal commands in that container fail, e.g.: image

I haven't investigated why yet, but thought I'd raise here in case it's useful.

If I can be cheeky for a moment, I'd also be keen to explore if there is comfort in exposing the kmd port from the reach devnet container too, it allows for programmatic interrogation of the default wallet address so it doesn't need to be hardcoded. e.g. this code as an example (using TypeScript):


export async function getSandboxDefaultAccount(client: Algodv2): Promise<Account> {
  if (!(await isSandbox(client))) {
    throw "Can't get default account from non Sandbox network"
  }

  if (await isReachSandbox(client)) {
    // https://github.com/reach-sh/reach-lang/blob/master/scripts/devnet-algo/algorand_network/FAUCET.mnemonic
    return getAccountFromMnemonic(
      'frown slush talent visual weather bounce evil teach tower view fossil trip sauce express moment sea garbage pave monkey exercise soap lawn army above dynamic'
    )
  }

  const kmd = getKmdClient()
  const wallets = await kmd.listWallets()

  // Sandbox starts with a single wallet called 'unencrypted-default-wallet', with heaps of tokens
  const defaultWalletId = wallets.wallets.filter((w: any) => w.name === 'unencrypted-default-wallet')[0].id

  const defaultWalletHandle = (await kmd.initWalletHandle(defaultWalletId, '')).wallet_handle_token
  const defaultKeyIds = (await kmd.listKeys(defaultWalletHandle)).addresses

  // When you create accounts using goal they get added to this wallet so check for an account that's actually a default account
  let i = 0
  for (i = 0; i < defaultKeyIds.length; i++) {
    const key = defaultKeyIds[i]
    const account = await client.accountInformation(key).do()
    if (account.status !== 'Offline' && account.amount > 1000_000_000) {
      break
    }
  }

  const defaultAccountKey = (await kmd.exportKey(defaultWalletHandle, '', defaultKeyIds[i])).private_key

  const defaultAccountMnemonic = algosdk.secretKeyToMnemonic(defaultAccountKey)
  return getAccountFromMnemonic(defaultAccountMnemonic)
}

export function getAccountFromMnemonic(mnemonic: string): Account {
  return algosdk.mnemonicToSecretKey(mnemonic)
}

export async function isSandbox(client: Algodv2): Promise<boolean> {
  const params = await client.getTransactionParams().do()

  return params.genesisID === 'devnet-v1' || params.genesisID === 'sandnet-v1'
}

export async function isReachSandbox(client: Algodv2): Promise<boolean> {
  const params = await client.getTransactionParams().do()

  return params.genesisHash === 'lgTq/JY/RNfiTJ6ZcZ/Er8uR775Hk76c7MvHVWjvjCA='
}
jeapostrophe commented 2 years ago

Thanks Rob.

I plan to update the version very soon. We generally do it when there's new TEAL available that we use. The version is specified in this file --- https://github.com/reach-sh/reach-lang/blob/master/scripts/devnet-algo/Dockerfile#L22 --- and provided our patches go through, we're in favor of upgrading to whatever stable versions are available.

The error you screenshot is because we don't run kmd at all. We'd start it by putting it in this file --- https://github.com/reach-sh/reach-lang/blob/master/scripts/devnet-algo/start.sh --- That's cool that we wouldn't need to hard code if we used its API, I had never looked into what kmd was.

jeapostrophe commented 2 years ago

I have an update in a PR #643 that will be merged soon.