Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Improved Logging and Flag Redesign for anvil-zksync #576

Open
dutterbutter opened this issue Feb 3, 2025 · 7 comments
Open

Proposal: Improved Logging and Flag Redesign for anvil-zksync #576

dutterbutter opened this issue Feb 3, 2025 · 7 comments

Comments

@dutterbutter
Copy link
Collaborator

dutterbutter commented Feb 3, 2025

Summary

This proposal aims to redesign the logging and trace cli options for anvil-zksync to improve usability, consistency, and scalability. The changes include consolidating verbosity flags, restructuring gas and VM reporting options.

Motivation

The current debugging CLI options for anvil-zksync includes multiple overlapping and sometimes unclear options for configuring logs and traces. Simplifying and unifying these options will improve developer experience, improve maintainability and keep consistency with anvil counterpart.

Proposed Design

  • Move away from tracing in favour of pure stdout logging
  • By default we only show tx summary:
    • Personally, I am in favour of keeping the tx summary even though anvil does not. For me personally, I like to see this info when developing with anvil-zksync but simply my own opinion here.
    • Everything else will be controlled via verbosity levels
[SUCCESS] Hash: 0x8d5abfaa7b8de4077677fbf873808a2605b3ef28098e9bec1932aa1cadbcb410
Initiator: 0x36615cf349d7f6344891b1e7ca7c72883f5dc049
Payer: 0x36615cf349d7f6344891b1e7ca7c72883f5dc049
Gas Limit: 372_350 | Used: 209_087 | Refunded: 163_263
Paid: 0.0000094612 ETH (209087 gas * 0.04525000 gwei)
Refunded: 0.0000073877 ETH 

Verbosity Levels

Propose consolidating logging into a tiered verbosity system (-v) with five levels:

  • v : Includes console logs, and meta logs (e.g. tracing::info!("created log filter '{:#x}'", self.id_counter);, impersonation changes )
    • Certainly worth discussing / classifying what logs should be included here, especially “meta logs”. We currently output a lot of these “meta logs” for snapshotting, impersonation etc.
  • vv: Includes user calls and event call traces.
  • vvv: Includes system calls, system event call traces.
  • vvvv: Includes system calls, system event calls, and precompiles traces.
  • vvvvv: Includes all of the above plus user/system l1-l2 logs (maybe storage logs?).
Example user trace (-vv)
Traces:
  [18748] RichAccount::validateTransaction(0x5509200fe661a286318a9111359469fbf6f5a7985a006e5896105e9b783e6f27, 0xf8525a4512b2a33499f93731d53707c9538477b04c7563ed5735a2fd5578a8c6, (113, 1079927674441348663698731742131369100870355833290 [1.079e48], 32774 [3.277e4], 35118880 [3.511e7], 50000 [5e4], 45250000 [4.525e7], 45250000 [4.525e7], 0, 0, 0, [0, 0, 0, 0], 0x9c4d535b0000000000000000000000000000000000000000000000000000000000000000010001556e69cb167b6cd0feb302b363b7045e5a8d960f60593983b2690bad3900000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000024869000000000000000000000000000000000000000000000000000000000000, 0x6dc18e29b7a1fd9815730b1cfdc211af3cc5bcfef0ae96290e00553a88661f116ed4dd3822a28e0007b18ca0af99a4c44ec14d6b6f79b22ee28062bc0ea6cbb31b, [0x010001556e69cb167b6cd0feb302b363b7045e5a8d960f60593983b2690bad39], 0x, 0x))
    └─ ← [Success] 202bcce700000000000000000000000000000000000000000000000000000000
  [8691] RichAccount::payForTransaction(0x5509200fe661a286318a9111359469fbf6f5a7985a006e5896105e9b783e6f27, 0xf8525a4512b2a33499f93731d53707c9538477b04c7563ed5735a2fd5578a8c6, (113, 1079927674441348663698731742131369100870355833290 [1.079e48], 32774 [3.277e4], 35118880 [3.511e7], 50000 [5e4], 45250000 [4.525e7], 45250000 [4.525e7], 0, 0, 0, [0, 0, 0, 0], 0x9c4d535b0000000000000000000000000000000000000000000000000000000000000000010001556e69cb167b6cd0feb302b363b7045e5a8d960f60593983b2690bad3900000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000024869000000000000000000000000000000000000000000000000000000000000, 0x6dc18e29b7a1fd9815730b1cfdc211af3cc5bcfef0ae96290e00553a88661f116ed4dd3822a28e0007b18ca0af99a4c44ec14d6b6f79b22ee28062bc0ea6cbb31b, [0x010001556e69cb167b6cd0feb302b363b7045e5a8d960f60593983b2690bad39], 0x, 0x))
    └─ ← [Success]
  [43918] RichAccount::executeTransaction(0x5509200fe661a286318a9111359469fbf6f5a7985a006e5896105e9b783e6f27, 0xf8525a4512b2a33499f93731d53707c9538477b04c7563ed5735a2fd5578a8c6, (113, 1079927674441348663698731742131369100870355833290 [1.079e48], 32774 [3.277e4], 35118880 [3.511e7], 50000 [5e4], 45250000 [4.525e7], 45250000 [4.525e7], 0, 0, 0, [0, 0, 0, 0], 0x9c4d535b0000000000000000000000000000000000000000000000000000000000000000010001556e69cb167b6cd0feb302b363b7045e5a8d960f60593983b2690bad3900000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000024869000000000000000000000000000000000000000000000000000000000000, 0x6dc18e29b7a1fd9815730b1cfdc211af3cc5bcfef0ae96290e00553a88661f116ed4dd3822a28e0007b18ca0af99a4c44ec14d6b6f79b22ee28062bc0ea6cbb31b, [0x010001556e69cb167b6cd0feb302b363b7045e5a8d960f60593983b2690bad39], 0x, 0x))
    ├─ [12412] → new <unknown>@0xa264dd5afe03dc84521f2b6e30e9e289bac6acd9
    │   ├─ emit OwnershipTransferred(param0: 0x0000000000000000000000000000000000000000, param1: RichAccount: [0xbd29A1B981925B94eEc5c4F1125AF02a2Ec4d1cA])
    │   └─ ← [Success] 64 bytes of code
    └─ ← [Success] 00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000
