dump.mjs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. #!/usr/bin/env zx
  2. import 'zx/globals';
  3. import {
  4. getExternalProgramAddresses,
  5. getExternalProgramOutputDir,
  6. } from '../utils.mjs';
  7. // Get input from environment variables.
  8. const rpc = process.env.RPC ?? 'https://api.mainnet-beta.solana.com';
  9. const outputDir = getExternalProgramOutputDir();
  10. await dump();
  11. /** Dump external programs binaries if needed. */
  12. async function dump() {
  13. // Ensure we have some external programs to dump.
  14. const addresses = getExternalProgramAddresses();
  15. if (addresses.length === 0) return;
  16. echo(`Dumping external accounts to '${outputDir}':`);
  17. // Create the output directory if needed.
  18. $`mkdir -p ${outputDir}`.quiet();
  19. // Copy the binaries from the chain or warn if they are different.
  20. await Promise.all(
  21. addresses.map(async (address) => {
  22. const binary = `${address}.so`;
  23. const hasBinary = await fs.exists(`${outputDir}/${binary}`);
  24. if (!hasBinary) {
  25. await copyFromChain(address, binary);
  26. echo(`Wrote account data to ${outputDir}/${binary}`);
  27. return;
  28. }
  29. await copyFromChain(address, `onchain-${binary}`);
  30. const [onChainHash, localHash] = await Promise.all([
  31. $`sha256sum -b ${outputDir}/onchain-${binary} | cut -d ' ' -f 1`.quiet(),
  32. $`sha256sum -b ${outputDir}/${binary} | cut -d ' ' -f 1`.quiet(),
  33. ]);
  34. if (onChainHash.toString() !== localHash.toString()) {
  35. echo(
  36. chalk.yellow('[ WARNING ]'),
  37. `on-chain and local binaries are different for '${binary}'`
  38. );
  39. } else {
  40. echo(
  41. chalk.green('[ SKIPPED ]'),
  42. `on-chain and local binaries are the same for '${binary}'`
  43. );
  44. }
  45. await $`rm ${outputDir}/onchain-${binary}`.quiet();
  46. })
  47. );
  48. }
  49. /** Helper function to copy external programs or accounts binaries from the chain. */
  50. async function copyFromChain(address, binary) {
  51. switch (binary.split('.').pop()) {
  52. case 'bin':
  53. return $`solana account -u ${rpc} ${address} -o ${outputDir}/${binary} >/dev/null`.quiet();
  54. case 'so':
  55. return $`solana program dump -u ${rpc} ${address} ${outputDir}/${binary} >/dev/null`.quiet();
  56. default:
  57. echo(chalk.red(`[ ERROR ] unknown account type for '${binary}'`));
  58. await $`exit 1`;
  59. }
  60. }