From 79dbe7b1bfdb34c80b296c025a6c11f2c437d4ff Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Tue, 5 Nov 2024 12:19:58 -0300 Subject: [PATCH 01/18] initial commit --- ...34d167462ce5de6a9c240f990856be8c4c88.json} | 12 +++++++--- ...900a8e5e705543f529e48d9fe96c35ddde75.json} | 12 +++++++--- ...8d3973cf8ce53871a2fab4febac60bb56583.json} | 12 +++++++--- ...6cc4a3da487ee4a928de1513b13b7b918575.json} | 12 +++++++--- ...186551207484769344d211d6c9d2fc452ef3.json} | 12 +++++++--- ...1fca0e375f1309b34ce09a5beb8ed688c3ef.json} | 12 +++++++--- ...afd7240ef53d95408a0d38bff65f786b038a.json} | 12 +++++++--- ...277d67f184d29082a03bc70b9d95700e8c05.json} | 12 +++++++--- core/lib/dal/src/blocks_dal.rs | 24 ++++++++++++------- core/lib/dal/src/models/storage_block.rs | 2 ++ .../structures/commit_batch_info.rs | 11 ++++++++- core/lib/types/src/commitment/mod.rs | 2 ++ core/node/eth_sender/src/tests.rs | 1 + core/node/test_utils/src/lib.rs | 1 + 14 files changed, 104 insertions(+), 33 deletions(-) rename core/lib/dal/.sqlx/{query-77864e5eb5eada8edf8f4457aa153369701d7cd5f75ca031bf77ca27d0437cb9.json => query-1df6a0c44dafb0d8932e9c9162b634d167462ce5de6a9c240f990856be8c4c88.json} (88%) rename core/lib/dal/.sqlx/{query-a42121cd85daeb95ee268ba5cff1806fcc54d73216a7dc54be6ba210ef02d789.json => query-47c31073d726572d282232bf550f900a8e5e705543f529e48d9fe96c35ddde75.json} (80%) rename core/lib/dal/.sqlx/{query-c5aedd2b1871d8f6276a31482caa673e4b5bba059ebe07bbbb64578881db030b.json => query-57686ab3e929331f7efafff78fa48d3973cf8ce53871a2fab4febac60bb56583.json} (85%) rename core/lib/dal/.sqlx/{query-1cb61327bed4d65a3fc81aa2229e01396dacefc0cea8cbcf5807185eb00fc0f7.json => query-6d4746aab463789bdd3ccb251f6b6cc4a3da487ee4a928de1513b13b7b918575.json} (86%) rename core/lib/dal/.sqlx/{query-b7d448837439a3e3dfe73070d3c20e9c138d0a6d35e9ce7fc396c5e76fbc25dd.json => query-8a3f130f3b1309b30b3f23bc3cff186551207484769344d211d6c9d2fc452ef3.json} (81%) rename core/lib/dal/.sqlx/{query-4bd1a4e612d10f2ca26068c140442f38816f163a3e3fba4fdbb81076b969e970.json => query-96de8839bee7d58e2807f98101271fca0e375f1309b34ce09a5beb8ed688c3ef.json} (94%) rename core/lib/dal/.sqlx/{query-45154c2efc8d07c4f83ae3e229f9892118f5732374e62f35e27800422afb5746.json => query-af2bab04895e886343f80077af31afd7240ef53d95408a0d38bff65f786b038a.json} (78%) rename core/lib/dal/.sqlx/{query-62e8330881b73917394384adbf73911add046315e5f8877bc57a34e3dadf9e37.json => query-fa52ecb8ee44f02f8d5a2061266c277d67f184d29082a03bc70b9d95700e8c05.json} (86%) diff --git a/core/lib/dal/.sqlx/query-77864e5eb5eada8edf8f4457aa153369701d7cd5f75ca031bf77ca27d0437cb9.json b/core/lib/dal/.sqlx/query-1df6a0c44dafb0d8932e9c9162b634d167462ce5de6a9c240f990856be8c4c88.json similarity index 88% rename from core/lib/dal/.sqlx/query-77864e5eb5eada8edf8f4457aa153369701d7cd5f75ca031bf77ca27d0437cb9.json rename to core/lib/dal/.sqlx/query-1df6a0c44dafb0d8932e9c9162b634d167462ce5de6a9c240f990856be8c4c88.json index f4e08abe31c5..294799d4906c 100644 --- a/core/lib/dal/.sqlx/query-77864e5eb5eada8edf8f4457aa153369701d7cd5f75ca031bf77ca27d0437cb9.json +++ b/core/lib/dal/.sqlx/query-1df6a0c44dafb0d8932e9c9162b634d167462ce5de6a9c240f990856be8c4c88.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n system_logs,\n compressed_state_diffs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n WHERE\n is_sealed\n AND number = $1\n ", + "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n system_logs,\n compressed_state_diffs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data,\n data_availability.blob_id AS \"blob_id?\"\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n WHERE\n is_sealed\n AND number = $1\n ", "describe": { "columns": [ { @@ -162,6 +162,11 @@ "ordinal": 31, "name": "inclusion_data", "type_info": "Bytea" + }, + { + "ordinal": 32, + "name": "blob_id?", + "type_info": "Text" } ], "parameters": { @@ -201,8 +206,9 @@ true, true, true, - true + true, + false ] }, - "hash": "77864e5eb5eada8edf8f4457aa153369701d7cd5f75ca031bf77ca27d0437cb9" + "hash": "1df6a0c44dafb0d8932e9c9162b634d167462ce5de6a9c240f990856be8c4c88" } diff --git a/core/lib/dal/.sqlx/query-a42121cd85daeb95ee268ba5cff1806fcc54d73216a7dc54be6ba210ef02d789.json b/core/lib/dal/.sqlx/query-47c31073d726572d282232bf550f900a8e5e705543f529e48d9fe96c35ddde75.json similarity index 80% rename from core/lib/dal/.sqlx/query-a42121cd85daeb95ee268ba5cff1806fcc54d73216a7dc54be6ba210ef02d789.json rename to core/lib/dal/.sqlx/query-47c31073d726572d282232bf550f900a8e5e705543f529e48d9fe96c35ddde75.json index 9a93ba45978e..64dbd1dcd019 100644 --- a/core/lib/dal/.sqlx/query-a42121cd85daeb95ee268ba5cff1806fcc54d73216a7dc54be6ba210ef02d789.json +++ b/core/lib/dal/.sqlx/query-47c31073d726572d282232bf550f900a8e5e705543f529e48d9fe96c35ddde75.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n system_logs,\n compressed_state_diffs,\n protocol_version,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data\n FROM\n (\n SELECT\n l1_batches.*,\n ROW_NUMBER() OVER (\n ORDER BY\n number ASC\n ) AS row_number\n FROM\n l1_batches\n WHERE\n eth_commit_tx_id IS NOT NULL\n AND l1_batches.skip_proof = TRUE\n AND l1_batches.number > $1\n ORDER BY\n number\n LIMIT\n $2\n ) inn\n LEFT JOIN commitments ON commitments.l1_batch_number = inn.number\n LEFT JOIN data_availability ON data_availability.l1_batch_number = inn.number\n WHERE\n number - row_number = $1\n ", + "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n system_logs,\n compressed_state_diffs,\n protocol_version,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data,\n data_availability.blob_id AS \"blob_id?\"\n FROM\n (\n SELECT\n l1_batches.*,\n ROW_NUMBER() OVER (\n ORDER BY\n number ASC\n ) AS row_number\n FROM\n l1_batches\n WHERE\n eth_commit_tx_id IS NOT NULL\n AND l1_batches.skip_proof = TRUE\n AND l1_batches.number > $1\n ORDER BY\n number\n LIMIT\n $2\n ) inn\n LEFT JOIN commitments ON commitments.l1_batch_number = inn.number\n LEFT JOIN data_availability ON data_availability.l1_batch_number = inn.number\n WHERE\n number - row_number = $1\n ", "describe": { "columns": [ { @@ -162,6 +162,11 @@ "ordinal": 31, "name": "inclusion_data", "type_info": "Bytea" + }, + { + "ordinal": 32, + "name": "blob_id?", + "type_info": "Text" } ], "parameters": { @@ -202,8 +207,9 @@ true, true, true, - true + true, + false ] }, - "hash": "a42121cd85daeb95ee268ba5cff1806fcc54d73216a7dc54be6ba210ef02d789" + "hash": "47c31073d726572d282232bf550f900a8e5e705543f529e48d9fe96c35ddde75" } diff --git a/core/lib/dal/.sqlx/query-c5aedd2b1871d8f6276a31482caa673e4b5bba059ebe07bbbb64578881db030b.json b/core/lib/dal/.sqlx/query-57686ab3e929331f7efafff78fa48d3973cf8ce53871a2fab4febac60bb56583.json similarity index 85% rename from core/lib/dal/.sqlx/query-c5aedd2b1871d8f6276a31482caa673e4b5bba059ebe07bbbb64578881db030b.json rename to core/lib/dal/.sqlx/query-57686ab3e929331f7efafff78fa48d3973cf8ce53871a2fab4febac60bb56583.json index f97ea8a6ccd5..f310b82954da 100644 --- a/core/lib/dal/.sqlx/query-c5aedd2b1871d8f6276a31482caa673e4b5bba059ebe07bbbb64578881db030b.json +++ b/core/lib/dal/.sqlx/query-57686ab3e929331f7efafff78fa48d3973cf8ce53871a2fab4febac60bb56583.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n WHERE\n eth_prove_tx_id IS NOT NULL\n AND eth_execute_tx_id IS NULL\n ORDER BY\n number\n LIMIT\n $1\n ", + "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data,\n data_availability.blob_id AS \"blob_id?\"\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n WHERE\n eth_prove_tx_id IS NOT NULL\n AND eth_execute_tx_id IS NULL\n ORDER BY\n number\n LIMIT\n $1\n ", "describe": { "columns": [ { @@ -162,6 +162,11 @@ "ordinal": 31, "name": "inclusion_data", "type_info": "Bytea" + }, + { + "ordinal": 32, + "name": "blob_id?", + "type_info": "Text" } ], "parameters": { @@ -201,8 +206,9 @@ true, true, true, - true + true, + false ] }, - "hash": "c5aedd2b1871d8f6276a31482caa673e4b5bba059ebe07bbbb64578881db030b" + "hash": "57686ab3e929331f7efafff78fa48d3973cf8ce53871a2fab4febac60bb56583" } diff --git a/core/lib/dal/.sqlx/query-1cb61327bed4d65a3fc81aa2229e01396dacefc0cea8cbcf5807185eb00fc0f7.json b/core/lib/dal/.sqlx/query-6d4746aab463789bdd3ccb251f6b6cc4a3da487ee4a928de1513b13b7b918575.json similarity index 86% rename from core/lib/dal/.sqlx/query-1cb61327bed4d65a3fc81aa2229e01396dacefc0cea8cbcf5807185eb00fc0f7.json rename to core/lib/dal/.sqlx/query-6d4746aab463789bdd3ccb251f6b6cc4a3da487ee4a928de1513b13b7b918575.json index 48adcd412676..2dd50bd6b4d9 100644 --- a/core/lib/dal/.sqlx/query-1cb61327bed4d65a3fc81aa2229e01396dacefc0cea8cbcf5807185eb00fc0f7.json +++ b/core/lib/dal/.sqlx/query-6d4746aab463789bdd3ccb251f6b6cc4a3da487ee4a928de1513b13b7b918575.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n WHERE\n number = 0\n OR eth_commit_tx_id IS NOT NULL\n AND commitment IS NOT NULL\n ORDER BY\n number DESC\n LIMIT\n 1\n ", + "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data,\n data_availability.blob_id AS \"blob_id?\"\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n WHERE\n number = 0\n OR eth_commit_tx_id IS NOT NULL\n AND commitment IS NOT NULL\n ORDER BY\n number DESC\n LIMIT\n 1\n ", "describe": { "columns": [ { @@ -162,6 +162,11 @@ "ordinal": 31, "name": "inclusion_data", "type_info": "Bytea" + }, + { + "ordinal": 32, + "name": "blob_id?", + "type_info": "Text" } ], "parameters": { @@ -199,8 +204,9 @@ true, true, true, - true + true, + false ] }, - "hash": "1cb61327bed4d65a3fc81aa2229e01396dacefc0cea8cbcf5807185eb00fc0f7" + "hash": "6d4746aab463789bdd3ccb251f6b6cc4a3da487ee4a928de1513b13b7b918575" } diff --git a/core/lib/dal/.sqlx/query-b7d448837439a3e3dfe73070d3c20e9c138d0a6d35e9ce7fc396c5e76fbc25dd.json b/core/lib/dal/.sqlx/query-8a3f130f3b1309b30b3f23bc3cff186551207484769344d211d6c9d2fc452ef3.json similarity index 81% rename from core/lib/dal/.sqlx/query-b7d448837439a3e3dfe73070d3c20e9c138d0a6d35e9ce7fc396c5e76fbc25dd.json rename to core/lib/dal/.sqlx/query-8a3f130f3b1309b30b3f23bc3cff186551207484769344d211d6c9d2fc452ef3.json index 8a68b1a9b9bd..b95fb8c82321 100644 --- a/core/lib/dal/.sqlx/query-b7d448837439a3e3dfe73070d3c20e9c138d0a6d35e9ce7fc396c5e76fbc25dd.json +++ b/core/lib/dal/.sqlx/query-8a3f130f3b1309b30b3f23bc3cff186551207484769344d211d6c9d2fc452ef3.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n number,\n l1_batches.timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n l1_batches.bootloader_code_hash,\n l1_batches.default_aa_code_hash,\n l1_batches.evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n JOIN protocol_versions ON protocol_versions.id = l1_batches.protocol_version\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n WHERE\n eth_commit_tx_id IS NULL\n AND number != 0\n AND protocol_versions.bootloader_code_hash = $1\n AND protocol_versions.default_account_code_hash = $2\n AND commitment IS NOT NULL\n AND (\n protocol_versions.id = $3\n OR protocol_versions.upgrade_tx_hash IS NULL\n )\n ORDER BY\n number\n LIMIT\n $4\n ", + "query": "\n SELECT\n number,\n l1_batches.timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n l1_batches.bootloader_code_hash,\n l1_batches.default_aa_code_hash,\n l1_batches.evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data,\n data_availability.blob_id AS \"blob_id?\"\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n JOIN protocol_versions ON protocol_versions.id = l1_batches.protocol_version\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n WHERE\n eth_commit_tx_id IS NULL\n AND number != 0\n AND protocol_versions.bootloader_code_hash = $1\n AND protocol_versions.default_account_code_hash = $2\n AND commitment IS NOT NULL\n AND (\n protocol_versions.id = $3\n OR protocol_versions.upgrade_tx_hash IS NULL\n )\n ORDER BY\n number\n LIMIT\n $4\n ", "describe": { "columns": [ { @@ -162,6 +162,11 @@ "ordinal": 31, "name": "inclusion_data", "type_info": "Bytea" + }, + { + "ordinal": 32, + "name": "blob_id?", + "type_info": "Text" } ], "parameters": { @@ -204,8 +209,9 @@ true, true, true, - true + true, + false ] }, - "hash": "b7d448837439a3e3dfe73070d3c20e9c138d0a6d35e9ce7fc396c5e76fbc25dd" + "hash": "8a3f130f3b1309b30b3f23bc3cff186551207484769344d211d6c9d2fc452ef3" } diff --git a/core/lib/dal/.sqlx/query-4bd1a4e612d10f2ca26068c140442f38816f163a3e3fba4fdbb81076b969e970.json b/core/lib/dal/.sqlx/query-96de8839bee7d58e2807f98101271fca0e375f1309b34ce09a5beb8ed688c3ef.json similarity index 94% rename from core/lib/dal/.sqlx/query-4bd1a4e612d10f2ca26068c140442f38816f163a3e3fba4fdbb81076b969e970.json rename to core/lib/dal/.sqlx/query-96de8839bee7d58e2807f98101271fca0e375f1309b34ce09a5beb8ed688c3ef.json index 66d3e18075bf..e45f0ceb6ef9 100644 --- a/core/lib/dal/.sqlx/query-4bd1a4e612d10f2ca26068c140442f38816f163a3e3fba4fdbb81076b969e970.json +++ b/core/lib/dal/.sqlx/query-96de8839bee7d58e2807f98101271fca0e375f1309b34ce09a5beb8ed688c3ef.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n WHERE\n number BETWEEN $1 AND $2\n ORDER BY\n number\n LIMIT\n $3\n ", + "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data,\n data_availability.blob_id AS \"blob_id?\"\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n WHERE\n number BETWEEN $1 AND $2\n ORDER BY\n number\n LIMIT\n $3\n ", "describe": { "columns": [ { @@ -162,6 +162,11 @@ "ordinal": 31, "name": "inclusion_data", "type_info": "Bytea" + }, + { + "ordinal": 32, + "name": "blob_id?", + "type_info": "Text" } ], "parameters": { @@ -203,8 +208,9 @@ true, true, true, - true + true, + false ] }, - "hash": "4bd1a4e612d10f2ca26068c140442f38816f163a3e3fba4fdbb81076b969e970" + "hash": "96de8839bee7d58e2807f98101271fca0e375f1309b34ce09a5beb8ed688c3ef" } diff --git a/core/lib/dal/.sqlx/query-45154c2efc8d07c4f83ae3e229f9892118f5732374e62f35e27800422afb5746.json b/core/lib/dal/.sqlx/query-af2bab04895e886343f80077af31afd7240ef53d95408a0d38bff65f786b038a.json similarity index 78% rename from core/lib/dal/.sqlx/query-45154c2efc8d07c4f83ae3e229f9892118f5732374e62f35e27800422afb5746.json rename to core/lib/dal/.sqlx/query-af2bab04895e886343f80077af31afd7240ef53d95408a0d38bff65f786b038a.json index 11bff1102932..63b5a6501105 100644 --- a/core/lib/dal/.sqlx/query-45154c2efc8d07c4f83ae3e229f9892118f5732374e62f35e27800422afb5746.json +++ b/core/lib/dal/.sqlx/query-af2bab04895e886343f80077af31afd7240ef53d95408a0d38bff65f786b038a.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n number,\n l1_batches.timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n l1_batches.bootloader_code_hash,\n l1_batches.default_aa_code_hash,\n l1_batches.evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n JOIN protocol_versions ON protocol_versions.id = l1_batches.protocol_version\n WHERE\n eth_commit_tx_id IS NULL\n AND number != 0\n AND protocol_versions.bootloader_code_hash = $1\n AND protocol_versions.default_account_code_hash = $2\n AND commitment IS NOT NULL\n AND (\n protocol_versions.id = $3\n OR protocol_versions.upgrade_tx_hash IS NULL\n )\n AND events_queue_commitment IS NOT NULL\n AND bootloader_initial_content_commitment IS NOT NULL\n AND (\n data_availability.inclusion_data IS NOT NULL\n OR $4 IS FALSE\n )\n ORDER BY\n number\n LIMIT\n $5\n ", + "query": "\n SELECT\n number,\n l1_batches.timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n l1_batches.bootloader_code_hash,\n l1_batches.default_aa_code_hash,\n l1_batches.evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data,\n data_availability.blob_id AS \"blob_id?\"\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n JOIN protocol_versions ON protocol_versions.id = l1_batches.protocol_version\n WHERE\n eth_commit_tx_id IS NULL\n AND number != 0\n AND protocol_versions.bootloader_code_hash = $1\n AND protocol_versions.default_account_code_hash = $2\n AND commitment IS NOT NULL\n AND (\n protocol_versions.id = $3\n OR protocol_versions.upgrade_tx_hash IS NULL\n )\n AND events_queue_commitment IS NOT NULL\n AND bootloader_initial_content_commitment IS NOT NULL\n AND (\n data_availability.inclusion_data IS NOT NULL\n OR $4 IS FALSE\n )\n ORDER BY\n number\n LIMIT\n $5\n ", "describe": { "columns": [ { @@ -162,6 +162,11 @@ "ordinal": 31, "name": "inclusion_data", "type_info": "Bytea" + }, + { + "ordinal": 32, + "name": "blob_id?", + "type_info": "Text" } ], "parameters": { @@ -205,8 +210,9 @@ true, true, true, - true + true, + false ] }, - "hash": "45154c2efc8d07c4f83ae3e229f9892118f5732374e62f35e27800422afb5746" + "hash": "af2bab04895e886343f80077af31afd7240ef53d95408a0d38bff65f786b038a" } diff --git a/core/lib/dal/.sqlx/query-62e8330881b73917394384adbf73911add046315e5f8877bc57a34e3dadf9e37.json b/core/lib/dal/.sqlx/query-fa52ecb8ee44f02f8d5a2061266c277d67f184d29082a03bc70b9d95700e8c05.json similarity index 86% rename from core/lib/dal/.sqlx/query-62e8330881b73917394384adbf73911add046315e5f8877bc57a34e3dadf9e37.json rename to core/lib/dal/.sqlx/query-fa52ecb8ee44f02f8d5a2061266c277d67f184d29082a03bc70b9d95700e8c05.json index dfdb4b6c82e7..e2c6df469102 100644 --- a/core/lib/dal/.sqlx/query-62e8330881b73917394384adbf73911add046315e5f8877bc57a34e3dadf9e37.json +++ b/core/lib/dal/.sqlx/query-fa52ecb8ee44f02f8d5a2061266c277d67f184d29082a03bc70b9d95700e8c05.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n WHERE\n eth_commit_tx_id IS NOT NULL\n AND eth_prove_tx_id IS NULL\n ORDER BY\n number\n LIMIT\n $1\n ", + "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data,\n data_availability.blob_id AS \"blob_id?\"\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n WHERE\n eth_commit_tx_id IS NOT NULL\n AND eth_prove_tx_id IS NULL\n ORDER BY\n number\n LIMIT\n $1\n ", "describe": { "columns": [ { @@ -162,6 +162,11 @@ "ordinal": 31, "name": "inclusion_data", "type_info": "Bytea" + }, + { + "ordinal": 32, + "name": "blob_id?", + "type_info": "Text" } ], "parameters": { @@ -201,8 +206,9 @@ true, true, true, - true + true, + false ] }, - "hash": "62e8330881b73917394384adbf73911add046315e5f8877bc57a34e3dadf9e37" + "hash": "fa52ecb8ee44f02f8d5a2061266c277d67f184d29082a03bc70b9d95700e8c05" } diff --git a/core/lib/dal/src/blocks_dal.rs b/core/lib/dal/src/blocks_dal.rs index 943aa12caf75..697514535193 100644 --- a/core/lib/dal/src/blocks_dal.rs +++ b/core/lib/dal/src/blocks_dal.rs @@ -348,7 +348,8 @@ impl BlocksDal<'_, '_> { aggregation_root, local_root, state_diff_hash, - data_availability.inclusion_data + data_availability.inclusion_data, + data_availability.blob_id AS "blob_id?" FROM l1_batches LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number @@ -1219,7 +1220,8 @@ impl BlocksDal<'_, '_> { aggregation_root, local_root, state_diff_hash, - data_availability.inclusion_data + data_availability.inclusion_data, + data_availability.blob_id AS "blob_id?" FROM l1_batches LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number @@ -1414,7 +1416,8 @@ impl BlocksDal<'_, '_> { aggregation_root, local_root, state_diff_hash, - data_availability.inclusion_data + data_availability.inclusion_data, + data_availability.blob_id AS "blob_id?" FROM l1_batches LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number @@ -1503,7 +1506,8 @@ impl BlocksDal<'_, '_> { aggregation_root, local_root, state_diff_hash, - data_availability.inclusion_data + data_availability.inclusion_data, + data_availability.blob_id AS "blob_id?" FROM ( SELECT @@ -1583,7 +1587,8 @@ impl BlocksDal<'_, '_> { aggregation_root, local_root, state_diff_hash, - data_availability.inclusion_data + data_availability.inclusion_data, + data_availability.blob_id AS "blob_id?" FROM l1_batches LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number @@ -1719,7 +1724,8 @@ impl BlocksDal<'_, '_> { aggregation_root, local_root, state_diff_hash, - data_availability.inclusion_data + data_availability.inclusion_data, + data_availability.blob_id AS "blob_id?" FROM l1_batches LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number @@ -1792,7 +1798,8 @@ impl BlocksDal<'_, '_> { aggregation_root, local_root, state_diff_hash, - data_availability.inclusion_data + data_availability.inclusion_data, + data_availability.blob_id AS "blob_id?" FROM l1_batches LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number @@ -1879,7 +1886,8 @@ impl BlocksDal<'_, '_> { aggregation_root, local_root, state_diff_hash, - data_availability.inclusion_data + data_availability.inclusion_data, + data_availability.blob_id AS "blob_id?" FROM l1_batches LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number diff --git a/core/lib/dal/src/models/storage_block.rs b/core/lib/dal/src/models/storage_block.rs index 159ed71cc3e9..95625c8b2955 100644 --- a/core/lib/dal/src/models/storage_block.rs +++ b/core/lib/dal/src/models/storage_block.rs @@ -159,6 +159,7 @@ pub(crate) struct StorageL1Batch { pub local_root: Option>, pub state_diff_hash: Option>, pub inclusion_data: Option>, + pub blob_id: Option, } impl StorageL1Batch { @@ -271,6 +272,7 @@ impl TryFrom for L1BatchMetadata { local_root: batch.local_root.map(|v| H256::from_slice(&v)), aggregation_root: batch.aggregation_root.map(|v| H256::from_slice(&v)), da_inclusion_data: batch.inclusion_data, + da_blob_id: batch.blob_id.map(|s| s.into_bytes()), }) } } diff --git a/core/lib/l1_contract_interface/src/i_executor/structures/commit_batch_info.rs b/core/lib/l1_contract_interface/src/i_executor/structures/commit_batch_info.rs index 6438aeb7f55c..3c8a3b26b935 100644 --- a/core/lib/l1_contract_interface/src/i_executor/structures/commit_batch_info.rs +++ b/core/lib/l1_contract_interface/src/i_executor/structures/commit_batch_info.rs @@ -216,7 +216,16 @@ impl Tokenizable for CommitBatchInfo<'_> { panic!("Custom pubdata DA is incompatible with Rollup mode") } (L1BatchCommitmentMode::Validium, PubdataSendingMode::Custom) => { - vec![PUBDATA_SOURCE_CUSTOM] + let mut operator_da_input = vec![PUBDATA_SOURCE_CUSTOM]; + operator_da_input.extend( + &self + .l1_batch_with_metadata + .metadata + .da_blob_id + .clone() + .unwrap_or_default(), + ); + operator_da_input } ( diff --git a/core/lib/types/src/commitment/mod.rs b/core/lib/types/src/commitment/mod.rs index 40532a1e5899..0dbea4742c3d 100644 --- a/core/lib/types/src/commitment/mod.rs +++ b/core/lib/types/src/commitment/mod.rs @@ -103,6 +103,8 @@ pub struct L1BatchMetadata { pub aggregation_root: Option, /// Data Availability inclusion proof, that has to be verified on the settlement layer. pub da_inclusion_data: Option>, + /// Data Availability blob id, persisted in L1 so it can be used for chain reconstruction. + pub da_blob_id: Option>, } impl L1BatchMetadata { diff --git a/core/node/eth_sender/src/tests.rs b/core/node/eth_sender/src/tests.rs index 8e5032a69cfc..6a21767f4ea3 100644 --- a/core/node/eth_sender/src/tests.rs +++ b/core/node/eth_sender/src/tests.rs @@ -130,6 +130,7 @@ pub(crate) fn default_l1_batch_metadata() -> L1BatchMetadata { local_root: Some(H256::default()), aggregation_root: Some(H256::default()), da_inclusion_data: Some(vec![]), + da_blob_id: Some(vec![]), } } diff --git a/core/node/test_utils/src/lib.rs b/core/node/test_utils/src/lib.rs index 86ce3aadd9a1..6cfcaa12bacc 100644 --- a/core/node/test_utils/src/lib.rs +++ b/core/node/test_utils/src/lib.rs @@ -103,6 +103,7 @@ pub fn create_l1_batch_metadata(number: u32) -> L1BatchMetadata { local_root: Some(H256::zero()), aggregation_root: Some(H256::zero()), da_inclusion_data: Some(vec![]), + da_blob_id: Some(vec![]), } } From 0c7b29e0093e4e924648c94ad9b106e8c97027d4 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Tue, 5 Nov 2024 14:24:09 -0300 Subject: [PATCH 02/18] add get_all_blobs --- get_all_blobs/Makefile | 15 + get_all_blobs/README.md | 19 + get_all_blobs/getallblobs.js | 257 ++++++++++ get_all_blobs/package-lock.json | 866 ++++++++++++++++++++++++++++++++ get_all_blobs/package.json | 15 + 5 files changed, 1172 insertions(+) create mode 100644 get_all_blobs/Makefile create mode 100644 get_all_blobs/README.md create mode 100644 get_all_blobs/getallblobs.js create mode 100644 get_all_blobs/package-lock.json create mode 100644 get_all_blobs/package.json diff --git a/get_all_blobs/Makefile b/get_all_blobs/Makefile new file mode 100644 index 000000000000..f68a70973dac --- /dev/null +++ b/get_all_blobs/Makefile @@ -0,0 +1,15 @@ +.PHONY: install getallblobs + +install: + npm install + +getallblobs: install + @if [ -z "$(VALIDATOR_TIMELOCK_ADDR)" ]; then \ + echo "Error: VALIDATOR_TIMELOCK_ADDR is not set"; \ + exit 1; \ + fi + @if [ -z "$(COMMIT_BATCHES_SB_FUNC_SELECTOR)" ]; then \ + echo "Error: COMMIT_BATCHES_SB_FUNC_SELECTOR is not set"; \ + exit 1; \ + fi + node getallblobs.js validatorTimelockAddress=$(VALIDATOR_TIMELOCK_ADDR) commitBatchesSharedBridge_functionSelector=$(COMMIT_BATCHES_SB_FUNC_SELECTOR) diff --git a/get_all_blobs/README.md b/get_all_blobs/README.md new file mode 100644 index 000000000000..c2b2fcb0bb27 --- /dev/null +++ b/get_all_blobs/README.md @@ -0,0 +1,19 @@ +# Get All Blobs + +This script retrieves all blobs commitments directly from L1. + +To make use of this tool, you need to have `make` and `npm` installed. + +### Run command: +``` +make getallblobs VALIDATOR_TIMELOCK_ADDR= COMMIT_BATCHES_SB_FUNC_SELECTOR= +``` + +This generates a `blob_data.json` file, where blobs and commitments are stored. + +### Environment Variables +`VALIDATOR_TIMELOCK_ADDR`: The address of the validator timelock. Check the value in `zkstack init` if running a local node. + +`COMMIT_BATCHES_SB_FUNC_SELECTOR`: The function selector for commitBatchesSharedBridge. For a local node, this is typically 0x6edd4f12. + +This variables can be exported in the shell in order to run `make getallblobs` without passing them as arguments. diff --git a/get_all_blobs/getallblobs.js b/get_all_blobs/getallblobs.js new file mode 100644 index 000000000000..e731ed2aa5c4 --- /dev/null +++ b/get_all_blobs/getallblobs.js @@ -0,0 +1,257 @@ +const { Web3 } = require('web3'); +const web3 = new Web3('http://127.0.0.1:8545'); +const fs = require('fs'); + +const abi = [ + { + inputs: [ + { + internalType: 'uint256', + name: '_chainId', + type: 'uint256' + }, + { + components: [ + { + internalType: 'uint64', + name: 'batchNumber', + type: 'uint64' + }, + { + internalType: 'bytes32', + name: 'batchHash', + type: 'bytes32' + }, + { + internalType: 'uint64', + name: 'indexRepeatedStorageChanges', + type: 'uint64' + }, + { + internalType: 'uint256', + name: 'numberOfLayer1Txs', + type: 'uint256' + }, + { + internalType: 'bytes32', + name: 'priorityOperationsHash', + type: 'bytes32' + }, + { + internalType: 'bytes32', + name: 'l2LogsTreeRoot', + type: 'bytes32' + }, + { + internalType: 'uint256', + name: 'timestamp', + type: 'uint256' + }, + { + internalType: 'bytes32', + name: 'commitment', + type: 'bytes32' + } + ], + internalType: 'struct IExecutor.StoredBatchInfo', + name: '', + type: 'tuple' + }, + { + components: [ + { + internalType: 'uint64', + name: 'batchNumber', + type: 'uint64' + }, + { + internalType: 'uint64', + name: 'timestamp', + type: 'uint64' + }, + { + internalType: 'uint64', + name: 'indexRepeatedStorageChanges', + type: 'uint64' + }, + { + internalType: 'bytes32', + name: 'newStateRoot', + type: 'bytes32' + }, + { + internalType: 'uint256', + name: 'numberOfLayer1Txs', + type: 'uint256' + }, + { + internalType: 'bytes32', + name: 'priorityOperationsHash', + type: 'bytes32' + }, + { + internalType: 'bytes32', + name: 'bootloaderHeapInitialContentsHash', + type: 'bytes32' + }, + { + internalType: 'bytes32', + name: 'eventsQueueStateHash', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: 'systemLogs', + type: 'bytes' + }, + { + internalType: 'bytes', + name: 'pubdataCommitments', + type: 'bytes' + } + ], + internalType: 'struct IExecutor.CommitBatchInfo[]', + name: '_newBatchesData', + type: 'tuple[]' + } + ], + name: 'commitBatchesSharedBridge', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + } +]; + +const contract = new web3.eth.Contract(abi); + +function hexToUtf8(hex) { + // Remove the '0x' prefix if present + if (hex.startsWith('0x')) { + hex = hex.slice(2); + } + + // Ensure the hex string has an even length + if (hex.length % 2 !== 0) { + throw new Error('Invalid hex string length'); + } + + // Convert hex string to a byte array + const bytes = []; + for (let i = 0; i < hex.length; i += 2) { + bytes.push(parseInt(hex.substr(i, 2), 16)); + } + + // Convert byte array to UTF-8 string + const utf8String = new TextDecoder('utf-8').decode(new Uint8Array(bytes)); + return utf8String; +} + +function uint8ArrayToHex(uint8Array) { + return Array.from(uint8Array) + .map((byte) => byte.toString(16).padStart(2, '0')) // Convert each byte to a 2-digit hex value + .join(''); // Join all the hex values into a single string +} + +async function getTransactions(validatorTimelockAddress, commitBatchesSharedBridge_functionSelector) { + const latestBlock = await web3.eth.getBlockNumber(); + let jsonArray = []; + for (let i = 0; i <= latestBlock; i++) { + const block = await web3.eth.getBlock(i, true); + await Promise.all( + block.transactions.map(async (tx) => { + if (tx.to && tx.to.toLowerCase() == validatorTimelockAddress.toLowerCase()) { + const input = tx.input; + const txSelector = input.slice(0, 10); + if (txSelector == commitBatchesSharedBridge_functionSelector) { + const functionAbi = contract.options.jsonInterface.find( + (item) => item.name === 'commitBatchesSharedBridge' + ); + const decodedParams = web3.eth.abi.decodeParameters( + functionAbi.inputs, + input.slice(10) // Remove the function selector (first 10 characters of the calldata) + ); + commitment = hexToUtf8(decodedParams._newBatchesData[0].pubdataCommitments.slice(4)); + let blob = await get(commitment); + const blobHex = uint8ArrayToHex(blob); + jsonArray.push({ + commitment: commitment, + blob: blobHex + }); + } + } + }) + ); + } + if (jsonArray.length == 0) { + console.error("No transactions found."); + return; + } + const jsonString = JSON.stringify(jsonArray, null, 2); + fs.writeFileSync('blob_data.json', jsonString, 'utf8'); + console.log("Data stored in blob_data.json file."); +} + +async function get(commitment) { + try { + const url = `http://localhost:4242/get/0x${commitment}`; + + const response = await fetch(url); + + if (response.ok) { + // Expecting the response body to be binary data + const body = await response.arrayBuffer(); + return new Uint8Array(body); + } else { + return []; // Return empty array if the response is not successful + } + } catch (error) { + // Handle any errors + console.error('Error fetching data:', error); + throw error; // Re-throw the error or return an empty array, depending on requirements + } +} + +function getArguments() { + const args = process.argv.slice(2); // Get arguments after the first two (which are node and script path) + + let validatorTimelockAddress = null; + let commitBatchesSharedBridge_functionSelector = null; + args.forEach((arg) => { + const [key, value] = arg.split('='); + if (key === 'validatorTimelockAddress') { + validatorTimelockAddress = value; + } else if (key === 'commitBatchesSharedBridge_functionSelector') { + commitBatchesSharedBridge_functionSelector = value; + } + }); + + // Check if both arguments are provided + if (!validatorTimelockAddress || !commitBatchesSharedBridge_functionSelector) { + console.error( + 'Usage: node getallblobs.js validatorTimelockAddress= commitBatchesSharedBridge_functionSelector=' + ); + process.exit(1); // Exit with error + } + + return { validatorTimelockAddress, commitBatchesSharedBridge_functionSelector }; +} + +function main() { + // Values for local node: + // validatorTimelockAddress = check in zk init + // commitBatchesSharedBridge_functionSelector = "0x6edd4f12" + const { validatorTimelockAddress, commitBatchesSharedBridge_functionSelector } = getArguments(); + getTransactions(validatorTimelockAddress, commitBatchesSharedBridge_functionSelector); +} + +main(); + +//Contracts being called in L1: +//Chain Admin +//Diamond Proxy +//Governance +//Validator Timelock //6edd4f12 function selector commitBatchesSharedBridge +//BridgeHub Proxy +//Transparent Proxy +//Create2 Factory +//Contracts Create2Factory (verifier) diff --git a/get_all_blobs/package-lock.json b/get_all_blobs/package-lock.json new file mode 100644 index 000000000000..c04d8c6632a2 --- /dev/null +++ b/get_all_blobs/package-lock.json @@ -0,0 +1,866 @@ +{ + "name": "get_all_blobs", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "get_all_blobs", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "web3": "^4.12.1" + } + }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.0.tgz", + "integrity": "sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==" + }, + "node_modules/@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "bin": { + "rlp": "bin/rlp" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "dependencies": { + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@types/node": { + "version": "22.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", + "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", + "dependencies": { + "undici-types": "~6.19.8" + } + }, + "node_modules/@types/ws": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", + "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/abitype": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-0.7.1.tgz", + "integrity": "sha512-VBkRHTDZf9Myaek/dO3yMmOzB/y2s3Zo6nVU7yaw1G+TvCHAjwaJzNGN9yo4K5D8bU/VZXKP1EJpRhFr862PlQ==", + "peerDependencies": { + "typescript": ">=4.9.4", + "zod": "^3 >=3.19.1" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + } + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/cross-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "dependencies": { + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isomorphic-ws": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", + "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/web3": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/web3/-/web3-4.14.0.tgz", + "integrity": "sha512-LohqxtSXXl4uA3abPK0bB91dziA5GygOLtO83p8bQzY+CYxp1fgGfiD8ahDRcu+WBttUhRFZmCsOhmrmP7HtTA==", + "dependencies": { + "web3-core": "^4.7.0", + "web3-errors": "^1.3.0", + "web3-eth": "^4.10.0", + "web3-eth-abi": "^4.3.0", + "web3-eth-accounts": "^4.2.1", + "web3-eth-contract": "^4.7.0", + "web3-eth-ens": "^4.4.0", + "web3-eth-iban": "^4.0.7", + "web3-eth-personal": "^4.1.0", + "web3-net": "^4.1.0", + "web3-providers-http": "^4.2.0", + "web3-providers-ws": "^4.0.8", + "web3-rpc-methods": "^1.3.0", + "web3-rpc-providers": "^1.0.0-rc.2", + "web3-types": "^1.8.1", + "web3-utils": "^4.3.2", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14.0.0", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-4.7.0.tgz", + "integrity": "sha512-skP4P56fhlrE+rIuS4WY9fTdja1DPml2xrrDmv+vQhPtmSFBs7CqesycIRLQh4dK1D4de/a23tkX6DLYdUt3nA==", + "dependencies": { + "web3-errors": "^1.3.0", + "web3-eth-accounts": "^4.2.1", + "web3-eth-iban": "^4.0.7", + "web3-providers-http": "^4.2.0", + "web3-providers-ws": "^4.0.8", + "web3-types": "^1.8.1", + "web3-utils": "^4.3.2", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + }, + "optionalDependencies": { + "web3-providers-ipc": "^4.0.7" + } + }, + "node_modules/web3-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/web3-errors/-/web3-errors-1.3.0.tgz", + "integrity": "sha512-j5JkAKCtuVMbY3F5PYXBqg1vWrtF4jcyyMY1rlw8a4PV67AkqlepjGgpzWJZd56Mt+TvHy6DA1F/3Id8LatDSQ==", + "dependencies": { + "web3-types": "^1.7.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-eth": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-4.10.0.tgz", + "integrity": "sha512-8d7epCOm1hv/xGnOW8pWNkO5Ze9b+LKl81Pa1VUdRi2xZKtBaQsk+4qg6EnqeDF6SPpL502wNmX6TAB69vGBWw==", + "dependencies": { + "setimmediate": "^1.0.5", + "web3-core": "^4.7.0", + "web3-errors": "^1.3.0", + "web3-eth-abi": "^4.3.0", + "web3-eth-accounts": "^4.2.1", + "web3-net": "^4.1.0", + "web3-providers-ws": "^4.0.8", + "web3-rpc-methods": "^1.3.0", + "web3-types": "^1.8.1", + "web3-utils": "^4.3.2", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-eth-abi": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-4.3.0.tgz", + "integrity": "sha512-OqZPGGxHmfKJt33BfpclEMmWvnnLJ/B+jVTnVagd2OIU1kIv09xf/E60ei0eGeG612uFy/pPq31u4RidF/gf6g==", + "dependencies": { + "abitype": "0.7.1", + "web3-errors": "^1.3.0", + "web3-types": "^1.8.1", + "web3-utils": "^4.3.2", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-eth-accounts": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-4.2.1.tgz", + "integrity": "sha512-aOlEZFzqAgKprKs7+DGArU4r9b+ILBjThpeq42aY7LAQcP+mSpsWcQgbIRK3r/n3OwTYZ3aLPk0Ih70O/LwnYA==", + "dependencies": { + "@ethereumjs/rlp": "^4.0.1", + "crc-32": "^1.2.2", + "ethereum-cryptography": "^2.0.0", + "web3-errors": "^1.3.0", + "web3-types": "^1.7.0", + "web3-utils": "^4.3.1", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-eth-contract": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-4.7.0.tgz", + "integrity": "sha512-fdStoBOjFyMHwlyJmSUt/BTDL1ATwKGmG3zDXQ/zTKlkkW/F/074ut0Vry4GuwSBg9acMHc0ycOiZx9ZKjNHsw==", + "dependencies": { + "@ethereumjs/rlp": "^5.0.2", + "web3-core": "^4.5.1", + "web3-errors": "^1.3.0", + "web3-eth": "^4.8.2", + "web3-eth-abi": "^4.2.3", + "web3-types": "^1.7.0", + "web3-utils": "^4.3.1", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethereumjs/rlp": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-5.0.2.tgz", + "integrity": "sha512-DziebCdg4JpGlEqEdGgXmjqcFoJi+JGulUXwEjsZGAscAQ7MyD/7LE/GVCP29vEQxKc7AAwjT3A2ywHp2xfoCA==", + "bin": { + "rlp": "bin/rlp.cjs" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/web3-eth-ens": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-4.4.0.tgz", + "integrity": "sha512-DeyVIS060hNV9g8dnTx92syqvgbvPricE3MerCxe/DquNZT3tD8aVgFfq65GATtpCgDDJffO2bVeHp3XBemnSQ==", + "dependencies": { + "@adraffy/ens-normalize": "^1.8.8", + "web3-core": "^4.5.0", + "web3-errors": "^1.2.0", + "web3-eth": "^4.8.0", + "web3-eth-contract": "^4.5.0", + "web3-net": "^4.1.0", + "web3-types": "^1.7.0", + "web3-utils": "^4.3.0", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-eth-iban": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-4.0.7.tgz", + "integrity": "sha512-8weKLa9KuKRzibC87vNLdkinpUE30gn0IGY027F8doeJdcPUfsa4IlBgNC4k4HLBembBB2CTU0Kr/HAOqMeYVQ==", + "dependencies": { + "web3-errors": "^1.1.3", + "web3-types": "^1.3.0", + "web3-utils": "^4.0.7", + "web3-validator": "^2.0.3" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-eth-personal": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-4.1.0.tgz", + "integrity": "sha512-RFN83uMuvA5cu1zIwwJh9A/bAj0OBxmGN3tgx19OD/9ygeUZbifOL06jgFzN0t+1ekHqm3DXYQM8UfHpXi7yDQ==", + "dependencies": { + "web3-core": "^4.6.0", + "web3-eth": "^4.9.0", + "web3-rpc-methods": "^1.3.0", + "web3-types": "^1.8.0", + "web3-utils": "^4.3.1", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-net": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-4.1.0.tgz", + "integrity": "sha512-WWmfvHVIXWEoBDWdgKNYKN8rAy6SgluZ0abyRyXOL3ESr7ym7pKWbfP4fjApIHlYTh8tNqkrdPfM4Dyi6CA0SA==", + "dependencies": { + "web3-core": "^4.4.0", + "web3-rpc-methods": "^1.3.0", + "web3-types": "^1.6.0", + "web3-utils": "^4.3.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-providers-http": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-4.2.0.tgz", + "integrity": "sha512-IPMnDtHB7dVwaB7/mMxAZzyq7d5ezfO1+Vw0bNfAeIi7gaDlJiggp85SdyAfOgov8AMUA/dyiY72kQ0KmjXKvQ==", + "dependencies": { + "cross-fetch": "^4.0.0", + "web3-errors": "^1.3.0", + "web3-types": "^1.7.0", + "web3-utils": "^4.3.1" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-providers-ipc": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-4.0.7.tgz", + "integrity": "sha512-YbNqY4zUvIaK2MHr1lQFE53/8t/ejHtJchrWn9zVbFMGXlTsOAbNoIoZWROrg1v+hCBvT2c9z8xt7e/+uz5p1g==", + "optional": true, + "dependencies": { + "web3-errors": "^1.1.3", + "web3-types": "^1.3.0", + "web3-utils": "^4.0.7" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-providers-ws": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-4.0.8.tgz", + "integrity": "sha512-goJdgata7v4pyzHRsg9fSegUG4gVnHZSHODhNnn6J93ykHkBI1nz4fjlGpcQLUMi4jAMz6SHl9Ibzs2jj9xqPw==", + "dependencies": { + "@types/ws": "8.5.3", + "isomorphic-ws": "^5.0.0", + "web3-errors": "^1.2.0", + "web3-types": "^1.7.0", + "web3-utils": "^4.3.1", + "ws": "^8.17.1" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-rpc-methods": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/web3-rpc-methods/-/web3-rpc-methods-1.3.0.tgz", + "integrity": "sha512-/CHmzGN+IYgdBOme7PdqzF+FNeMleefzqs0LVOduncSaqsppeOEoskLXb2anSpzmQAP3xZJPaTrkQPWSJMORig==", + "dependencies": { + "web3-core": "^4.4.0", + "web3-types": "^1.6.0", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-rpc-providers": { + "version": "1.0.0-rc.2", + "resolved": "https://registry.npmjs.org/web3-rpc-providers/-/web3-rpc-providers-1.0.0-rc.2.tgz", + "integrity": "sha512-ocFIEXcBx/DYQ90HhVepTBUVnL9pGsZw8wyPb1ZINSenwYus9SvcFkjU1Hfvd/fXjuhAv2bUVch9vxvMx1mXAQ==", + "dependencies": { + "web3-errors": "^1.3.0", + "web3-providers-http": "^4.2.0", + "web3-providers-ws": "^4.0.8", + "web3-types": "^1.7.0", + "web3-utils": "^4.3.1", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-types": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/web3-types/-/web3-types-1.8.1.tgz", + "integrity": "sha512-isspsvQbBJFUkJYz2Badb7dz/BrLLLpOop/WmnL5InyYMr7kYYc8038NYO7Vkp1M7Bupa/wg+yALvBm7EGbyoQ==", + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-utils": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-4.3.2.tgz", + "integrity": "sha512-bEFpYEBMf6ER78Uvj2mdsCbaLGLK9kABOsa3TtXOEEhuaMy/RK0KlRkKoZ2vmf/p3hB8e1q5erknZ6Hy7AVp7A==", + "dependencies": { + "ethereum-cryptography": "^2.0.0", + "eventemitter3": "^5.0.1", + "web3-errors": "^1.3.0", + "web3-types": "^1.8.1", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/web3-validator/-/web3-validator-2.0.6.tgz", + "integrity": "sha512-qn9id0/l1bWmvH4XfnG/JtGKKwut2Vokl6YXP5Kfg424npysmtRLe9DgiNBM9Op7QL/aSiaA0TVXibuIuWcizg==", + "dependencies": { + "ethereum-cryptography": "^2.0.0", + "util": "^0.12.5", + "web3-errors": "^1.2.0", + "web3-types": "^1.6.0", + "zod": "^3.21.4" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/get_all_blobs/package.json b/get_all_blobs/package.json new file mode 100644 index 000000000000..2f3f16d0b2c1 --- /dev/null +++ b/get_all_blobs/package.json @@ -0,0 +1,15 @@ +{ + "name": "get_all_blobs", + "version": "1.0.0", + "description": "", + "main": "getallblobs.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "web3": "^4.12.1" + } +} From 4752116723259f530f097d9e11ba9c87651da848 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Tue, 5 Nov 2024 14:24:51 -0300 Subject: [PATCH 03/18] get_all_blobs fmt --- get_all_blobs/README.md | 8 ++++++-- get_all_blobs/getallblobs.js | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/get_all_blobs/README.md b/get_all_blobs/README.md index c2b2fcb0bb27..5139ea0b044c 100644 --- a/get_all_blobs/README.md +++ b/get_all_blobs/README.md @@ -5,6 +5,7 @@ This script retrieves all blobs commitments directly from L1. To make use of this tool, you need to have `make` and `npm` installed. ### Run command: + ``` make getallblobs VALIDATOR_TIMELOCK_ADDR= COMMIT_BATCHES_SB_FUNC_SELECTOR= ``` @@ -12,8 +13,11 @@ make getallblobs VALIDATOR_TIMELOCK_ADDR= COMMIT_BATCH This generates a `blob_data.json` file, where blobs and commitments are stored. ### Environment Variables -`VALIDATOR_TIMELOCK_ADDR`: The address of the validator timelock. Check the value in `zkstack init` if running a local node. -`COMMIT_BATCHES_SB_FUNC_SELECTOR`: The function selector for commitBatchesSharedBridge. For a local node, this is typically 0x6edd4f12. +`VALIDATOR_TIMELOCK_ADDR`: The address of the validator timelock. Check the value in `zkstack init` if running a local +node. + +`COMMIT_BATCHES_SB_FUNC_SELECTOR`: The function selector for commitBatchesSharedBridge. For a local node, this is +typically 0x6edd4f12. This variables can be exported in the shell in order to run `make getallblobs` without passing them as arguments. diff --git a/get_all_blobs/getallblobs.js b/get_all_blobs/getallblobs.js index e731ed2aa5c4..6475d443216e 100644 --- a/get_all_blobs/getallblobs.js +++ b/get_all_blobs/getallblobs.js @@ -183,12 +183,12 @@ async function getTransactions(validatorTimelockAddress, commitBatchesSharedBrid ); } if (jsonArray.length == 0) { - console.error("No transactions found."); + console.error('No transactions found.'); return; } const jsonString = JSON.stringify(jsonArray, null, 2); fs.writeFileSync('blob_data.json', jsonString, 'utf8'); - console.log("Data stored in blob_data.json file."); + console.log('Data stored in blob_data.json file.'); } async function get(commitment) { From b7ae63df1c12a58d13746a1e3a14d4a37a28cb75 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Tue, 5 Nov 2024 14:30:29 -0300 Subject: [PATCH 04/18] add colored output --- get_all_blobs/getallblobs.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/get_all_blobs/getallblobs.js b/get_all_blobs/getallblobs.js index 6475d443216e..79a5e4a8c4b8 100644 --- a/get_all_blobs/getallblobs.js +++ b/get_all_blobs/getallblobs.js @@ -183,12 +183,12 @@ async function getTransactions(validatorTimelockAddress, commitBatchesSharedBrid ); } if (jsonArray.length == 0) { - console.error('No transactions found.'); + console.error('\x1b[31m%s\x1b[0m', 'No transactions found.'); return; } const jsonString = JSON.stringify(jsonArray, null, 2); fs.writeFileSync('blob_data.json', jsonString, 'utf8'); - console.log('Data stored in blob_data.json file.'); + console.log('\x1b[32m%s\x1b[0m', 'Data stored in blob_data.json file.'); } async function get(commitment) { From daae8af0f79cc9a82932aa644ff08f9c1b4c0962 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Tue, 5 Nov 2024 16:05:03 -0300 Subject: [PATCH 05/18] update contracts submodule --- contracts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts b/contracts index 84d5e3716f64..6cb0da8abd85 160000 --- a/contracts +++ b/contracts @@ -1 +1 @@ -Subproject commit 84d5e3716f645909e8144c7d50af9dd6dd9ded62 +Subproject commit 6cb0da8abd850389b8d886288dfc5d64dcf409d1 From 56daed3a7fb66f3f4971e9f94bd8c6f295566b45 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Tue, 5 Nov 2024 16:14:58 -0300 Subject: [PATCH 06/18] add proxy to get_all_blobs --- get_all_blobs/.gitignore | 1 + get_all_blobs/Makefile | 24 +++++++++++++++++++++++- get_all_blobs/README.md | 16 ++++++++++++++-- 3 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 get_all_blobs/.gitignore diff --git a/get_all_blobs/.gitignore b/get_all_blobs/.gitignore new file mode 100644 index 000000000000..cb0d0200b31e --- /dev/null +++ b/get_all_blobs/.gitignore @@ -0,0 +1 @@ +eigenda-proxy/ diff --git a/get_all_blobs/Makefile b/get_all_blobs/Makefile index f68a70973dac..fce6910b5248 100644 --- a/get_all_blobs/Makefile +++ b/get_all_blobs/Makefile @@ -3,7 +3,29 @@ install: npm install -getallblobs: install +clone-proxy: + @if [ ! -d eigenda-proxy ]; then \ + git clone https://github.com/Layr-Labs/eigenda-proxy.git; \ + fi + +setup-proxy: clone-proxy + @echo "Installing proxy dependencies" + cd eigenda-proxy && make + +run-proxy: setup-proxy + @if [ -z "$(PRIVATE_KEY)" ]; then \ + echo "Error: PRIVATE_KEY is not set"; \ + exit 1; \ + fi + cd eigenda-proxy && ./bin/eigenda-proxy \ + --addr 127.0.0.1 \ + --port 4242 \ + --eigenda.disperser-rpc disperser-holesky.eigenda.xyz:443 \ + --eigenda.signer-private-key-hex $(PRIVATE_KEY) \ + --eigenda.eth-rpc https://ethereum-holesky-rpc.publicnode.com \ + --eigenda.svc-manager-addr 0xD4A7E1Bd8015057293f0D0A557088c286942e84b + +get-all-blobs: install @if [ -z "$(VALIDATOR_TIMELOCK_ADDR)" ]; then \ echo "Error: VALIDATOR_TIMELOCK_ADDR is not set"; \ exit 1; \ diff --git a/get_all_blobs/README.md b/get_all_blobs/README.md index 5139ea0b044c..c71c88926594 100644 --- a/get_all_blobs/README.md +++ b/get_all_blobs/README.md @@ -1,13 +1,25 @@ # Get All Blobs -This script retrieves all blobs commitments directly from L1. +This script retrieves all blobs commitments directly from L1, this script is set up to use an EigenDA proxy connected to +_holesky_, so the chain won't work if it was set up to run with a `Memstore` client implementation. To make use of this tool, you need to have `make` and `npm` installed. +### Start Proxy + +Before running the command, you need to start the proxy. To do so, first export the variable `PRIVATE_KEY` (without 0x). +Then run the following command: + +``` +make start-proxy +``` + ### Run command: +Run in a separate terminal: + ``` -make getallblobs VALIDATOR_TIMELOCK_ADDR= COMMIT_BATCHES_SB_FUNC_SELECTOR= +make get-all-blobs VALIDATOR_TIMELOCK_ADDR= COMMIT_BATCHES_SB_FUNC_SELECTOR= ``` This generates a `blob_data.json` file, where blobs and commitments are stored. From e0c58a113360ce72af8d57c8f70a3064dce035f6 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Wed, 6 Nov 2024 11:27:41 -0300 Subject: [PATCH 07/18] fixes --- get_all_blobs/.gitignore | 1 + get_all_blobs/README.md | 2 +- get_all_blobs/getallblobs.js | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/get_all_blobs/.gitignore b/get_all_blobs/.gitignore index cb0d0200b31e..d2f27f4fc30b 100644 --- a/get_all_blobs/.gitignore +++ b/get_all_blobs/.gitignore @@ -1 +1,2 @@ eigenda-proxy/ +blob_data.json diff --git a/get_all_blobs/README.md b/get_all_blobs/README.md index c71c88926594..e0cf74b5995c 100644 --- a/get_all_blobs/README.md +++ b/get_all_blobs/README.md @@ -26,7 +26,7 @@ This generates a `blob_data.json` file, where blobs and commitments are stored. ### Environment Variables -`VALIDATOR_TIMELOCK_ADDR`: The address of the validator timelock. Check the value in `zkstack init` if running a local +`VALIDATOR_TIMELOCK_ADDR`: The address of the validator timelock. Check for `ValidatorTimelock deployed at: ` in `zkstack init` if running a local node. `COMMIT_BATCHES_SB_FUNC_SELECTOR`: The function selector for commitBatchesSharedBridge. For a local node, this is diff --git a/get_all_blobs/getallblobs.js b/get_all_blobs/getallblobs.js index 79a5e4a8c4b8..a80d76b2d087 100644 --- a/get_all_blobs/getallblobs.js +++ b/get_all_blobs/getallblobs.js @@ -193,7 +193,7 @@ async function getTransactions(validatorTimelockAddress, commitBatchesSharedBrid async function get(commitment) { try { - const url = `http://localhost:4242/get/0x${commitment}`; + const url = `http://127.0.0.1:4242/get/0x${commitment}`; const response = await fetch(url); From d2ddf17e14b989cf3f59af8b65552d387db6937b Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Wed, 6 Nov 2024 11:30:11 -0300 Subject: [PATCH 08/18] update cargo lock --- Cargo.lock | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 177f035c810c..fce65dc54918 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -128,9 +128,9 @@ dependencies = [ [[package]] name = "alloy-chains" -version = "0.1.46" +version = "0.1.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836cf02383d9ebb35502d379bcd1ae803155094077eaab9c29131d888cd5fa3e" +checksum = "18c5c520273946ecf715c0010b4e3503d7eba9893cd9ce6b7fff5654c4a3c470" dependencies = [ "alloy-primitives", "num_enum 0.7.3", @@ -174,9 +174,9 @@ dependencies = [ [[package]] name = "alloy-core" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b72bf30967a232bec83809bea1623031f6285a013096229330c68c406192a4ca" +checksum = "47ef9e96462d0b9fee9008c53c1f3d017b9498fcdef3ad8d728db98afef47955" dependencies = [ "alloy-dyn-abi", "alloy-json-abi", @@ -187,9 +187,9 @@ dependencies = [ [[package]] name = "alloy-dyn-abi" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5228b189b18b85761340dc9eaac0141148a8503657b36f9bc3a869413d987ca" +checksum = "85132f2698b520fab3f54beed55a44389f7006a7b557a0261e1e69439dcc1572" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -256,9 +256,9 @@ dependencies = [ [[package]] name = "alloy-json-abi" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31a0f0d51db8a1a30a4d98a9f90e090a94c8f44cb4d9eafc7e03aa6d00aae984" +checksum = "ded610181f3dad5810f6ff12d1a99994cf9b42d2fcb7709029352398a5da5ae6" dependencies = [ "alloy-primitives", "alloy-sol-type-parser", @@ -315,9 +315,9 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8edae627382349b56cd6a7a2106f4fd69b243a9233e560c55c2e03cabb7e1d3c" +checksum = "fd58d377699e6cfeab52c4a9d28bdc4ef37e2bd235ff2db525071fe37a2e9af5" dependencies = [ "alloy-rlp", "bytes", @@ -533,9 +533,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841eabaa4710f719fddbc24c95d386eae313f07e6da4babc25830ee37945be0c" +checksum = "8a1b42ac8f45e2f49f4bcdd72cbfde0bb148f5481d403774ffa546e48b83efc1" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", @@ -547,9 +547,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-expander" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6672337f19d837b9f7073c45853aeb528ed9f7dd6a4154ce683e9e5cb7794014" +checksum = "06318f1778e57f36333e850aa71bd1bb5e560c10279e236622faae0470c50412" dependencies = [ "alloy-json-abi", "alloy-sol-macro-input", @@ -566,9 +566,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-input" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dff37dd20bfb118b777c96eda83b2067f4226d2644c5cfa00187b3bc01770ba" +checksum = "eaebb9b0ad61a41345a22c9279975c0cdd231b97947b10d7aad1cf0a7181e4a5" dependencies = [ "alloy-json-abi", "const-hex", @@ -583,9 +583,9 @@ dependencies = [ [[package]] name = "alloy-sol-type-parser" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b853d42292dbb159671a3edae3b2750277ff130f32b726fe07dc2b17aa6f2b5" +checksum = "12c71028bfbfec210e24106a542aad3def7caf1a70e2c05710e92a98481980d3" dependencies = [ "serde", "winnow 0.6.20", @@ -593,9 +593,9 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa828bb1b9a6dc52208fbb18084fb9ce2c30facc2bfda6a5d922349b4990354f" +checksum = "374d7fb042d68ddfe79ccb23359de3007f6d4d53c13f703b64fb0db422132111" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -9686,9 +9686,9 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16320d4a2021ba1a32470b3759676114a918885e9800e68ad60f2c67969fba62" +checksum = "edf42e81491fb8871b74df3d222c64ae8cbc1269ea509fa768a3ed3e1b0ac8cb" dependencies = [ "paste", "proc-macro2 1.0.89", From 8fcb9acb10d26e1c9a7439840862d0a7113fbe54 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Wed, 6 Nov 2024 15:30:30 -0300 Subject: [PATCH 09/18] fix readme --- get_all_blobs/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/get_all_blobs/README.md b/get_all_blobs/README.md index e0cf74b5995c..19e3bb46a5f1 100644 --- a/get_all_blobs/README.md +++ b/get_all_blobs/README.md @@ -11,7 +11,7 @@ Before running the command, you need to start the proxy. To do so, first export Then run the following command: ``` -make start-proxy +make run-proxy ``` ### Run command: @@ -32,4 +32,4 @@ node. `COMMIT_BATCHES_SB_FUNC_SELECTOR`: The function selector for commitBatchesSharedBridge. For a local node, this is typically 0x6edd4f12. -This variables can be exported in the shell in order to run `make getallblobs` without passing them as arguments. +This variables can be exported in the shell in order to run `make get-all-blobs` without passing them as arguments. From 5e8c2aa4b3a35793b7b1f33a78d061fe4f517d07 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Wed, 6 Nov 2024 18:43:15 -0300 Subject: [PATCH 10/18] initial impl move get all blobs to rust --- Cargo.lock | 37 ++ Cargo.toml | 2 +- get_all_blobs_rs/Cargo.toml | 29 ++ get_all_blobs_rs/src/blob_info.rs | 505 ++++++++++++++++++++ get_all_blobs_rs/src/client.rs | 52 ++ get_all_blobs_rs/src/generated/common.rs | 63 +++ get_all_blobs_rs/src/generated/disperser.rs | 486 +++++++++++++++++++ get_all_blobs_rs/src/generated/mod.rs | 3 + get_all_blobs_rs/src/main.rs | 182 +++++++ 9 files changed, 1358 insertions(+), 1 deletion(-) create mode 100644 get_all_blobs_rs/Cargo.toml create mode 100644 get_all_blobs_rs/src/blob_info.rs create mode 100644 get_all_blobs_rs/src/client.rs create mode 100644 get_all_blobs_rs/src/generated/common.rs create mode 100644 get_all_blobs_rs/src/generated/disperser.rs create mode 100644 get_all_blobs_rs/src/generated/mod.rs create mode 100644 get_all_blobs_rs/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index fce65dc54918..3ad74027c0ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4132,6 +4132,27 @@ dependencies = [ "zksync_utils", ] +[[package]] +name = "get_all_blobs_rs" +version = "0.1.0" +dependencies = [ + "alloy", + "anyhow", + "axum 0.7.7", + "futures 0.3.31", + "hex", + "kzgpad-rs", + "prost 0.13.3", + "reqwest 0.12.9", + "rlp", + "rustls 0.23.16", + "serde", + "serde_json", + "tokio", + "tonic 0.12.3", + "zksync_node_framework", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -8050,6 +8071,19 @@ dependencies = [ "security-framework", ] +[[package]] +name = "rustls-native-certs" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcaf18a4f2be7326cd874a5fa579fae794320a0f388d365dca7e480e55f83f8a" +dependencies = [ + "openssl-probe", + "rustls-pemfile 2.2.0", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pemfile" version = "1.0.4" @@ -10273,8 +10307,11 @@ dependencies = [ "percent-encoding", "pin-project", "prost 0.13.3", + "rustls-native-certs 0.8.0", + "rustls-pemfile 2.2.0", "socket2", "tokio", + "tokio-rustls 0.26.0", "tokio-stream", "tower 0.4.13", "tower-layer", diff --git a/Cargo.toml b/Cargo.toml index e7cce4c4c421..8a638c110418 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -78,7 +78,7 @@ members = [ # Test infrastructure "core/tests/test_account", "core/tests/loadnext", - "core/tests/vm-benchmark", + "core/tests/vm-benchmark", "get_all_blobs_rs", ] resolver = "2" diff --git a/get_all_blobs_rs/Cargo.toml b/get_all_blobs_rs/Cargo.toml new file mode 100644 index 000000000000..585c6cb42475 --- /dev/null +++ b/get_all_blobs_rs/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "get_all_blobs_rs" +version.workspace = true +edition.workspace = true +authors.workspace = true +homepage.workspace = true +repository.workspace = true +license.workspace = true +keywords.workspace = true +categories.workspace = true + +[dependencies] +anyhow.workspace = true +zksync_node_framework.workspace = true +tokio.workspace = true +axum.workspace = true +rustls.workspace = true +rlp.workspace = true +hex.workspace = true + +reqwest.workspace = true +serde.workspace = true +serde_json.workspace = true + +tonic = { version = "0.12.1", features = ["tls", "channel", "tls-roots"]} +prost = "0.13.1" +kzgpad-rs = { git = "https://github.com/Layr-Labs/kzgpad-rs.git", tag = "v0.1.0" } +alloy = { version = "0.3", features = ["full"] } +futures = "0.3" diff --git a/get_all_blobs_rs/src/blob_info.rs b/get_all_blobs_rs/src/blob_info.rs new file mode 100644 index 000000000000..05564e750bdd --- /dev/null +++ b/get_all_blobs_rs/src/blob_info.rs @@ -0,0 +1,505 @@ +use std::fmt; + +use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream}; + +use crate::generated::{ + common::G1Commitment as DisperserG1Commitment, + disperser::{ + BatchHeader as DisperserBatchHeader, BatchMetadata as DisperserBatchMetadata, + BlobHeader as DisperserBlobHeader, BlobInfo as DisperserBlobInfo, + BlobQuorumParam as DisperserBlobQuorumParam, + BlobVerificationProof as DisperserBlobVerificationProof, + }, +}; + +#[derive(Debug)] +pub enum ConversionError { + NotPresentError, +} + +impl fmt::Display for ConversionError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + ConversionError::NotPresentError => write!(f, "Failed to convert BlobInfo"), + } + } +} + +#[derive(Debug, PartialEq, Clone)] +pub struct G1Commitment { + pub x: Vec, + pub y: Vec, +} + +impl G1Commitment { + pub fn into_bytes(&self) -> Vec { + let mut bytes = vec![]; + bytes.extend(&self.x.len().to_be_bytes()); + bytes.extend(&self.x); + bytes.extend(&self.y.len().to_be_bytes()); + bytes.extend(&self.y); + + bytes + } +} + +impl Decodable for G1Commitment { + fn decode(rlp: &Rlp) -> Result { + let x: Vec = rlp.val_at(0)?; // Decode first element as Vec + let y: Vec = rlp.val_at(1)?; // Decode second element as Vec + + Ok(G1Commitment { x, y }) + } +} + +impl Encodable for G1Commitment { + fn rlp_append(&self, s: &mut RlpStream) { + s.begin_list(2); + s.append(&self.x); + s.append(&self.y); + } +} + +impl From for G1Commitment { + fn from(value: DisperserG1Commitment) -> Self { + Self { + x: value.x, + y: value.y, + } + } +} + +#[derive(Debug, PartialEq, Clone)] +pub struct BlobQuorumParam { + pub quorum_number: u32, + pub adversary_threshold_percentage: u32, + pub confirmation_threshold_percentage: u32, + pub chunk_length: u32, +} + +impl BlobQuorumParam { + pub fn into_bytes(&self) -> Vec { + let mut bytes = vec![]; + bytes.extend(&self.quorum_number.to_be_bytes()); + bytes.extend(&self.adversary_threshold_percentage.to_be_bytes()); + bytes.extend(&self.confirmation_threshold_percentage.to_be_bytes()); + bytes.extend(&self.chunk_length.to_be_bytes()); + + bytes + } +} + +impl Decodable for BlobQuorumParam { + fn decode(rlp: &Rlp) -> Result { + Ok(BlobQuorumParam { + quorum_number: rlp.val_at(0)?, + adversary_threshold_percentage: rlp.val_at(1)?, + confirmation_threshold_percentage: rlp.val_at(2)?, + chunk_length: rlp.val_at(3)?, + }) + } +} + +impl Encodable for BlobQuorumParam { + fn rlp_append(&self, s: &mut RlpStream) { + s.begin_list(4); + s.append(&self.quorum_number); + s.append(&self.adversary_threshold_percentage); + s.append(&self.confirmation_threshold_percentage); + s.append(&self.chunk_length); + } +} + +impl From for BlobQuorumParam { + fn from(value: DisperserBlobQuorumParam) -> Self { + Self { + quorum_number: value.quorum_number, + adversary_threshold_percentage: value.adversary_threshold_percentage, + confirmation_threshold_percentage: value.confirmation_threshold_percentage, + chunk_length: value.chunk_length, + } + } +} + +#[derive(Debug, PartialEq, Clone)] +pub struct BlobHeader { + pub commitment: G1Commitment, + pub data_length: u32, + pub blob_quorum_params: Vec, +} + +impl BlobHeader { + pub fn into_bytes(&self) -> Vec { + let mut bytes = vec![]; + bytes.extend(self.commitment.into_bytes()); + bytes.extend(&self.data_length.to_be_bytes()); + bytes.extend(&self.blob_quorum_params.len().to_be_bytes()); + + for quorum in &self.blob_quorum_params { + bytes.extend(quorum.into_bytes()); + } + + bytes + } +} + +impl Decodable for BlobHeader { + fn decode(rlp: &Rlp) -> Result { + let commitment: G1Commitment = rlp.val_at(0)?; + let data_length: u32 = rlp.val_at(1)?; + let blob_quorum_params: Vec = rlp.list_at(2)?; + + Ok(BlobHeader { + commitment, + data_length, + blob_quorum_params, + }) + } +} + +impl Encodable for BlobHeader { + fn rlp_append(&self, s: &mut RlpStream) { + s.begin_list(3); + s.append(&self.commitment); + s.append(&self.data_length); + s.append_list(&self.blob_quorum_params); + } +} + +impl TryFrom for BlobHeader { + type Error = ConversionError; + fn try_from(value: DisperserBlobHeader) -> Result { + if value.commitment.is_none() { + return Err(ConversionError::NotPresentError); + } + let blob_quorum_params: Vec = value + .blob_quorum_params + .iter() + .map(|param| BlobQuorumParam::from(param.clone())) + .collect(); + let blob_quorum_params = blob_quorum_params; + Ok(Self { + commitment: G1Commitment::from(value.commitment.unwrap()), + data_length: value.data_length, + blob_quorum_params, + }) + } +} + +#[derive(Debug, PartialEq, Clone)] +pub struct BatchHeader { + pub batch_root: Vec, + pub quorum_numbers: Vec, + pub quorum_signed_percentages: Vec, + pub reference_block_number: u32, +} + +impl BatchHeader { + pub fn into_bytes(&self) -> Vec { + let mut bytes = vec![]; + bytes.extend(&self.batch_root.len().to_be_bytes()); + bytes.extend(&self.batch_root); + bytes.extend(&self.quorum_numbers.len().to_be_bytes()); + bytes.extend(&self.quorum_numbers); + bytes.extend(&self.quorum_signed_percentages.len().to_be_bytes()); + bytes.extend(&self.quorum_signed_percentages); + bytes.extend(&self.reference_block_number.to_be_bytes()); + + bytes + } +} + +impl Decodable for BatchHeader { + fn decode(rlp: &Rlp) -> Result { + Ok(BatchHeader { + batch_root: rlp.val_at(0)?, + quorum_numbers: rlp.val_at(1)?, + quorum_signed_percentages: rlp.val_at(2)?, + reference_block_number: rlp.val_at(3)?, + }) + } +} + +impl Encodable for BatchHeader { + fn rlp_append(&self, s: &mut RlpStream) { + s.begin_list(4); + s.append(&self.batch_root); + s.append(&self.quorum_numbers); + s.append(&self.quorum_signed_percentages); + s.append(&self.reference_block_number); + } +} + +impl From for BatchHeader { + fn from(value: DisperserBatchHeader) -> Self { + Self { + batch_root: value.batch_root, + quorum_numbers: value.quorum_numbers, + quorum_signed_percentages: value.quorum_signed_percentages, + reference_block_number: value.reference_block_number, + } + } +} + +#[derive(Debug, PartialEq, Clone)] +pub struct BatchMetadata { + pub batch_header: BatchHeader, + pub signatory_record_hash: Vec, + pub fee: Vec, + pub confirmation_block_number: u32, + pub batch_header_hash: Vec, +} + +impl BatchMetadata { + pub fn into_bytes(&self) -> Vec { + let mut bytes = vec![]; + bytes.extend(self.batch_header.into_bytes()); + bytes.extend(&self.signatory_record_hash); + bytes.extend(&self.confirmation_block_number.to_be_bytes()); + + bytes + } +} + +impl Decodable for BatchMetadata { + fn decode(rlp: &Rlp) -> Result { + let batch_header: BatchHeader = rlp.val_at(0)?; + + Ok(BatchMetadata { + batch_header, + signatory_record_hash: rlp.val_at(1)?, + fee: rlp.val_at(2)?, + confirmation_block_number: rlp.val_at(3)?, + batch_header_hash: rlp.val_at(4)?, + }) + } +} + +impl Encodable for BatchMetadata { + fn rlp_append(&self, s: &mut RlpStream) { + s.begin_list(5); + s.append(&self.batch_header); + s.append(&self.signatory_record_hash); + s.append(&self.fee); + s.append(&self.confirmation_block_number); + s.append(&self.batch_header_hash); + } +} + +impl TryFrom for BatchMetadata { + type Error = ConversionError; + fn try_from(value: DisperserBatchMetadata) -> Result { + if value.batch_header.is_none() { + return Err(ConversionError::NotPresentError); + } + Ok(Self { + batch_header: BatchHeader::from(value.batch_header.unwrap()), + signatory_record_hash: value.signatory_record_hash, + fee: value.fee, + confirmation_block_number: value.confirmation_block_number, + batch_header_hash: value.batch_header_hash, + }) + } +} + +#[derive(Debug, PartialEq, Clone)] +pub struct BlobVerificationProof { + pub batch_id: u32, + pub blob_index: u32, + pub batch_medatada: BatchMetadata, + pub inclusion_proof: Vec, + pub quorum_indexes: Vec, +} + +impl BlobVerificationProof { + pub fn into_bytes(&self) -> Vec { + let mut bytes = vec![]; + bytes.extend(&self.batch_id.to_be_bytes()); + bytes.extend(&self.blob_index.to_be_bytes()); + bytes.extend(self.batch_medatada.into_bytes()); + bytes.extend(&self.inclusion_proof.len().to_be_bytes()); + bytes.extend(&self.inclusion_proof); + bytes.extend(&self.quorum_indexes.len().to_be_bytes()); + bytes.extend(&self.quorum_indexes); + + bytes + } +} + +impl Decodable for BlobVerificationProof { + fn decode(rlp: &Rlp) -> Result { + Ok(BlobVerificationProof { + batch_id: rlp.val_at(0)?, + blob_index: rlp.val_at(1)?, + batch_medatada: rlp.val_at(2)?, + inclusion_proof: rlp.val_at(3)?, + quorum_indexes: rlp.val_at(4)?, + }) + } +} + +impl Encodable for BlobVerificationProof { + fn rlp_append(&self, s: &mut RlpStream) { + s.begin_list(5); + s.append(&self.batch_id); + s.append(&self.blob_index); + s.append(&self.batch_medatada); + s.append(&self.inclusion_proof); + s.append(&self.quorum_indexes); + } +} + +impl TryFrom for BlobVerificationProof { + type Error = ConversionError; + fn try_from(value: DisperserBlobVerificationProof) -> Result { + if value.batch_metadata.is_none() { + return Err(ConversionError::NotPresentError); + } + Ok(Self { + batch_id: value.batch_id, + blob_index: value.blob_index, + batch_medatada: BatchMetadata::try_from(value.batch_metadata.unwrap())?, + inclusion_proof: value.inclusion_proof, + quorum_indexes: value.quorum_indexes, + }) + } +} + +#[derive(Debug, PartialEq, Clone)] +pub struct BlobInfo { + pub blob_header: BlobHeader, + pub blob_verification_proof: BlobVerificationProof, +} + +impl BlobInfo { + pub fn into_bytes(&self) -> Vec { + let mut bytes = vec![]; + let blob_header_bytes = self.blob_header.into_bytes(); + bytes.extend(blob_header_bytes.len().to_be_bytes()); + bytes.extend(blob_header_bytes); + let blob_verification_proof_bytes = self.blob_verification_proof.into_bytes(); + bytes.extend(blob_verification_proof_bytes); + bytes + } +} + +impl Decodable for BlobInfo { + fn decode(rlp: &Rlp) -> Result { + let blob_header: BlobHeader = rlp.val_at(0)?; + let blob_verification_proof: BlobVerificationProof = rlp.val_at(1)?; + + Ok(BlobInfo { + blob_header, + blob_verification_proof, + }) + } +} + +impl Encodable for BlobInfo { + fn rlp_append(&self, s: &mut RlpStream) { + s.begin_list(2); + s.append(&self.blob_header); + s.append(&self.blob_verification_proof); + } +} + +impl TryFrom for BlobInfo { + type Error = ConversionError; + fn try_from(value: DisperserBlobInfo) -> Result { + if value.blob_header.is_none() || value.blob_verification_proof.is_none() { + return Err(ConversionError::NotPresentError); + } + Ok(Self { + blob_header: BlobHeader::try_from(value.blob_header.unwrap())?, + blob_verification_proof: BlobVerificationProof::try_from( + value.blob_verification_proof.unwrap(), + )?, + }) + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_blob_info_encoding_and_decoding() { + let blob_info = BlobInfo { + blob_header: BlobHeader { + commitment: G1Commitment { + x: vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + ], + y: vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + ], + }, + data_length: 4, + blob_quorum_params: vec![ + BlobQuorumParam { + quorum_number: 0, + adversary_threshold_percentage: 33, + confirmation_threshold_percentage: 55, + chunk_length: 1, + }, + BlobQuorumParam { + quorum_number: 1, + adversary_threshold_percentage: 33, + confirmation_threshold_percentage: 55, + chunk_length: 1, + }, + ], + }, + blob_verification_proof: BlobVerificationProof { + batch_id: 66507, + blob_index: 92, + batch_medatada: BatchMetadata { + batch_header: BatchHeader { + batch_root: vec![ + 179, 187, 53, 98, 192, 80, 151, 28, 125, 192, 115, 29, 129, 238, 216, + 8, 213, 210, 203, 143, 181, 19, 146, 113, 98, 131, 39, 238, 149, 248, + 211, 43, + ], + quorum_numbers: vec![0, 1], + quorum_signed_percentages: vec![100, 100], + reference_block_number: 2624794, + }, + signatory_record_hash: vec![ + 172, 32, 172, 142, 197, 52, 84, 143, 120, 26, 190, 9, 143, 217, 62, 19, 17, + 107, 105, 67, 203, 5, 172, 249, 6, 60, 105, 240, 134, 34, 66, 133, + ], + fee: vec![0], + confirmation_block_number: 2624876, + batch_header_hash: vec![ + 122, 115, 2, 85, 233, 75, 121, 85, 51, 81, 248, 170, 198, 252, 42, 16, 1, + 146, 96, 218, 159, 44, 41, 40, 94, 247, 147, 11, 255, 68, 40, 177, + ], + }, + inclusion_proof: vec![ + 203, 160, 237, 48, 117, 255, 75, 254, 117, 144, 164, 77, 29, 146, 36, 48, 190, + 140, 50, 100, 144, 237, 125, 125, 75, 54, 210, 247, 147, 23, 48, 189, 120, 4, + 125, 123, 195, 244, 207, 239, 145, 109, 0, 21, 11, 162, 109, 79, 192, 100, 138, + 157, 203, 22, 17, 114, 234, 72, 174, 231, 209, 133, 99, 118, 201, 160, 137, + 128, 112, 84, 34, 136, 174, 139, 96, 26, 246, 148, 134, 52, 200, 229, 160, 145, + 5, 120, 18, 187, 51, 11, 109, 91, 237, 171, 215, 207, 90, 95, 146, 54, 135, + 166, 66, 157, 255, 237, 69, 183, 141, 45, 162, 145, 71, 16, 87, 184, 120, 84, + 156, 220, 159, 4, 99, 48, 191, 203, 136, 112, 127, 226, 192, 184, 110, 6, 177, + 182, 109, 207, 197, 239, 161, 132, 17, 89, 56, 137, 205, 202, 101, 97, 60, 162, + 253, 23, 169, 75, 236, 211, 126, 121, 132, 191, 68, 167, 200, 16, 154, 149, + 202, 197, 7, 191, 26, 8, 67, 3, 37, 137, 16, 153, 30, 209, 238, 53, 233, 148, + 198, 253, 94, 216, 73, 25, 190, 205, 132, 208, 255, 219, 170, 98, 17, 160, 179, + 183, 200, 17, 99, 36, 130, 216, 223, 72, 222, 250, 73, 78, 79, 72, 253, 105, + 245, 84, 244, 196, + ], + quorum_indexes: vec![0, 1], + }, + }; + + let encoded_blob_info = rlp::encode(&blob_info); + let decoded_blob_info: BlobInfo = rlp::decode(&encoded_blob_info).unwrap(); + + assert_eq!(blob_info, decoded_blob_info); + } +} diff --git a/get_all_blobs_rs/src/client.rs b/get_all_blobs_rs/src/client.rs new file mode 100644 index 000000000000..51107a0ee195 --- /dev/null +++ b/get_all_blobs_rs/src/client.rs @@ -0,0 +1,52 @@ +use std::str::FromStr; + +use tonic::transport::{Channel, ClientTlsConfig, Endpoint}; + +use crate::{ + blob_info::BlobInfo, + generated::{disperser, disperser::disperser_client::DisperserClient}, +}; + +#[derive(Debug, Clone)] +pub struct EigenClientRetriever { + client: DisperserClient, +} + +impl EigenClientRetriever { + pub async fn new(disperser_rpc: &str) -> anyhow::Result { + let endpoint = Endpoint::from_str(disperser_rpc)?.tls_config(ClientTlsConfig::new())?; + let client = DisperserClient::connect(endpoint) + .await + .map_err(|e| anyhow::anyhow!("Failed to connect to Disperser server: {}", e))?; + + Ok(EigenClientRetriever { client }) + } + + pub async fn get_blob_data(&self, blob_id: &str) -> anyhow::Result>> { + let commit = hex::decode(blob_id).unwrap(); + + let blob_info: BlobInfo = rlp::decode(&commit).unwrap(); + let blob_index = blob_info.blob_verification_proof.blob_index; + let batch_header_hash = blob_info + .blob_verification_proof + .batch_medatada + .batch_header_hash; + let get_response = self + .client + .clone() + .retrieve_blob(disperser::RetrieveBlobRequest { + batch_header_hash, + blob_index, + }) + .await + .unwrap() + .into_inner(); + + if get_response.data.len() == 0 { + panic!("Empty data returned from Disperser") + } + + let data = kzgpad_rs::remove_empty_byte_from_padded_bytes(&get_response.data); + return Ok(Some(data)); + } +} diff --git a/get_all_blobs_rs/src/generated/common.rs b/get_all_blobs_rs/src/generated/common.rs new file mode 100644 index 000000000000..0599b9af4127 --- /dev/null +++ b/get_all_blobs_rs/src/generated/common.rs @@ -0,0 +1,63 @@ +// This file is @generated by prost-build. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct G1Commitment { + /// The X coordinate of the KZG commitment. This is the raw byte representation of the field element. + #[prost(bytes = "vec", tag = "1")] + pub x: ::prost::alloc::vec::Vec, + /// The Y coordinate of the KZG commitment. This is the raw byte representation of the field element. + #[prost(bytes = "vec", tag = "2")] + pub y: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct G2Commitment { + /// The A0 element of the X coordinate of G2 point. + #[prost(bytes = "vec", tag = "1")] + pub x_a0: ::prost::alloc::vec::Vec, + /// The A1 element of the X coordinate of G2 point. + #[prost(bytes = "vec", tag = "2")] + pub x_a1: ::prost::alloc::vec::Vec, + /// The A0 element of the Y coordinate of G2 point. + #[prost(bytes = "vec", tag = "3")] + pub y_a0: ::prost::alloc::vec::Vec, + /// The A1 element of the Y coordinate of G2 point. + #[prost(bytes = "vec", tag = "4")] + pub y_a1: ::prost::alloc::vec::Vec, +} +/// BlobCommitment represents commitment of a specific blob, containing its +/// KZG commitment, degree proof, the actual degree, and data length in number of symbols. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BlobCommitment { + #[prost(message, optional, tag = "1")] + pub commitment: ::core::option::Option, + #[prost(message, optional, tag = "2")] + pub length_commitment: ::core::option::Option, + #[prost(message, optional, tag = "3")] + pub length_proof: ::core::option::Option, + #[prost(uint32, tag = "4")] + pub data_length: u32, +} +/// BlobCertificate is what gets attested by the network +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BlobCertificate { + #[prost(uint32, tag = "1")] + pub version: u32, + #[prost(bytes = "vec", tag = "2")] + pub blob_key: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "3")] + pub blob_commitment: ::core::option::Option, + #[prost(uint32, repeated, tag = "4")] + pub quorum_numbers: ::prost::alloc::vec::Vec, + #[prost(uint32, tag = "5")] + pub reference_block_number: u32, +} +/// A chunk of a blob. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ChunkData { + #[prost(bytes = "vec", tag = "1")] + pub data: ::prost::alloc::vec::Vec, +} diff --git a/get_all_blobs_rs/src/generated/disperser.rs b/get_all_blobs_rs/src/generated/disperser.rs new file mode 100644 index 000000000000..16c330ae8e50 --- /dev/null +++ b/get_all_blobs_rs/src/generated/disperser.rs @@ -0,0 +1,486 @@ +// This file is @generated by prost-build. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AuthenticatedRequest { + #[prost(oneof = "authenticated_request::Payload", tags = "1, 2")] + pub payload: ::core::option::Option, +} +/// Nested message and enum types in `AuthenticatedRequest`. +pub mod authenticated_request { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Payload { + #[prost(message, tag = "1")] + DisperseRequest(super::DisperseBlobRequest), + #[prost(message, tag = "2")] + AuthenticationData(super::AuthenticationData), + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AuthenticatedReply { + #[prost(oneof = "authenticated_reply::Payload", tags = "1, 2")] + pub payload: ::core::option::Option, +} +/// Nested message and enum types in `AuthenticatedReply`. +pub mod authenticated_reply { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Payload { + #[prost(message, tag = "1")] + BlobAuthHeader(super::BlobAuthHeader), + #[prost(message, tag = "2")] + DisperseReply(super::DisperseBlobReply), + } +} +/// BlobAuthHeader contains information about the blob for the client to verify and sign. +/// - Once payments are enabled, the BlobAuthHeader will contain the KZG commitment to the blob, which the client +/// will verify and sign. Having the client verify the KZG commitment instead of calculating it avoids +/// the need for the client to have the KZG structured reference string (SRS), which can be large. +/// The signed KZG commitment prevents the disperser from sending a different blob to the DA Nodes +/// than the one the client sent. +/// - In the meantime, the BlobAuthHeader contains a simple challenge parameter is used to prevent +/// replay attacks in the event that a signature is leaked. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BlobAuthHeader { + #[prost(uint32, tag = "1")] + pub challenge_parameter: u32, +} +/// AuthenticationData contains the signature of the BlobAuthHeader. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AuthenticationData { + #[prost(bytes = "vec", tag = "1")] + pub authentication_data: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DisperseBlobRequest { + /// The data to be dispersed. + /// The size of data must be <= 2MiB. Every 32 bytes of data chunk is interpreted as an integer in big endian format + /// where the lower address has more significant bits. The integer must stay in the valid range to be interpreted + /// as a field element on the bn254 curve. The valid range is + /// 0 <= x < 21888242871839275222246405745257275088548364400416034343698204186575808495617 + /// containing slightly less than 254 bits and more than 253 bits. If any one of the 32 bytes chunk is outside the range, + /// the whole request is deemed as invalid, and rejected. + #[prost(bytes = "vec", tag = "1")] + pub data: ::prost::alloc::vec::Vec, + /// The quorums to which the blob will be sent, in addition to the required quorums which are configured + /// on the EigenDA smart contract. If required quorums are included here, an error will be returned. + /// The disperser will ensure that the encoded blobs for each quorum are all processed + /// within the same batch. + #[prost(uint32, repeated, tag = "2")] + pub custom_quorum_numbers: ::prost::alloc::vec::Vec, + /// The account ID of the client. This should be a hex-encoded string of the ECSDA public key + /// corresponding to the key used by the client to sign the BlobAuthHeader. + #[prost(string, tag = "3")] + pub account_id: ::prost::alloc::string::String, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DisperseBlobReply { + /// The status of the blob associated with the request_id. + #[prost(enumeration = "BlobStatus", tag = "1")] + pub result: i32, + /// The request ID generated by the disperser. + /// Once a request is accepted (although not processed), a unique request ID will be + /// generated. + /// Two different DisperseBlobRequests (determined by the hash of the DisperseBlobRequest) + /// will have different IDs, and the same DisperseBlobRequest sent repeatedly at different + /// times will also have different IDs. + /// The client should use this ID to query the processing status of the request (via + /// the GetBlobStatus API). + #[prost(bytes = "vec", tag = "2")] + pub request_id: ::prost::alloc::vec::Vec, +} +/// BlobStatusRequest is used to query the status of a blob. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BlobStatusRequest { + #[prost(bytes = "vec", tag = "1")] + pub request_id: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BlobStatusReply { + /// The status of the blob. + #[prost(enumeration = "BlobStatus", tag = "1")] + pub status: i32, + /// The blob info needed for clients to confirm the blob against the EigenDA contracts. + #[prost(message, optional, tag = "2")] + pub info: ::core::option::Option, +} +/// RetrieveBlobRequest contains parameters to retrieve the blob. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct RetrieveBlobRequest { + #[prost(bytes = "vec", tag = "1")] + pub batch_header_hash: ::prost::alloc::vec::Vec, + #[prost(uint32, tag = "2")] + pub blob_index: u32, +} +/// RetrieveBlobReply contains the retrieved blob data +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct RetrieveBlobReply { + #[prost(bytes = "vec", tag = "1")] + pub data: ::prost::alloc::vec::Vec, +} +/// BlobInfo contains information needed to confirm the blob against the EigenDA contracts +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BlobInfo { + #[prost(message, optional, tag = "1")] + pub blob_header: ::core::option::Option, + #[prost(message, optional, tag = "2")] + pub blob_verification_proof: ::core::option::Option, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BlobHeader { + /// KZG commitment of the blob. + #[prost(message, optional, tag = "1")] + pub commitment: ::core::option::Option, + /// The length of the blob in symbols (each symbol is 32 bytes). + #[prost(uint32, tag = "2")] + pub data_length: u32, + /// The params of the quorums that this blob participates in. + #[prost(message, repeated, tag = "3")] + pub blob_quorum_params: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BlobQuorumParam { + /// The ID of the quorum. + #[prost(uint32, tag = "1")] + pub quorum_number: u32, + /// The max percentage of stake within the quorum that can be held by or delegated + /// to adversarial operators. Currently, this and the next parameter are standardized + /// across the quorum using values read from the EigenDA contracts. + #[prost(uint32, tag = "2")] + pub adversary_threshold_percentage: u32, + /// The min percentage of stake that must attest in order to consider + /// the dispersal is successful. + #[prost(uint32, tag = "3")] + pub confirmation_threshold_percentage: u32, + /// The length of each chunk. + #[prost(uint32, tag = "4")] + pub chunk_length: u32, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BlobVerificationProof { + /// batch_id is an incremental ID assigned to a batch by EigenDAServiceManager + #[prost(uint32, tag = "1")] + pub batch_id: u32, + /// The index of the blob in the batch (which is logically an ordered list of blobs). + #[prost(uint32, tag = "2")] + pub blob_index: u32, + #[prost(message, optional, tag = "3")] + pub batch_metadata: ::core::option::Option, + /// inclusion_proof is a merkle proof for a blob header's inclusion in a batch + #[prost(bytes = "vec", tag = "4")] + pub inclusion_proof: ::prost::alloc::vec::Vec, + /// indexes of quorums in BatchHeader.quorum_numbers that match the quorums in BlobHeader.blob_quorum_params + /// Ex. BlobHeader.blob_quorum_params = [ + /// { + /// quorum_number = 0, + /// ... + /// }, + /// { + /// quorum_number = 3, + /// ... + /// }, + /// { + /// quorum_number = 5, + /// ... + /// }, + /// ] + /// BatchHeader.quorum_numbers = \[0, 5, 3\] => 0x000503 + /// Then, quorum_indexes = \[0, 2, 1\] => 0x000201 + #[prost(bytes = "vec", tag = "5")] + pub quorum_indexes: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BatchMetadata { + #[prost(message, optional, tag = "1")] + pub batch_header: ::core::option::Option, + /// The hash of all public keys of the operators that did not sign the batch. + #[prost(bytes = "vec", tag = "2")] + pub signatory_record_hash: ::prost::alloc::vec::Vec, + /// The fee payment paid by users for dispersing this batch. It's the bytes + /// representation of a big.Int value. + #[prost(bytes = "vec", tag = "3")] + pub fee: ::prost::alloc::vec::Vec, + /// The Ethereum block number at which the batch is confirmed onchain. + #[prost(uint32, tag = "4")] + pub confirmation_block_number: u32, + /// This is the hash of the ReducedBatchHeader defined onchain, see: + /// + /// The is the message that the operators will sign their signatures on. + #[prost(bytes = "vec", tag = "5")] + pub batch_header_hash: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BatchHeader { + /// The root of the merkle tree with the hashes of blob headers as leaves. + #[prost(bytes = "vec", tag = "1")] + pub batch_root: ::prost::alloc::vec::Vec, + /// All quorums associated with blobs in this batch. Sorted in ascending order. + /// Ex. \[0, 2, 1\] => 0x000102 + #[prost(bytes = "vec", tag = "2")] + pub quorum_numbers: ::prost::alloc::vec::Vec, + /// The percentage of stake that has signed for this batch. + /// The quorum_signed_percentages\[i\] is percentage for the quorum_numbers\[i\]. + #[prost(bytes = "vec", tag = "3")] + pub quorum_signed_percentages: ::prost::alloc::vec::Vec, + /// The Ethereum block number at which the batch was created. + /// The Disperser will encode and disperse the blobs based on the onchain info + /// (e.g. operator stakes) at this block number. + #[prost(uint32, tag = "4")] + pub reference_block_number: u32, +} +/// BlobStatus represents the status of a blob. +/// The status of a blob is updated as the blob is processed by the disperser. +/// The status of a blob can be queried by the client using the GetBlobStatus API. +/// Intermediate states are states that the blob can be in while being processed, and it can be updated to a differet state: +/// - PROCESSING +/// - DISPERSING +/// - CONFIRMED +/// Terminal states are states that will not be updated to a different state: +/// - FAILED +/// - FINALIZED +/// - INSUFFICIENT_SIGNATURES +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum BlobStatus { + Unknown = 0, + /// PROCESSING means that the blob is currently being processed by the disperser + Processing = 1, + /// CONFIRMED means that the blob has been dispersed to DA Nodes and the dispersed + /// batch containing the blob has been confirmed onchain + Confirmed = 2, + /// FAILED means that the blob has failed permanently (for reasons other than insufficient + /// signatures, which is a separate state) + Failed = 3, + /// FINALIZED means that the block containing the blob's confirmation transaction has been finalized on Ethereum + Finalized = 4, + /// INSUFFICIENT_SIGNATURES means that the confirmation threshold for the blob was not met + /// for at least one quorum. + InsufficientSignatures = 5, + /// DISPERSING means that the blob is currently being dispersed to DA Nodes and being confirmed onchain + Dispersing = 6, +} +impl BlobStatus { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + BlobStatus::Unknown => "UNKNOWN", + BlobStatus::Processing => "PROCESSING", + BlobStatus::Confirmed => "CONFIRMED", + BlobStatus::Failed => "FAILED", + BlobStatus::Finalized => "FINALIZED", + BlobStatus::InsufficientSignatures => "INSUFFICIENT_SIGNATURES", + BlobStatus::Dispersing => "DISPERSING", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "UNKNOWN" => Some(Self::Unknown), + "PROCESSING" => Some(Self::Processing), + "CONFIRMED" => Some(Self::Confirmed), + "FAILED" => Some(Self::Failed), + "FINALIZED" => Some(Self::Finalized), + "INSUFFICIENT_SIGNATURES" => Some(Self::InsufficientSignatures), + "DISPERSING" => Some(Self::Dispersing), + _ => None, + } + } +} +/// Generated client implementations. +pub mod disperser_client { + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + use tonic::codegen::{http::Uri, *}; + /// Disperser defines the public APIs for dispersing blobs. + #[derive(Debug, Clone)] + pub struct DisperserClient { + inner: tonic::client::Grpc, + } + impl DisperserClient { + /// Attempt to create a new client by connecting to a given endpoint. + pub async fn connect(dst: D) -> Result + where + D: TryInto, + D::Error: Into, + { + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; + Ok(Self::new(conn)) + } + } + impl DisperserClient + where + T: tonic::client::GrpcService, + T::Error: Into, + T::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + { + pub fn new(inner: T) -> Self { + let inner = tonic::client::Grpc::new(inner); + Self { inner } + } + pub fn with_origin(inner: T, origin: Uri) -> Self { + let inner = tonic::client::Grpc::with_origin(inner, origin); + Self { inner } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> DisperserClient> + where + F: tonic::service::Interceptor, + T::ResponseBody: Default, + T: tonic::codegen::Service< + http::Request, + Response = http::Response< + >::ResponseBody, + >, + >, + >>::Error: + Into + Send + Sync, + { + DisperserClient::new(InterceptedService::new(inner, interceptor)) + } + /// Compress requests with the given encoding. + /// + /// This requires the server to support it otherwise it might respond with an + /// error. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.send_compressed(encoding); + self + } + /// Enable decompressing responses. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.accept_compressed(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_decoding_message_size(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_encoding_message_size(limit); + self + } + /// This API accepts blob to disperse from clients. + /// This executes the dispersal async, i.e. it returns once the request + /// is accepted. The client could use GetBlobStatus() API to poll the the + /// processing status of the blob. + pub async fn disperse_blob( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static("/disperser.Disperser/DisperseBlob"); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("disperser.Disperser", "DisperseBlob")); + self.inner.unary(req, path, codec).await + } + /// DisperseBlobAuthenticated is similar to DisperseBlob, except that it requires the + /// client to authenticate itself via the AuthenticationData message. The protoco is as follows: + /// 1. The client sends a DisperseBlobAuthenticated request with the DisperseBlobRequest message + /// 2. The Disperser sends back a BlobAuthHeader message containing information for the client to + /// verify and sign. + /// 3. The client verifies the BlobAuthHeader and sends back the signed BlobAuthHeader in an + /// AuthenticationData message. + /// 4. The Disperser verifies the signature and returns a DisperseBlobReply message. + pub async fn disperse_blob_authenticated( + &mut self, + request: impl tonic::IntoStreamingRequest, + ) -> std::result::Result< + tonic::Response>, + tonic::Status, + > { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/disperser.Disperser/DisperseBlobAuthenticated", + ); + let mut req = request.into_streaming_request(); + req.extensions_mut().insert(GrpcMethod::new( + "disperser.Disperser", + "DisperseBlobAuthenticated", + )); + self.inner.streaming(req, path, codec).await + } + /// This API is meant to be polled for the blob status. + pub async fn get_blob_status( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static("/disperser.Disperser/GetBlobStatus"); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("disperser.Disperser", "GetBlobStatus")); + self.inner.unary(req, path, codec).await + } + /// This retrieves the requested blob from the Disperser's backend. + /// This is a more efficient way to retrieve blobs than directly retrieving + /// from the DA Nodes (see detail about this approach in + /// api/proto/retriever/retriever.proto). + /// The blob should have been initially dispersed via this Disperser service + /// for this API to work. + pub async fn retrieve_blob( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static("/disperser.Disperser/RetrieveBlob"); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("disperser.Disperser", "RetrieveBlob")); + self.inner.unary(req, path, codec).await + } + } +} diff --git a/get_all_blobs_rs/src/generated/mod.rs b/get_all_blobs_rs/src/generated/mod.rs new file mode 100644 index 000000000000..d77a351741d9 --- /dev/null +++ b/get_all_blobs_rs/src/generated/mod.rs @@ -0,0 +1,3 @@ +pub(crate) mod common; +pub(crate) mod disperser; +// pub(crate) mod eigendaservicemanager; diff --git a/get_all_blobs_rs/src/main.rs b/get_all_blobs_rs/src/main.rs new file mode 100644 index 000000000000..71f0ee815490 --- /dev/null +++ b/get_all_blobs_rs/src/main.rs @@ -0,0 +1,182 @@ +use std::{collections::HashMap, error::Error, fs, str::FromStr}; + +use alloy::{ + json_abi::{Function, InternalType, JsonAbi, Param}, + network::Ethereum, + primitives::{Address, Bytes, U256}, + providers::{Provider, ProviderBuilder, RootProvider}, + rpc::types::{Block, Transaction}, +}; +use client::EigenClientRetriever; +use futures::StreamExt; +use reqwest; +use serde::{Deserialize, Serialize}; + +mod blob_info; +mod client; +mod generated; + +#[derive(Debug, Serialize, Deserialize)] +struct BlobData { + commitment: String, + blob: String, +} + +#[derive(Debug)] +struct StoredBatchInfo { + batch_number: u64, + batch_hash: [u8; 32], + index_repeated_storage_changes: u64, + number_of_layer1_txs: U256, + priority_operations_hash: [u8; 32], + l2_logs_tree_root: [u8; 32], + timestamp: U256, + commitment: [u8; 32], +} + +#[derive(Debug)] +struct CommitBatchInfo { + batch_number: u64, + timestamp: u64, + index_repeated_storage_changes: u64, + new_state_root: [u8; 32], + number_of_layer1_txs: U256, + priority_operations_hash: [u8; 32], + bootloader_heap_initial_contents_hash: [u8; 32], + events_queue_state_hash: [u8; 32], + system_logs: Bytes, + pubdata_commitments: Bytes, +} + +const EIGENDA_API_URL: &str = "https://disperser-holesky.eigenda.xyz:443"; + +async fn get_blob(commitment: &str) -> anyhow::Result> { + let client = EigenClientRetriever::new(EIGENDA_API_URL).await.unwrap(); + let data = client + .get_blob_data(&commitment) + .await + .unwrap() + .unwrap_or_default(); // TODO: Remove unwrap + Ok(data) +} + +fn hex_to_utf8(hex: &str) -> Result> { + let hex = hex.trim_start_matches("0x"); + let bytes = hex::decode(hex)?; + String::from_utf8(bytes).map_err(|e| e.into()) +} + +fn bytes_to_hex(bytes: &[u8]) -> String { + hex::encode(bytes) +} + +async fn get_transactions( + provider: &RootProvider< + alloy::transports::http::Http, + Ethereum, + >, + validator_timelock_address: Address, + commit_batches_selector: &str, +) -> Result<(), Box> { + let latest_block = provider.get_block_number().await?; + let mut json_array = Vec::new(); + + // Define ABI for the function + // let abi = JsonAbi::new(vec![Function { + // name: "commitBatchesSharedBridge".to_string(), + // inputs: vec![ + // Param { + // name: "_chainId".to_string(), + // ty: "uint256".to_string(), + // components: vec![], + // internal_type: Some(InternalType::Uint(256)), + // }, + // // Add other parameters as needed + // // This is simplified for brevity + // ], + // outputs: vec![], + // state_mutability: "nonpayable".to_string(), + // }]); + + for block_number in 0..=latest_block { + if let Ok(Some(block)) = provider + .get_block_by_number(block_number.into(), true) + .await + { + for tx in block.transactions.into_transactions() { + if let Some(to) = tx.to { + if to == validator_timelock_address { + println!("Validator timelock match!"); + // if let Some(input) = tx.input { + let input = tx.input; + let selector = &input[0..4]; + if selector == hex::decode(commit_batches_selector).unwrap() { + println!("Commit batches selector match!"); + // Decode parameters + // Note: This is simplified. You'll need to implement proper ABI decoding + if let Ok(decoded) = decode_input(&input[4..]) { + let commitment = + hex::decode(&decoded.pubdata_commitments[4..]).unwrap(); + let commitment = hex::encode(&commitment); + let blob = get_blob(&commitment).await?; + + json_array.push(BlobData { + commitment, + blob: bytes_to_hex(&blob), + }); + } + } + // } + } + } + } + } + } + + if json_array.is_empty() { + println!("\x1b[31mNo transactions found.\x1b[0m"); + return Ok(()); + } + + let json_string = serde_json::to_string_pretty(&json_array)?; + fs::write("blob_data.json", json_string)?; + println!("\x1b[32mData stored in blob_data.json file.\x1b[0m"); + + Ok(()) +} + +// This is a placeholder for actual ABI decoding implementation +fn decode_input(input: &[u8]) -> Result> { + // Implement proper ABI decoding here + // This is just a placeholder + todo!("Implement proper ABI decoding") +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // let args: Vec = std::env::args().collect(); + + // if args.len() != 3 { + // eprintln!("Usage: {} validatorTimelockAddress=
commitBatchesSharedBridge_functionSelector=", args[0]); + // std::process::exit(1); + // } + + let validator_timelock_address = + Address::from_str("0x95af79aAB990f9740c029013ef18f3D3d666B4e8")?; + let commit_batches_selector = "6edd4f12"; + + let url = alloy::transports::http::reqwest::Url::from_str(&"http://127.0.0.1:8545").unwrap(); + let provider: RootProvider< + alloy::transports::http::Http, + Ethereum, + > = RootProvider::new_http(url); + + get_transactions( + &provider, + validator_timelock_address, + commit_batches_selector, + ) + .await?; + + Ok(()) +} From 138dd1800615df2acd2e8cd6a2ebfeacb7daa2fc Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Thu, 7 Nov 2024 13:18:20 -0300 Subject: [PATCH 11/18] remove get_all_blob js implementation --- Cargo.lock | 2 +- Cargo.toml | 3 +- get_all_blobs/.gitignore | 1 - .../Cargo.toml | 2 +- get_all_blobs/Makefile | 37 - get_all_blobs/README.md | 35 - .../abi/commitBatchesSharedBridge.json | 119 +++ get_all_blobs/getallblobs.js | 257 ------ get_all_blobs/package-lock.json | 866 ------------------ get_all_blobs/package.json | 15 - .../src/blob_info.rs | 0 .../src/client.rs | 0 .../src/generated/common.rs | 0 .../src/generated/disperser.rs | 0 .../src/generated/mod.rs | 0 get_all_blobs/src/main.rs | 142 +++ get_all_blobs_rs/src/main.rs | 182 ---- 17 files changed, 265 insertions(+), 1396 deletions(-) rename {get_all_blobs_rs => get_all_blobs}/Cargo.toml (96%) delete mode 100644 get_all_blobs/Makefile delete mode 100644 get_all_blobs/README.md create mode 100644 get_all_blobs/abi/commitBatchesSharedBridge.json delete mode 100644 get_all_blobs/getallblobs.js delete mode 100644 get_all_blobs/package-lock.json delete mode 100644 get_all_blobs/package.json rename {get_all_blobs_rs => get_all_blobs}/src/blob_info.rs (100%) rename {get_all_blobs_rs => get_all_blobs}/src/client.rs (100%) rename {get_all_blobs_rs => get_all_blobs}/src/generated/common.rs (100%) rename {get_all_blobs_rs => get_all_blobs}/src/generated/disperser.rs (100%) rename {get_all_blobs_rs => get_all_blobs}/src/generated/mod.rs (100%) create mode 100644 get_all_blobs/src/main.rs delete mode 100644 get_all_blobs_rs/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 3ad74027c0ec..88f38b88d8b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4133,7 +4133,7 @@ dependencies = [ ] [[package]] -name = "get_all_blobs_rs" +name = "get_all_blobs" version = "0.1.0" dependencies = [ "alloy", diff --git a/Cargo.toml b/Cargo.toml index 8a638c110418..9de60c7dca23 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -78,7 +78,8 @@ members = [ # Test infrastructure "core/tests/test_account", "core/tests/loadnext", - "core/tests/vm-benchmark", "get_all_blobs_rs", + "core/tests/vm-benchmark", + "get_all_blobs", ] resolver = "2" diff --git a/get_all_blobs/.gitignore b/get_all_blobs/.gitignore index d2f27f4fc30b..a1ee59a11803 100644 --- a/get_all_blobs/.gitignore +++ b/get_all_blobs/.gitignore @@ -1,2 +1 @@ -eigenda-proxy/ blob_data.json diff --git a/get_all_blobs_rs/Cargo.toml b/get_all_blobs/Cargo.toml similarity index 96% rename from get_all_blobs_rs/Cargo.toml rename to get_all_blobs/Cargo.toml index 585c6cb42475..325868bc5b07 100644 --- a/get_all_blobs_rs/Cargo.toml +++ b/get_all_blobs/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "get_all_blobs_rs" +name = "get_all_blobs" version.workspace = true edition.workspace = true authors.workspace = true diff --git a/get_all_blobs/Makefile b/get_all_blobs/Makefile deleted file mode 100644 index fce6910b5248..000000000000 --- a/get_all_blobs/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -.PHONY: install getallblobs - -install: - npm install - -clone-proxy: - @if [ ! -d eigenda-proxy ]; then \ - git clone https://github.com/Layr-Labs/eigenda-proxy.git; \ - fi - -setup-proxy: clone-proxy - @echo "Installing proxy dependencies" - cd eigenda-proxy && make - -run-proxy: setup-proxy - @if [ -z "$(PRIVATE_KEY)" ]; then \ - echo "Error: PRIVATE_KEY is not set"; \ - exit 1; \ - fi - cd eigenda-proxy && ./bin/eigenda-proxy \ - --addr 127.0.0.1 \ - --port 4242 \ - --eigenda.disperser-rpc disperser-holesky.eigenda.xyz:443 \ - --eigenda.signer-private-key-hex $(PRIVATE_KEY) \ - --eigenda.eth-rpc https://ethereum-holesky-rpc.publicnode.com \ - --eigenda.svc-manager-addr 0xD4A7E1Bd8015057293f0D0A557088c286942e84b - -get-all-blobs: install - @if [ -z "$(VALIDATOR_TIMELOCK_ADDR)" ]; then \ - echo "Error: VALIDATOR_TIMELOCK_ADDR is not set"; \ - exit 1; \ - fi - @if [ -z "$(COMMIT_BATCHES_SB_FUNC_SELECTOR)" ]; then \ - echo "Error: COMMIT_BATCHES_SB_FUNC_SELECTOR is not set"; \ - exit 1; \ - fi - node getallblobs.js validatorTimelockAddress=$(VALIDATOR_TIMELOCK_ADDR) commitBatchesSharedBridge_functionSelector=$(COMMIT_BATCHES_SB_FUNC_SELECTOR) diff --git a/get_all_blobs/README.md b/get_all_blobs/README.md deleted file mode 100644 index 19e3bb46a5f1..000000000000 --- a/get_all_blobs/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# Get All Blobs - -This script retrieves all blobs commitments directly from L1, this script is set up to use an EigenDA proxy connected to -_holesky_, so the chain won't work if it was set up to run with a `Memstore` client implementation. - -To make use of this tool, you need to have `make` and `npm` installed. - -### Start Proxy - -Before running the command, you need to start the proxy. To do so, first export the variable `PRIVATE_KEY` (without 0x). -Then run the following command: - -``` -make run-proxy -``` - -### Run command: - -Run in a separate terminal: - -``` -make get-all-blobs VALIDATOR_TIMELOCK_ADDR= COMMIT_BATCHES_SB_FUNC_SELECTOR= -``` - -This generates a `blob_data.json` file, where blobs and commitments are stored. - -### Environment Variables - -`VALIDATOR_TIMELOCK_ADDR`: The address of the validator timelock. Check for `ValidatorTimelock deployed at: ` in `zkstack init` if running a local -node. - -`COMMIT_BATCHES_SB_FUNC_SELECTOR`: The function selector for commitBatchesSharedBridge. For a local node, this is -typically 0x6edd4f12. - -This variables can be exported in the shell in order to run `make get-all-blobs` without passing them as arguments. diff --git a/get_all_blobs/abi/commitBatchesSharedBridge.json b/get_all_blobs/abi/commitBatchesSharedBridge.json new file mode 100644 index 000000000000..877ce399c1c6 --- /dev/null +++ b/get_all_blobs/abi/commitBatchesSharedBridge.json @@ -0,0 +1,119 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint64", + "name": "batchNumber", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "indexRepeatedStorageChanges", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "numberOfLayer1Txs", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "priorityOperationsHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "l2LogsTreeRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + } + ], + "internalType": "struct IExecutor.StoredBatchInfo", + "name": "", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint64", + "name": "batchNumber", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "timestamp", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "indexRepeatedStorageChanges", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "newStateRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "numberOfLayer1Txs", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "priorityOperationsHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "bootloaderHeapInitialContentsHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "eventsQueueStateHash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "systemLogs", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "pubdataCommitments", + "type": "bytes" + } + ], + "internalType": "struct IExecutor.CommitBatchInfo[]", + "name": "_newBatchesData", + "type": "tuple[]" + } + ], + "name": "commitBatchesSharedBridge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/get_all_blobs/getallblobs.js b/get_all_blobs/getallblobs.js deleted file mode 100644 index a80d76b2d087..000000000000 --- a/get_all_blobs/getallblobs.js +++ /dev/null @@ -1,257 +0,0 @@ -const { Web3 } = require('web3'); -const web3 = new Web3('http://127.0.0.1:8545'); -const fs = require('fs'); - -const abi = [ - { - inputs: [ - { - internalType: 'uint256', - name: '_chainId', - type: 'uint256' - }, - { - components: [ - { - internalType: 'uint64', - name: 'batchNumber', - type: 'uint64' - }, - { - internalType: 'bytes32', - name: 'batchHash', - type: 'bytes32' - }, - { - internalType: 'uint64', - name: 'indexRepeatedStorageChanges', - type: 'uint64' - }, - { - internalType: 'uint256', - name: 'numberOfLayer1Txs', - type: 'uint256' - }, - { - internalType: 'bytes32', - name: 'priorityOperationsHash', - type: 'bytes32' - }, - { - internalType: 'bytes32', - name: 'l2LogsTreeRoot', - type: 'bytes32' - }, - { - internalType: 'uint256', - name: 'timestamp', - type: 'uint256' - }, - { - internalType: 'bytes32', - name: 'commitment', - type: 'bytes32' - } - ], - internalType: 'struct IExecutor.StoredBatchInfo', - name: '', - type: 'tuple' - }, - { - components: [ - { - internalType: 'uint64', - name: 'batchNumber', - type: 'uint64' - }, - { - internalType: 'uint64', - name: 'timestamp', - type: 'uint64' - }, - { - internalType: 'uint64', - name: 'indexRepeatedStorageChanges', - type: 'uint64' - }, - { - internalType: 'bytes32', - name: 'newStateRoot', - type: 'bytes32' - }, - { - internalType: 'uint256', - name: 'numberOfLayer1Txs', - type: 'uint256' - }, - { - internalType: 'bytes32', - name: 'priorityOperationsHash', - type: 'bytes32' - }, - { - internalType: 'bytes32', - name: 'bootloaderHeapInitialContentsHash', - type: 'bytes32' - }, - { - internalType: 'bytes32', - name: 'eventsQueueStateHash', - type: 'bytes32' - }, - { - internalType: 'bytes', - name: 'systemLogs', - type: 'bytes' - }, - { - internalType: 'bytes', - name: 'pubdataCommitments', - type: 'bytes' - } - ], - internalType: 'struct IExecutor.CommitBatchInfo[]', - name: '_newBatchesData', - type: 'tuple[]' - } - ], - name: 'commitBatchesSharedBridge', - outputs: [], - stateMutability: 'nonpayable', - type: 'function' - } -]; - -const contract = new web3.eth.Contract(abi); - -function hexToUtf8(hex) { - // Remove the '0x' prefix if present - if (hex.startsWith('0x')) { - hex = hex.slice(2); - } - - // Ensure the hex string has an even length - if (hex.length % 2 !== 0) { - throw new Error('Invalid hex string length'); - } - - // Convert hex string to a byte array - const bytes = []; - for (let i = 0; i < hex.length; i += 2) { - bytes.push(parseInt(hex.substr(i, 2), 16)); - } - - // Convert byte array to UTF-8 string - const utf8String = new TextDecoder('utf-8').decode(new Uint8Array(bytes)); - return utf8String; -} - -function uint8ArrayToHex(uint8Array) { - return Array.from(uint8Array) - .map((byte) => byte.toString(16).padStart(2, '0')) // Convert each byte to a 2-digit hex value - .join(''); // Join all the hex values into a single string -} - -async function getTransactions(validatorTimelockAddress, commitBatchesSharedBridge_functionSelector) { - const latestBlock = await web3.eth.getBlockNumber(); - let jsonArray = []; - for (let i = 0; i <= latestBlock; i++) { - const block = await web3.eth.getBlock(i, true); - await Promise.all( - block.transactions.map(async (tx) => { - if (tx.to && tx.to.toLowerCase() == validatorTimelockAddress.toLowerCase()) { - const input = tx.input; - const txSelector = input.slice(0, 10); - if (txSelector == commitBatchesSharedBridge_functionSelector) { - const functionAbi = contract.options.jsonInterface.find( - (item) => item.name === 'commitBatchesSharedBridge' - ); - const decodedParams = web3.eth.abi.decodeParameters( - functionAbi.inputs, - input.slice(10) // Remove the function selector (first 10 characters of the calldata) - ); - commitment = hexToUtf8(decodedParams._newBatchesData[0].pubdataCommitments.slice(4)); - let blob = await get(commitment); - const blobHex = uint8ArrayToHex(blob); - jsonArray.push({ - commitment: commitment, - blob: blobHex - }); - } - } - }) - ); - } - if (jsonArray.length == 0) { - console.error('\x1b[31m%s\x1b[0m', 'No transactions found.'); - return; - } - const jsonString = JSON.stringify(jsonArray, null, 2); - fs.writeFileSync('blob_data.json', jsonString, 'utf8'); - console.log('\x1b[32m%s\x1b[0m', 'Data stored in blob_data.json file.'); -} - -async function get(commitment) { - try { - const url = `http://127.0.0.1:4242/get/0x${commitment}`; - - const response = await fetch(url); - - if (response.ok) { - // Expecting the response body to be binary data - const body = await response.arrayBuffer(); - return new Uint8Array(body); - } else { - return []; // Return empty array if the response is not successful - } - } catch (error) { - // Handle any errors - console.error('Error fetching data:', error); - throw error; // Re-throw the error or return an empty array, depending on requirements - } -} - -function getArguments() { - const args = process.argv.slice(2); // Get arguments after the first two (which are node and script path) - - let validatorTimelockAddress = null; - let commitBatchesSharedBridge_functionSelector = null; - args.forEach((arg) => { - const [key, value] = arg.split('='); - if (key === 'validatorTimelockAddress') { - validatorTimelockAddress = value; - } else if (key === 'commitBatchesSharedBridge_functionSelector') { - commitBatchesSharedBridge_functionSelector = value; - } - }); - - // Check if both arguments are provided - if (!validatorTimelockAddress || !commitBatchesSharedBridge_functionSelector) { - console.error( - 'Usage: node getallblobs.js validatorTimelockAddress= commitBatchesSharedBridge_functionSelector=' - ); - process.exit(1); // Exit with error - } - - return { validatorTimelockAddress, commitBatchesSharedBridge_functionSelector }; -} - -function main() { - // Values for local node: - // validatorTimelockAddress = check in zk init - // commitBatchesSharedBridge_functionSelector = "0x6edd4f12" - const { validatorTimelockAddress, commitBatchesSharedBridge_functionSelector } = getArguments(); - getTransactions(validatorTimelockAddress, commitBatchesSharedBridge_functionSelector); -} - -main(); - -//Contracts being called in L1: -//Chain Admin -//Diamond Proxy -//Governance -//Validator Timelock //6edd4f12 function selector commitBatchesSharedBridge -//BridgeHub Proxy -//Transparent Proxy -//Create2 Factory -//Contracts Create2Factory (verifier) diff --git a/get_all_blobs/package-lock.json b/get_all_blobs/package-lock.json deleted file mode 100644 index c04d8c6632a2..000000000000 --- a/get_all_blobs/package-lock.json +++ /dev/null @@ -1,866 +0,0 @@ -{ - "name": "get_all_blobs", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "get_all_blobs", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "web3": "^4.12.1" - } - }, - "node_modules/@adraffy/ens-normalize": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.0.tgz", - "integrity": "sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==" - }, - "node_modules/@ethereumjs/rlp": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", - "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", - "bin": { - "rlp": "bin/rlp" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@noble/curves": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", - "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", - "dependencies": { - "@noble/hashes": "1.4.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/hashes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/base": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", - "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip32": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", - "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", - "dependencies": { - "@noble/curves": "~1.4.0", - "@noble/hashes": "~1.4.0", - "@scure/base": "~1.1.6" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip39": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", - "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", - "dependencies": { - "@noble/hashes": "~1.4.0", - "@scure/base": "~1.1.6" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@types/node": { - "version": "22.9.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", - "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", - "dependencies": { - "undici-types": "~6.19.8" - } - }, - "node_modules/@types/ws": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", - "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/abitype": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/abitype/-/abitype-0.7.1.tgz", - "integrity": "sha512-VBkRHTDZf9Myaek/dO3yMmOzB/y2s3Zo6nVU7yaw1G+TvCHAjwaJzNGN9yo4K5D8bU/VZXKP1EJpRhFr862PlQ==", - "peerDependencies": { - "typescript": ">=4.9.4", - "zod": "^3 >=3.19.1" - }, - "peerDependenciesMeta": { - "zod": { - "optional": true - } - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "bin": { - "crc32": "bin/crc32.njs" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/cross-fetch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", - "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", - "dependencies": { - "node-fetch": "^2.6.12" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ethereum-cryptography": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", - "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", - "dependencies": { - "@noble/curves": "1.4.2", - "@noble/hashes": "1.4.0", - "@scure/bip32": "1.4.0", - "@scure/bip39": "1.3.0" - } - }, - "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dependencies": { - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isomorphic-ws": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", - "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", - "peerDependencies": { - "ws": "*" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" - }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/web3": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/web3/-/web3-4.14.0.tgz", - "integrity": "sha512-LohqxtSXXl4uA3abPK0bB91dziA5GygOLtO83p8bQzY+CYxp1fgGfiD8ahDRcu+WBttUhRFZmCsOhmrmP7HtTA==", - "dependencies": { - "web3-core": "^4.7.0", - "web3-errors": "^1.3.0", - "web3-eth": "^4.10.0", - "web3-eth-abi": "^4.3.0", - "web3-eth-accounts": "^4.2.1", - "web3-eth-contract": "^4.7.0", - "web3-eth-ens": "^4.4.0", - "web3-eth-iban": "^4.0.7", - "web3-eth-personal": "^4.1.0", - "web3-net": "^4.1.0", - "web3-providers-http": "^4.2.0", - "web3-providers-ws": "^4.0.8", - "web3-rpc-methods": "^1.3.0", - "web3-rpc-providers": "^1.0.0-rc.2", - "web3-types": "^1.8.1", - "web3-utils": "^4.3.2", - "web3-validator": "^2.0.6" - }, - "engines": { - "node": ">=14.0.0", - "npm": ">=6.12.0" - } - }, - "node_modules/web3-core": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-4.7.0.tgz", - "integrity": "sha512-skP4P56fhlrE+rIuS4WY9fTdja1DPml2xrrDmv+vQhPtmSFBs7CqesycIRLQh4dK1D4de/a23tkX6DLYdUt3nA==", - "dependencies": { - "web3-errors": "^1.3.0", - "web3-eth-accounts": "^4.2.1", - "web3-eth-iban": "^4.0.7", - "web3-providers-http": "^4.2.0", - "web3-providers-ws": "^4.0.8", - "web3-types": "^1.8.1", - "web3-utils": "^4.3.2", - "web3-validator": "^2.0.6" - }, - "engines": { - "node": ">=14", - "npm": ">=6.12.0" - }, - "optionalDependencies": { - "web3-providers-ipc": "^4.0.7" - } - }, - "node_modules/web3-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/web3-errors/-/web3-errors-1.3.0.tgz", - "integrity": "sha512-j5JkAKCtuVMbY3F5PYXBqg1vWrtF4jcyyMY1rlw8a4PV67AkqlepjGgpzWJZd56Mt+TvHy6DA1F/3Id8LatDSQ==", - "dependencies": { - "web3-types": "^1.7.0" - }, - "engines": { - "node": ">=14", - "npm": ">=6.12.0" - } - }, - "node_modules/web3-eth": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-4.10.0.tgz", - "integrity": "sha512-8d7epCOm1hv/xGnOW8pWNkO5Ze9b+LKl81Pa1VUdRi2xZKtBaQsk+4qg6EnqeDF6SPpL502wNmX6TAB69vGBWw==", - "dependencies": { - "setimmediate": "^1.0.5", - "web3-core": "^4.7.0", - "web3-errors": "^1.3.0", - "web3-eth-abi": "^4.3.0", - "web3-eth-accounts": "^4.2.1", - "web3-net": "^4.1.0", - "web3-providers-ws": "^4.0.8", - "web3-rpc-methods": "^1.3.0", - "web3-types": "^1.8.1", - "web3-utils": "^4.3.2", - "web3-validator": "^2.0.6" - }, - "engines": { - "node": ">=14", - "npm": ">=6.12.0" - } - }, - "node_modules/web3-eth-abi": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-4.3.0.tgz", - "integrity": "sha512-OqZPGGxHmfKJt33BfpclEMmWvnnLJ/B+jVTnVagd2OIU1kIv09xf/E60ei0eGeG612uFy/pPq31u4RidF/gf6g==", - "dependencies": { - "abitype": "0.7.1", - "web3-errors": "^1.3.0", - "web3-types": "^1.8.1", - "web3-utils": "^4.3.2", - "web3-validator": "^2.0.6" - }, - "engines": { - "node": ">=14", - "npm": ">=6.12.0" - } - }, - "node_modules/web3-eth-accounts": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-4.2.1.tgz", - "integrity": "sha512-aOlEZFzqAgKprKs7+DGArU4r9b+ILBjThpeq42aY7LAQcP+mSpsWcQgbIRK3r/n3OwTYZ3aLPk0Ih70O/LwnYA==", - "dependencies": { - "@ethereumjs/rlp": "^4.0.1", - "crc-32": "^1.2.2", - "ethereum-cryptography": "^2.0.0", - "web3-errors": "^1.3.0", - "web3-types": "^1.7.0", - "web3-utils": "^4.3.1", - "web3-validator": "^2.0.6" - }, - "engines": { - "node": ">=14", - "npm": ">=6.12.0" - } - }, - "node_modules/web3-eth-contract": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-4.7.0.tgz", - "integrity": "sha512-fdStoBOjFyMHwlyJmSUt/BTDL1ATwKGmG3zDXQ/zTKlkkW/F/074ut0Vry4GuwSBg9acMHc0ycOiZx9ZKjNHsw==", - "dependencies": { - "@ethereumjs/rlp": "^5.0.2", - "web3-core": "^4.5.1", - "web3-errors": "^1.3.0", - "web3-eth": "^4.8.2", - "web3-eth-abi": "^4.2.3", - "web3-types": "^1.7.0", - "web3-utils": "^4.3.1", - "web3-validator": "^2.0.6" - }, - "engines": { - "node": ">=14", - "npm": ">=6.12.0" - } - }, - "node_modules/web3-eth-contract/node_modules/@ethereumjs/rlp": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-5.0.2.tgz", - "integrity": "sha512-DziebCdg4JpGlEqEdGgXmjqcFoJi+JGulUXwEjsZGAscAQ7MyD/7LE/GVCP29vEQxKc7AAwjT3A2ywHp2xfoCA==", - "bin": { - "rlp": "bin/rlp.cjs" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/web3-eth-ens": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-4.4.0.tgz", - "integrity": "sha512-DeyVIS060hNV9g8dnTx92syqvgbvPricE3MerCxe/DquNZT3tD8aVgFfq65GATtpCgDDJffO2bVeHp3XBemnSQ==", - "dependencies": { - "@adraffy/ens-normalize": "^1.8.8", - "web3-core": "^4.5.0", - "web3-errors": "^1.2.0", - "web3-eth": "^4.8.0", - "web3-eth-contract": "^4.5.0", - "web3-net": "^4.1.0", - "web3-types": "^1.7.0", - "web3-utils": "^4.3.0", - "web3-validator": "^2.0.6" - }, - "engines": { - "node": ">=14", - "npm": ">=6.12.0" - } - }, - "node_modules/web3-eth-iban": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-4.0.7.tgz", - "integrity": "sha512-8weKLa9KuKRzibC87vNLdkinpUE30gn0IGY027F8doeJdcPUfsa4IlBgNC4k4HLBembBB2CTU0Kr/HAOqMeYVQ==", - "dependencies": { - "web3-errors": "^1.1.3", - "web3-types": "^1.3.0", - "web3-utils": "^4.0.7", - "web3-validator": "^2.0.3" - }, - "engines": { - "node": ">=14", - "npm": ">=6.12.0" - } - }, - "node_modules/web3-eth-personal": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-4.1.0.tgz", - "integrity": "sha512-RFN83uMuvA5cu1zIwwJh9A/bAj0OBxmGN3tgx19OD/9ygeUZbifOL06jgFzN0t+1ekHqm3DXYQM8UfHpXi7yDQ==", - "dependencies": { - "web3-core": "^4.6.0", - "web3-eth": "^4.9.0", - "web3-rpc-methods": "^1.3.0", - "web3-types": "^1.8.0", - "web3-utils": "^4.3.1", - "web3-validator": "^2.0.6" - }, - "engines": { - "node": ">=14", - "npm": ">=6.12.0" - } - }, - "node_modules/web3-net": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-4.1.0.tgz", - "integrity": "sha512-WWmfvHVIXWEoBDWdgKNYKN8rAy6SgluZ0abyRyXOL3ESr7ym7pKWbfP4fjApIHlYTh8tNqkrdPfM4Dyi6CA0SA==", - "dependencies": { - "web3-core": "^4.4.0", - "web3-rpc-methods": "^1.3.0", - "web3-types": "^1.6.0", - "web3-utils": "^4.3.0" - }, - "engines": { - "node": ">=14", - "npm": ">=6.12.0" - } - }, - "node_modules/web3-providers-http": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-4.2.0.tgz", - "integrity": "sha512-IPMnDtHB7dVwaB7/mMxAZzyq7d5ezfO1+Vw0bNfAeIi7gaDlJiggp85SdyAfOgov8AMUA/dyiY72kQ0KmjXKvQ==", - "dependencies": { - "cross-fetch": "^4.0.0", - "web3-errors": "^1.3.0", - "web3-types": "^1.7.0", - "web3-utils": "^4.3.1" - }, - "engines": { - "node": ">=14", - "npm": ">=6.12.0" - } - }, - "node_modules/web3-providers-ipc": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-4.0.7.tgz", - "integrity": "sha512-YbNqY4zUvIaK2MHr1lQFE53/8t/ejHtJchrWn9zVbFMGXlTsOAbNoIoZWROrg1v+hCBvT2c9z8xt7e/+uz5p1g==", - "optional": true, - "dependencies": { - "web3-errors": "^1.1.3", - "web3-types": "^1.3.0", - "web3-utils": "^4.0.7" - }, - "engines": { - "node": ">=14", - "npm": ">=6.12.0" - } - }, - "node_modules/web3-providers-ws": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-4.0.8.tgz", - "integrity": "sha512-goJdgata7v4pyzHRsg9fSegUG4gVnHZSHODhNnn6J93ykHkBI1nz4fjlGpcQLUMi4jAMz6SHl9Ibzs2jj9xqPw==", - "dependencies": { - "@types/ws": "8.5.3", - "isomorphic-ws": "^5.0.0", - "web3-errors": "^1.2.0", - "web3-types": "^1.7.0", - "web3-utils": "^4.3.1", - "ws": "^8.17.1" - }, - "engines": { - "node": ">=14", - "npm": ">=6.12.0" - } - }, - "node_modules/web3-rpc-methods": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/web3-rpc-methods/-/web3-rpc-methods-1.3.0.tgz", - "integrity": "sha512-/CHmzGN+IYgdBOme7PdqzF+FNeMleefzqs0LVOduncSaqsppeOEoskLXb2anSpzmQAP3xZJPaTrkQPWSJMORig==", - "dependencies": { - "web3-core": "^4.4.0", - "web3-types": "^1.6.0", - "web3-validator": "^2.0.6" - }, - "engines": { - "node": ">=14", - "npm": ">=6.12.0" - } - }, - "node_modules/web3-rpc-providers": { - "version": "1.0.0-rc.2", - "resolved": "https://registry.npmjs.org/web3-rpc-providers/-/web3-rpc-providers-1.0.0-rc.2.tgz", - "integrity": "sha512-ocFIEXcBx/DYQ90HhVepTBUVnL9pGsZw8wyPb1ZINSenwYus9SvcFkjU1Hfvd/fXjuhAv2bUVch9vxvMx1mXAQ==", - "dependencies": { - "web3-errors": "^1.3.0", - "web3-providers-http": "^4.2.0", - "web3-providers-ws": "^4.0.8", - "web3-types": "^1.7.0", - "web3-utils": "^4.3.1", - "web3-validator": "^2.0.6" - }, - "engines": { - "node": ">=14", - "npm": ">=6.12.0" - } - }, - "node_modules/web3-types": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/web3-types/-/web3-types-1.8.1.tgz", - "integrity": "sha512-isspsvQbBJFUkJYz2Badb7dz/BrLLLpOop/WmnL5InyYMr7kYYc8038NYO7Vkp1M7Bupa/wg+yALvBm7EGbyoQ==", - "engines": { - "node": ">=14", - "npm": ">=6.12.0" - } - }, - "node_modules/web3-utils": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-4.3.2.tgz", - "integrity": "sha512-bEFpYEBMf6ER78Uvj2mdsCbaLGLK9kABOsa3TtXOEEhuaMy/RK0KlRkKoZ2vmf/p3hB8e1q5erknZ6Hy7AVp7A==", - "dependencies": { - "ethereum-cryptography": "^2.0.0", - "eventemitter3": "^5.0.1", - "web3-errors": "^1.3.0", - "web3-types": "^1.8.1", - "web3-validator": "^2.0.6" - }, - "engines": { - "node": ">=14", - "npm": ">=6.12.0" - } - }, - "node_modules/web3-validator": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/web3-validator/-/web3-validator-2.0.6.tgz", - "integrity": "sha512-qn9id0/l1bWmvH4XfnG/JtGKKwut2Vokl6YXP5Kfg424npysmtRLe9DgiNBM9Op7QL/aSiaA0TVXibuIuWcizg==", - "dependencies": { - "ethereum-cryptography": "^2.0.0", - "util": "^0.12.5", - "web3-errors": "^1.2.0", - "web3-types": "^1.6.0", - "zod": "^3.21.4" - }, - "engines": { - "node": ">=14", - "npm": ">=6.12.0" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/zod": { - "version": "3.23.8", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", - "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - } - } -} diff --git a/get_all_blobs/package.json b/get_all_blobs/package.json deleted file mode 100644 index 2f3f16d0b2c1..000000000000 --- a/get_all_blobs/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "get_all_blobs", - "version": "1.0.0", - "description": "", - "main": "getallblobs.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "web3": "^4.12.1" - } -} diff --git a/get_all_blobs_rs/src/blob_info.rs b/get_all_blobs/src/blob_info.rs similarity index 100% rename from get_all_blobs_rs/src/blob_info.rs rename to get_all_blobs/src/blob_info.rs diff --git a/get_all_blobs_rs/src/client.rs b/get_all_blobs/src/client.rs similarity index 100% rename from get_all_blobs_rs/src/client.rs rename to get_all_blobs/src/client.rs diff --git a/get_all_blobs_rs/src/generated/common.rs b/get_all_blobs/src/generated/common.rs similarity index 100% rename from get_all_blobs_rs/src/generated/common.rs rename to get_all_blobs/src/generated/common.rs diff --git a/get_all_blobs_rs/src/generated/disperser.rs b/get_all_blobs/src/generated/disperser.rs similarity index 100% rename from get_all_blobs_rs/src/generated/disperser.rs rename to get_all_blobs/src/generated/disperser.rs diff --git a/get_all_blobs_rs/src/generated/mod.rs b/get_all_blobs/src/generated/mod.rs similarity index 100% rename from get_all_blobs_rs/src/generated/mod.rs rename to get_all_blobs/src/generated/mod.rs diff --git a/get_all_blobs/src/main.rs b/get_all_blobs/src/main.rs new file mode 100644 index 000000000000..18cf5958cc96 --- /dev/null +++ b/get_all_blobs/src/main.rs @@ -0,0 +1,142 @@ +use std::{fs, str::FromStr}; + +use alloy::{ + dyn_abi::JsonAbiExt, + json_abi::JsonAbi, + network::Ethereum, + primitives::Address, + providers::{Provider, RootProvider}, +}; +use client::EigenClientRetriever; +use serde::{Deserialize, Serialize}; + +mod blob_info; +mod client; +mod generated; + +#[derive(Debug, Serialize, Deserialize)] +struct BlobData { + pub commitment: String, + pub blob: String, +} + +const EIGENDA_API_URL: &str = "https://disperser-holesky.eigenda.xyz:443"; + +async fn get_blob(commitment: &str) -> anyhow::Result> { + let client = EigenClientRetriever::new(EIGENDA_API_URL).await?; + let data = client + .get_blob_data(&commitment) + .await? + .ok_or_else(|| anyhow::anyhow!("Blob not found"))?; + Ok(data) +} + +async fn get_transactions( + provider: &RootProvider< + alloy::transports::http::Http, + Ethereum, + >, + validator_timelock_address: Address, + commit_batches_selector: &str, +) -> anyhow::Result<()> { + let latest_block = provider.get_block_number().await?; + let mut json_array = Vec::new(); + + for block_number in 0..=latest_block { + if let Ok(Some(block)) = provider + .get_block_by_number(block_number.into(), true) + .await + { + for tx in block.transactions.into_transactions() { + if let Some(to) = tx.to { + if to == validator_timelock_address { + let input = tx.input; + let selector = &input[0..4]; + if selector == hex::decode(commit_batches_selector)? { + if let Ok(decoded) = decode_blob_data_input(&input[4..]).await { + json_array.push(decoded); + } + } + } + } + } + } + } + + if json_array.is_empty() { + println!("\x1b[31mNo transactions found.\x1b[0m"); + return Ok(()); + } + + let json_string = serde_json::to_string_pretty(&json_array)?; + fs::write("blob_data.json", json_string)?; + println!("\x1b[32mData stored in blob_data.json file.\x1b[0m"); + + Ok(()) +} + +async fn decode_blob_data_input(input: &[u8]) -> anyhow::Result { + let path = "./abi/commitBatchesSharedBridge.json"; + let json = std::fs::read_to_string(path)?; + let json_abi: JsonAbi = serde_json::from_str(&json)?; + let function = json_abi + .functions + .iter() + .find(|f| f.0 == "commitBatchesSharedBridge") + .ok_or(anyhow::anyhow!("Function not found"))? + .1; + + let decoded = function[0].abi_decode_input(input, true)?; + let commit_batch_info = decoded[2].as_array().ok_or(anyhow::anyhow!( + "CommitBatchInfo cannot be represented as an array" + ))?[0] + .as_tuple() + .ok_or(anyhow::anyhow!( + "CommitBatchInfo components cannot be represented as a tuple" + ))?; + let pubdata_commitments = commit_batch_info.last().ok_or(anyhow::anyhow!( + "pubdata_commitments not found in commitBatchesSharedBridge input" + ))?; + let pubdata_commitments_bytes = pubdata_commitments + .as_bytes() + .ok_or(anyhow::anyhow!("pubdata_commitments is not a bytes array"))?; + + let commitment = hex::decode(&pubdata_commitments_bytes[1..])?; + let commitment = hex::encode(&commitment); + let blob = get_blob(&commitment).await?; + + Ok(BlobData { + commitment, + blob: hex::encode(blob), + }) +} + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + // let args: Vec = std::env::args().collect(); + + // if args.len() != 3 { + // eprintln!("Usage: {} validatorTimelockAddress=
commitBatchesSharedBridge_functionSelector=", args[0]); + // std::process::exit(1); + // } + let validator_timelock_address = + Address::from_str("0x95af79aAB990f9740c029013ef18f3D3d666B4e8")?; + let commit_batches_selector = "6edd4f12"; + + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); + + let url = alloy::transports::http::reqwest::Url::from_str(&"http://127.0.0.1:8545")?; + let provider: RootProvider< + alloy::transports::http::Http, + Ethereum, + > = RootProvider::new_http(url); + + get_transactions( + &provider, + validator_timelock_address, + commit_batches_selector, + ) + .await?; + + Ok(()) +} diff --git a/get_all_blobs_rs/src/main.rs b/get_all_blobs_rs/src/main.rs deleted file mode 100644 index 71f0ee815490..000000000000 --- a/get_all_blobs_rs/src/main.rs +++ /dev/null @@ -1,182 +0,0 @@ -use std::{collections::HashMap, error::Error, fs, str::FromStr}; - -use alloy::{ - json_abi::{Function, InternalType, JsonAbi, Param}, - network::Ethereum, - primitives::{Address, Bytes, U256}, - providers::{Provider, ProviderBuilder, RootProvider}, - rpc::types::{Block, Transaction}, -}; -use client::EigenClientRetriever; -use futures::StreamExt; -use reqwest; -use serde::{Deserialize, Serialize}; - -mod blob_info; -mod client; -mod generated; - -#[derive(Debug, Serialize, Deserialize)] -struct BlobData { - commitment: String, - blob: String, -} - -#[derive(Debug)] -struct StoredBatchInfo { - batch_number: u64, - batch_hash: [u8; 32], - index_repeated_storage_changes: u64, - number_of_layer1_txs: U256, - priority_operations_hash: [u8; 32], - l2_logs_tree_root: [u8; 32], - timestamp: U256, - commitment: [u8; 32], -} - -#[derive(Debug)] -struct CommitBatchInfo { - batch_number: u64, - timestamp: u64, - index_repeated_storage_changes: u64, - new_state_root: [u8; 32], - number_of_layer1_txs: U256, - priority_operations_hash: [u8; 32], - bootloader_heap_initial_contents_hash: [u8; 32], - events_queue_state_hash: [u8; 32], - system_logs: Bytes, - pubdata_commitments: Bytes, -} - -const EIGENDA_API_URL: &str = "https://disperser-holesky.eigenda.xyz:443"; - -async fn get_blob(commitment: &str) -> anyhow::Result> { - let client = EigenClientRetriever::new(EIGENDA_API_URL).await.unwrap(); - let data = client - .get_blob_data(&commitment) - .await - .unwrap() - .unwrap_or_default(); // TODO: Remove unwrap - Ok(data) -} - -fn hex_to_utf8(hex: &str) -> Result> { - let hex = hex.trim_start_matches("0x"); - let bytes = hex::decode(hex)?; - String::from_utf8(bytes).map_err(|e| e.into()) -} - -fn bytes_to_hex(bytes: &[u8]) -> String { - hex::encode(bytes) -} - -async fn get_transactions( - provider: &RootProvider< - alloy::transports::http::Http, - Ethereum, - >, - validator_timelock_address: Address, - commit_batches_selector: &str, -) -> Result<(), Box> { - let latest_block = provider.get_block_number().await?; - let mut json_array = Vec::new(); - - // Define ABI for the function - // let abi = JsonAbi::new(vec![Function { - // name: "commitBatchesSharedBridge".to_string(), - // inputs: vec![ - // Param { - // name: "_chainId".to_string(), - // ty: "uint256".to_string(), - // components: vec![], - // internal_type: Some(InternalType::Uint(256)), - // }, - // // Add other parameters as needed - // // This is simplified for brevity - // ], - // outputs: vec![], - // state_mutability: "nonpayable".to_string(), - // }]); - - for block_number in 0..=latest_block { - if let Ok(Some(block)) = provider - .get_block_by_number(block_number.into(), true) - .await - { - for tx in block.transactions.into_transactions() { - if let Some(to) = tx.to { - if to == validator_timelock_address { - println!("Validator timelock match!"); - // if let Some(input) = tx.input { - let input = tx.input; - let selector = &input[0..4]; - if selector == hex::decode(commit_batches_selector).unwrap() { - println!("Commit batches selector match!"); - // Decode parameters - // Note: This is simplified. You'll need to implement proper ABI decoding - if let Ok(decoded) = decode_input(&input[4..]) { - let commitment = - hex::decode(&decoded.pubdata_commitments[4..]).unwrap(); - let commitment = hex::encode(&commitment); - let blob = get_blob(&commitment).await?; - - json_array.push(BlobData { - commitment, - blob: bytes_to_hex(&blob), - }); - } - } - // } - } - } - } - } - } - - if json_array.is_empty() { - println!("\x1b[31mNo transactions found.\x1b[0m"); - return Ok(()); - } - - let json_string = serde_json::to_string_pretty(&json_array)?; - fs::write("blob_data.json", json_string)?; - println!("\x1b[32mData stored in blob_data.json file.\x1b[0m"); - - Ok(()) -} - -// This is a placeholder for actual ABI decoding implementation -fn decode_input(input: &[u8]) -> Result> { - // Implement proper ABI decoding here - // This is just a placeholder - todo!("Implement proper ABI decoding") -} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // let args: Vec = std::env::args().collect(); - - // if args.len() != 3 { - // eprintln!("Usage: {} validatorTimelockAddress=
commitBatchesSharedBridge_functionSelector=", args[0]); - // std::process::exit(1); - // } - - let validator_timelock_address = - Address::from_str("0x95af79aAB990f9740c029013ef18f3D3d666B4e8")?; - let commit_batches_selector = "6edd4f12"; - - let url = alloy::transports::http::reqwest::Url::from_str(&"http://127.0.0.1:8545").unwrap(); - let provider: RootProvider< - alloy::transports::http::Http, - Ethereum, - > = RootProvider::new_http(url); - - get_transactions( - &provider, - validator_timelock_address, - commit_batches_selector, - ) - .await?; - - Ok(()) -} From f2936d529381256ac60ca8a105770c8474132d8d Mon Sep 17 00:00:00 2001 From: Gianbelinche <39842759+gianbelinche@users.noreply.github.com> Date: Mon, 11 Nov 2024 15:12:06 -0300 Subject: [PATCH 12/18] Simplify get all blobs toml --- Cargo.lock | 1 - get_all_blobs/Cargo.toml | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 88f38b88d8b6..e18c14f41aac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4150,7 +4150,6 @@ dependencies = [ "serde_json", "tokio", "tonic 0.12.3", - "zksync_node_framework", ] [[package]] diff --git a/get_all_blobs/Cargo.toml b/get_all_blobs/Cargo.toml index 325868bc5b07..d629650f6ff1 100644 --- a/get_all_blobs/Cargo.toml +++ b/get_all_blobs/Cargo.toml @@ -11,15 +11,14 @@ categories.workspace = true [dependencies] anyhow.workspace = true -zksync_node_framework.workspace = true -tokio.workspace = true +tokio = { version = "1" , features = ["full"] } axum.workspace = true rustls.workspace = true rlp.workspace = true hex.workspace = true reqwest.workspace = true -serde.workspace = true +serde = { version = "1.0", features = ["derive"] } serde_json.workspace = true tonic = { version = "0.12.1", features = ["tls", "channel", "tls-roots"]} From 62aa40502dbadd0f0a4980ca7806d3229cda8fee Mon Sep 17 00:00:00 2001 From: Gianbelinche <39842759+gianbelinche@users.noreply.github.com> Date: Mon, 11 Nov 2024 15:23:07 -0300 Subject: [PATCH 13/18] Add parameters --- get_all_blobs/src/main.rs | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/get_all_blobs/src/main.rs b/get_all_blobs/src/main.rs index 18cf5958cc96..53c03aac127d 100644 --- a/get_all_blobs/src/main.rs +++ b/get_all_blobs/src/main.rs @@ -38,11 +38,12 @@ async fn get_transactions( >, validator_timelock_address: Address, commit_batches_selector: &str, + block_start: u64, ) -> anyhow::Result<()> { let latest_block = provider.get_block_number().await?; let mut json_array = Vec::new(); - for block_number in 0..=latest_block { + for block_number in block_start..=latest_block { if let Ok(Some(block)) = provider .get_block_by_number(block_number.into(), true) .await @@ -113,28 +114,32 @@ async fn decode_blob_data_input(input: &[u8]) -> anyhow::Result { #[tokio::main] async fn main() -> anyhow::Result<()> { - // let args: Vec = std::env::args().collect(); - - // if args.len() != 3 { - // eprintln!("Usage: {} validatorTimelockAddress=
commitBatchesSharedBridge_functionSelector=", args[0]); - // std::process::exit(1); - // } - let validator_timelock_address = - Address::from_str("0x95af79aAB990f9740c029013ef18f3D3d666B4e8")?; + let args: Vec = std::env::args().collect(); + + if args.len() != 4 { + eprintln!("Usage: cargo run "); + std::process::exit(1); + } + + let validator_timelock_address = Address::from_str(&args[1])?; + let commit_batches_selector = "6edd4f12"; let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); - let url = alloy::transports::http::reqwest::Url::from_str(&"http://127.0.0.1:8545")?; + let url = alloy::transports::http::reqwest::Url::from_str(&args[2])?; let provider: RootProvider< alloy::transports::http::Http, Ethereum, > = RootProvider::new_http(url); + let block_start = args[3].parse::()?; + get_transactions( &provider, validator_timelock_address, commit_batches_selector, + block_start, ) .await?; From 774e610bcc4e66d38ee038120ce7e85cb8a2080c Mon Sep 17 00:00:00 2001 From: Gianbelinche <39842759+gianbelinche@users.noreply.github.com> Date: Mon, 11 Nov 2024 15:46:19 -0300 Subject: [PATCH 14/18] Add get all blobs steps on readme --- core/node/da_clients/src/eigen/eigenda-integration.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/core/node/da_clients/src/eigen/eigenda-integration.md b/core/node/da_clients/src/eigen/eigenda-integration.md index 3dbe81e09525..c0205135146c 100644 --- a/core/node/da_clients/src/eigen/eigenda-integration.md +++ b/core/node/da_clients/src/eigen/eigenda-integration.md @@ -113,6 +113,15 @@ You may enable observability here if you want to. zkstack server --chain eigen_da ``` +### Get Blobs from L1 + +In order to retrieve the blobs sent to EigenDA whose commitments are stored on L1 in order to be able to rebuild the chain from them run: + +```bash +cd get_all_blobs +cargo run +``` + ### Testing Modify the following flag in `core/lib/config/src/configs/da_dispatcher.rs` (then restart the server) From e34397d2227061e0874ebe5c3d7ac25b4b54fa5d Mon Sep 17 00:00:00 2001 From: Gianbelinche <39842759+gianbelinche@users.noreply.github.com> Date: Mon, 11 Nov 2024 16:42:22 -0300 Subject: [PATCH 15/18] Make loop for getting blobs --- .../src/eigen/eigenda-integration.md | 3 +- get_all_blobs/src/client.rs | 4 +-- get_all_blobs/src/main.rs | 35 ++++++++++++++----- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/core/node/da_clients/src/eigen/eigenda-integration.md b/core/node/da_clients/src/eigen/eigenda-integration.md index c0205135146c..db82aaf03c25 100644 --- a/core/node/da_clients/src/eigen/eigenda-integration.md +++ b/core/node/da_clients/src/eigen/eigenda-integration.md @@ -115,7 +115,8 @@ zkstack server --chain eigen_da ### Get Blobs from L1 -In order to retrieve the blobs sent to EigenDA whose commitments are stored on L1 in order to be able to rebuild the chain from them run: +In order to retrieve the blobs sent to EigenDA whose commitments are stored on L1 in order to be able to rebuild the +chain from them run: ```bash cd get_all_blobs diff --git a/get_all_blobs/src/client.rs b/get_all_blobs/src/client.rs index 51107a0ee195..2b95d72b9400 100644 --- a/get_all_blobs/src/client.rs +++ b/get_all_blobs/src/client.rs @@ -23,9 +23,9 @@ impl EigenClientRetriever { } pub async fn get_blob_data(&self, blob_id: &str) -> anyhow::Result>> { - let commit = hex::decode(blob_id).unwrap(); + let commit = hex::decode(blob_id)?; - let blob_info: BlobInfo = rlp::decode(&commit).unwrap(); + let blob_info: BlobInfo = rlp::decode(&commit)?; let blob_index = blob_info.blob_verification_proof.blob_index; let batch_header_hash = blob_info .blob_verification_proof diff --git a/get_all_blobs/src/main.rs b/get_all_blobs/src/main.rs index 53c03aac127d..e421c36229f2 100644 --- a/get_all_blobs/src/main.rs +++ b/get_all_blobs/src/main.rs @@ -55,7 +55,9 @@ async fn get_transactions( let selector = &input[0..4]; if selector == hex::decode(commit_batches_selector)? { if let Ok(decoded) = decode_blob_data_input(&input[4..]).await { - json_array.push(decoded); + for blob in decoded { + json_array.push(blob); + } } } } @@ -76,7 +78,7 @@ async fn get_transactions( Ok(()) } -async fn decode_blob_data_input(input: &[u8]) -> anyhow::Result { +async fn decode_blob_data_input(input: &[u8]) -> anyhow::Result> { let path = "./abi/commitBatchesSharedBridge.json"; let json = std::fs::read_to_string(path)?; let json_abi: JsonAbi = serde_json::from_str(&json)?; @@ -95,17 +97,32 @@ async fn decode_blob_data_input(input: &[u8]) -> anyhow::Result { .ok_or(anyhow::anyhow!( "CommitBatchInfo components cannot be represented as a tuple" ))?; - let pubdata_commitments = commit_batch_info.last().ok_or(anyhow::anyhow!( - "pubdata_commitments not found in commitBatchesSharedBridge input" - ))?; - let pubdata_commitments_bytes = pubdata_commitments - .as_bytes() - .ok_or(anyhow::anyhow!("pubdata_commitments is not a bytes array"))?; + let mut blobs = vec![]; + + for pubdata_commitments in commit_batch_info.iter() { + let pubdata_commitments_bytes = pubdata_commitments.as_bytes(); + match get_blob_from_pubdata_commitment(pubdata_commitments_bytes).await { + Ok(blob_data) => blobs.push(blob_data), + Err(_) => (), + } + } + + Ok(blobs) +} + +async fn get_blob_from_pubdata_commitment( + pubdata_commitments_bytes: Option<&[u8]>, +) -> anyhow::Result { + if pubdata_commitments_bytes.is_none() { + return Err(anyhow::anyhow!( + "CommitBatchInfo components cannot be represented as a tuple" + )); + } + let pubdata_commitments_bytes = pubdata_commitments_bytes.unwrap(); let commitment = hex::decode(&pubdata_commitments_bytes[1..])?; let commitment = hex::encode(&commitment); let blob = get_blob(&commitment).await?; - Ok(BlobData { commitment, blob: hex::encode(blob), From 40b485176508eeca255a1d63537051cd885b983b Mon Sep 17 00:00:00 2001 From: Gianbelinche <39842759+gianbelinche@users.noreply.github.com> Date: Mon, 11 Nov 2024 16:45:35 -0300 Subject: [PATCH 16/18] Add log for blocks proccessed --- get_all_blobs/src/main.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/get_all_blobs/src/main.rs b/get_all_blobs/src/main.rs index e421c36229f2..ed3670f0e659 100644 --- a/get_all_blobs/src/main.rs +++ b/get_all_blobs/src/main.rs @@ -43,7 +43,15 @@ async fn get_transactions( let latest_block = provider.get_block_number().await?; let mut json_array = Vec::new(); + let mut i = 0; for block_number in block_start..=latest_block { + i += 1; + if i % 50 == 0 { + println!( + "\x1b[32mProcessed up to block {} of {}\x1b[0m", + block_number, latest_block + ); + } if let Ok(Some(block)) = provider .get_block_by_number(block_number.into(), true) .await From 79d5071548236ced4c809feb0c63cd460e5ad392 Mon Sep 17 00:00:00 2001 From: Gianbelinche <39842759+gianbelinche@users.noreply.github.com> Date: Mon, 11 Nov 2024 18:33:44 -0300 Subject: [PATCH 17/18] Add constants --- get_all_blobs/src/main.rs | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/get_all_blobs/src/main.rs b/get_all_blobs/src/main.rs index ed3670f0e659..87a8ab21d420 100644 --- a/get_all_blobs/src/main.rs +++ b/get_all_blobs/src/main.rs @@ -21,6 +21,9 @@ struct BlobData { } const EIGENDA_API_URL: &str = "https://disperser-holesky.eigenda.xyz:443"; +const BLOB_DATA_JSON: &str = "blob_data.json"; +const ABI_JSON: &str = "./abi/commitBatchesSharedBridge.json"; +const COMMIT_BATCHES_SELECTOR: &str = "6edd4f12"; async fn get_blob(commitment: &str) -> anyhow::Result> { let client = EigenClientRetriever::new(EIGENDA_API_URL).await?; @@ -37,7 +40,6 @@ async fn get_transactions( Ethereum, >, validator_timelock_address: Address, - commit_batches_selector: &str, block_start: u64, ) -> anyhow::Result<()> { let latest_block = provider.get_block_number().await?; @@ -61,7 +63,7 @@ async fn get_transactions( if to == validator_timelock_address { let input = tx.input; let selector = &input[0..4]; - if selector == hex::decode(commit_batches_selector)? { + if selector == hex::decode(COMMIT_BATCHES_SELECTOR)? { if let Ok(decoded) = decode_blob_data_input(&input[4..]).await { for blob in decoded { json_array.push(blob); @@ -80,15 +82,14 @@ async fn get_transactions( } let json_string = serde_json::to_string_pretty(&json_array)?; - fs::write("blob_data.json", json_string)?; + fs::write(BLOB_DATA_JSON, json_string)?; println!("\x1b[32mData stored in blob_data.json file.\x1b[0m"); Ok(()) } async fn decode_blob_data_input(input: &[u8]) -> anyhow::Result> { - let path = "./abi/commitBatchesSharedBridge.json"; - let json = std::fs::read_to_string(path)?; + let json = std::fs::read_to_string(ABI_JSON)?; let json_abi: JsonAbi = serde_json::from_str(&json)?; let function = json_abi .functions @@ -148,8 +149,6 @@ async fn main() -> anyhow::Result<()> { let validator_timelock_address = Address::from_str(&args[1])?; - let commit_batches_selector = "6edd4f12"; - let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let url = alloy::transports::http::reqwest::Url::from_str(&args[2])?; @@ -160,13 +159,7 @@ async fn main() -> anyhow::Result<()> { let block_start = args[3].parse::()?; - get_transactions( - &provider, - validator_timelock_address, - commit_batches_selector, - block_start, - ) - .await?; + get_transactions(&provider, validator_timelock_address, block_start).await?; Ok(()) } From 32c964d8d03eb33488c7e8f9aaa3013d1ed3b770 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Tue, 19 Nov 2024 15:48:40 -0300 Subject: [PATCH 18/18] update contracts submodule --- contracts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts b/contracts index 6cb0da8abd85..64ed0ab97ff4 160000 --- a/contracts +++ b/contracts @@ -1 +1 @@ -Subproject commit 6cb0da8abd850389b8d886288dfc5d64dcf409d1 +Subproject commit 64ed0ab97ff4e9d2a265522025bdb8e1a4a4d2eb