Example system trace (-vvv):
Traces:
  [1502] SystemContext::setNewBatch(0x0000000000000000000000000000000000000000000000000000000000000000, 1025, 13, 45250000 [4.525e7])
    └─ ← [Success]
  [1861] SystemContext::setL2Block(25, 1025, 0xb99d45ffbdcaa0661df42b5c86168cec7b010b088e1b86d7e4a797d67a2eba35, true, 1)
    └─ ← [Success]
  [243] SystemContext::baseFee()
    └─ ← [Success] 0000000000000000000000000000000000000000000000000000000002b275d0
  [8354] BootloaderUtilities::getTransactionHashes((113, 310456771025820669616026695872740475403597889609 [3.104e47], 1047216528011964193815200329491493203465035215187 [1.047e48], 372350 [3.723e5], 3143, 45250000 [4.525e7], 45250000 [4.525e7], 0, 11, 0, [0, 0, 0, 0], 0xa41368620000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000e4c756b6520536b7977616c6b6572000000000000000000000000000000000000, 0x7d52a2ac22599490472675a56f248fe1294c2f38685cb4160f19357786fd635d09824a1282606c037f4417d12ea23243ee58dc660d26569541a517bfd8c782c01c, [], 0x, 0x))
    ├─ [237] SystemContext::chainId()
    │   └─ ← [Success] 0000000000000000000000000000000000000000000000000000000000000104
    └─ ← [Success] 42fb9e0eada45fd09952e9f93b4031db60777050c17f6cf8ed9c43383570aa2827d0fa90c1f472f953f63835d6542a65569f7d174cca51275fa57f796aa71ee6
  [959] SystemContext::appendTransactionToCurrentL2Block(0x42fb9e0eada45fd09952e9f93b4031db60777050c17f6cf8ed9c43383570aa28)
    └─ ← [Success]
  [395] SystemContext::setPubdataInfo(1572, 0)
    └─ ← [Success]
  [373] SystemContext::setTxOrigin(bootloader: [0x0000000000000000000000000000000000008001])
    └─ ← [Success]
  [323] SystemContext::setGasPrice(45250000 [4.525e7])
    └─ ← [Success]
  [6233] ContractDeployer::extendedAccountVersion(RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049])
    ├─ [2226] AccountCodeStorage::getRawCodeHash(RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049])
    │   └─ ← [Success] 0000000000000000000000000000000000000000000000000000000000000000
    └─ ← [Success] 0000000000000000000000000000000000000000000000000000000000000001
  [5747] NonceHolder::validateNonceUsage(RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], 11, false)
    └─ ← [Success]
  [18748] RichAccount::validateTransaction(0x42fb9e0eada45fd09952e9f93b4031db60777050c17f6cf8ed9c43383570aa28, 0x27d0fa90c1f472f953f63835d6542a65569f7d174cca51275fa57f796aa71ee6, (113, 310456771025820669616026695872740475403597889609 [3.104e47], 1047216528011964193815200329491493203465035215187 [1.047e48], 372350 [3.723e5], 3143, 45250000 [4.525e7], 45250000 [4.525e7], 0, 11, 0, [0, 0, 0, 0], 0xa41368620000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000e4c756b6520536b7977616c6b6572000000000000000000000000000000000000, 0x7d52a2ac22599490472675a56f248fe1294c2f38685cb4160f19357786fd635d09824a1282606c037f4417d12ea23243ee58dc660d26569541a517bfd8c782c01c, [], 0x, 0x))
    ├─ [4795] NonceHolder::incrementMinNonceIfEquals(11)
    │   └─ ← [Success]
    ├─ [2744] L2BaseToken::balanceOf(310456771025820669616026695872740475403597889609 [3.104e47])
    │   ├─ emit Transfer(param0: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param1: bootloader: [0x0000000000000000000000000000000000008001], param2: 16848837500000 [1.684e13])
    │   ├─ emit Transfer(param0: bootloader: [0x0000000000000000000000000000000000008001], param1: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param2: 7387650750000 [7.387e12])
    │   └─ ← [Success] 00000000000000000000000000000000000000000000021dc699bf65f83d3950
    └─ ← [Success] 202bcce700000000000000000000000000000000000000000000000000000000
  [811] NonceHolder::validateNonceUsage(RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], 11, true)
    └─ ← [Success]
  [774] L2BaseToken::balanceOf(32769 [3.276e4])
    ├─ emit Transfer(param0: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param1: bootloader: [0x0000000000000000000000000000000000008001], param2: 16848837500000 [1.684e13])
    ├─ emit Transfer(param0: bootloader: [0x0000000000000000000000000000000000008001], param1: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param2: 7387650750000 [7.387e12])
    └─ ← [Success] 0000000000000000000000000000000000000000000000000000000000000000
  [8691] RichAccount::payForTransaction(0x42fb9e0eada45fd09952e9f93b4031db60777050c17f6cf8ed9c43383570aa28, 0x27d0fa90c1f472f953f63835d6542a65569f7d174cca51275fa57f796aa71ee6, (113, 310456771025820669616026695872740475403597889609 [3.104e47], 1047216528011964193815200329491493203465035215187 [1.047e48], 372350 [3.723e5], 3143, 45250000 [4.525e7], 45250000 [4.525e7], 0, 11, 0, [0, 0, 0, 0], 0xa41368620000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000e4c756b6520536b7977616c6b6572000000000000000000000000000000000000, 0x7d52a2ac22599490472675a56f248fe1294c2f38685cb4160f19357786fd635d09824a1282606c037f4417d12ea23243ee58dc660d26569541a517bfd8c782c01c, [], 0x, 0x))
    ├─ [7466] MsgValueSimulator::fallback()
    │   ├─ [6086] L2BaseToken::transferFromTo(RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], bootloader: [0x0000000000000000000000000000000000008001], 16848837500000 [1.684e13])
    │   │   ├─ emit Transfer(param0: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param1: bootloader: [0x0000000000000000000000000000000000008001], param2: 16848837500000 [1.684e13])
    │   │   ├─ emit Transfer(param0: bootloader: [0x0000000000000000000000000000000000008001], param1: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param2: 7387650750000 [7.387e12])
    │   │   ├─ [251] EventWriter::00000000(000000000000000000000000000000000000000000000f52ecf95c60)
    │   │   │   └─ ← [Success]
    │   │   └─ ← [Success]
    │   ├─ [23] bootloader::fallback{value: 16848837500000}() [mimiccall]
    │   │   └─ ← [Success]
    │   └─ ← [Success]
    └─ ← [Success]
