validation-utils.ts 3 KB
Newer Older
1
import { createInterface } from 'readline'
2

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
import { hexStringEquals } from '@eth-optimism/core-utils'

export const getInput = (query) => {
  const rl = createInterface({
    input: process.stdin,
    output: process.stdout,
  })

  return new Promise((resolve) =>
    rl.question(query, (ans) => {
      rl.close()
      resolve(ans)
    })
  )
}

const codes = {
  reset: '\x1b[0m',
  red: '\x1b[0;31m',
  green: '\x1b[0;32m',
  cyan: '\x1b[0;36m',
  yellow: '\x1b[1;33m',
}

27 28 29 30
export const color = Object.entries(codes).reduce((obj, [k]) => {
  obj[k] = (msg: string) => `${codes[k]}${msg}${codes.reset}`
  return obj
}, {}) as any
31

32 33 34
// helper for finding the right artifact from the deployed name
const locateArtifact = (name: string) => {
  return {
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
    'ChainStorageContainer-CTC-batches':
      'L1/rollup/ChainStorageContainer.sol/ChainStorageContainer.json',
    'ChainStorageContainer-SCC-batches':
      'L1/rollup/ChainStorageContainer.sol/ChainStorageContainer.json',
    CanonicalTransactionChain:
      'L1/rollup/CanonicalTransactionChain.sol/CanonicalTransactionChain.json',
    StateCommitmentChain:
      'L1/rollup/StateCommitmentChain.sol/StateCommitmentChain.json',
    BondManager: 'L1/verification/BondManager.sol/BondManager.json',
    OVM_L1CrossDomainMessenger:
      'L1/messaging/L1CrossDomainMessenger.sol/L1CrossDomainMessenger.json',
    Proxy__OVM_L1CrossDomainMessenger:
      'libraries/resolver/Lib_ResolvedDelegateProxy.sol/Lib_ResolvedDelegateProxy.json',
    Proxy__OVM_L1StandardBridge:
      'chugsplash/L1ChugSplashProxy.sol/L1ChugSplashProxy.json',
50 51 52 53
  }[name]
}

export const getArtifactFromManagedName = (name: string) => {
54
  // eslint-disable-next-line @typescript-eslint/no-var-requires
55
  return require(`../artifacts/contracts/${locateArtifact(name)}`)
56 57 58 59 60 61 62 63 64 65 66 67
}

export const getEtherscanUrl = (network, address: string) => {
  const escPrefix = network.chainId !== 1 ? `${network.name}.` : ''
  return `https://${escPrefix}etherscan.io/address/${address}`
}

// Reduces a byte string to first 32 bytes, with a '...' to indicate when it was shortened
const truncateLongString = (value: string): string => {
  return value.length > 66 ? `${value.slice(0, 66)}...` : value
}

68 69 70 71 72 73 74
export const printSectionHead = (msg: string) => {
  console.log(color.cyan(msg))
  console.log(
    color.cyan('='.repeat(Math.max(...msg.split('\n').map((s) => s.length))))
  )
}

75 76 77
export const printComparison = (
  action: string,
  description: string,
78 79
  expected: { name: string; value: any },
  deployed: { name: string; value: any }
80
) => {
81
  console.log(`\n${action}:`)
82 83
  if (hexStringEquals(expected.value, deployed.value)) {
    console.log(
84 85 86 87 88
      color.green(`${expected.name}: ${truncateLongString(expected.value)}`)
    )
    console.log('matches')
    console.log(
      color.green(`${deployed.name}: ${truncateLongString(deployed.value)}`)
89 90 91
    )
    console.log(color.green(`${description} looks good! 😎`))
  } else {
92 93 94
    throw new Error(
      `${description} looks wrong. ${expected.value}\ndoes not match\n${deployed.value}.`
    )
95 96
  }
}