diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 0ca11a3e..b00a4bd6 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -127,10 +127,10 @@ jobs: include: - type: wasm target: wasm32-unknown-unknown - exclude: scroll-engine,scroll-wire,scroll-bridge,scroll-network,rollup-node-manager,rollup-node-watcher + exclude: scroll-engine,scroll-wire,scroll-bridge,scroll-network,rollup-node-manager,rollup-node-watcher,scroll-db,scroll-migration - type: riscv target: riscv32imac-unknown-none-elf - exclude: scroll-engine,scroll-wire,scroll-bridge,scroll-network,rollup-node-manager,rollup-node-watcher + exclude: scroll-engine,scroll-wire,scroll-bridge,scroll-network,rollup-node-manager,rollup-node-watcher,scroll-db,scroll-migration steps: - uses: actions/checkout@v4 - uses: rui314/setup-mold@v1 diff --git a/Cargo.lock b/Cargo.lock index fa2df1cd..a23b134b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,6 +52,17 @@ dependencies = [ "subtle", ] +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom 0.2.15", + "once_cell", + "version_check", +] + [[package]] name = "ahash" version = "0.8.11" @@ -74,6 +85,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "aliasable" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" + [[package]] name = "alloc-no-stdlib" version = "2.0.4" @@ -706,7 +723,7 @@ checksum = "46ff7aa715eb2404cb87fa94390d2c5d5addd70d9617e20b2398ee6f48cb21f0" dependencies = [ "alloy-sol-macro-input", "const-hex", - "heck", + "heck 0.5.0", "indexmap 2.8.0", "proc-macro-error2", "proc-macro2", @@ -724,7 +741,7 @@ checksum = "6f105fa700140c0cc6e2c3377adef650c389ac57b8ead8318a2e6bd52f1ae841" dependencies = [ "const-hex", "dunce", - "heck", + "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.100", @@ -1090,6 +1107,39 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "155a5a185e42c6b77ac7b88a15143d930a9e9727a5b7b77eed417404ab15c247" +[[package]] +name = "async-attributes" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + [[package]] name = "async-compression" version = "0.4.20" @@ -1106,6 +1156,65 @@ dependencies = [ "zstd-safe", ] +[[package]] +name = "async-executor" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" +dependencies = [ + "async-channel 2.3.1", + "async-executor", + "async-io", + "async-lock", + "blocking", + "futures-lite", + "once_cell", + "tokio", +] + +[[package]] +name = "async-io" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" +dependencies = [ + "async-lock", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix 0.38.44", + "slab", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener 5.4.0", + "event-listener-strategy", + "pin-project-lite", +] + [[package]] name = "async-recursion" version = "1.1.1" @@ -1117,6 +1226,33 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "async-std" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "730294c1c08c2e0f85759590518f6333f0d5a0a766a27d519c1b244c3dfd8a24" +dependencies = [ + "async-attributes", + "async-channel 1.9.0", + "async-global-executor", + "async-io", + "async-lock", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers 0.3.0", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + [[package]] name = "async-stream" version = "0.3.6" @@ -1139,6 +1275,12 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + [[package]] name = "async-trait" version = "0.1.87" @@ -1161,6 +1303,15 @@ dependencies = [ "rustc_version 0.4.1", ] +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + [[package]] name = "atomic-waker" version = "1.1.2" @@ -1261,6 +1412,20 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" +[[package]] +name = "bigdecimal" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f31f3af01c5c65a07985c804d3366560e6fa7883d640a122819b14ec327482c" +dependencies = [ + "autocfg", + "libm", + "num-bigint", + "num-integer", + "num-traits", + "serde", +] + [[package]] name = "bimap" version = "0.6.3" @@ -1393,6 +1558,19 @@ dependencies = [ "generic-array", ] +[[package]] +name = "blocking" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +dependencies = [ + "async-channel 2.3.1", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + [[package]] name = "blst" version = "0.3.14" @@ -1405,6 +1583,29 @@ dependencies = [ "zeroize", ] +[[package]] +name = "borsh" +version = "1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5430e3be710b68d984d1391c854eb431a9d548640711faa54eecb1df93db91cc" +dependencies = [ + "borsh-derive", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8b668d39970baad5356d7c83a86fee3a539e6f93bf6764c97368243e17a0487" +dependencies = [ + "once_cell", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "boyer-moore-magiclen" version = "0.2.20" @@ -1457,6 +1658,28 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d" +[[package]] +name = "bytecheck" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "bytecount" version = "0.6.8" @@ -1661,7 +1884,7 @@ version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.100", @@ -1774,6 +1997,15 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "const-hex" version = "1.14.0" @@ -1939,6 +2171,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -2158,6 +2399,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", + "pem-rfc7468", "zeroize", ] @@ -2332,7 +2574,7 @@ dependencies = [ "enr", "fnv", "futures", - "hashlink", + "hashlink 0.9.1", "hex", "hkdf", "lazy_static", @@ -2367,6 +2609,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aac81fa3e28d21450aa4d2ac065992ba96a1d7303efbce51a95f4fd175b67562" +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + [[package]] name = "dunce" version = "1.0.5" @@ -2474,7 +2722,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.100", @@ -2516,6 +2764,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + [[package]] name = "ethereum_hashing" version = "0.7.0" @@ -2567,6 +2826,33 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" +dependencies = [ + "event-listener 5.4.0", + "pin-project-lite", +] + [[package]] name = "eyre" version = "0.6.12" @@ -2665,6 +2951,17 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "flume" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +dependencies = [ + "futures-core", + "futures-sink", + "spin", +] + [[package]] name = "fnv" version = "1.0.7" @@ -2677,6 +2974,21 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -2743,12 +3055,36 @@ dependencies = [ "futures-util", ] +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + [[package]] name = "futures-io" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +[[package]] +name = "futures-lite" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + [[package]] name = "futures-macro" version = "0.3.31" @@ -2778,7 +3114,7 @@ version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" dependencies = [ - "gloo-timers", + "gloo-timers 0.2.6", "send_wrapper 0.4.0", ] @@ -2911,6 +3247,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + [[package]] name = "gloo-utils" version = "0.2.0" @@ -2965,6 +3313,9 @@ name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.8", +] [[package]] name = "hashbrown" @@ -2978,7 +3329,7 @@ version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "ahash", + "ahash 0.8.11", ] [[package]] @@ -3002,6 +3353,15 @@ dependencies = [ "hashbrown 0.14.5", ] +[[package]] +name = "hashlink" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown 0.15.2", +] + [[package]] name = "hdrhistogram" version = "7.5.4" @@ -3012,6 +3372,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "heck" version = "0.5.0" @@ -3024,6 +3390,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "hex" version = "0.4.3" @@ -3130,10 +3502,19 @@ dependencies = [ ] [[package]] -name = "hostname" -version = "0.3.1" +name = "home" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" dependencies = [ "libc", "match_cfg", @@ -3526,6 +3907,17 @@ version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" +[[package]] +name = "inherent" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c38228f24186d9cc68c729accb4d413be9eaed6ad07ff79e0270d9e56f3de13" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "inotify" version = "0.11.0" @@ -3791,7 +4183,7 @@ version = "0.24.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fcae0c6c159e11541080f1f829873d8f374f81eda0abc67695a13fc8dc1a580" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro-crate", "proc-macro2", "quote", @@ -3930,6 +4322,15 @@ dependencies = [ "libc", ] +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -4050,6 +4451,17 @@ dependencies = [ "libsecp256k1-core", ] +[[package]] +name = "libsqlite3-sys" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linked-hash-map" version = "0.5.6" @@ -4100,6 +4512,9 @@ name = "log" version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" +dependencies = [ + "value-bag", +] [[package]] name = "loom" @@ -4162,6 +4577,16 @@ dependencies = [ "regex-automata 0.1.10", ] +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest 0.10.7", +] + [[package]] name = "memchr" version = "2.7.4" @@ -4183,7 +4608,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a7deb012b3b2767169ff203fadb4c6b0b82b947512e5eb9e0b78c2e186ad9e3" dependencies = [ - "ahash", + "ahash 0.8.11", "portable-atomic", ] @@ -4389,6 +4814,23 @@ dependencies = [ "unsigned-varint", ] +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework 2.11.1", + "security-framework-sys", + "tempfile", +] + [[package]] name = "nom" version = "7.1.3" @@ -4470,6 +4912,23 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", +] + [[package]] name = "num-complex" version = "0.4.6" @@ -4532,7 +4991,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", ] @@ -4654,18 +5113,89 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "openssl" +version = "0.10.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" +dependencies = [ + "bitflags 2.9.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "openssl-probe" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" +[[package]] +name = "openssl-sys" +version = "0.9.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "option-ext" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "ordered-float" +version = "3.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" +dependencies = [ + "num-traits", +] + +[[package]] +name = "ouroboros" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0f050db9c44b97a94723127e6be766ac5c340c48f2c4bb3ffa11713744be59" +dependencies = [ + "aliasable", + "ouroboros_macro", + "static_assertions", +] + +[[package]] +name = "ouroboros_macro" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c7028bdd3d43083f6d8d4d5187680d0d3560d54df4cc9d752005268b41e64d0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn 2.0.100", +] + [[package]] name = "overload" version = "0.1.1" @@ -4724,6 +5254,12 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + [[package]] name = "parking_lot" version = "0.12.3" @@ -4773,6 +5309,15 @@ dependencies = [ "serde", ] +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -4790,6 +5335,15 @@ dependencies = [ "ucd-trie", ] +[[package]] +name = "pgvector" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0e8871b6d7ca78348c6cd29b911b94851f3429f0cd403130ca17f26c1fb91a6" +dependencies = [ + "serde", +] + [[package]] name = "pharos" version = "0.5.3" @@ -4832,6 +5386,28 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "piper" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + [[package]] name = "pkcs8" version = "0.10.2" @@ -4857,6 +5433,21 @@ dependencies = [ "crunchy", ] +[[package]] +name = "polling" +version = "3.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi 0.4.0", + "pin-project-lite", + "rustix 0.38.44", + "tracing", + "windows-sys 0.59.0", +] + [[package]] name = "polyval" version = "0.6.2" @@ -4960,6 +5551,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", + "version_check", + "yansi", +] + [[package]] name = "procfs" version = "0.17.0" @@ -5026,6 +5630,26 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "pulldown-cmark" version = "0.9.6" @@ -5333,6 +5957,15 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "rend" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" +dependencies = [ + "bytecheck", +] + [[package]] name = "reqwest" version = "0.12.13" @@ -5481,7 +6114,7 @@ name = "reth-cli-commands" version = "1.2.2" source = "git+https://github.com/scroll-tech/reth.git#2de81fce858e35ed374c8105c45f02831887ff0a" dependencies = [ - "ahash", + "ahash 0.8.11", "alloy-consensus", "alloy-eips", "alloy-primitives", @@ -8245,6 +8878,35 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "rkyv" +version = "0.7.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" +dependencies = [ + "bitvec", + "bytecheck", + "bytes", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "rlimit" version = "0.10.2" @@ -8332,6 +8994,7 @@ version = "0.0.1" dependencies = [ "alloy-primitives", "alloy-rpc-types-engine", + "arbitrary", "derive_more 2.0.1", "scroll-alloy-consensus", ] @@ -8369,6 +9032,26 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746" +[[package]] +name = "rsa" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b" +dependencies = [ + "const-oid", + "digest 0.10.7", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature", + "spki", + "subtle", + "zeroize", +] + [[package]] name = "ruint" version = "1.13.1" @@ -8402,6 +9085,22 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" +[[package]] +name = "rust_decimal" +version = "1.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555" +dependencies = [ + "arrayvec", + "borsh", + "bytes", + "num-traits", + "rand 0.8.5", + "rkyv", + "serde", + "serde_json", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -8617,7 +9316,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "356285bbf17bea63d9e52e96bd18f039672ac92b55b8cb997d6162a2a37d1649" dependencies = [ - "ahash", + "ahash 0.8.11", "cfg-if", "hashbrown 0.13.2", ] @@ -8788,6 +9487,26 @@ dependencies = [ "tracing", ] +[[package]] +name = "scroll-db" +version = "0.0.1" +dependencies = [ + "alloy-primitives", + "arbitrary", + "async-trait", + "futures", + "rand 0.9.0", + "rollup-node-primitives", + "scroll-alloy-consensus", + "scroll-migration", + "sea-orm", + "serde", + "serde_json", + "thiserror 2.0.12", + "tokio", + "tracing", +] + [[package]] name = "scroll-engine" version = "0.0.1" @@ -8825,7 +9544,16 @@ dependencies = [ ] [[package]] -name = "scroll-network" +name = "scroll-migration" +version = "0.1.0" +dependencies = [ + "async-std", + "sea-orm-migration", + "tracing", +] + +[[package]] +name = "scroll-network" version = "0.0.1" dependencies = [ "alloy-primitives", @@ -8865,6 +9593,171 @@ dependencies = [ "tracing", ] +[[package]] +name = "sea-bae" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f694a6ab48f14bc063cfadff30ab551d3c7e46d8f81836c51989d548f44a2a25" +dependencies = [ + "heck 0.4.1", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "sea-orm" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3417812d38049e8ec3d588c03570f8c60de811d2453fb48e424045a1600ffd86" +dependencies = [ + "async-stream", + "async-trait", + "bigdecimal", + "chrono", + "futures-util", + "log", + "ouroboros", + "pgvector", + "rust_decimal", + "sea-orm-macros", + "sea-query", + "sea-query-binder", + "serde", + "serde_json", + "sqlx", + "strum 0.26.3", + "thiserror 1.0.69", + "time", + "tracing", + "url", + "uuid", +] + +[[package]] +name = "sea-orm-cli" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf2a390d6528f8e5c9ecd327bbb1a4c6cd7ab8333ef0da97010d5dc8f83f01c4" +dependencies = [ + "chrono", + "clap", + "dotenvy", + "glob", + "regex", + "sea-schema", + "tracing", + "tracing-subscriber", + "url", +] + +[[package]] +name = "sea-orm-macros" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d705ba84e1c74c8ac27784e4ac6f21584058c1dc0cadb9d39b43e109fcf8139c" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "sea-bae", + "syn 2.0.100", + "unicode-ident", +] + +[[package]] +name = "sea-orm-migration" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c38451d5112e3a518a02251b5e6d3bc72e626957a44a79264716808a4c28ee0" +dependencies = [ + "async-trait", + "clap", + "dotenvy", + "sea-orm", + "sea-orm-cli", + "sea-schema", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "sea-query" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b731192738ebf56d20580fc8ba2d23940333befe900b04dd08a26a77cd056f02" +dependencies = [ + "bigdecimal", + "chrono", + "inherent", + "ordered-float", + "rust_decimal", + "sea-query-derive", + "serde_json", + "time", + "uuid", +] + +[[package]] +name = "sea-query-binder" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0019f47430f7995af63deda77e238c17323359af241233ec768aba1faea7608" +dependencies = [ + "bigdecimal", + "chrono", + "rust_decimal", + "sea-query", + "serde_json", + "sqlx", + "time", + "uuid", +] + +[[package]] +name = "sea-query-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9834af2c4bd8c5162f00c89f1701fb6886119a88062cf76fe842ea9e232b9839" +dependencies = [ + "darling", + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 2.0.100", + "thiserror 1.0.69", +] + +[[package]] +name = "sea-schema" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef5dd7848c993f3789d09a2616484c72c9330cae2b048df59d8c9b8c0343e95" +dependencies = [ + "futures", + "sea-query", + "sea-schema-derive", +] + +[[package]] +name = "sea-schema-derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "debdc8729c37fdbf88472f97fd470393089f997a909e535ff67c544d18cfccf0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + [[package]] name = "sec1" version = "0.7.3" @@ -9200,6 +10093,12 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "simple_asn1" version = "0.6.3" @@ -9289,6 +10188,9 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] [[package]] name = "spki" @@ -9300,6 +10202,213 @@ dependencies = [ "der", ] +[[package]] +name = "sqlx" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4410e73b3c0d8442c5f99b425d7a435b5ee0ae4167b3196771dd3f7a01be745f" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a007b6936676aa9ab40207cde35daab0a04b823be8ae004368c0793b96a61e0" +dependencies = [ + "bigdecimal", + "bytes", + "chrono", + "crc", + "crossbeam-queue", + "either", + "event-listener 5.4.0", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashbrown 0.15.2", + "hashlink 0.10.0", + "indexmap 2.8.0", + "log", + "memchr", + "native-tls", + "once_cell", + "percent-encoding", + "rust_decimal", + "serde", + "serde_json", + "sha2 0.10.8", + "smallvec", + "thiserror 2.0.12", + "time", + "tokio", + "tokio-stream", + "tracing", + "url", + "uuid", +] + +[[package]] +name = "sqlx-macros" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3112e2ad78643fef903618d78cf0aec1cb3134b019730edb039b69eaf531f310" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 2.0.100", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e9f90acc5ab146a99bf5061a7eb4976b573f560bc898ef3bf8435448dd5e7ad" +dependencies = [ + "dotenvy", + "either", + "heck 0.5.0", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2 0.10.8", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn 2.0.100", + "tempfile", + "tokio", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4560278f0e00ce64938540546f59f590d60beee33fffbd3b9cd47851e5fff233" +dependencies = [ + "atoi", + "base64 0.22.1", + "bigdecimal", + "bitflags 2.9.0", + "byteorder", + "bytes", + "chrono", + "crc", + "digest 0.10.7", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac 0.12.1", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand 0.8.5", + "rsa", + "rust_decimal", + "serde", + "sha1", + "sha2 0.10.8", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror 2.0.12", + "time", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5b98a57f363ed6764d5b3a12bfedf62f07aa16e1856a7ddc2a0bb190a959613" +dependencies = [ + "atoi", + "base64 0.22.1", + "bigdecimal", + "bitflags 2.9.0", + "byteorder", + "chrono", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-util", + "hex", + "hkdf", + "hmac 0.12.1", + "home", + "itoa", + "log", + "md-5", + "memchr", + "num-bigint", + "once_cell", + "rand 0.8.5", + "rust_decimal", + "serde", + "serde_json", + "sha2 0.10.8", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror 2.0.12", + "time", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f85ca71d3a5b24e64e1d08dd8fe36c6c95c339a896cc33068148906784620540" +dependencies = [ + "atoi", + "chrono", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "serde_urlencoded", + "sqlx-core", + "time", + "tracing", + "url", + "uuid", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -9312,6 +10421,17 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "stringprep" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", + "unicode-properties", +] + [[package]] name = "strsim" version = "0.11.1" @@ -9342,7 +10462,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", "rustversion", @@ -9355,7 +10475,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", "rustversion", @@ -10029,12 +11149,33 @@ version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" +[[package]] +name = "unicode-bidi" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" + [[package]] name = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-properties" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" + [[package]] name = "unicode-segmentation" version = "1.12.0" @@ -10135,6 +11276,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0f540e3240398cce6128b64ba83fdbdd86129c16a3aa1a3a252efd66eb3d587" dependencies = [ "getrandom 0.3.1", + "serde", ] [[package]] @@ -10143,6 +11285,18 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" +[[package]] +name = "value-bag" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "vergen" version = "8.3.2" @@ -10217,6 +11371,12 @@ dependencies = [ "wit-bindgen-rt", ] +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + [[package]] name = "wasm-bindgen" version = "0.2.100" @@ -10331,6 +11491,16 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "whoami" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d" +dependencies = [ + "redox_syscall", + "wasite", +] + [[package]] name = "widestring" version = "1.1.0" diff --git a/Cargo.toml b/Cargo.toml index b3e3ca25..0b6a3846 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,8 @@ exclude = [".github/"] [workspace] members = [ "bin/bridge", + "crates/database/db", + "crates/database/migration", "crates/engine", "crates/l1", "crates/node", @@ -149,6 +151,7 @@ scroll-engine = { path = "crates/engine" } scroll-l1 = { path = "crates/l1" } scroll-network = { path = "crates/network" } scroll-wire = { path = "crates/scroll-wire" } +scroll-migration = { path = "crates/database/migration" } # misc arbitrary = { version = "1.4", default-features = false } @@ -156,6 +159,7 @@ async-trait = "0.1" derive_more = { version = "2.0", default-features = false } eyre = "0.6" futures = { version = "0.3", default-features = false } +rand = { version = "0.9" } secp256k1 = { version = "0.29", default-features = false } thiserror = "2.0" tokio = { version = "1.39", default-features = false } diff --git a/Makefile b/Makefile index 0bcee135..a2e79074 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,18 @@ clippy: --all-features \ -- -D warnings +.PHONY: clippy-fix +clippy-fix: + cargo +nightly clippy \ + --workspace \ + --lib \ + --examples \ + --tests \ + --benches \ + --all-features \ + --fix \ + -- -D warnings + .PHONY: udeps udeps: cargo +nightly udeps --workspace --lib --examples --tests --benches --all-features --locked diff --git a/crates/database/db/Cargo.toml b/crates/database/db/Cargo.toml new file mode 100644 index 00000000..cce33a32 --- /dev/null +++ b/crates/database/db/Cargo.toml @@ -0,0 +1,43 @@ +[package] +name = "scroll-db" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +exclude.workspace = true + +[lints] +workspace = true + +[dependencies] +# alloy +alloy-primitives.workspace = true + +# scroll-alloy +scroll-alloy-consensus.workspace = true + +# scroll +scroll-migration = { workspace = true, optional = true } +rollup-node-primitives.workspace = true + +# misc +async-trait.workspace = true +futures.workspace = true +sea-orm = { version = "1.1.0", features = ["sqlx-sqlite", "runtime-tokio-native-tls", "macros"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +thiserror.workspace = true +tokio = { workspace = true, features = ["macros", "sync"] } +tracing.workspace = true + +[dev-dependencies] +# scroll +scroll-migration.workspace = true +rollup-node-primitives = { workspace = true, features = ["arbitrary"] } + +# misc +arbitrary.workspace = true +rand.workspace = true + +[features] +test-utils = ["dep:scroll-migration"] diff --git a/crates/database/db/src/connection.rs b/crates/database/db/src/connection.rs new file mode 100644 index 00000000..27afad12 --- /dev/null +++ b/crates/database/db/src/connection.rs @@ -0,0 +1,10 @@ +/// The [`DatabaseConnectionProvider`] trait provides a way to get a connection to the database. +/// This is implemented by the [`crate::Database`] and [`crate::DatabaseTransaction`] types. +pub trait DatabaseConnectionProvider { + /// The type of the database connection. + type Connection: sea_orm::ConnectionTrait + sea_orm::StreamTrait; + + /// Returns a reference to the database connection that implements the `ConnectionTrait` and + /// `StreamTrait` traits. + fn get_connection(&self) -> &Self::Connection; +} diff --git a/crates/database/db/src/db.rs b/crates/database/db/src/db.rs new file mode 100644 index 00000000..1e27998a --- /dev/null +++ b/crates/database/db/src/db.rs @@ -0,0 +1,162 @@ +use super::{transaction::DatabaseTransaction, DatabaseConnectionProvider}; +use crate::error::DatabaseError; + +use sea_orm::{Database as SeaOrmDatabase, DatabaseConnection, TransactionTrait}; + +/// The [`Database`] struct is responsible for interacting with the database. +/// +/// The [`Database`] type wraps a [`sea_orm::DatabaseConnection`]. We implement +/// [`DatabaseConnectionProvider`] for [`Database`] such that it can be used to perform the +/// operations defined in [`crate::DatabaseOperations`]. Atomic operations can be performed using +/// the [`Database::tx`] method which returns a [`DatabaseTransaction`] that also implements the +/// [`DatabaseConnectionProvider`] trait and also the [`crate::DatabaseOperations`] trait. +#[derive(Debug)] +pub struct Database { + /// The underlying database connection. + connection: DatabaseConnection, +} + +impl Database { + /// Creates a new [`Database`] instance associated with the provided database URL. + pub async fn new(database_url: &str) -> Result { + let connection = SeaOrmDatabase::connect(database_url).await?; + Ok(Self { connection }) + } + + /// Creates a new [`DatabaseTransaction`] which can be used for atomic operations. + pub async fn tx(&self) -> Result { + Ok(DatabaseTransaction::new(self.connection.begin().await?)) + } +} + +impl DatabaseConnectionProvider for Database { + type Connection = DatabaseConnection; + + fn get_connection(&self) -> &Self::Connection { + &self.connection + } +} + +impl From for Database { + fn from(connection: DatabaseConnection) -> Self { + Self { connection } + } +} + +#[cfg(test)] +mod test { + use crate::{operations::DatabaseOperations, test_utils::setup_test_db}; + use arbitrary::{Arbitrary, Unstructured}; + use futures::StreamExt; + use rand::Rng; + use rollup_node_primitives::{ + BatchInput, BatchInputV1, BatchInputV2, L1MessageWithBlockNumber, + }; + + #[tokio::test] + async fn test_database_round_trip_batch_input() { + // Set up the test database. + let db = setup_test_db().await; + + // Generate unstructured bytes. + let mut bytes = [0u8; 1024]; + rand::rng().fill(bytes.as_mut_slice()); + let mut u = Unstructured::new(&bytes); + + // Generate a random BatchInputV1. + let batch_input_v1 = BatchInputV1::arbitrary(&mut u).unwrap(); + let batch_input = BatchInput::BatchInputDataV1(batch_input_v1); + + // Round trip the BatchInput through the database. + db.insert_batch_input(batch_input.clone()).await.unwrap(); + let batch_input_from_db = + db.get_batch_input_by_batch_index(batch_input.batch_index()).await.unwrap().unwrap(); + assert_eq!(batch_input, batch_input_from_db); + + // Generate a random BatchInputV2. + let batch_input_v2 = BatchInputV2::arbitrary(&mut u).unwrap(); + let batch_input = BatchInput::BatchInputDataV2(batch_input_v2); + + // Round trip the BatchInput through the database. + db.insert_batch_input(batch_input.clone()).await.unwrap(); + let batch_input_from_db = + db.get_batch_input_by_batch_index(batch_input.batch_index()).await.unwrap().unwrap(); + assert_eq!(batch_input, batch_input_from_db); + } + + #[tokio::test] + async fn test_database_round_trip_l1_message() { + // Set up the test database. + let db = setup_test_db().await; + + // Generate unstructured bytes. + let mut bytes = [0u8; 1024]; + rand::rng().fill(bytes.as_mut_slice()); + let mut u = Unstructured::new(&bytes); + + // Generate a random L1Message. + let l1_message = L1MessageWithBlockNumber::arbitrary(&mut u).unwrap(); + + // Round trip the L1Message through the database. + db.insert_l1_message(l1_message.clone()).await.unwrap(); + let l1_message_from_db = + db.get_l1_message(l1_message.transaction.queue_index).await.unwrap().unwrap(); + assert_eq!(l1_message, l1_message_from_db); + } + + #[tokio::test] + async fn test_database_tx() { + // Setup the test database. + let db = setup_test_db().await; + + // Generate unstructured bytes. + let mut bytes = [0u8; 2048]; + rand::rng().fill(bytes.as_mut_slice()); + let mut u = Unstructured::new(&bytes); + + // Generate 2 random L1Messages. + let l1_message_1 = L1MessageWithBlockNumber::arbitrary(&mut u).unwrap(); + let l1_message_2 = L1MessageWithBlockNumber::arbitrary(&mut u).unwrap(); + + // Insert the L1Messages into the database in a transaction. + let tx = db.tx().await.unwrap(); + tx.insert_l1_message(l1_message_1.clone()).await.unwrap(); + tx.insert_l1_message(l1_message_2.clone()).await.unwrap(); + tx.commit().await.unwrap(); + + // Check that the L1Messages are in the database. + let l1_message_1_from_db = + db.get_l1_message(l1_message_1.transaction.queue_index).await.unwrap().unwrap(); + assert_eq!(l1_message_1, l1_message_1_from_db); + let l1_message_2_from_db = + db.get_l1_message(l1_message_2.transaction.queue_index).await.unwrap().unwrap(); + assert_eq!(l1_message_2, l1_message_2_from_db); + } + + #[tokio::test] + async fn test_database_iterator() { + // Setup the test database. + let db = setup_test_db().await; + + // Generate unstructured bytes. + let mut bytes = [0u8; 2048]; + rand::rng().fill(bytes.as_mut_slice()); + let mut u = Unstructured::new(&bytes); + + // Generate 2 random L1Messages. + let l1_message_1 = L1MessageWithBlockNumber::arbitrary(&mut u).unwrap(); + let l1_message_2 = L1MessageWithBlockNumber::arbitrary(&mut u).unwrap(); + + // Insert the L1Messages into the database. + db.insert_l1_message(l1_message_1.clone()).await.unwrap(); + db.insert_l1_message(l1_message_2.clone()).await.unwrap(); + + // collect the L1Messages + let l1_messages = + db.get_l1_messages().await.unwrap().map(|res| res.unwrap()).collect::>().await; + + // Apply the assertions. + assert!(l1_messages.contains(&l1_message_1)); + assert!(l1_messages.contains(&l1_message_2)); + } +} diff --git a/crates/database/db/src/error.rs b/crates/database/db/src/error.rs new file mode 100644 index 00000000..702a3483 --- /dev/null +++ b/crates/database/db/src/error.rs @@ -0,0 +1,12 @@ +use alloy_primitives::B256; + +/// The error type for database operations. +#[derive(Debug, thiserror::Error)] +pub enum DatabaseError { + /// A database error occurred. + #[error("database error: {0}")] + DatabaseError(#[from] sea_orm::DbErr), + /// A batch was not found in the database. + #[error("batch with hash [{0}] not found in database")] + BatchNotFound(B256), +} diff --git a/crates/database/db/src/lib.rs b/crates/database/db/src/lib.rs new file mode 100644 index 00000000..cee41638 --- /dev/null +++ b/crates/database/db/src/lib.rs @@ -0,0 +1,22 @@ +//! A library responsible for interacting with the database. + +mod connection; +pub use connection::DatabaseConnectionProvider; + +mod db; +pub use db::Database; + +mod error; +pub use error::DatabaseError; + +mod models; +pub use models::*; + +mod operations; +pub use operations::DatabaseOperations; + +mod transaction; +pub use transaction::DatabaseTransaction; + +#[cfg(feature = "test-utils")] +pub mod test_utils; diff --git a/crates/database/db/src/models/batch_input.rs b/crates/database/db/src/models/batch_input.rs new file mode 100644 index 00000000..9ba77d91 --- /dev/null +++ b/crates/database/db/src/models/batch_input.rs @@ -0,0 +1,105 @@ +use std::ops::Deref; + +use rollup_node_primitives::{BatchInput as BatchInputPrimitive, BatchInputV1, BatchInputV2}; +use sea_orm::{entity::prelude::*, ActiveValue, FromJsonQueryResult}; + +/// A database model that represents a batch input. +#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)] +#[sea_orm(table_name = "batch_input")] +pub struct Model { + #[sea_orm(primary_key)] + index: i64, + version: u8, + codec_version: u8, + hash: Vec, + block_number: i64, + parent_batch_header: Vec, + #[sea_orm(column_type = "JsonBinary")] + chunks: Chunks, + skipped_l1_message_bitmap: Vec, + blob_hash: Vec, + finalized_block_number: Option, +} + +/// The relation for the batch input model. +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +/// The active model behavior for the batch input model. +impl ActiveModelBehavior for ActiveModel {} + +/// A wrapper for a list of chunks. +#[derive( + Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, FromJsonQueryResult, +)] +pub struct Chunks(pub Vec>); + +impl Deref for Chunks { + type Target = Vec>; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for ActiveModel { + fn from(batch_input: BatchInputPrimitive) -> Self { + let (version, batch_input_v1, blob_hash) = match batch_input { + BatchInputPrimitive::BatchInputDataV1(batch_input) => (1, batch_input, vec![]), + BatchInputPrimitive::BatchInputDataV2(batch_input) => { + (2, batch_input.batch_input_base, batch_input.blob_hash.to_vec()) + } + }; + Self { + index: ActiveValue::Set( + batch_input_v1.batch_index.try_into().expect("index should fit in i64"), + ), + version: ActiveValue::Set(version), + codec_version: ActiveValue::Set(batch_input_v1.version), + hash: ActiveValue::Set(batch_input_v1.batch_hash.to_vec()), + block_number: ActiveValue::Set( + batch_input_v1.block_number.try_into().expect("block number should fit in i64"), + ), + parent_batch_header: ActiveValue::Set(batch_input_v1.parent_batch_header), + chunks: ActiveValue::Set(Chunks(batch_input_v1.chunks)), + skipped_l1_message_bitmap: ActiveValue::Set(batch_input_v1.skipped_l1_message_bitmap), + blob_hash: ActiveValue::Set(blob_hash), + finalized_block_number: ActiveValue::Unchanged(None), + } + } +} + +impl From for BatchInputPrimitive { + fn from(value: Model) -> Self { + let chunks = value.chunks.0; + let batch_input_v1 = BatchInputV1 { + version: value.codec_version, + batch_index: value.index.try_into().expect("data persisted in database is valid"), + batch_hash: value + .hash + .as_slice() + .try_into() + .expect("data persisted in database is valid"), + block_number: value + .block_number + .try_into() + .expect("data persisted in database is valid"), + parent_batch_header: value.parent_batch_header, + chunks, + skipped_l1_message_bitmap: value.skipped_l1_message_bitmap, + }; + + if value.version == 1 { + Self::BatchInputDataV1(batch_input_v1) + } else { + Self::BatchInputDataV2(BatchInputV2 { + batch_input_base: batch_input_v1, + blob_hash: value + .blob_hash + .as_slice() + .try_into() + .expect("data persisted in database is valid"), + }) + } + } +} diff --git a/crates/database/db/src/models/l1_message.rs b/crates/database/db/src/models/l1_message.rs new file mode 100644 index 00000000..5d959b74 --- /dev/null +++ b/crates/database/db/src/models/l1_message.rs @@ -0,0 +1,55 @@ +use alloy_primitives::{Address, U256}; +use rollup_node_primitives::L1MessageWithBlockNumber; +use scroll_alloy_consensus::TxL1Message; +use sea_orm::{entity::prelude::*, ActiveValue}; + +/// A database model that represents a L1 message. +#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)] +#[sea_orm(table_name = "l1_message")] +pub struct Model { + #[sea_orm(primary_key)] + queue_index: i64, + block_number: i64, + gas_limit: String, + to: Vec, + value: Vec, + sender: Vec, + input: Vec, +} + +/// The relation for the L1 message model. +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +/// The active model behavior for the L1 message model. +impl ActiveModelBehavior for ActiveModel {} + +impl From for ActiveModel { + fn from(value: L1MessageWithBlockNumber) -> Self { + Self { + queue_index: ActiveValue::Set(value.transaction.queue_index as i64), + block_number: ActiveValue::Set(value.block_number as i64), + gas_limit: ActiveValue::Set(value.transaction.gas_limit.to_string()), + to: ActiveValue::Set(value.transaction.to.to_vec()), + value: ActiveValue::Set(value.transaction.value.to_le_bytes_vec()), + sender: ActiveValue::Set(value.transaction.sender.to_vec()), + input: ActiveValue::Set(value.transaction.input.to_vec()), + } + } +} + +impl From for L1MessageWithBlockNumber { + fn from(value: Model) -> Self { + Self { + block_number: value.block_number as u64, + transaction: TxL1Message { + queue_index: value.queue_index as u64, + gas_limit: value.gas_limit.parse().expect("gas limit is valid"), + to: Address::from_slice(&value.to), + value: U256::from_le_slice(&value.value), + sender: Address::from_slice(&value.sender), + input: value.input.into(), + }, + } + } +} diff --git a/crates/database/db/src/models/mod.rs b/crates/database/db/src/models/mod.rs new file mode 100644 index 00000000..97eb8b6d --- /dev/null +++ b/crates/database/db/src/models/mod.rs @@ -0,0 +1,5 @@ +/// This module contains the batch input database model. +pub mod batch_input; + +/// This module contains the L1 message database model. +pub mod l1_message; diff --git a/crates/database/db/src/operations.rs b/crates/database/db/src/operations.rs new file mode 100644 index 00000000..e28d3f3b --- /dev/null +++ b/crates/database/db/src/operations.rs @@ -0,0 +1,129 @@ +use super::{models, DatabaseError}; +use crate::DatabaseConnectionProvider; +use alloy_primitives::B256; +use futures::{Stream, StreamExt}; +use rollup_node_primitives::{BatchInput, L1MessageWithBlockNumber}; +use sea_orm::{ActiveModelTrait, ColumnTrait, DbErr, EntityTrait, QueryFilter, Set}; + +/// The [`DatabaseOperations`] trait provides methods for interacting with the database. +#[async_trait::async_trait] +pub trait DatabaseOperations: DatabaseConnectionProvider { + /// Insert a [`BatchInput`] into the database. + async fn insert_batch_input(&self, batch_input: BatchInput) -> Result<(), DatabaseError> { + tracing::trace!(target: "scroll::db", batch_hash = ?batch_input.batch_hash(), batch_index = batch_input.batch_index(), "Inserting batch input into database."); + let batch_input: models::batch_input::ActiveModel = batch_input.into(); + batch_input.insert(self.get_connection()).await?; + Ok(()) + } + + /// Finalize a [`BatchInput`] with the provided `batch_hash` in the database and set the + /// finalized block number to the provided block number. + /// + /// Errors if the [`BatchInput`] associated with the provided `batch_hash` is not found in the + /// database, this method logs and returns an error. + async fn finalize_batch_input( + &self, + batch_hash: B256, + block_number: u64, + ) -> Result<(), DatabaseError> { + if let Some(batch) = models::batch_input::Entity::find() + .filter(models::batch_input::Column::Hash.eq(batch_hash.to_vec())) + .one(self.get_connection()) + .await? + { + tracing::trace!(target: "scroll::db", batch_hash = ?batch_hash, block_number, "Finalizing batch input in database."); + let mut batch: models::batch_input::ActiveModel = batch.into(); + batch.finalized_block_number = Set(Some(block_number as i64)); + batch.update(self.get_connection()).await?; + } else { + tracing::error!( + target: "scroll::db", + batch_hash = ?batch_hash, + block_number, + "Batch not found in DB when trying to finalize." + ); + return Err(DatabaseError::BatchNotFound(batch_hash)); + } + + Ok(()) + } + + /// Get a [`BatchInput`] from the database by its batch index. + async fn get_batch_input_by_batch_index( + &self, + batch_index: u64, + ) -> Result, DatabaseError> { + Ok(models::batch_input::Entity::find_by_id( + TryInto::::try_into(batch_index).expect("index should fit in i64"), + ) + .one(self.get_connection()) + .await + .map(|x| x.map(Into::into))?) + } + + /// Delete all [`BatchInput`]s with a block number greater than the provided block number. + async fn delete_batch_inputs_gt(&self, block_number: u64) -> Result<(), DatabaseError> { + tracing::trace!(target: "scroll::db", block_number, "Deleting batch inputs greater than block number."); + Ok(models::batch_input::Entity::delete_many() + .filter(models::batch_input::Column::BlockNumber.gt(block_number as i64)) + .exec(self.get_connection()) + .await + .map(|_| ())?) + } + + /// Get an iterator over all [`BatchInput`]s in the database. + async fn get_batch_inputs<'a>( + &'a self, + ) -> Result> + 'a, DbErr> { + Ok(models::batch_input::Entity::find() + .stream(self.get_connection()) + .await? + .map(|res| res.map(Into::into))) + } + + /// Insert an [`L1MessageWithBlockNumber`] into the database. + async fn insert_l1_message( + &self, + l1_message: L1MessageWithBlockNumber, + ) -> Result<(), DatabaseError> { + tracing::trace!(target: "scroll::db", queue_index = l1_message.transaction.queue_index, "Inserting L1 message into database."); + let l1_message: models::l1_message::ActiveModel = l1_message.into(); + l1_message.insert(self.get_connection()).await?; + Ok(()) + } + + /// Delete all [`L1MessageWithBlockNumber`]s with a block number greater than the provided block + /// number. + async fn delete_l1_messages_gt(&self, block_number: u64) -> Result<(), DatabaseError> { + tracing::trace!(target: "scroll::db", block_number, "Deleting L1 messages greater than block number."); + Ok(models::l1_message::Entity::delete_many() + .filter(models::l1_message::Column::BlockNumber.gt(block_number as i64)) + .exec(self.get_connection()) + .await + .map(|_| ())?) + } + + /// Get a [`L1MessageWithBlockNumber`] from the database by its message queue index. + async fn get_l1_message( + &self, + queue_index: u64, + ) -> Result, DatabaseError> { + Ok(models::l1_message::Entity::find_by_id(queue_index as i64) + .one(self.get_connection()) + .await + .map(|x| x.map(Into::into))?) + } + + /// Gets an iterator over all [`L1MessageWithBlockNumber`]s in the database. + async fn get_l1_messages<'a>( + &'a self, + ) -> Result> + 'a, DatabaseError> + { + Ok(models::l1_message::Entity::find() + .stream(self.get_connection()) + .await? + .map(|res| res.map(Into::into))) + } +} + +impl DatabaseOperations for T where T: DatabaseConnectionProvider {} diff --git a/crates/database/db/src/test_utils.rs b/crates/database/db/src/test_utils.rs new file mode 100644 index 00000000..af05e399 --- /dev/null +++ b/crates/database/db/src/test_utils.rs @@ -0,0 +1,13 @@ +//! Test utilities for the database crate. + +use super::Database; +use migration::{Migrator, MigratorTrait}; + +/// Instantiates a new in-memory database and runs the migrations +/// to set up the schema. +pub async fn setup_test_db() -> Database { + let database_url = "sqlite::memory:"; + let connection = sea_orm::Database::connect(database_url).await.unwrap(); + Migrator::up(&connection, None).await.unwrap(); + connection.into() +} diff --git a/crates/database/db/src/transaction.rs b/crates/database/db/src/transaction.rs new file mode 100644 index 00000000..e970440d --- /dev/null +++ b/crates/database/db/src/transaction.rs @@ -0,0 +1,40 @@ +use super::{DatabaseConnectionProvider, DatabaseError}; + +/// A type that represents a database transaction. +/// +/// This type is used to perform operations on the database within a single atomic transaction. +#[derive(Debug)] +pub struct DatabaseTransaction { + /// The underlying database transaction. + tx: sea_orm::DatabaseTransaction, +} + +impl DatabaseTransaction { + /// Creates a new [`DatabaseTransaction`] instance associated with the provided database + /// transaction. + pub const fn new(tx: sea_orm::DatabaseTransaction) -> Self { + Self { tx } + } +} + +impl DatabaseTransaction { + /// Commits the transaction. + pub async fn commit(self) -> Result<(), DatabaseError> { + self.tx.commit().await?; + Ok(()) + } + + /// Rolls back the transaction. + pub async fn rollback(self) -> Result<(), DatabaseError> { + self.tx.rollback().await?; + Ok(()) + } +} + +impl DatabaseConnectionProvider for DatabaseTransaction { + type Connection = sea_orm::DatabaseTransaction; + + fn get_connection(&self) -> &Self::Connection { + &self.tx + } +} diff --git a/crates/database/migration/Cargo.toml b/crates/database/migration/Cargo.toml new file mode 100644 index 00000000..5821f2f2 --- /dev/null +++ b/crates/database/migration/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "scroll-migration" +version = "0.1.0" +edition = "2021" +publish = false + +[lib] +name = "migration" +path = "src/lib.rs" + +[dependencies] +async-std = { version = "1", features = ["attributes", "tokio1"] } +tracing.workspace = true + +[dependencies.sea-orm-migration] +version = "1.1.0" +features = [ + # Enable at least one `ASYNC_RUNTIME` and `DATABASE_DRIVER` feature if you want to run migration via CLI. + # View the list of supported features at https://www.sea-ql.org/SeaORM/docs/install-and-config/database-and-async-runtime. + # e.g. + # "runtime-tokio-rustls", # `ASYNC_RUNTIME` feature + # "sqlx-postgres", # `DATABASE_DRIVER` feature + "runtime-tokio-native-tls", + "sqlx-sqlite", +] diff --git a/crates/database/migration/README.md b/crates/database/migration/README.md new file mode 100644 index 00000000..3b438d89 --- /dev/null +++ b/crates/database/migration/README.md @@ -0,0 +1,41 @@ +# Running Migrator CLI + +- Generate a new migration file + ```sh + cargo run -- generate MIGRATION_NAME + ``` +- Apply all pending migrations + ```sh + cargo run + ``` + ```sh + cargo run -- up + ``` +- Apply first 10 pending migrations + ```sh + cargo run -- up -n 10 + ``` +- Rollback last applied migrations + ```sh + cargo run -- down + ``` +- Rollback last 10 applied migrations + ```sh + cargo run -- down -n 10 + ``` +- Drop all tables from the database, then reapply all migrations + ```sh + cargo run -- fresh + ``` +- Rollback all applied migrations, then reapply all migrations + ```sh + cargo run -- refresh + ``` +- Rollback all applied migrations + ```sh + cargo run -- reset + ``` +- Check the status of all migrations + ```sh + cargo run -- status + ``` diff --git a/crates/database/migration/src/lib.rs b/crates/database/migration/src/lib.rs new file mode 100644 index 00000000..4485aaf2 --- /dev/null +++ b/crates/database/migration/src/lib.rs @@ -0,0 +1,16 @@ +pub use sea_orm_migration::prelude::*; + +mod m20220101_000001_create_batch_input_table; +mod m20250304_125946_add_l1_msg_table; + +pub struct Migrator; + +#[async_trait::async_trait] +impl MigratorTrait for Migrator { + fn migrations() -> Vec> { + vec![ + Box::new(m20220101_000001_create_batch_input_table::Migration), + Box::new(m20250304_125946_add_l1_msg_table::Migration), + ] + } +} diff --git a/crates/database/migration/src/m20220101_000001_create_batch_input_table.rs b/crates/database/migration/src/m20220101_000001_create_batch_input_table.rs new file mode 100644 index 00000000..a0a22e02 --- /dev/null +++ b/crates/database/migration/src/m20220101_000001_create_batch_input_table.rs @@ -0,0 +1,57 @@ +use sea_orm_migration::{prelude::*, schema::*}; + +// TODO: migrate these to a constants module +// CONSTANTS +const BATCH_HEADER_LENGTH: u32 = 32; + +const CHUNKS_LENGTH: u32 = 1024; + +const HASH_LENGTH: u32 = 32; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .create_table( + Table::create() + .table(BatchInput::Table) + .if_not_exists() + .col(pk_auto(BatchInput::Index)) + .col(tiny_integer(BatchInput::Version)) + .col(tiny_integer(BatchInput::CodecVersion)) + .col(binary_len(BatchInput::Hash, HASH_LENGTH)) + .col(big_unsigned(BatchInput::BlockNumber)) + .col(binary_len(BatchInput::ParentBatchHeader, BATCH_HEADER_LENGTH)) + .col(var_binary(BatchInput::Chunks, CHUNKS_LENGTH)) + .col(var_binary(BatchInput::SkippedL1MessageBitmap, HASH_LENGTH)) + // TODO: Set the blob hash as nullable + .col(binary_len(BatchInput::BlobHash, HASH_LENGTH)) + .col(boolean_null(BatchInput::FinalizedBlockNumber)) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager.drop_table(Table::drop().table(BatchInput::Table).to_owned()).await + } +} + +#[derive(DeriveIden)] +enum BatchInput { + Table, + Version, + Index, + CodecVersion, + Hash, + BlockNumber, + ParentBatchHeader, + Chunks, + SkippedL1MessageBitmap, + BlobHash, + FinalizedBlockNumber, + // TODO: Do we need the blob proof? +} diff --git a/crates/database/migration/src/m20250304_125946_add_l1_msg_table.rs b/crates/database/migration/src/m20250304_125946_add_l1_msg_table.rs new file mode 100644 index 00000000..81e76a17 --- /dev/null +++ b/crates/database/migration/src/m20250304_125946_add_l1_msg_table.rs @@ -0,0 +1,41 @@ +use sea_orm_migration::{prelude::*, schema::*}; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .create_table( + Table::create() + .table(L1Message::Table) + .if_not_exists() + .col(pk_auto(L1Message::QueueIndex)) + .col(unsigned(L1Message::BlockNumber)) + .col(text(L1Message::GasLimit)) + .col(binary_len(L1Message::To, 20)) + .col(binary_len(L1Message::Value, 32)) + .col(binary_len(L1Message::Sender, 20)) + .col(var_binary(L1Message::Input, 1024)) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager.drop_table(Table::drop().table(L1Message::Table).to_owned()).await + } +} + +#[derive(DeriveIden)] +enum L1Message { + Table, + QueueIndex, + BlockNumber, + GasLimit, + To, + Value, + Sender, + Input, +} diff --git a/crates/database/migration/src/main.rs b/crates/database/migration/src/main.rs new file mode 100644 index 00000000..e1a4dcf2 --- /dev/null +++ b/crates/database/migration/src/main.rs @@ -0,0 +1,8 @@ +use sea_orm_migration::prelude::*; + +#[async_std::main] +async fn main() { + tracing::info!(target: "scroll::migration", "Running database migrations."); + cli::run_cli(migration::Migrator).await; + tracing::info!(target: "scroll::migration", "Database migrations complete.") +} diff --git a/crates/engine/Cargo.toml b/crates/engine/Cargo.toml index e05e09f6..a78a706e 100644 --- a/crates/engine/Cargo.toml +++ b/crates/engine/Cargo.toml @@ -54,6 +54,7 @@ arbitrary = [ "reth-scroll-primitives/arbitrary", "scroll-alloy-rpc-types-engine/arbitrary", "alloy-chains/arbitrary", + "rollup-node-primitives/arbitrary", ] test-utils = [ "arbitrary", diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index 6b49602d..8a404a5e 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -18,8 +18,14 @@ alloy-rpc-types-engine.workspace = true scroll-alloy-consensus.workspace = true # misc +arbitrary = { workspace = true, optional = true } derive_more = { workspace = true, features = ["from"] } [features] default = ["std"] std = ["alloy-primitives/std", "alloy-rpc-types-engine/std", "scroll-alloy-consensus/std", "derive_more/std"] +arbitrary = [ + "dep:arbitrary", + "alloy-primitives/arbitrary", + "scroll-alloy-consensus/arbitrary", +] diff --git a/crates/primitives/src/batch.rs b/crates/primitives/src/batch.rs index c358236e..2b389cbf 100644 --- a/crates/primitives/src/batch.rs +++ b/crates/primitives/src/batch.rs @@ -6,7 +6,7 @@ use alloy_primitives::{BlockNumber, B256}; /// /// This is used as input for the derivation pipeline. All data remains in its raw serialized form. /// The data is then deserialized, enriched and processed in the derivation pipeline. -#[derive(Debug, PartialEq, Eq, derive_more::From)] +#[derive(Debug, Clone, PartialEq, Eq, derive_more::From)] pub enum BatchInput { /// The input data for a batch. BatchInputDataV1(BatchInputV1), @@ -14,8 +14,42 @@ pub enum BatchInput { BatchInputDataV2(BatchInputV2), } +impl BatchInput { + /// Returns the coded (protocol) version of the batch input. + pub const fn version(&self) -> u8 { + match self { + Self::BatchInputDataV1(data) => data.version, + Self::BatchInputDataV2(data) => data.batch_input_base.version, + } + } + + /// Returns the index of the batch. + pub const fn batch_index(&self) -> u64 { + match self { + Self::BatchInputDataV1(data) => data.batch_index, + Self::BatchInputDataV2(data) => data.batch_input_base.batch_index, + } + } + + /// Returns the hash of the batch. + pub const fn batch_hash(&self) -> &B256 { + match self { + Self::BatchInputDataV1(data) => &data.batch_hash, + Self::BatchInputDataV2(data) => &data.batch_input_base.batch_hash, + } + } + + /// Sets the block number of the batch. + pub fn set_block_number(&mut self, block_number: BlockNumber) { + match self { + Self::BatchInputDataV1(data) => data.block_number = block_number, + Self::BatchInputDataV2(data) => data.batch_input_base.block_number = block_number, + } + } +} + /// The input data for a batch. -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct BatchInputV1 { /// The version of the batch input data. pub version: u8, @@ -34,10 +68,10 @@ pub struct BatchInputV1 { } /// The input data for a batch including the L1 blob hash. -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct BatchInputV2 { /// The base input data for the batch. - pub batch_input_data: BatchInputV1, + pub batch_input_base: BatchInputV1, /// The L1 blob hash associated with the batch. pub blob_hash: B256, } @@ -138,7 +172,7 @@ impl BatchInputBuilder { skipped_l1_message_bitmap, }; let blob_hash = blob.first().copied()?; - Some(BatchInputV2 { batch_input_data, blob_hash }.into()) + Some(BatchInputV2 { batch_input_base: batch_input_data, blob_hash }.into()) } (None, None, Some(_blobs)) => { // TODO(greg): for now None but this will be used in Euclid. @@ -148,3 +182,47 @@ impl BatchInputBuilder { } } } + +#[cfg(feature = "arbitrary")] +mod arbitrary_impl { + use super::*; + + impl arbitrary::Arbitrary<'_> for BatchInput { + fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result { + let version = u.arbitrary::()? % 2; + match version { + 0 => Ok(Self::BatchInputDataV1(u.arbitrary()?)), + 1 => Ok(Self::BatchInputDataV2(u.arbitrary()?)), + _ => unreachable!(), + } + } + } + + impl arbitrary::Arbitrary<'_> for BatchInputV1 { + fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result { + let version = u.arbitrary::()? % 8; + let batch_index = u.arbitrary::()? as u64; + let batch_hash = u.arbitrary::()?; + let block_number = u.arbitrary::()? as u64; + let parent_batch_header = u.arbitrary::>()?; + let chunks = u.arbitrary::>>()?; + let skipped_l1_message_bitmap = u.arbitrary::>()?; + + Ok(Self { + version, + batch_index, + batch_hash, + block_number, + parent_batch_header, + chunks, + skipped_l1_message_bitmap, + }) + } + } + + impl arbitrary::Arbitrary<'_> for BatchInputV2 { + fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result { + Ok(Self { batch_input_base: u.arbitrary()?, blob_hash: u.arbitrary()? }) + } + } +} diff --git a/crates/primitives/src/transaction.rs b/crates/primitives/src/transaction.rs index 9a0c2cef..33831f4b 100644 --- a/crates/primitives/src/transaction.rs +++ b/crates/primitives/src/transaction.rs @@ -1,7 +1,7 @@ use scroll_alloy_consensus::TxL1Message; /// A L1 message that is part of the L1 message queue. -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct L1MessageWithBlockNumber { /// The L1 block number at which the L1 message was generated. pub block_number: u64, @@ -15,3 +15,20 @@ impl L1MessageWithBlockNumber { Self { block_number, transaction } } } + +#[cfg(feature = "arbitrary")] +impl arbitrary::Arbitrary<'_> for L1MessageWithBlockNumber { + fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result { + Ok(Self { + block_number: u.arbitrary::()? as u64, + transaction: TxL1Message { + queue_index: u.arbitrary::()? as u64, + gas_limit: u.arbitrary()?, + to: u.arbitrary()?, + value: u.arbitrary()?, + sender: u.arbitrary()?, + input: u.arbitrary()?, + }, + }) + } +} diff --git a/crates/watcher/Cargo.toml b/crates/watcher/Cargo.toml index af886574..21b2d4d5 100644 --- a/crates/watcher/Cargo.toml +++ b/crates/watcher/Cargo.toml @@ -32,7 +32,7 @@ scroll-alloy-consensus.workspace = true arbitrary = { workspace = true, optional = true } async-trait.workspace = true derive_more = { workspace = true, features = ["from"] } -rand = { version = "0.9", optional = true } +rand = { workspace = true, optional = true } thiserror.workspace = true tokio = { workspace = true, features = ["full"] } tracing.workspace = true @@ -43,7 +43,7 @@ alloy-eips.workspace = true alloy-rpc-types-eth = { workspace = true, features = ["arbitrary"] } arbitrary.workspace = true eyre.workspace = true -rand = "0.9" +rand.workspace = true scroll-l1 = { workspace = true, features = ["test-utils"] } tracing-subscriber = "0.3" @@ -57,4 +57,5 @@ arbitrary = [ "alloy-rpc-types-eth/arbitrary", "scroll-alloy-consensus/arbitrary", "alloy-sol-types/arbitrary", + "rollup-node-primitives/arbitrary", ]