Example user, system, precompiles (-vvvv):
Traces:
  [1502] SystemContext::setNewBatch(0x0000000000000000000000000000000000000000000000000000000000000000, 1087, 3, 45250000 [4.525e7])
    ├─ [159] Keccak::00000000(000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000008)
    │   └─ ← [Success] 6add646517a5b0f6793cd5891b7937d28a5b2981a5d88ebc7cd776088fea9041
    └─ ← [Success]
  [1861] SystemContext::setL2Block(5, 1087, 0x64f75bc46d91a7c347714e9b1eca789c6b978c0ac60cef0e6b453c2c13507d3b, true, 1)
    ├─ [159] Keccak::00000000(000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000415e7d7341157e173978190427554e92e37592d100f9b70971744c62b1dcdc5b6200000000000000000000000000000000000000000000000000000000000000000)
    │   └─ ← [Success] 64f75bc46d91a7c347714e9b1eca789c6b978c0ac60cef0e6b453c2c13507d3b
    └─ ← [Success]
  [243] SystemContext::baseFee()
    └─ ← [Success] 0000000000000000000000000000000000000000000000000000000002b275d0
  [8354] BootloaderUtilities::getTransactionHashes((113, 310456771025820669616026695872740475403597889609 [3.104e47], 673824189905747573000529064841380527045184055776 [6.738e47], 278256 [2.782e5], 3143, 45250000 [4.525e7], 45250000 [4.525e7], 0, 2, 100000000000000000 [1e17], [0, 0, 0, 0], 0x, 0x74e8d7b7f395829bc79883cf1ced4f68e8d42bfffdae16fdafb1c6ee0128216f744f3ef944db2d060e00071fbd4f56f6e9e53604d908a4f3af7be48569778f411c, [], 0x, 0x))
    ├─ [159] Keccak::fallback()
    │   └─ ← [Success] c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
    ├─ [159] Keccak::fallback()
    │   └─ ← [Success] c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
    ├─ [159] Keccak::fallback()
    │   └─ ← [Success] c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
    ├─ [279] Keccak::848e1bfa(1ac4e3576b728bda6721b215c70a7799a5b4866282a71bab954baac8000000000000000000000000000000000000000000000000000000000000007100000000000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc04900000000000000000000000076075259b43b113e14226c78c4b0db965c23e9e00000000000000000000000000000000000000000000000000000000000043ef00000000000000000000000000000000000000000000000000000000000000c470000000000000000000000000000000000000000000000000000000002b275d00000000000000000000000000000000000000000000000000000000002b275d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000016345785d8a0000c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470)
    │   └─ ← [Success] 5892bd12dd942147033e01fcc2454221cb83d8c8f97a5b5b56dea20cd1c6abf6
    ├─ [237] SystemContext::chainId()
    │   └─ ← [Success] 0000000000000000000000000000000000000000000000000000000000000104
    ├─ [159] Keccak::c2f87871(76b8ac6bf7215b4adcc1e069bf4ab82d9ab1df05a57a91d425935b6e19b453ce45aaaaf3a300f5a9ec95869b4f28ab10430b572ee218c3a6a5e07d6fad7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a50000000000000000000000000000000000000000000000000000000000000104)
    │   └─ ← [Success] c45dc49b15b65fc61d587350dee45ae95b92abefd26985df11dd926751b44bbb
    ├─ [159] Keccak::1901c45d(c49b15b65fc61d587350dee45ae95b92abefd26985df11dd926751b44bbb5892bd12dd942147033e01fcc2454221cb83d8c8f97a5b5b56dea20cd1c6abf6)
    │   └─ ← [Success] b9488af029051cd053de391f340db9799bb54833d5153fb525a061b29a9b0ea2
    ├─ [159] Keccak::74e8d7b7(f395829bc79883cf1ced4f68e8d42bfffdae16fdafb1c6ee0128216f744f3ef944db2d060e00071fbd4f56f6e9e53604d908a4f3af7be48569778f411c)
    │   └─ ← [Success] e79b60b0a244e3cd55d5e2cb382239bc22cc22a89d92d0214c1eec473f2c0114
    ├─ [159] Keccak::b9488af0(29051cd053de391f340db9799bb54833d5153fb525a061b29a9b0ea2e79b60b0a244e3cd55d5e2cb382239bc22cc22a89d92d0214c1eec473f2c0114)
    │   └─ ← [Success] 9cc491283cd026c74ffb03eee9a1ea8aec37b71288152a5221fd6b40194b97a5
    └─ ← [Success] 9cc491283cd026c74ffb03eee9a1ea8aec37b71288152a5221fd6b40194b97a5b9488af029051cd053de391f340db9799bb54833d5153fb525a061b29a9b0ea2
  [959] SystemContext::appendTransactionToCurrentL2Block(0x9cc491283cd026c74ffb03eee9a1ea8aec37b71288152a5221fd6b40194b97a5)
    ├─ [159] Keccak::00000000(000000000000000000000000000000000000000000000000000000009cc491283cd026c74ffb03eee9a1ea8aec37b71288152a5221fd6b40194b97a5)
    │   └─ ← [Success] 7c79a5751587e19e84e925ddef9fa7d6f850209bc258b88faed63c3cc25bdf32
    └─ ← [Success]
  [395] SystemContext::setPubdataInfo(1572, 0)
    └─ ← [Success]
  [373] SystemContext::setTxOrigin(bootloader: [0x0000000000000000000000000000000000008001])
    └─ ← [Success]
  [323] SystemContext::setGasPrice(45250000 [4.525e7])
    └─ ← [Success]
  [6233] ContractDeployer::extendedAccountVersion(RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049])
    ├─ [159] Keccak::00000000(000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc0490000000000000000000000000000000000000000000000000000000000000000)
    │   └─ ← [Success] eaa2b2fbf0b42c559059e5e9510edc15755f1c1883f0e41d5ba5f9aea4ac201a
    ├─ [2226] AccountCodeStorage::getRawCodeHash(RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049])
    │   └─ ← [Success] 0000000000000000000000000000000000000000000000000000000000000000
    └─ ← [Success] 0000000000000000000000000000000000000000000000000000000000000001
  [5747] NonceHolder::validateNonceUsage(RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], 2, false)
    ├─ [159] Keccak::00000000(000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc0490000000000000000000000000000000000000000000000000000000000000000)
    │   └─ ← [Success] eaa2b2fbf0b42c559059e5e9510edc15755f1c1883f0e41d5ba5f9aea4ac201a
    ├─ [159] Keccak::00000000(000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc0490000000000000000000000000000000000000000000000000000000000000001)
    │   └─ ← [Success] 1aaedb9739e2eccf88498b4b7b94dc130336bc3f6f75d8479999c9f1cf84be6f
    ├─ [159] Keccak::00000000(000000000000000000000000000000000000000000000000000000021aaedb9739e2eccf88498b4b7b94dc130336bc3f6f75d8479999c9f1cf84be6f)
    │   └─ ← [Success] a7150de3da3bcc3d203423a5e279ed3bcf1017e1c898e1b1948a226176e7b60c
    └─ ← [Success]
  [18748] RichAccount::validateTransaction(0x9cc491283cd026c74ffb03eee9a1ea8aec37b71288152a5221fd6b40194b97a5, 0xb9488af029051cd053de391f340db9799bb54833d5153fb525a061b29a9b0ea2, (113, 310456771025820669616026695872740475403597889609 [3.104e47], 673824189905747573000529064841380527045184055776 [6.738e47], 278256 [2.782e5], 3143, 45250000 [4.525e7], 45250000 [4.525e7], 0, 2, 100000000000000000 [1e17], [0, 0, 0, 0], 0x, 0x74e8d7b7f395829bc79883cf1ced4f68e8d42bfffdae16fdafb1c6ee0128216f744f3ef944db2d060e00071fbd4f56f6e9e53604d908a4f3af7be48569778f411c, [], 0x, 0x))
    ├─ [4795] NonceHolder::incrementMinNonceIfEquals(2)
    │   ├─ [159] Keccak::00000000(000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc0490000000000000000000000000000000000000000000000000000000000000000)
    │   │   └─ ← [Success] eaa2b2fbf0b42c559059e5e9510edc15755f1c1883f0e41d5ba5f9aea4ac201a
    │   ├─ [159] Keccak::00000000(000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc0490000000000000000000000000000000000000000000000000000000000000000)
    │   │   └─ ← [Success] eaa2b2fbf0b42c559059e5e9510edc15755f1c1883f0e41d5ba5f9aea4ac201a
    │   └─ ← [Success]
    ├─ [2744] L2BaseToken::balanceOf(310456771025820669616026695872740475403597889609 [3.104e47])
    │   ├─ emit Transfer(param0: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param1: bootloader: [0x0000000000000000000000000000000000008001], param2: 12591084000000 [1.259e13])
    │   ├─ emit Transfer(param0: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param1: 0x76075259b43b113E14226c78C4B0dB965C23e9E0, param2: 100000000000000000 [1e17])
    │   ├─ emit Transfer(param0: bootloader: [0x0000000000000000000000000000000000008001], param1: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param2: 4798400500000 [4.798e12])
    │   ├─ [159] Keccak::00000000(000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc0490000000000000000000000000000000000000000000000000000000000000000)
    │   │   └─ ← [Success] eaa2b2fbf0b42c559059e5e9510edc15755f1c1883f0e41d5ba5f9aea4ac201a
    │   └─ ← [Success] 00000000000000000000000000000000000000000000021e171a2b2eac2b8fb8
    ├─ [7224] ECRecover::b9488af0(29051cd053de391f340db9799bb54833d5153fb525a061b29a9b0ea2000000000000000000000000000000000000000000000000000000000000001c74e8d7b7f395829bc79883cf1ced4f68e8d42bfffdae16fdafb1c6ee0128216f744f3ef944db2d060e00071fbd4f56f6e9e53604d908a4f3af7be48569778f41)
    │   └─ ← [Success] 00000000000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc049
    └─ ← [Success] 202bcce700000000000000000000000000000000000000000000000000000000
  [811] NonceHolder::validateNonceUsage(RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], 2, true)
    ├─ [159] Keccak::00000000(000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc0490000000000000000000000000000000000000000000000000000000000000000)
    │   └─ ← [Success] eaa2b2fbf0b42c559059e5e9510edc15755f1c1883f0e41d5ba5f9aea4ac201a
    └─ ← [Success]
  [774] L2BaseToken::balanceOf(32769 [3.276e4])
    ├─ emit Transfer(param0: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param1: bootloader: [0x0000000000000000000000000000000000008001], param2: 12591084000000 [1.259e13])
    ├─ emit Transfer(param0: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param1: 0x76075259b43b113E14226c78C4B0dB965C23e9E0, param2: 100000000000000000 [1e17])
    ├─ emit Transfer(param0: bootloader: [0x0000000000000000000000000000000000008001], param1: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param2: 4798400500000 [4.798e12])
    ├─ [159] Keccak::00000000(000000000000000000000000000000000000000000000000000080010000000000000000000000000000000000000000000000000000000000000000)
    │   └─ ← [Success] 31b66141c575a054316a84da9cf4aa6fe0abd373cab1bf4ac029ffc061aae0da
    └─ ← [Success] 0000000000000000000000000000000000000000000000000000000000000000
  [8691] RichAccount::payForTransaction(0x9cc491283cd026c74ffb03eee9a1ea8aec37b71288152a5221fd6b40194b97a5, 0xb9488af029051cd053de391f340db9799bb54833d5153fb525a061b29a9b0ea2, (113, 310456771025820669616026695872740475403597889609 [3.104e47], 673824189905747573000529064841380527045184055776 [6.738e47], 278256 [2.782e5], 3143, 45250000 [4.525e7], 45250000 [4.525e7], 0, 2, 100000000000000000 [1e17], [0, 0, 0, 0], 0x, 0x74e8d7b7f395829bc79883cf1ced4f68e8d42bfffdae16fdafb1c6ee0128216f744f3ef944db2d060e00071fbd4f56f6e9e53604d908a4f3af7be48569778f411c, [], 0x, 0x))
    ├─ [7466] MsgValueSimulator::fallback()
    │   ├─ [6086] L2BaseToken::transferFromTo(RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], bootloader: [0x0000000000000000000000000000000000008001], 12591084000000 [1.259e13])
    │   │   ├─ emit Transfer(param0: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param1: bootloader: [0x0000000000000000000000000000000000008001], param2: 12591084000000 [1.259e13])
    │   │   ├─ emit Transfer(param0: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param1: 0x76075259b43b113E14226c78C4B0dB965C23e9E0, param2: 100000000000000000 [1e17])
    │   │   ├─ emit Transfer(param0: bootloader: [0x0000000000000000000000000000000000008001], param1: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param2: 4798400500000 [4.798e12])
    │   │   ├─ [159] Keccak::00000000(000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc0490000000000000000000000000000000000000000000000000000000000000000)
    │   │   │   └─ ← [Success] eaa2b2fbf0b42c559059e5e9510edc15755f1c1883f0e41d5ba5f9aea4ac201a
    │   │   ├─ [159] Keccak::00000000(000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc0490000000000000000000000000000000000000000000000000000000000000000)
    │   │   │   └─ ← [Success] eaa2b2fbf0b42c559059e5e9510edc15755f1c1883f0e41d5ba5f9aea4ac201a
    │   │   ├─ [159] Keccak::00000000(000000000000000000000000000000000000000000000000000080010000000000000000000000000000000000000000000000000000000000000000)
    │   │   │   └─ ← [Success] 31b66141c575a054316a84da9cf4aa6fe0abd373cab1bf4ac029ffc061aae0da
    │   │   ├─ [251] EventWriter::00000000(000000000000000000000000000000000000000000000b739716d300)
    │   │   │   └─ ← [Success]
    │   │   └─ ← [Success]
    │   ├─ [23] bootloader::fallback{value: 12591084000000}() [mimiccall]
    │   │   └─ ← [Success]
    │   └─ ← [Success]
    └─ ← [Success]
  [774] L2BaseToken::balanceOf(32769 [3.276e4])
    ├─ emit Transfer(param0: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param1: bootloader: [0x0000000000000000000000000000000000008001], param2: 12591084000000 [1.259e13])
    ├─ emit Transfer(param0: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param1: 0x76075259b43b113E14226c78C4B0dB965C23e9E0, param2: 100000000000000000 [1e17])
    ├─ emit Transfer(param0: bootloader: [0x0000000000000000000000000000000000008001], param1: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param2: 4798400500000 [4.798e12])
    ├─ [159] Keccak::00000000(000000000000000000000000000000000000000000000000000080010000000000000000000000000000000000000000000000000000000000000000)
    │   └─ ← [Success] 31b66141c575a054316a84da9cf4aa6fe0abd373cab1bf4ac029ffc061aae0da
    └─ ← [Success] 00000000000000000000000000000000000000000000000000000b739716d300
  [398] KnownCodesStorage::markFactoryDeps(true, [])
    └─ ← [Success]
  [256] AccountCodeStorage::getRawCodeHash(RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049])
    └─ ← [Success] 0000000000000000000000000000000000000000000000000000000000000000
  [373] SystemContext::setTxOrigin(RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049])
    └─ ← [Success]
  [10820] RichAccount::executeTransaction(0x9cc491283cd026c74ffb03eee9a1ea8aec37b71288152a5221fd6b40194b97a5, 0xb9488af029051cd053de391f340db9799bb54833d5153fb525a061b29a9b0ea2, (113, 310456771025820669616026695872740475403597889609 [3.104e47], 673824189905747573000529064841380527045184055776 [6.738e47], 278256 [2.782e5], 3143, 45250000 [4.525e7], 45250000 [4.525e7], 0, 2, 100000000000000000 [1e17], [0, 0, 0, 0], 0x, 0x74e8d7b7f395829bc79883cf1ced4f68e8d42bfffdae16fdafb1c6ee0128216f744f3ef944db2d060e00071fbd4f56f6e9e53604d908a4f3af7be48569778f411c, [], 0x, 0x))
    ├─ [9511] MsgValueSimulator::fallback()
    │   ├─ [7972] L2BaseToken::transferFromTo(RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], 0x76075259b43b113E14226c78C4B0dB965C23e9E0, 100000000000000000 [1e17])
    │   │   ├─ emit Transfer(param0: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param1: bootloader: [0x0000000000000000000000000000000000008001], param2: 12591084000000 [1.259e13])
    │   │   ├─ emit Transfer(param0: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param1: 0x76075259b43b113E14226c78C4B0dB965C23e9E0, param2: 100000000000000000 [1e17])
    │   │   ├─ emit Transfer(param0: bootloader: [0x0000000000000000000000000000000000008001], param1: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param2: 4798400500000 [4.798e12])
    │   │   ├─ [159] Keccak::00000000(000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc0490000000000000000000000000000000000000000000000000000000000000000)
    │   │   │   └─ ← [Success] eaa2b2fbf0b42c559059e5e9510edc15755f1c1883f0e41d5ba5f9aea4ac201a
    │   │   ├─ [159] Keccak::00000000(000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc0490000000000000000000000000000000000000000000000000000000000000000)
    │   │   │   └─ ← [Success] eaa2b2fbf0b42c559059e5e9510edc15755f1c1883f0e41d5ba5f9aea4ac201a
    │   │   ├─ [159] Keccak::00000000(000000000000000076075259b43b113e14226c78c4b0db965c23e9e00000000000000000000000000000000000000000000000000000000000000000)
    │   │   │   └─ ← [Success] be6e5d94cf632fdfc8b13696ec6d1a3cd5cc6c7456574c02fc3b846847485876
    │   │   ├─ [251] EventWriter::00000000(0000000000000000000000000000000000000000016345785d8a0000)
    │   │   │   └─ ← [Success]
    │   │   └─ ← [Success]
    │   ├─ [210] 0x76075259b43b113e14226c78c4b0db965c23e9e0::fallback{value: 100000000000000000}() [mimiccall]
    │   │   └─ ← [Success]
    │   └─ ← [Success]
    └─ ← [Success] 00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000
  [373] SystemContext::setTxOrigin(bootloader: [0x0000000000000000000000000000000000008001])
    └─ ← [Success]
  [2538] L2BaseToken::transferFromTo(bootloader: [0x0000000000000000000000000000000000008001], RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], 4798400500000 [4.798e12])
    ├─ emit Transfer(param0: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param1: bootloader: [0x0000000000000000000000000000000000008001], param2: 12591084000000 [1.259e13])
    ├─ emit Transfer(param0: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param1: 0x76075259b43b113E14226c78C4B0dB965C23e9E0, param2: 100000000000000000 [1e17])
    ├─ emit Transfer(param0: bootloader: [0x0000000000000000000000000000000000008001], param1: RichAccount: [0x36615Cf349d7F6344891B1e7CA7C72883F5dc049], param2: 4798400500000 [4.798e12])
    ├─ [159] Keccak::00000000(000000000000000000000000000000000000000000000000000080010000000000000000000000000000000000000000000000000000000000000000)
    │   └─ ← [Success] 31b66141c575a054316a84da9cf4aa6fe0abd373cab1bf4ac029ffc061aae0da
    ├─ [159] Keccak::00000000(000000000000000000000000000000000000000000000000000080010000000000000000000000000000000000000000000000000000000000000000)
    │   └─ ← [Success] 31b66141c575a054316a84da9cf4aa6fe0abd373cab1bf4ac029ffc061aae0da
    ├─ [159] Keccak::00000000(000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc0490000000000000000000000000000000000000000000000000000000000000000)
    │   └─ ← [Success] eaa2b2fbf0b42c559059e5e9510edc15755f1c1883f0e41d5ba5f9aea4ac201a
    ├─ [251] EventWriter::00000000(00000000000000000000000000000000000000000000045d36f51120)
    │   └─ ← [Success]
    └─ ← [Success]

Storage Logs

To include storage logs in the verbosity system is to be discussed. They are quite noisy as they are so many.

One of the use cases for showing storage logs is contract optimizations and ensuring you make use of repeated writes as often instead of initial writes, but how can we make the logs reflect that use case / value?

They can be filtered between read / write (current display)
02:11:09  INFO [Storage Logs] (118 entries)
02:11:09  INFO Log #1
02:11:09  INFO │   ├─ Kind: Read
02:11:09  INFO │   ├─ Address: AccountCodeStorage@0x0000000000000000000000000000000000008002
02:11:09  INFO │   ├─ Key: 0x000000000000000000000000000000000000000000000000000000000000800b
02:11:09  INFO │   ├─ Read Value: 0x0100017feeccbcf3933db74d7163fe8261c69c09d5f1e7c371327264110875c9
02:11:09  INFO │   └─ Pubdata Bytes: None
02:11:09  INFO Log #2
02:11:09  INFO │   ├─ Kind: Read
02:11:09  INFO │   ├─ Address: SystemContext@0x000000000000000000000000000000000000800b
02:11:09  INFO │   ├─ Key: 0x0000000000000000000000000000000000000000000000000000000000000007
02:11:09  INFO │   ├─ Read Value: 0x0000000000000000000000000000000000000000000000000000000000000000
02:11:09  INFO │   └─ Pubdata Bytes: None
02:11:09  INFO Log #3
02:11:09  INFO │   ├─ Kind: Read
02:11:09  INFO │   ├─ Address: SystemContext@0x000000000000000000000000000000000000800b
02:11:09  INFO │   ├─ Key: 0x0000000000000000000000000000000000000000000000000000000000000009
02:11:09  INFO │   ├─ Read Value: 0x0000000000000000000000000000000000000000000000000000000000000000
02:11:09  INFO │   └─ Pubdata Bytes: None
02:11:09  INFO Log #4
02:11:09  INFO │   ├─ Kind: Read
02:11:09  INFO │   ├─ Address: AccountCodeStorage@0x0000000000000000000000000000000000008002
02:11:09  INFO │   ├─ Key: 0x0000000000000000000000000000000000000000000000000000000000008010
02:11:09  INFO │   ├─ Read Value: 0x0100000ff991d5847f1e9c10c5969d0f03b34a25411ad86d5cb3e0d9c3931e0b
02:11:09  INFO │   └─ Pubdata Bytes: None
02:11:09  INFO Log #5
02:11:09  INFO │   ├─ Kind: InitialWrite
02:11:09  INFO │   ├─ Address: SystemContext@0x000000000000000000000000000000000000800b
02:11:09  INFO │   ├─ Key: 0x5eff886ea0ce6ca488a3d6e336d6c0f75f46d19b42c06ce5ee98e42c96d256c7
02:11:09  INFO │   ├─ Read Value: 0x0000000000000000000000000000000000000000000000000000000000000000
02:11:09  INFO │   ├─ Written Value: 0x0000000000000000000000000000000000000000000000000000000000000000
02:11:09  INFO │   └─ Pubdata Bytes: Free Slot (no cost)
02:11:09  INFO Log #6
02:11:09  INFO │   ├─ Kind: InitialWrite
02:11:09  INFO │   ├─ Address: SystemContext@0x000000000000000000000000000000000000800b
02:11:09  INFO │   ├─ Key: 0x0000000000000000000000000000000000000000000000000000000000000007
02:11:09  INFO │   ├─ Read Value: 0x0000000000000000000000000000000000000000000000000000000000000000
02:11:09  INFO │   ├─ Written Value: 0x00000000000000000000000000000001000000000000000000000000000003e9
02:11:09  INFO │   └─ Pubdata Bytes: Free Slot (no cost)
02:11:09  INFO Log #19
02:11:09  INFO │   ├─ Kind: RepeatedWrite
02:11:09  INFO │   ├─ Address: SystemContext@0x000000000000000000000000000000000000800b
02:11:09  INFO │   ├─ Key: 0x000000000000000000000000000000000000000000000000000000000000010c
02:11:09  INFO │   ├─ Read Value: 0x00000000000000000000000000000002000000000000000000000000000003ea
02:11:09  INFO │   ├─ Written Value: 0x0000000000000000000000000000000300000000000000000000000000000414
02:11:09  INFO │   └─ Pubdata Bytes: Free Slot (no cost)

JSON dump

To facilitate programmatic log analysis, add an optional format flag:

  • --json: Outputs logs in JSON format

Gas Reporting

Change --show-gas-details to a gas reporting table:

  • -gas-report [summary|verbose]:
    • summary (default): Provides a high-level overview of gas usage. (Similar to what is shown now, a gas breakdown)

    • Alternatively we could consolidate summary and verbose so it shows what functions are included in the execution gas breakdown?

    • I think for most devs, understanding what part of their contract / project consumes the most gas is what is of value. How can we emphasizes this?

      Category Sub-Category Gas/Value Percentage
      Execution Gas Breakdown Transaction Setup 24,070 gas 9%
        Bytecode Preparation 0 gas 0%
        Account Validation 240,798 gas 90%
        Computations (Opcodes) 0 gas 0%
      Transaction Setup Cost Breakdown Total Setup Cost 24,070 gas 100%
        Fixed Cost 14,070 gas 58%
        Operator Cost 10,000 gas 41%
      L1 Publishing Costs Published 0 bytes
        Cost per Byte 598 gas
        Total Gas Cost 0 gas 0%
      Block Contribution Length Overhead 8,960 gas
        Slot Overhead 10,000 gas
        Full Block Cost ~478,400,000 L2 gas
    • verbose: Includes detailed function call breakdowns similar to hardhat-gas-reporter (below)

      • It would be slightly different, as for anvil-zksync it would be reported per tx rather then for an entire suite so min , max and avg would not be relevant. Rather it would be a table outlining the gas used per contract function call, deployment costs.
      • Personally I think this is much more useful then existing --show-gas-details option we currently have available.

      Image

VM Reporting

Move VM details to follow similar naming convention rather then --show-vm-details:

  • -vm-report

Offline Mode

Refine the behaviour of --offline to strictly enforce offline operations. Currently not well respected.

  • Disables forking and fetching from explorers or other online sources.

Deprecated Flags

The following flags will be removed or aliased, with deprecation warnings provided for a few releases:

  • d (can default to -vv).
  • -show-events (included in verbosity levels)
  • -show-calls (included in verbosity levels)
  • --show-outputs (included in verbosity levels)
  • -show-gas-details (turns to --gas-report)
  • -show-vm-details (turns to --vm-report )
  • -resolve-hashes (will be turned on unless offline is used, same as anvil)
  • --show-storage-logs (tbd what that becomes)

Where applicable, users will be directed to the new flag equivalents.

[WIP] Transition Plan

Phase 1: Deprecation

  • Introduce New Flags:

    • Implement the new verbosity flags (v, vv, etc.),
    • -gas-report,
    • -vm-report
    • Internally alias old flags to new ones so that the user experience continues uninterrupted where applicable
  • Deprecation Warnings & Logs:

    • Whenever a deprecated flag (e.g. d, -show-events, etc.) is used, print a deprecation warning indicating which new flag to use instead. For example:

      
      [DEPRECATION WARNING] The flag '-d' will be removed in a future release. Please use '-vv' instead.
      
  • Documentation Updates:

    • Update the official docs, README, and examples to reflect the new flags/verbosity levels

Phase 2: Remove deprecated flags

  • Remove references to the old flags, and remove the aliasing logic that forwards the option to the new one.
    • Deprecation warnings are no longer needed after this point.
    • This would be considered a breaking change at this point. I think its sensible as we don’t want to carry all these old flags forever?
  • Ensure clearly outlined in the release notes / changelog
@dutterbutter
Copy link
Collaborator Author

dutterbutter commented Feb 3, 2025

This may be better suited for a Discussion post, but did not want it to live in an Notion doc so posted as an issue instead.

CC: @popzxc @itegulov for feedback / input 🙏

@popzxc
Copy link
Member

popzxc commented Feb 4, 2025

That's a very nice write-up. Like it a lot.

Thoughts here:

  • Compressing flags to -v/vv/vvv/vvvv/vvvvv makes a lot of sense to me.
  • Migrating from tracing to println makes some sense, but there are caveats.

tracing is a tool for developers, not for users, it's meant for situations where you want to debug the application. So I think there are two separate scopes here:

  • printing for users
  • printing for ourselves.

User should probably never have to do RUST_LOG=... when they run the application. However, us may want to have some logs to troubleshoot stuff if required.

So probably we just need to separate the concepts. tracing is fine as long as it's OK for user to never see this line.

Foundry has a shell wrapper with custom macros for it, and they, in fact, forbid using println (which is nice, since it prevents debugging artifacts from slipping into main), which seems to be a better model. It also provides a layer of encapsulation, making it easier for us to change the implementation if required.

So we can probably just implement a similar wrapper for a shell (also note that it handles verbosity) and use it instead of both tracing::info and println.

@sayon
Copy link

sayon commented Feb 4, 2025

Thank you Dustin!
I have a couple of thoughts:

  1. If we categorise logs it would be nice to keep their separation with the highest granularity. For example, supporting the config file:
log_user_calls = true
log_system_calls = false
log_l1 = true

Then the CLI options like -v or -vvv will just be shorthands for predefined sets of on/off switch states.
That also allows more granularity (not just on/off but none/some/more/all) and additional parameters like outputting them in different streams.

  1. It can also be achieved through something like --log=vm,gas,outputs, in which cases -v or -vvv will be aliases for on/off states. It is simpler than 1 but forces every switch to a binary state.

  2. I agree about logs for users and logs for developers, but I would like to add the third party -- logs for tooling. If we take on them, they should be optimized for ease of parsing and verbosity. Logs for users and for developers can be derived from such events.

  3. I am very much with @popzxc on the println usage -- it has a very generic semantic whereas logging is contextual.

@popzxc
Copy link
Member

popzxc commented Feb 4, 2025

@sayon I'm not sure if the ability to fine-tune the parameters is actually needed (at least, for now). You usually just need either more or less information, depending on the situation.

@dutterbutter
Copy link
Collaborator Author

dutterbutter commented Feb 4, 2025

Thanks for the feedback. Yes, much better approach to make use of a shell wrapper with macro usage. I started refactoring #578 to use a simplified version of Foundrys implementation. 🙏

Any particular thoughts on gas-report and storage logs? As mentioned these are particular useful for optimizing contracts during development so I'd like to determine the best approach to extract that use case.

@sayon
Copy link

sayon commented Feb 4, 2025

On logging by categories vs -vN

  1. From the user perspective, what if I know that my problem is related to L1 messaging and I am only interested in that? With the proposed approach my only solution would be to use -vvvvv and then filter the output using grep or similar tool to select the lines relevant to the L1-L2.
  2. Architecturally, I imagine logging with just -vN options as still something to be implemented on top of the log lines categorisation. It allows quickly rematching categories between verbosity levels (e.g. moving VM-related messages from -vvv to -vv). So, internally, we would still keep the categories, assign -v, -vv ... to different subsets of categories, but we won't allow users to select these subsets directly. My point is that allowing users to specify directly --logs=vm,l1,smthelse does not demand an additional effort from our side.

I can think of the following arguments against allowing users to filter logs by categories and in favor of simple -vN approach:

  1. Introducing new categories, or moving message types between categories becomes a breaking change. Although a similar problem exists with -vN approach, there is just less options available (say, 5 for -v,...,-vvvvv instead of $2^{\text{number of categories}}$
  2. If the categories exposed to users match the categories that anvil-zksync uses internally, that allows users to depend on our implementation details, therefore Hyrum's Law applies.

On the shell wrappers

I think this makes sense, but there are two levels of abstraction here:

  • for logging/tracing/events
  • for writing pretty text to streams

Let's be careful not to fusion them together, as otherwise implementing features like the proposed --json flag may be complicated.

@itegulov
Copy link
Contributor

itegulov commented Feb 5, 2025

Great write-up and initiative!

tracing's status in our code

Overall I agree with the main points and direction, but just wanted to make an amendment to the quote below:

v : Includes console logs, and meta logs (e.g. tracing::info!("created log filter '{:#x}'", self.id_counter);, impersonation changes )

I don't think the majority of tracing::info entries would be useful for users. With log filter for example, if an RPC call returned success then they can just assume a filter was created fine, not sure what extra information they would get from seeing that log. It is useful for us debugging why log filter is not being created though; to expand on @popzxc's point:

  • tracing is strictly for us (developers of anvil-zksync)
  • a wrapper over println! is both for us and users

A good way of thinking about whether a newly introduced log belongs to former or latter is asking yourself "would seeing this log under a certain verbosity level help user debug a bug in their contract/RPC request?". If no, then this is tracing::{level}. If yes, then it is shell::{level}. So IMHO -v should not enable tracing::info and, even further, tracing should be disabled entirely by default (I believe this is also anvil's behaviour). Maybe there is an argument for leaving ERROR level be.

At least this is roughly what I had in mind a few months back when we were discussing this.

shell wrapper

@sayon makes a great point here - lets make sure table printing is not an inherent property of the new logging mechanism and instead a way to serialize struct GasTable into both struct PrettyUserLog and struct JsonUserLog (just off the cuff names here obviously). Not suggesting a specific approach here, just noting that we would have to design a proper general API for this.

logging categories

I see merit in both having them and not having them so no strong opinion here. I will say though so far it feels like verbosity level only affects verbosity of VM tracers in which case it is more of a "linear" progression. To address @sayon's concern, I would move user L1 logs to -vv level so that -vvv and below would get progressively more and more "obscure" for an average user. Very unlikely someone cares for L1 system logs without also caring for all user logs first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants