mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-06-02 07:09:29 +00:00
Merge branch 'main' into Pravdyvy/wallet-ffi-extension
This commit is contained in:
commit
9746ec5860
@ -16,6 +16,7 @@ ignore = [
|
||||
{ id = "RUSTSEC-2026-0097", reason = "`rand` v0.8.5 is present transitively from logos crates, modification may break integration" },
|
||||
{ id = "RUSTSEC-2026-0118", reason = "`hickory-proto` v0.25.0-alpha.5 is present transitively from logos crates, modification may break integration" },
|
||||
{ id = "RUSTSEC-2026-0119", reason = "`hickory-proto` v0.25.0-alpha.5 is present transitively from logos crates, modification may break integration" },
|
||||
{ id = "RUSTSEC-2024-0370", reason = "transitive dependency of `logos-blockchain-http-api-common`, can't do anything than wait for upstream fix" },
|
||||
]
|
||||
yanked = "deny"
|
||||
unused-ignored-advisory = "deny"
|
||||
|
||||
390
Cargo.lock
generated
390
Cargo.lock
generated
@ -733,8 +733,6 @@ checksum = "86887daca11d02e0b04f37a9cb81888aae881397fb48ff66494e356aea97554a"
|
||||
dependencies = [
|
||||
"itertools 0.10.5",
|
||||
"lazy_static",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1056,7 +1054,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cffb0e931875b666fc4fcb20fee52e9bbd1ef836fd9e9e04ec21555f9f85f7ef"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"gloo-timers 0.3.0",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
@ -1319,6 +1316,14 @@ dependencies = [
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bridge_core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"nssa_core",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bs58"
|
||||
version = "0.5.1"
|
||||
@ -2181,7 +2186,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ab67060fc6b8ef687992d439ca0fa36e7ed17e9a0b16b25b601e8757df720de"
|
||||
dependencies = [
|
||||
"data-encoding",
|
||||
"syn 2.0.117",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2665,7 +2670,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2847,6 +2852,15 @@ version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
dependencies = [
|
||||
"foreign-types-shared 0.1.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.5.0"
|
||||
@ -2854,7 +2868,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965"
|
||||
dependencies = [
|
||||
"foreign-types-macros",
|
||||
"foreign-types-shared",
|
||||
"foreign-types-shared 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2868,6 +2882,12 @@ dependencies = [
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.3.1"
|
||||
@ -2997,7 +3017,7 @@ version = "3.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24"
|
||||
dependencies = [
|
||||
"gloo-timers 0.2.6",
|
||||
"gloo-timers",
|
||||
"send_wrapper 0.4.0",
|
||||
]
|
||||
|
||||
@ -3167,18 +3187,6 @@ 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"
|
||||
@ -3638,6 +3646,22 @@ dependencies = [
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-tls"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-util",
|
||||
"native-tls",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-util"
|
||||
version = "0.1.20"
|
||||
@ -3655,10 +3679,12 @@ dependencies = [
|
||||
"libc",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"socket2 0.5.10",
|
||||
"socket2 0.6.3",
|
||||
"system-configuration 0.7.0",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
"windows-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4071,6 +4097,8 @@ dependencies = [
|
||||
"anyhow",
|
||||
"ata_core",
|
||||
"authenticated_transfer_core",
|
||||
"borsh",
|
||||
"bridge_core",
|
||||
"bytesize",
|
||||
"common",
|
||||
"faucet_core",
|
||||
@ -4080,8 +4108,11 @@ dependencies = [
|
||||
"indexer_service_rpc",
|
||||
"key_protocol",
|
||||
"log",
|
||||
"logos-blockchain-core",
|
||||
"logos-blockchain-http-api-common",
|
||||
"nssa",
|
||||
"nssa_core",
|
||||
"reqwest",
|
||||
"sequencer_core",
|
||||
"sequencer_service_rpc",
|
||||
"serde_json",
|
||||
@ -5283,7 +5314,7 @@ checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
||||
[[package]]
|
||||
name = "logos-blockchain-blend-crypto"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"blake2",
|
||||
"logos-blockchain-groth16",
|
||||
@ -5291,13 +5322,13 @@ dependencies = [
|
||||
"logos-blockchain-poseidon2",
|
||||
"logos-blockchain-utils",
|
||||
"rs-merkle-tree",
|
||||
"thiserror 1.0.69",
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-blend-message"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"blake2",
|
||||
"derivative",
|
||||
@ -5308,11 +5339,12 @@ dependencies = [
|
||||
"logos-blockchain-core",
|
||||
"logos-blockchain-groth16",
|
||||
"logos-blockchain-key-management-system-keys",
|
||||
"logos-blockchain-log-targets",
|
||||
"logos-blockchain-utils",
|
||||
"serde",
|
||||
"serde-big-array",
|
||||
"serde_with",
|
||||
"thiserror 1.0.69",
|
||||
"thiserror 2.0.18",
|
||||
"tracing",
|
||||
"zeroize",
|
||||
]
|
||||
@ -5320,7 +5352,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "logos-blockchain-blend-proofs"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"ed25519-dalek",
|
||||
"generic-array 1.3.5",
|
||||
@ -5329,17 +5361,18 @@ dependencies = [
|
||||
"logos-blockchain-groth16",
|
||||
"logos-blockchain-pol",
|
||||
"logos-blockchain-poq",
|
||||
"logos-blockchain-poseidon2",
|
||||
"logos-blockchain-utils",
|
||||
"num-bigint 0.4.6",
|
||||
"serde",
|
||||
"thiserror 1.0.69",
|
||||
"thiserror 2.0.18",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-chain-broadcast-service"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"derivative",
|
||||
@ -5355,7 +5388,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "logos-blockchain-chain-service"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
@ -5377,7 +5410,8 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_with",
|
||||
"strum",
|
||||
"thiserror 1.0.69",
|
||||
"thiserror 2.0.18",
|
||||
"time",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-futures",
|
||||
@ -5386,7 +5420,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "logos-blockchain-circuits-prover"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"logos-blockchain-circuits-utils",
|
||||
"tempfile",
|
||||
@ -5395,7 +5429,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "logos-blockchain-circuits-utils"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"dirs",
|
||||
]
|
||||
@ -5403,10 +5437,11 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "logos-blockchain-common-http-client"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"hex",
|
||||
"log",
|
||||
"logos-blockchain-chain-broadcast-service",
|
||||
"logos-blockchain-chain-service",
|
||||
"logos-blockchain-core",
|
||||
@ -5416,14 +5451,15 @@ dependencies = [
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 1.0.69",
|
||||
"thiserror 2.0.18",
|
||||
"tokio-util",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-core"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"ark-ff 0.4.2",
|
||||
"bincode",
|
||||
@ -5448,20 +5484,21 @@ dependencies = [
|
||||
"rpds",
|
||||
"serde",
|
||||
"strum",
|
||||
"thiserror 1.0.69",
|
||||
"thiserror 2.0.18",
|
||||
"time",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-cryptarchia-engine"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"logos-blockchain-pol",
|
||||
"logos-blockchain-utils",
|
||||
"serde",
|
||||
"serde_with",
|
||||
"thiserror 1.0.69",
|
||||
"thiserror 2.0.18",
|
||||
"time",
|
||||
"tokio",
|
||||
"tracing",
|
||||
@ -5470,7 +5507,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "logos-blockchain-cryptarchia-sync"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures",
|
||||
@ -5481,7 +5518,7 @@ dependencies = [
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_with",
|
||||
"thiserror 1.0.69",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
@ -5489,7 +5526,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "logos-blockchain-groth16"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"ark-bn254 0.4.0",
|
||||
"ark-ec 0.4.2",
|
||||
@ -5507,7 +5544,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "logos-blockchain-http-api-common"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"axum 0.7.9",
|
||||
"logos-blockchain-core",
|
||||
@ -5515,14 +5552,19 @@ dependencies = [
|
||||
"logos-blockchain-tracing",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"serde_with",
|
||||
"time",
|
||||
"tracing",
|
||||
"url",
|
||||
"utoipa",
|
||||
"validator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-key-management-system-keys"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
@ -5548,7 +5590,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "logos-blockchain-key-management-system-macros"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -5558,7 +5600,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "logos-blockchain-key-management-system-operators"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"logos-blockchain-blend-proofs",
|
||||
@ -5574,7 +5616,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "logos-blockchain-key-management-system-service"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"log",
|
||||
@ -5591,7 +5633,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "logos-blockchain-ledger"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"derivative",
|
||||
"logos-blockchain-blend-crypto",
|
||||
@ -5610,14 +5652,14 @@ dependencies = [
|
||||
"rpds",
|
||||
"serde",
|
||||
"serde_arrays",
|
||||
"thiserror 1.0.69",
|
||||
"thiserror 2.0.18",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-libp2p"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"backon",
|
||||
@ -5628,6 +5670,7 @@ dependencies = [
|
||||
"igd-next 0.16.2",
|
||||
"libp2p",
|
||||
"logos-blockchain-cryptarchia-sync",
|
||||
"logos-blockchain-log-targets",
|
||||
"logos-blockchain-utils",
|
||||
"multiaddr",
|
||||
"natpmp",
|
||||
@ -5636,16 +5679,34 @@ dependencies = [
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_with",
|
||||
"thiserror 1.0.69",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-log-targets"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"logos-blockchain-log-targets-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-log-targets-macros"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-mmr"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"ark-ff 0.4.2",
|
||||
"logos-blockchain-groth16",
|
||||
@ -5658,13 +5719,14 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "logos-blockchain-network-service"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"futures",
|
||||
"logos-blockchain-core",
|
||||
"logos-blockchain-cryptarchia-sync",
|
||||
"logos-blockchain-libp2p",
|
||||
"logos-blockchain-log-targets",
|
||||
"logos-blockchain-tracing",
|
||||
"overwatch",
|
||||
"rand 0.8.5",
|
||||
@ -5678,47 +5740,48 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "logos-blockchain-poc"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"logos-blockchain-circuits-prover",
|
||||
"logos-blockchain-circuits-utils",
|
||||
"logos-blockchain-groth16",
|
||||
"logos-blockchain-proofs-error",
|
||||
"logos-blockchain-witness-generator",
|
||||
"num-bigint 0.4.6",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.18",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-pol"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"astro-float",
|
||||
"logos-blockchain-circuits-prover",
|
||||
"logos-blockchain-circuits-utils",
|
||||
"logos-blockchain-groth16",
|
||||
"logos-blockchain-proofs-error",
|
||||
"logos-blockchain-utils",
|
||||
"logos-blockchain-witness-generator",
|
||||
"num-bigint 0.4.6",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.18",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-poq"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"logos-blockchain-circuits-prover",
|
||||
"logos-blockchain-circuits-utils",
|
||||
"logos-blockchain-groth16",
|
||||
"logos-blockchain-pol",
|
||||
"logos-blockchain-proofs-error",
|
||||
"logos-blockchain-witness-generator",
|
||||
"num-bigint 0.4.6",
|
||||
"serde",
|
||||
@ -5730,7 +5793,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "logos-blockchain-poseidon2"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"ark-bn254 0.4.0",
|
||||
"ark-ff 0.4.2",
|
||||
@ -5738,10 +5801,20 @@ dependencies = [
|
||||
"num-bigint 0.4.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-proofs-error"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"logos-blockchain-groth16",
|
||||
"serde_json",
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-services-utils"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"futures",
|
||||
@ -5749,24 +5822,25 @@ dependencies = [
|
||||
"overwatch",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 1.0.69",
|
||||
"thiserror 2.0.18",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-storage-service"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"futures",
|
||||
"logos-blockchain-core",
|
||||
"logos-blockchain-cryptarchia-engine",
|
||||
"logos-blockchain-log-targets",
|
||||
"logos-blockchain-tracing",
|
||||
"overwatch",
|
||||
"serde",
|
||||
"thiserror 1.0.69",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
@ -5774,12 +5848,13 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "logos-blockchain-time-service"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"futures",
|
||||
"log",
|
||||
"logos-blockchain-cryptarchia-engine",
|
||||
"logos-blockchain-log-targets",
|
||||
"logos-blockchain-tracing",
|
||||
"logos-blockchain-utils",
|
||||
"overwatch",
|
||||
@ -5796,8 +5871,10 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "logos-blockchain-tracing"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"flate2",
|
||||
"logos-blockchain-log-targets",
|
||||
"opentelemetry",
|
||||
"opentelemetry-appender-tracing",
|
||||
"opentelemetry-http",
|
||||
@ -5820,7 +5897,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "logos-blockchain-utils"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"blake2",
|
||||
@ -5831,13 +5908,15 @@ dependencies = [
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_with",
|
||||
"serde_yaml",
|
||||
"thiserror 2.0.18",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-utxotree"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"ark-ff 0.4.2",
|
||||
"logos-blockchain-groth16",
|
||||
@ -5845,13 +5924,13 @@ dependencies = [
|
||||
"num-bigint 0.4.6",
|
||||
"rpds",
|
||||
"serde",
|
||||
"thiserror 1.0.69",
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-witness-generator"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"tempfile",
|
||||
]
|
||||
@ -5859,12 +5938,13 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "logos-blockchain-zksign"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"logos-blockchain-circuits-prover",
|
||||
"logos-blockchain-circuits-utils",
|
||||
"logos-blockchain-groth16",
|
||||
"logos-blockchain-poseidon2",
|
||||
"logos-blockchain-proofs-error",
|
||||
"logos-blockchain-witness-generator",
|
||||
"num-bigint 0.4.6",
|
||||
"serde",
|
||||
@ -5876,13 +5956,15 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "logos-blockchain-zone-sdk"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=ee281a447d95a951752461ee0a6e88eb4a0f17cf#ee281a447d95a951752461ee0a6e88eb4a0f17cf"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=dd055cc1ef7c130f710a52a190edd97bc7b0f71b#dd055cc1ef7c130f710a52a190edd97bc7b0f71b"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"futures",
|
||||
"hex",
|
||||
"logos-blockchain-common-http-client",
|
||||
"logos-blockchain-core",
|
||||
"logos-blockchain-groth16",
|
||||
"logos-blockchain-http-api-common",
|
||||
"logos-blockchain-key-management-system-service",
|
||||
"rand 0.8.5",
|
||||
"reqwest",
|
||||
@ -6114,7 +6196,7 @@ dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"block",
|
||||
"core-graphics-types",
|
||||
"foreign-types",
|
||||
"foreign-types 0.5.0",
|
||||
"log",
|
||||
"objc",
|
||||
"paste",
|
||||
@ -6253,6 +6335,23 @@ dependencies = [
|
||||
"unsigned-varint 0.7.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "465500e14ea162429d264d44189adc38b199b62b1c21eea9f69e4b73cb03bbf2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "natpmp"
|
||||
version = "0.5.0"
|
||||
@ -6460,6 +6559,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"authenticated_transfer_core",
|
||||
"borsh",
|
||||
"bridge_core",
|
||||
"clock_core",
|
||||
"env_logger",
|
||||
"faucet_core",
|
||||
@ -6718,12 +6818,49 @@ version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"cfg-if",
|
||||
"foreign-types 0.3.2",
|
||||
"libc",
|
||||
"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.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.116"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f28a22dc7140cda5f096e5e7724a6962ca81a7f8bfd2979f9b18c11af56318c4"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry"
|
||||
version = "0.31.0"
|
||||
@ -7157,6 +7294,30 @@ dependencies = [
|
||||
"toml_edit 0.25.4+spec-1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr2"
|
||||
version = "2.0.0"
|
||||
@ -7241,6 +7402,7 @@ dependencies = [
|
||||
"ata_core",
|
||||
"ata_program",
|
||||
"authenticated_transfer_core",
|
||||
"bridge_core",
|
||||
"clock_core",
|
||||
"faucet_core",
|
||||
"nssa_core",
|
||||
@ -7820,6 +7982,7 @@ checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"encoding_rs",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
@ -7828,9 +7991,12 @@ dependencies = [
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-rustls",
|
||||
"hyper-tls",
|
||||
"hyper-util",
|
||||
"js-sys",
|
||||
"log",
|
||||
"mime",
|
||||
"native-tls",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"quinn",
|
||||
@ -7841,6 +8007,7 @@ dependencies = [
|
||||
"serde_urlencoded",
|
||||
"sync_wrapper",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tokio-rustls",
|
||||
"tokio-util",
|
||||
"tower",
|
||||
@ -8418,7 +8585,7 @@ dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -8686,11 +8853,13 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"borsh",
|
||||
"bridge_core",
|
||||
"bytesize",
|
||||
"chrono",
|
||||
"common",
|
||||
"faucet_core",
|
||||
"futures",
|
||||
"hex",
|
||||
"humantime-serde",
|
||||
"log",
|
||||
"logos-blockchain-core",
|
||||
@ -9249,6 +9418,12 @@ version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||
|
||||
[[package]]
|
||||
name = "symlink"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7973cce6668464ea31f176d85b13c7ab3bba2cb3b77a2ed26abd7801688010a"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
@ -9395,7 +9570,7 @@ dependencies = [
|
||||
"getrandom 0.4.2",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -9700,6 +9875,16 @@ dependencies = [
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-native-tls"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
|
||||
dependencies = [
|
||||
"native-tls",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.26.4"
|
||||
@ -9962,11 +10147,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-appender"
|
||||
version = "0.2.4"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf"
|
||||
checksum = "050686193eb999b4bb3bc2acfa891a13da00f79734704c4b8b4ef1a10b368a3c"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"symlink",
|
||||
"thiserror 2.0.18",
|
||||
"time",
|
||||
"tracing-subscriber 0.3.23",
|
||||
@ -10380,6 +10566,30 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
|
||||
[[package]]
|
||||
name = "utoipa"
|
||||
version = "4.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c5afb1a60e207dca502682537fefcfd9921e71d0b83e9576060f09abc6efab23"
|
||||
dependencies = [
|
||||
"indexmap 2.13.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"utoipa-gen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utoipa-gen"
|
||||
version = "4.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20c24e8ab68ff9ee746aad22d39b5535601e6416d1b0feeabf78be986a5c4392"
|
||||
dependencies = [
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.22.0"
|
||||
@ -10391,6 +10601,36 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "validator"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43fb22e1a008ece370ce08a3e9e4447a910e92621bb49b85d6e48a45397e7cfa"
|
||||
dependencies = [
|
||||
"idna",
|
||||
"once_cell",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"url",
|
||||
"validator_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "validator_derive"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7df16e474ef958526d1205f6dda359fdfab79d9aa6d54bafcb92dcd07673dca"
|
||||
dependencies = [
|
||||
"darling 0.20.11",
|
||||
"once_cell",
|
||||
"proc-macro-error2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.1"
|
||||
@ -10747,7 +10987,7 @@ version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
15
Cargo.toml
15
Cargo.toml
@ -22,6 +22,7 @@ members = [
|
||||
"programs/associated_token_account",
|
||||
"programs/authenticated_transfer/core",
|
||||
"programs/faucet/core",
|
||||
"programs/bridge/core",
|
||||
"programs/vault/core",
|
||||
"sequencer/core",
|
||||
"sequencer/service",
|
||||
@ -75,6 +76,7 @@ ata_core = { path = "programs/associated_token_account/core" }
|
||||
ata_program = { path = "programs/associated_token_account" }
|
||||
authenticated_transfer_core = { path = "programs/authenticated_transfer/core" }
|
||||
faucet_core = { path = "programs/faucet/core" }
|
||||
bridge_core = { path = "programs/bridge/core" }
|
||||
vault_core = { path = "programs/vault/core" }
|
||||
test_program_methods = { path = "test_program_methods" }
|
||||
testnet_initial_state = { path = "testnet_initial_state" }
|
||||
@ -135,12 +137,13 @@ schemars = "1.2"
|
||||
async-stream = "0.3.6"
|
||||
criterion = { version = "0.8", features = ["html_reports"] }
|
||||
|
||||
logos-blockchain-common-http-client = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "ee281a447d95a951752461ee0a6e88eb4a0f17cf" }
|
||||
logos-blockchain-key-management-system-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "ee281a447d95a951752461ee0a6e88eb4a0f17cf" }
|
||||
logos-blockchain-core = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "ee281a447d95a951752461ee0a6e88eb4a0f17cf" }
|
||||
logos-blockchain-chain-broadcast-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "ee281a447d95a951752461ee0a6e88eb4a0f17cf" }
|
||||
logos-blockchain-chain-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "ee281a447d95a951752461ee0a6e88eb4a0f17cf" }
|
||||
logos-blockchain-zone-sdk = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "ee281a447d95a951752461ee0a6e88eb4a0f17cf" }
|
||||
logos-blockchain-common-http-client = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "dd055cc1ef7c130f710a52a190edd97bc7b0f71b" }
|
||||
logos-blockchain-key-management-system-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "dd055cc1ef7c130f710a52a190edd97bc7b0f71b" }
|
||||
logos-blockchain-core = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "dd055cc1ef7c130f710a52a190edd97bc7b0f71b" }
|
||||
logos-blockchain-chain-broadcast-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "dd055cc1ef7c130f710a52a190edd97bc7b0f71b" }
|
||||
logos-blockchain-chain-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "dd055cc1ef7c130f710a52a190edd97bc7b0f71b" }
|
||||
logos-blockchain-zone-sdk = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "dd055cc1ef7c130f710a52a190edd97bc7b0f71b" }
|
||||
logos-blockchain-http-api-common = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "dd055cc1ef7c130f710a52a190edd97bc7b0f71b" }
|
||||
|
||||
rocksdb = { version = "0.24.0", default-features = false, features = [
|
||||
"snappy",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -67,7 +67,9 @@ cryptarchia:
|
||||
- opcode: 17
|
||||
payload:
|
||||
channel_id: '0000000000000000000000000000000000000000000000000000000000000000'
|
||||
inscription: '67656e65736973'
|
||||
# chain_id_len=12 (u64_le), chain_id=logos-devnet (utf-8),
|
||||
# genesis_time=2026-01-10T07:47:56Z (u64_le), epoch_nonce=[0u8; 32]
|
||||
inscription: '0c000000000000006c6f676f732d6465766e65742c046269000000000000000000000000000000000000000000000000000000000000000000000000'
|
||||
parent: '0000000000000000000000000000000000000000000000000000000000000000'
|
||||
signer: '0000000000000000000000000000000000000000000000000000000000000000'
|
||||
execution_gas_price: 0
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
services:
|
||||
|
||||
logos-blockchain-node-0:
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain@sha256:9f1829dea335c56f6ff68ae37ea872ed5313b96b69e8ffe143c02b7217de85fc
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain@sha256:f160cfbf898a06554451cc066d84cfd0f8ab62d59bd3e62d9cde3bd5582c12ab
|
||||
ports:
|
||||
- "${PORT:-8080}:18080/tcp"
|
||||
volumes:
|
||||
|
||||
@ -67,7 +67,7 @@ impl NSSATransaction {
|
||||
}
|
||||
|
||||
/// Validates the transaction against the current state and returns the resulting diff
|
||||
/// without applying it. Rejects transactions that modify clock or faucet system accounts,
|
||||
/// without applying it. Rejects transactions that modify clock, faucet or bridge accounts,
|
||||
/// whether directly or indirectly via chain calls.
|
||||
///
|
||||
/// This check is required for all user transactions. Only sequencer transactions may bypass
|
||||
@ -90,26 +90,12 @@ impl NSSATransaction {
|
||||
}
|
||||
}?;
|
||||
|
||||
let public_diff = diff.public_diff();
|
||||
let touches_clock = nssa::CLOCK_PROGRAM_ACCOUNT_IDS.iter().any(|id| {
|
||||
public_diff
|
||||
.get(id)
|
||||
.is_some_and(|post| *post != state.get_account_by_id(*id))
|
||||
});
|
||||
if touches_clock {
|
||||
return Err(nssa::error::NssaError::InvalidInput(
|
||||
"Transaction modifies system clock accounts".into(),
|
||||
));
|
||||
}
|
||||
|
||||
let faucet_id = nssa::system_faucet_account_id();
|
||||
if public_diff
|
||||
.get(&faucet_id)
|
||||
.is_some_and(|post| *post != state.get_account_by_id(faucet_id))
|
||||
{
|
||||
return Err(nssa::error::NssaError::InvalidInput(
|
||||
"Transaction modifies system faucet account".into(),
|
||||
));
|
||||
let system_accounts = nssa::CLOCK_PROGRAM_ACCOUNT_IDS.iter().copied().chain([
|
||||
nssa::system_faucet_account_id(),
|
||||
nssa::system_bridge_account_id(),
|
||||
]);
|
||||
for account_id in system_accounts {
|
||||
validate_doesnt_modify_account(state, &diff, account_id)?;
|
||||
}
|
||||
|
||||
Ok(diff)
|
||||
@ -184,3 +170,21 @@ pub fn clock_invocation(timestamp: clock_core::Instruction) -> nssa::PublicTrans
|
||||
nssa::public_transaction::WitnessSet::from_raw_parts(vec![]),
|
||||
)
|
||||
}
|
||||
|
||||
fn validate_doesnt_modify_account(
|
||||
state: &V03State,
|
||||
diff: &ValidatedStateDiff,
|
||||
account_id: AccountId,
|
||||
) -> Result<(), nssa::error::NssaError> {
|
||||
if diff
|
||||
.public_diff()
|
||||
.get(&account_id)
|
||||
.is_some_and(|post| *post != state.get_account_by_id(account_id))
|
||||
{
|
||||
Err(nssa::error::NssaError::InvalidInput(format!(
|
||||
"Transaction modifies restricted system account {account_id}"
|
||||
)))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,6 +15,11 @@
|
||||
},
|
||||
"indexer_rpc_url": "ws://indexer_service:8779",
|
||||
"genesis": [
|
||||
{
|
||||
"supply_bridge_account": {
|
||||
"balance": 1000000
|
||||
}
|
||||
},
|
||||
{
|
||||
"supply_account": {
|
||||
"account_id": "6iArKUXxhUJqS7kCaPNhwMWt3ro71PDyBj7jwAyE2VQV",
|
||||
|
||||
@ -6,7 +6,7 @@ use common::{
|
||||
transaction::{NSSATransaction, clock_invocation},
|
||||
};
|
||||
use log::info;
|
||||
use logos_blockchain_core::{header::HeaderId, mantle::ops::channel::MsgId};
|
||||
use logos_blockchain_core::header::HeaderId;
|
||||
use logos_blockchain_zone_sdk::Slot;
|
||||
use nssa::{Account, AccountId, V03State};
|
||||
use nssa_core::BlockId;
|
||||
@ -97,16 +97,16 @@ impl IndexerStore {
|
||||
Ok(self.dbio.calculate_state_for_id(block_id)?)
|
||||
}
|
||||
|
||||
pub fn get_zone_cursor(&self) -> Result<Option<(MsgId, Slot)>> {
|
||||
pub fn get_zone_cursor(&self) -> Result<Option<Slot>> {
|
||||
let Some(bytes) = self.dbio.get_zone_sdk_indexer_cursor_bytes()? else {
|
||||
return Ok(None);
|
||||
};
|
||||
let cursor: (MsgId, Slot) = serde_json::from_slice(&bytes)
|
||||
let cursor: Slot = serde_json::from_slice(&bytes)
|
||||
.context("Failed to deserialize stored zone-sdk indexer cursor")?;
|
||||
Ok(Some(cursor))
|
||||
}
|
||||
|
||||
pub fn set_zone_cursor(&self, cursor: &(MsgId, Slot)) -> Result<()> {
|
||||
pub fn set_zone_cursor(&self, cursor: &Slot) -> Result<()> {
|
||||
let bytes =
|
||||
serde_json::to_vec(cursor).context("Failed to serialize zone-sdk indexer cursor")?;
|
||||
self.dbio.put_zone_sdk_indexer_cursor_bytes(&bytes)?;
|
||||
|
||||
@ -81,8 +81,8 @@ impl IndexerCore {
|
||||
error!("Failed to deserialize L2 block from zone-sdk: {e}");
|
||||
// Advance past the broken inscription so we don't
|
||||
// re-process it on restart.
|
||||
cursor = Some((zone_block.id, slot));
|
||||
if let Err(err) = self.store.set_zone_cursor(&(zone_block.id, slot)) {
|
||||
cursor = Some(slot);
|
||||
if let Err(err) = self.store.set_zone_cursor(&slot) {
|
||||
warn!("Failed to persist indexer cursor: {err:#}");
|
||||
}
|
||||
continue;
|
||||
@ -98,8 +98,8 @@ impl IndexerCore {
|
||||
error!("Failed to store block {}: {err:#}", block.header.block_id);
|
||||
}
|
||||
|
||||
cursor = Some((zone_block.id, slot));
|
||||
if let Err(err) = self.store.set_zone_cursor(&(zone_block.id, slot)) {
|
||||
cursor = Some(slot);
|
||||
if let Err(err) = self.store.set_zone_cursor(&slot) {
|
||||
warn!("Failed to persist indexer cursor: {err:#}");
|
||||
}
|
||||
yield Ok(block);
|
||||
|
||||
@ -22,6 +22,7 @@ token_core.workspace = true
|
||||
ata_core.workspace = true
|
||||
vault_core.workspace = true
|
||||
faucet_core.workspace = true
|
||||
bridge_core.workspace = true
|
||||
indexer_service_rpc = { workspace = true, features = ["client"] }
|
||||
sequencer_service_rpc = { workspace = true, features = ["client"] }
|
||||
wallet-ffi.workspace = true
|
||||
@ -34,3 +35,7 @@ tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
|
||||
hex.workspace = true
|
||||
tempfile.workspace = true
|
||||
bytesize.workspace = true
|
||||
reqwest.workspace = true
|
||||
borsh.workspace = true
|
||||
logos-blockchain-http-api-common.workspace = true
|
||||
logos-blockchain-core.workspace = true
|
||||
|
||||
@ -7,8 +7,14 @@ use integration_tests::{
|
||||
public_mention, verify_commitment_is_in_state,
|
||||
};
|
||||
use log::info;
|
||||
use nssa::{AccountId, program::Program};
|
||||
use nssa_core::{NullifierPublicKey, encryption::shared_key_derivation::Secp256k1Point};
|
||||
use nssa::{
|
||||
AccountId, SharedSecretKey, execute_and_prove,
|
||||
privacy_preserving_transaction::circuit::ProgramWithDependencies, program::Program,
|
||||
};
|
||||
use nssa_core::{
|
||||
InputAccountIdentity, NullifierPublicKey, account::AccountWithMetadata,
|
||||
encryption::shared_key_derivation::Secp256k1Point,
|
||||
};
|
||||
use sequencer_service_rpc::RpcClient as _;
|
||||
use tokio::test;
|
||||
use wallet::{
|
||||
@ -626,13 +632,7 @@ async fn shielded_transfers_to_two_identifiers_same_npk() -> Result<()> {
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn ppt_that_chain_calls_faucet_is_dropped() -> Result<()> {
|
||||
use nssa::{
|
||||
EphemeralPublicKey, SharedSecretKey, execute_and_prove,
|
||||
privacy_preserving_transaction::{self, circuit::ProgramWithDependencies},
|
||||
};
|
||||
use nssa_core::{InputAccountIdentity, account::AccountWithMetadata};
|
||||
|
||||
async fn ppt_cant_chain_call_faucet() -> Result<()> {
|
||||
let ctx = TestContext::new().await?;
|
||||
|
||||
let binary = std::fs::read(
|
||||
@ -656,7 +656,6 @@ async fn ppt_that_chain_calls_faucet_is_dropped() -> Result<()> {
|
||||
let npk = NullifierPublicKey::from(&nsk);
|
||||
let vpk = Secp256k1Point::from_scalar([4; 32]);
|
||||
let ssk = SharedSecretKey::new([55; 32], &vpk);
|
||||
let epk = EphemeralPublicKey::from_scalar([55; 32]);
|
||||
let attacker_vault_id = {
|
||||
let seed = vault_core::compute_vault_seed(attacker_id);
|
||||
AccountId::for_private_pda(&vault_program_id, &seed, &npk, 1337)
|
||||
@ -695,7 +694,7 @@ async fn ppt_that_chain_calls_faucet_is_dropped() -> Result<()> {
|
||||
let instruction =
|
||||
Program::serialize_instruction((faucet_program_id, vault_program_id, attacker_id, amount))?;
|
||||
|
||||
let (output, proof) = execute_and_prove(
|
||||
let res = execute_and_prove(
|
||||
vec![faucet_pre, vault_pda_pre],
|
||||
instruction,
|
||||
vec![
|
||||
@ -708,47 +707,9 @@ async fn ppt_that_chain_calls_faucet_is_dropped() -> Result<()> {
|
||||
},
|
||||
],
|
||||
&program_with_deps,
|
||||
)?;
|
||||
);
|
||||
|
||||
let message = privacy_preserving_transaction::Message::try_from_circuit_output(
|
||||
vec![faucet_account_id],
|
||||
vec![],
|
||||
vec![(npk, vpk, epk)],
|
||||
output,
|
||||
)?;
|
||||
let witness_set = privacy_preserving_transaction::WitnessSet::for_message(&message, proof, &[]);
|
||||
let attack_ppt = NSSATransaction::PrivacyPreserving(nssa::PrivacyPreservingTransaction::new(
|
||||
message,
|
||||
witness_set,
|
||||
));
|
||||
|
||||
let faucet_balance_before = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(faucet_account_id)
|
||||
.await?;
|
||||
let vault_balance_before = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(attacker_vault_id)
|
||||
.await?;
|
||||
|
||||
let tx_hash = ctx.sequencer_client().send_transaction(attack_ppt).await?;
|
||||
|
||||
info!("Waiting for next block creation");
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
let faucet_balance_after = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(faucet_account_id)
|
||||
.await?;
|
||||
let vault_balance_after = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(attacker_vault_id)
|
||||
.await?;
|
||||
let tx_on_chain = ctx.sequencer_client().get_transaction(tx_hash).await?;
|
||||
|
||||
assert_eq!(faucet_balance_after, faucet_balance_before);
|
||||
assert_eq!(vault_balance_after, vault_balance_before);
|
||||
assert!(tx_on_chain.is_none());
|
||||
assert!(res.is_err());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -420,7 +420,7 @@ async fn cannot_execute_faucet_program() -> Result<()> {
|
||||
Program::faucet().id(),
|
||||
vec![faucet_account_id, recipient_vault_id],
|
||||
vec![],
|
||||
faucet_core::Instruction::Transfer {
|
||||
faucet_core::Instruction::GenesisTransferVault {
|
||||
vault_program_id,
|
||||
recipient_id: recipient,
|
||||
amount,
|
||||
|
||||
450
integration_tests/tests/bridge.rs
Normal file
450
integration_tests/tests/bridge.rs
Normal file
@ -0,0 +1,450 @@
|
||||
#![expect(
|
||||
clippy::tests_outside_test_module,
|
||||
clippy::arithmetic_side_effects,
|
||||
reason = "We don't care about these in tests"
|
||||
)]
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::Context as _;
|
||||
use borsh::BorshSerialize;
|
||||
use common::transaction::NSSATransaction;
|
||||
use integration_tests::{TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext};
|
||||
use log::info;
|
||||
use logos_blockchain_core::mantle::{Value, ledger::Inputs, ops::channel::deposit::DepositOp};
|
||||
use logos_blockchain_http_api_common::bodies::{
|
||||
channel::ChannelDepositRequestBody,
|
||||
wallet::{
|
||||
balance::WalletBalanceResponseBody,
|
||||
transfer_funds::{WalletTransferFundsRequestBody, WalletTransferFundsResponseBody},
|
||||
},
|
||||
};
|
||||
use nssa::{
|
||||
AccountId, execute_and_prove, privacy_preserving_transaction, program::Program,
|
||||
public_transaction,
|
||||
};
|
||||
use nssa_core::{InputAccountIdentity, account::AccountWithMetadata};
|
||||
use sequencer_service_rpc::RpcClient as _;
|
||||
use tokio::test;
|
||||
|
||||
const TIME_TO_FINALIZE_DEPOSIT_EVENT_ON_BEDROCK: Duration = Duration::from_mins(2);
|
||||
|
||||
#[test]
|
||||
async fn public_bridge_deposit_invocation_is_dropped() -> anyhow::Result<()> {
|
||||
let ctx = TestContext::new().await?;
|
||||
|
||||
let recipient_id = ctx.existing_public_accounts()[0];
|
||||
let bridge_account_id = nssa::system_bridge_account_id();
|
||||
let vault_program_id = Program::vault().id();
|
||||
let recipient_vault_id = vault_core::compute_vault_account_id(vault_program_id, recipient_id);
|
||||
|
||||
let message = public_transaction::Message::try_new(
|
||||
Program::bridge().id(),
|
||||
vec![bridge_account_id, recipient_vault_id],
|
||||
vec![],
|
||||
bridge_core::Instruction::Deposit {
|
||||
vault_program_id,
|
||||
recipient_id,
|
||||
amount: 1,
|
||||
},
|
||||
)
|
||||
.context("Failed to build public bridge deposit transaction")?;
|
||||
|
||||
let attack_tx = NSSATransaction::Public(nssa::PublicTransaction::new(
|
||||
message,
|
||||
nssa::public_transaction::WitnessSet::from_raw_parts(vec![]),
|
||||
));
|
||||
|
||||
let bridge_balance_before = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(bridge_account_id)
|
||||
.await?;
|
||||
let vault_balance_before = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(recipient_vault_id)
|
||||
.await?;
|
||||
|
||||
let tx_hash = ctx.sequencer_client().send_transaction(attack_tx).await?;
|
||||
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
let bridge_balance_after = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(bridge_account_id)
|
||||
.await?;
|
||||
let vault_balance_after = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(recipient_vault_id)
|
||||
.await?;
|
||||
let tx_on_chain = ctx.sequencer_client().get_transaction(tx_hash).await?;
|
||||
|
||||
assert_eq!(bridge_balance_after, bridge_balance_before);
|
||||
assert_eq!(vault_balance_after, vault_balance_before);
|
||||
assert!(
|
||||
tx_on_chain.is_none(),
|
||||
"Direct public bridge::Deposit invocation should be rejected"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn private_bridge_deposit_invocation_is_dropped() -> anyhow::Result<()> {
|
||||
let ctx = TestContext::new().await?;
|
||||
|
||||
let recipient_id = ctx.existing_public_accounts()[0];
|
||||
let bridge_account_id = nssa::system_bridge_account_id();
|
||||
let vault_program_id = Program::vault().id();
|
||||
let recipient_vault_id = vault_core::compute_vault_account_id(vault_program_id, recipient_id);
|
||||
|
||||
// Get pre-state of bridge and vault accounts
|
||||
let bridge_pre = AccountWithMetadata::new(
|
||||
ctx.sequencer_client()
|
||||
.get_account(bridge_account_id)
|
||||
.await?,
|
||||
false,
|
||||
bridge_account_id,
|
||||
);
|
||||
let vault_pre = AccountWithMetadata::new(
|
||||
ctx.sequencer_client()
|
||||
.get_account(recipient_vault_id)
|
||||
.await?,
|
||||
false,
|
||||
recipient_vault_id,
|
||||
);
|
||||
|
||||
// Create program with dependencies
|
||||
let program_with_deps =
|
||||
nssa::privacy_preserving_transaction::circuit::ProgramWithDependencies::new(
|
||||
Program::bridge(),
|
||||
[
|
||||
(vault_program_id, Program::vault()),
|
||||
(
|
||||
Program::authenticated_transfer_program().id(),
|
||||
Program::authenticated_transfer_program(),
|
||||
),
|
||||
]
|
||||
.into(),
|
||||
);
|
||||
|
||||
// Serialize the bridge deposit instruction
|
||||
let instruction = Program::serialize_instruction(bridge_core::Instruction::Deposit {
|
||||
vault_program_id,
|
||||
recipient_id,
|
||||
amount: 1,
|
||||
})
|
||||
.context("Failed to serialize bridge deposit instruction")?;
|
||||
|
||||
// Execute and prove the bridge deposit
|
||||
let (output, proof) = execute_and_prove(
|
||||
vec![bridge_pre.clone(), vault_pre.clone()],
|
||||
instruction,
|
||||
vec![InputAccountIdentity::Public, InputAccountIdentity::Public],
|
||||
&program_with_deps,
|
||||
)
|
||||
.context("Failed to execute/prove bridge deposit")?;
|
||||
|
||||
// Create privacy-preserving transaction from circuit output
|
||||
let message = privacy_preserving_transaction::Message::try_from_circuit_output(
|
||||
vec![bridge_account_id, recipient_vault_id],
|
||||
vec![bridge_pre.account.nonce, vault_pre.account.nonce],
|
||||
vec![],
|
||||
output,
|
||||
)
|
||||
.context("Failed to build privacy-preserving bridge deposit message")?;
|
||||
|
||||
let witness_set = privacy_preserving_transaction::WitnessSet::for_message(&message, proof, &[]);
|
||||
let attack_tx = NSSATransaction::PrivacyPreserving(nssa::PrivacyPreservingTransaction::new(
|
||||
message,
|
||||
witness_set,
|
||||
));
|
||||
|
||||
let bridge_balance_before = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(bridge_account_id)
|
||||
.await?;
|
||||
let vault_balance_before = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(recipient_vault_id)
|
||||
.await?;
|
||||
|
||||
let tx_hash = ctx.sequencer_client().send_transaction(attack_tx).await?;
|
||||
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
let bridge_balance_after = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(bridge_account_id)
|
||||
.await?;
|
||||
let vault_balance_after = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(recipient_vault_id)
|
||||
.await?;
|
||||
let tx_on_chain = ctx.sequencer_client().get_transaction(tx_hash).await?;
|
||||
|
||||
assert_eq!(bridge_balance_after, bridge_balance_before);
|
||||
assert_eq!(vault_balance_after, vault_balance_before);
|
||||
assert!(
|
||||
tx_on_chain.is_none(),
|
||||
"Privacy-preserving bridge::Deposit invocation should be rejected"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn submit_bedrock_deposit(
|
||||
bedrock_addr: std::net::SocketAddr,
|
||||
recipient_id: AccountId,
|
||||
amount: u128,
|
||||
) -> anyhow::Result<()> {
|
||||
#[derive(BorshSerialize)]
|
||||
struct DepositMetadata {
|
||||
recipient_id: AccountId,
|
||||
}
|
||||
|
||||
// Encode deposit metadata
|
||||
let metadata = borsh::to_vec(&DepositMetadata { recipient_id })
|
||||
.context("Failed to encode deposit metadata")?;
|
||||
|
||||
let funding_key = "2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26";
|
||||
|
||||
let amount: Value = amount
|
||||
.try_into()
|
||||
.context("Deposit amount does not fit Bedrock Value type")?;
|
||||
let channel_id = integration_tests::config::bedrock_channel_id();
|
||||
let client = reqwest::Client::new();
|
||||
|
||||
let query_balance = || async {
|
||||
let balance_response = client
|
||||
.get(format!(
|
||||
"http://{bedrock_addr}/wallet/{funding_key}/balance"
|
||||
))
|
||||
.send()
|
||||
.await
|
||||
.context("Failed to query Bedrock wallet balance")?;
|
||||
|
||||
let balance_response = check_response_success(balance_response).await?;
|
||||
|
||||
balance_response
|
||||
.json::<WalletBalanceResponseBody>()
|
||||
.await
|
||||
.context("Failed to decode Bedrock balance response")
|
||||
};
|
||||
|
||||
let mut balance = query_balance().await?;
|
||||
|
||||
info!(
|
||||
"Queried Bedrock balance for key {funding_key}: {:?}",
|
||||
balance.balance
|
||||
);
|
||||
|
||||
if balance.balance < amount {
|
||||
anyhow::bail!(
|
||||
"Bedrock wallet with key {funding_key} has insufficient balance {:?} for deposit amount {:?}",
|
||||
balance.balance,
|
||||
amount
|
||||
);
|
||||
}
|
||||
|
||||
let mut selected_note_id = balance
|
||||
.notes
|
||||
.iter()
|
||||
.find_map(|(note_id, value)| (*value == amount).then_some(*note_id));
|
||||
|
||||
if selected_note_id.is_none() {
|
||||
let transfer_body = WalletTransferFundsRequestBody {
|
||||
tip: None,
|
||||
change_public_key: balance.address,
|
||||
funding_public_keys: vec![balance.address],
|
||||
recipient_public_key: balance.address,
|
||||
amount,
|
||||
};
|
||||
|
||||
let transfer_response = client
|
||||
.post(format!(
|
||||
"http://{bedrock_addr}/wallet/transactions/transfer-funds"
|
||||
))
|
||||
.json(&transfer_body)
|
||||
.send()
|
||||
.await
|
||||
.context("Failed to submit Bedrock transfer-funds request")?;
|
||||
let transfer_response = check_response_success(transfer_response).await?;
|
||||
|
||||
let transfer: WalletTransferFundsResponseBody = transfer_response
|
||||
.json()
|
||||
.await
|
||||
.context("Failed to decode Bedrock transfer-funds response")?;
|
||||
|
||||
info!(
|
||||
"Submitted transfer-funds to create exact deposit note, tx hash {:?}",
|
||||
transfer.hash
|
||||
);
|
||||
|
||||
let mut found_note = None;
|
||||
for _ in 0..20 {
|
||||
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
balance = query_balance().await?;
|
||||
found_note = balance
|
||||
.notes
|
||||
.iter()
|
||||
.find_map(|(note_id, value)| (*value == amount).then_some(*note_id));
|
||||
if found_note.is_some() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
selected_note_id = found_note;
|
||||
}
|
||||
|
||||
let Some(selected_note_id) = selected_note_id else {
|
||||
anyhow::bail!(
|
||||
"Failed to locate exact-value note {amount:?} for Bedrock deposit; available notes: {:?}",
|
||||
balance.notes,
|
||||
);
|
||||
};
|
||||
|
||||
let body = ChannelDepositRequestBody {
|
||||
tip: None,
|
||||
deposit: DepositOp {
|
||||
channel_id,
|
||||
inputs: Inputs::new(vec![selected_note_id]),
|
||||
metadata,
|
||||
},
|
||||
change_public_key: balance.address,
|
||||
funding_public_keys: vec![balance.address],
|
||||
max_tx_fee: 1_000_u64.into(),
|
||||
};
|
||||
|
||||
let response = client
|
||||
.post(format!("http://{bedrock_addr}/channel/deposit"))
|
||||
.json(&body)
|
||||
.send()
|
||||
.await
|
||||
.context("Failed to submit Bedrock deposit request")?;
|
||||
let response = check_response_success(response).await?;
|
||||
|
||||
let body_text = response
|
||||
.text()
|
||||
.await
|
||||
.unwrap_or_else(|_| "<failed to decode>".to_owned());
|
||||
info!(
|
||||
"Successfully submitted Bedrock deposit request for recipient {recipient_id} and amount {amount}, response body: {body_text}",
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn check_response_success(response: reqwest::Response) -> anyhow::Result<reqwest::Response> {
|
||||
if response.status().is_success() {
|
||||
Ok(response)
|
||||
} else {
|
||||
let status = response.status();
|
||||
let body_text = response.text().await.unwrap_or_default();
|
||||
anyhow::bail!("Request failed with status {status} and body {body_text}");
|
||||
}
|
||||
}
|
||||
|
||||
async fn wait_for_vault_balance(
|
||||
ctx: &TestContext,
|
||||
vault_id: AccountId,
|
||||
expected_balance: u128,
|
||||
) -> anyhow::Result<()> {
|
||||
let timeout = TIME_TO_FINALIZE_DEPOSIT_EVENT_ON_BEDROCK
|
||||
+ Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS);
|
||||
tokio::time::timeout(timeout, async {
|
||||
loop {
|
||||
let balance = ctx.sequencer_client().get_account_balance(vault_id).await?;
|
||||
if balance == expected_balance {
|
||||
return Ok(());
|
||||
}
|
||||
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
}
|
||||
})
|
||||
.await
|
||||
.with_context(|| {
|
||||
format!("Timed out waiting for vault {vault_id} balance to reach {expected_balance}")
|
||||
})?
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn bedrock_deposit_mints_to_vault_then_claim_succeeds() -> anyhow::Result<()> {
|
||||
let ctx = TestContext::new().await?;
|
||||
|
||||
let recipient_id = ctx.existing_public_accounts()[0];
|
||||
let vault_program_id = Program::vault().id();
|
||||
let recipient_vault_id = vault_core::compute_vault_account_id(vault_program_id, recipient_id);
|
||||
|
||||
let vault_balance_before = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(recipient_vault_id)
|
||||
.await?;
|
||||
let recipient_balance_before = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(recipient_id)
|
||||
.await?;
|
||||
|
||||
// Submit deposit to Bedrock
|
||||
submit_bedrock_deposit(ctx.bedrock_addr(), recipient_id, 1).await?;
|
||||
|
||||
// Wait for vault to receive the deposit (minted from bridge to vault)
|
||||
wait_for_vault_balance(&ctx, recipient_vault_id, vault_balance_before + 1).await?;
|
||||
|
||||
// Now claim funds from vault back to recipient
|
||||
let nonces = ctx
|
||||
.wallet()
|
||||
.get_accounts_nonces(vec![recipient_id])
|
||||
.await
|
||||
.context("Failed to get nonce for vault claim")?;
|
||||
|
||||
let signing_key = ctx
|
||||
.wallet()
|
||||
.storage()
|
||||
.key_chain()
|
||||
.pub_account_signing_key(recipient_id)
|
||||
.with_context(|| format!("Missing signing key for account {recipient_id}"))?;
|
||||
|
||||
let claim_message = public_transaction::Message::try_new(
|
||||
vault_program_id,
|
||||
vec![recipient_id, recipient_vault_id],
|
||||
nonces,
|
||||
vault_core::Instruction::Claim { amount: 1 },
|
||||
)
|
||||
.context("Failed to build vault claim message")?;
|
||||
|
||||
let claim_witness_set =
|
||||
public_transaction::WitnessSet::for_message(&claim_message, &[signing_key]);
|
||||
let claim_tx = NSSATransaction::Public(nssa::PublicTransaction::new(
|
||||
claim_message,
|
||||
claim_witness_set,
|
||||
));
|
||||
|
||||
let claim_hash = ctx.sequencer_client().send_transaction(claim_tx).await?;
|
||||
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
let claim_on_chain = ctx.sequencer_client().get_transaction(claim_hash).await?;
|
||||
let vault_balance_after_claim = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(recipient_vault_id)
|
||||
.await?;
|
||||
let recipient_balance_after_claim = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(recipient_id)
|
||||
.await?;
|
||||
|
||||
assert!(
|
||||
claim_on_chain.is_some(),
|
||||
"Vault claim transaction must be included on-chain"
|
||||
);
|
||||
assert_eq!(
|
||||
vault_balance_after_claim, vault_balance_before,
|
||||
"Vault balance should return to initial state after claim"
|
||||
);
|
||||
assert_eq!(
|
||||
recipient_balance_after_claim,
|
||||
recipient_balance_before + 1,
|
||||
"Recipient balance should increase by claimed amount"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -20,13 +20,12 @@ use wallet::{
|
||||
};
|
||||
|
||||
/// Maximum time to wait for the indexer to catch up to the sequencer.
|
||||
const L2_TO_L1_TIMEOUT_MILLIS: u64 = 180_000;
|
||||
const L2_TO_L1_TIMEOUT: Duration = Duration::from_mins(6);
|
||||
|
||||
/// Poll the indexer until its last finalized block id reaches the sequencer's
|
||||
/// current last block id or until [`L2_TO_L1_TIMEOUT_MILLIS`] elapses.
|
||||
/// Returns the last indexer block id observed.
|
||||
async fn wait_for_indexer_to_catch_up(ctx: &TestContext) -> Result<u64> {
|
||||
let timeout = Duration::from_millis(L2_TO_L1_TIMEOUT_MILLIS);
|
||||
let block_id_to_catch_up =
|
||||
sequencer_service_rpc::RpcClient::get_last_block_id(ctx.sequencer_client()).await?;
|
||||
let mut last_ind: u64 = 1;
|
||||
@ -50,11 +49,11 @@ async fn wait_for_indexer_to_catch_up(ctx: &TestContext) -> Result<u64> {
|
||||
tokio::time::sleep(Duration::from_secs(2)).await;
|
||||
}
|
||||
};
|
||||
tokio::time::timeout(timeout, inner)
|
||||
tokio::time::timeout(L2_TO_L1_TIMEOUT, inner)
|
||||
.await
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"Indexer failed to catch up within {L2_TO_L1_TIMEOUT_MILLIS} milliseconds. Last indexer block id observed: {last_ind}, but needed to catch up to at least {block_id_to_catch_up}"
|
||||
"Indexer failed to catch up within {L2_TO_L1_TIMEOUT:?}. Last indexer block id observed: {last_ind}, but needed to catch up to at least {block_id_to_catch_up}"
|
||||
)
|
||||
})?
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ use std::{
|
||||
fs::File,
|
||||
io::Write as _,
|
||||
net::SocketAddr,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use anyhow::{Context as _, Result};
|
||||
@ -34,7 +35,7 @@ use wallet::{
|
||||
};
|
||||
|
||||
/// Maximum time to wait for the indexer to catch up to the sequencer.
|
||||
const L2_TO_L1_TIMEOUT_MILLIS: u64 = 180_000;
|
||||
const L2_TO_L1_TIMEOUT: Duration = Duration::from_mins(6);
|
||||
|
||||
unsafe extern "C" {
|
||||
unsafe fn query_last_block(
|
||||
@ -114,7 +115,7 @@ fn indexer_test_run_ffi() -> Result<()> {
|
||||
let (ctx, indexer_ffi, _indexer_dir) = setup()?;
|
||||
|
||||
// RUN OBSERVATION
|
||||
std::thread::sleep(std::time::Duration::from_millis(L2_TO_L1_TIMEOUT_MILLIS));
|
||||
std::thread::sleep(L2_TO_L1_TIMEOUT);
|
||||
|
||||
// Safety: ctx runtime is valid for the lifetime of the returned Runtime
|
||||
let runtime = unsafe { Runtime::from_borrowed(ctx.runtime()) };
|
||||
@ -138,7 +139,7 @@ fn indexer_ffi_block_batching() -> Result<()> {
|
||||
|
||||
// WAIT
|
||||
info!("Waiting for indexer to parse blocks");
|
||||
std::thread::sleep(std::time::Duration::from_millis(L2_TO_L1_TIMEOUT_MILLIS));
|
||||
std::thread::sleep(L2_TO_L1_TIMEOUT);
|
||||
|
||||
// Safety: ctx runtime is valid for the lifetime of the returned Runtime
|
||||
let runtime = unsafe { Runtime::from_borrowed(ctx.runtime()) };
|
||||
@ -265,7 +266,7 @@ fn indexer_ffi_state_consistency() -> Result<()> {
|
||||
|
||||
// WAIT
|
||||
info!("Waiting for indexer to parse blocks");
|
||||
std::thread::sleep(std::time::Duration::from_millis(L2_TO_L1_TIMEOUT_MILLIS));
|
||||
std::thread::sleep(L2_TO_L1_TIMEOUT);
|
||||
|
||||
// Safety: ctx runtime is valid for the lifetime of the returned Runtime
|
||||
let runtime = unsafe { Runtime::from_borrowed(ctx.runtime()) };
|
||||
@ -371,7 +372,7 @@ fn indexer_ffi_state_consistency_with_labels() -> Result<()> {
|
||||
assert_eq!(acc_2_balance, 20100);
|
||||
|
||||
info!("Waiting for indexer to parse blocks");
|
||||
std::thread::sleep(std::time::Duration::from_millis(L2_TO_L1_TIMEOUT_MILLIS));
|
||||
std::thread::sleep(L2_TO_L1_TIMEOUT);
|
||||
|
||||
// Safety: ctx runtime is valid for the lifetime of the returned Runtime
|
||||
let runtime = unsafe { Runtime::from_borrowed(ctx.runtime()) };
|
||||
|
||||
@ -48,6 +48,14 @@ pub struct MemPoolHandle<T> {
|
||||
sender: Sender<T>,
|
||||
}
|
||||
|
||||
impl<T> Clone for MemPoolHandle<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
sender: self.sender.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> MemPoolHandle<T> {
|
||||
const fn new(sender: Sender<T>) -> Self {
|
||||
Self { sender }
|
||||
|
||||
@ -11,6 +11,7 @@ workspace = true
|
||||
nssa_core = { workspace = true, features = ["host"] }
|
||||
clock_core.workspace = true
|
||||
faucet_core.workspace = true
|
||||
bridge_core.workspace = true
|
||||
|
||||
anyhow.workspace = true
|
||||
thiserror.workspace = true
|
||||
|
||||
@ -18,7 +18,7 @@ pub use public_transaction::PublicTransaction;
|
||||
pub use signature::{PrivateKey, PublicKey, Signature};
|
||||
pub use state::{
|
||||
CLOCK_01_PROGRAM_ACCOUNT_ID, CLOCK_10_PROGRAM_ACCOUNT_ID, CLOCK_50_PROGRAM_ACCOUNT_ID,
|
||||
CLOCK_PROGRAM_ACCOUNT_IDS, V03State, system_faucet_account_id,
|
||||
CLOCK_PROGRAM_ACCOUNT_IDS, V03State, system_bridge_account_id, system_faucet_account_id,
|
||||
};
|
||||
pub use validated_state_diff::ValidatedStateDiff;
|
||||
|
||||
|
||||
@ -10,8 +10,9 @@ use crate::{
|
||||
error::NssaError,
|
||||
program_methods::{
|
||||
AMM_ELF, AMM_ID, ASSOCIATED_TOKEN_ACCOUNT_ELF, ASSOCIATED_TOKEN_ACCOUNT_ID,
|
||||
AUTHENTICATED_TRANSFER_ELF, AUTHENTICATED_TRANSFER_ID, CLOCK_ELF, CLOCK_ID, FAUCET_ELF,
|
||||
FAUCET_ID, PINATA_ELF, PINATA_ID, TOKEN_ELF, TOKEN_ID, VAULT_ELF, VAULT_ID,
|
||||
AUTHENTICATED_TRANSFER_ELF, AUTHENTICATED_TRANSFER_ID, BRIDGE_ELF, BRIDGE_ID, CLOCK_ELF,
|
||||
CLOCK_ID, FAUCET_ELF, FAUCET_ID, PINATA_ELF, PINATA_ID, TOKEN_ELF, TOKEN_ID, VAULT_ELF,
|
||||
VAULT_ID,
|
||||
},
|
||||
};
|
||||
|
||||
@ -164,6 +165,14 @@ impl Program {
|
||||
elf: FAUCET_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn bridge() -> Self {
|
||||
Self {
|
||||
id: BRIDGE_ID,
|
||||
elf: BRIDGE_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Testnet only. Refactor to prevent compilation on mainnet.
|
||||
@ -194,9 +203,9 @@ mod tests {
|
||||
program::Program,
|
||||
program_methods::{
|
||||
AMM_ELF, AMM_ID, ASSOCIATED_TOKEN_ACCOUNT_ELF, ASSOCIATED_TOKEN_ACCOUNT_ID,
|
||||
AUTHENTICATED_TRANSFER_ELF, AUTHENTICATED_TRANSFER_ID, CLOCK_ELF, CLOCK_ID, FAUCET_ELF,
|
||||
FAUCET_ID, PINATA_ELF, PINATA_ID, PINATA_TOKEN_ELF, PINATA_TOKEN_ID, TOKEN_ELF,
|
||||
TOKEN_ID, VAULT_ELF, VAULT_ID,
|
||||
AUTHENTICATED_TRANSFER_ELF, AUTHENTICATED_TRANSFER_ID, BRIDGE_ELF, BRIDGE_ID,
|
||||
CLOCK_ELF, CLOCK_ID, FAUCET_ELF, FAUCET_ID, PINATA_ELF, PINATA_ID, PINATA_TOKEN_ELF,
|
||||
PINATA_TOKEN_ID, TOKEN_ELF, TOKEN_ID, VAULT_ELF, VAULT_ID,
|
||||
},
|
||||
};
|
||||
|
||||
@ -529,6 +538,7 @@ mod tests {
|
||||
let token_program = Program::token();
|
||||
let vault_program = Program::vault();
|
||||
let faucet_program = Program::faucet();
|
||||
let bridge_program = Program::bridge();
|
||||
let pinata_program = Program::pinata();
|
||||
|
||||
assert_eq!(auth_transfer_program.id, AUTHENTICATED_TRANSFER_ID);
|
||||
@ -539,6 +549,8 @@ mod tests {
|
||||
assert_eq!(vault_program.elf, VAULT_ELF);
|
||||
assert_eq!(faucet_program.id, FAUCET_ID);
|
||||
assert_eq!(faucet_program.elf, FAUCET_ELF);
|
||||
assert_eq!(bridge_program.id, BRIDGE_ID);
|
||||
assert_eq!(bridge_program.elf, BRIDGE_ELF);
|
||||
assert_eq!(pinata_program.id, PINATA_ID);
|
||||
assert_eq!(pinata_program.elf, PINATA_ELF);
|
||||
}
|
||||
@ -551,6 +563,7 @@ mod tests {
|
||||
(ASSOCIATED_TOKEN_ACCOUNT_ELF, ASSOCIATED_TOKEN_ACCOUNT_ID),
|
||||
(CLOCK_ELF, CLOCK_ID),
|
||||
(FAUCET_ELF, FAUCET_ID),
|
||||
(BRIDGE_ELF, BRIDGE_ID),
|
||||
(PINATA_ELF, PINATA_ID),
|
||||
(PINATA_TOKEN_ELF, PINATA_TOKEN_ID),
|
||||
(TOKEN_ELF, TOKEN_ID),
|
||||
|
||||
@ -126,8 +126,11 @@ impl Default for V03State {
|
||||
fn default() -> Self {
|
||||
let faucet_account_id = system_faucet_account_id();
|
||||
let faucet_account = system_faucet_account();
|
||||
let bridge_account_id = system_bridge_account_id();
|
||||
let bridge_account = system_bridge_account();
|
||||
let mut public_state = HashMap::new();
|
||||
public_state.insert(faucet_account_id, faucet_account);
|
||||
public_state.insert(bridge_account_id, bridge_account);
|
||||
|
||||
Self {
|
||||
public_state,
|
||||
@ -150,6 +153,7 @@ impl V03State {
|
||||
genesis_timestamp: nssa_core::Timestamp,
|
||||
) -> Self {
|
||||
let faucet_account_id = system_faucet_account_id();
|
||||
let bridge_account_id = system_bridge_account_id();
|
||||
let authenticated_transfer_program = Program::authenticated_transfer_program();
|
||||
let mut public_state: HashMap<_, _> = initial_data
|
||||
.iter()
|
||||
@ -164,7 +168,9 @@ impl V03State {
|
||||
})
|
||||
.collect();
|
||||
let faucet_account = system_faucet_account();
|
||||
let bridge_account = system_bridge_account();
|
||||
public_state.insert(faucet_account_id, faucet_account);
|
||||
public_state.insert(bridge_account_id, bridge_account);
|
||||
|
||||
let mut commitment_set = CommitmentSet::with_capacity(32);
|
||||
commitment_set.extend(&[DUMMY_COMMITMENT]);
|
||||
@ -190,6 +196,7 @@ impl V03State {
|
||||
this.insert_program(Program::ata());
|
||||
this.insert_program(Program::vault());
|
||||
this.insert_program(Program::faucet());
|
||||
this.insert_program(Program::bridge());
|
||||
|
||||
this
|
||||
}
|
||||
@ -384,11 +391,23 @@ fn system_faucet_account() -> Account {
|
||||
}
|
||||
}
|
||||
|
||||
fn system_bridge_account() -> Account {
|
||||
Account {
|
||||
program_owner: Program::authenticated_transfer_program().id(),
|
||||
..Account::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn system_faucet_account_id() -> AccountId {
|
||||
faucet_core::compute_faucet_account_id(Program::faucet().id())
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn system_bridge_account_id() -> AccountId {
|
||||
bridge_core::compute_bridge_account_id(Program::bridge().id())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
#![expect(
|
||||
@ -426,9 +445,10 @@ pub mod tests {
|
||||
signature::PrivateKey,
|
||||
state::{
|
||||
CLOCK_01_PROGRAM_ACCOUNT_ID, CLOCK_10_PROGRAM_ACCOUNT_ID, CLOCK_50_PROGRAM_ACCOUNT_ID,
|
||||
CLOCK_PROGRAM_ACCOUNT_IDS, MAX_NUMBER_CHAINED_CALLS, system_faucet_account,
|
||||
CLOCK_PROGRAM_ACCOUNT_IDS, MAX_NUMBER_CHAINED_CALLS, system_bridge_account,
|
||||
system_faucet_account,
|
||||
},
|
||||
system_faucet_account_id,
|
||||
system_bridge_account_id, system_faucet_account_id,
|
||||
};
|
||||
|
||||
impl V03State {
|
||||
@ -622,6 +642,7 @@ pub mod tests {
|
||||
},
|
||||
);
|
||||
this.insert(system_faucet_account_id(), system_faucet_account());
|
||||
this.insert(system_bridge_account_id(), system_bridge_account());
|
||||
for account_id in CLOCK_PROGRAM_ACCOUNT_IDS {
|
||||
this.insert(
|
||||
account_id,
|
||||
@ -646,6 +667,7 @@ pub mod tests {
|
||||
this.insert(Program::ata().id(), Program::ata());
|
||||
this.insert(Program::vault().id(), Program::vault());
|
||||
this.insert(Program::faucet().id(), Program::faucet());
|
||||
this.insert(Program::bridge().id(), Program::bridge());
|
||||
this
|
||||
};
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@ amm_program.workspace = true
|
||||
ata_core.workspace = true
|
||||
ata_program.workspace = true
|
||||
faucet_core.workspace = true
|
||||
bridge_core.workspace = true
|
||||
vault_core.workspace = true
|
||||
risc0-zkvm.workspace = true
|
||||
serde = { workspace = true, default-features = false }
|
||||
|
||||
82
program_methods/guest/src/bin/bridge.rs
Normal file
82
program_methods/guest/src/bin/bridge.rs
Normal file
@ -0,0 +1,82 @@
|
||||
use bridge_core::Instruction;
|
||||
use nssa_core::program::{
|
||||
AccountPostState, ChainedCall, ProgramInput, ProgramOutput, read_nssa_inputs,
|
||||
};
|
||||
|
||||
fn unchanged_post_states(
|
||||
pre_states: &[nssa_core::account::AccountWithMetadata],
|
||||
) -> Vec<AccountPostState> {
|
||||
pre_states
|
||||
.iter()
|
||||
.map(|pre_state| AccountPostState::new(pre_state.account.clone()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
caller_program_id,
|
||||
pre_states,
|
||||
instruction,
|
||||
},
|
||||
instruction_words,
|
||||
) = read_nssa_inputs::<Instruction>();
|
||||
|
||||
assert!(
|
||||
caller_program_id.is_none(),
|
||||
"Bridge cannot be invoked through chain calls"
|
||||
);
|
||||
|
||||
let pre_states_clone = pre_states.clone();
|
||||
let post_states = unchanged_post_states(&pre_states_clone);
|
||||
|
||||
let chained_calls = match instruction {
|
||||
Instruction::Deposit {
|
||||
vault_program_id,
|
||||
recipient_id,
|
||||
amount,
|
||||
} => {
|
||||
let [bridge, recipient_vault] = pre_states
|
||||
.try_into()
|
||||
.expect("Deposit requires exactly 2 accounts");
|
||||
|
||||
assert_eq!(
|
||||
bridge.account_id,
|
||||
bridge_core::compute_bridge_account_id(self_program_id),
|
||||
"First account must be bridge PDA"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
recipient_vault.account_id,
|
||||
vault_core::compute_vault_account_id(vault_program_id, recipient_id),
|
||||
"Second account must be recipient vault PDA"
|
||||
);
|
||||
|
||||
let mut bridge_for_vault = bridge;
|
||||
bridge_for_vault.is_authorized = true;
|
||||
|
||||
vec![
|
||||
ChainedCall::new(
|
||||
vault_program_id,
|
||||
vec![bridge_for_vault, recipient_vault],
|
||||
&vault_core::Instruction::Transfer {
|
||||
recipient_id,
|
||||
amount,
|
||||
},
|
||||
)
|
||||
.with_pda_seeds(vec![bridge_core::compute_bridge_seed()]),
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
caller_program_id,
|
||||
instruction_words,
|
||||
pre_states_clone,
|
||||
post_states,
|
||||
)
|
||||
.with_chained_calls(chained_calls)
|
||||
.write();
|
||||
}
|
||||
@ -23,11 +23,16 @@ fn main() {
|
||||
instruction_words,
|
||||
) = read_nssa_inputs::<Instruction>();
|
||||
|
||||
assert!(
|
||||
caller_program_id.is_none(),
|
||||
"Faucet cannot be invoked through chain calls"
|
||||
);
|
||||
|
||||
let pre_states_clone = pre_states.clone();
|
||||
let post_states = unchanged_post_states(&pre_states_clone);
|
||||
|
||||
let chained_calls = match instruction {
|
||||
Instruction::Transfer {
|
||||
Instruction::GenesisTransferVault {
|
||||
vault_program_id,
|
||||
recipient_id,
|
||||
amount,
|
||||
@ -57,6 +62,29 @@ fn main() {
|
||||
.with_pda_seeds(vec![faucet_core::compute_faucet_seed()]),
|
||||
]
|
||||
}
|
||||
Instruction::GenesisTransferDirect { amount } => {
|
||||
let [faucet, recipient] = pre_states
|
||||
.try_into()
|
||||
.expect("TransferDirect requires exactly 2 accounts");
|
||||
|
||||
assert_eq!(
|
||||
faucet.account_id,
|
||||
faucet_core::compute_faucet_account_id(self_program_id),
|
||||
"First account must be faucet PDA"
|
||||
);
|
||||
|
||||
let mut faucet_for_transfer = faucet;
|
||||
faucet_for_transfer.is_authorized = true;
|
||||
|
||||
vec![
|
||||
ChainedCall::new(
|
||||
faucet_for_transfer.account.program_owner,
|
||||
vec![faucet_for_transfer, recipient],
|
||||
&authenticated_transfer_core::Instruction::Transfer { amount },
|
||||
)
|
||||
.with_pda_seeds(vec![faucet_core::compute_faucet_seed()]),
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
ProgramOutput::new(
|
||||
|
||||
12
programs/bridge/core/Cargo.toml
Normal file
12
programs/bridge/core/Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "bridge_core"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
license = { workspace = true }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
nssa_core.workspace = true
|
||||
serde = { workspace = true, default-features = false }
|
||||
29
programs/bridge/core/src/lib.rs
Normal file
29
programs/bridge/core/src/lib.rs
Normal file
@ -0,0 +1,29 @@
|
||||
pub use nssa_core::program::PdaSeed;
|
||||
use nssa_core::{account::AccountId, program::ProgramId};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
const BRIDGE_SEED_DOMAIN_SEPARATOR: [u8; 32] = *b"/LEZ/v0.3/BridgeSeed/0000000000/";
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub enum Instruction {
|
||||
/// Transfers native tokens from the bridge PDA account to a recipient vault.
|
||||
///
|
||||
/// Required accounts (2):
|
||||
/// - Bridge PDA account
|
||||
/// - Recipient vault PDA account
|
||||
Deposit {
|
||||
vault_program_id: ProgramId,
|
||||
recipient_id: AccountId,
|
||||
amount: u128,
|
||||
},
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn compute_bridge_seed() -> PdaSeed {
|
||||
PdaSeed::new(BRIDGE_SEED_DOMAIN_SEPARATOR)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn compute_bridge_account_id(bridge_program_id: ProgramId) -> AccountId {
|
||||
AccountId::for_public_pda(&bridge_program_id, &compute_bridge_seed())
|
||||
}
|
||||
@ -8,14 +8,25 @@ const FAUCET_SEED_DOMAIN_SEPARATOR: [u8; 32] = *b"/LEZ/v0.3/FaucetSeed/000000000
|
||||
pub enum Instruction {
|
||||
/// Transfers native tokens from system faucet to recipient's vault.
|
||||
///
|
||||
/// Executed only in genesis block by sequencer it-self. User transactions will be denied.
|
||||
///
|
||||
/// Required accounts (2):
|
||||
/// - Faucet PDA account
|
||||
/// - Recipient vault PDA account
|
||||
Transfer {
|
||||
GenesisTransferVault {
|
||||
vault_program_id: ProgramId,
|
||||
recipient_id: AccountId,
|
||||
amount: u128,
|
||||
},
|
||||
|
||||
/// Transfers native tokens from system faucet directly to a recipient account.
|
||||
///
|
||||
/// Executed only in genesis block by sequencer it-self. User transactions will be denied.
|
||||
///
|
||||
/// Required accounts (2):
|
||||
/// - Faucet PDA account
|
||||
/// - Recipient account
|
||||
GenesisTransferDirect { amount: u128 },
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
|
||||
@ -16,6 +16,7 @@ mempool.workspace = true
|
||||
logos-blockchain-zone-sdk.workspace = true
|
||||
testnet_initial_state.workspace = true
|
||||
faucet_core.workspace = true
|
||||
bridge_core.workspace = true
|
||||
vault_core.workspace = true
|
||||
|
||||
anyhow.workspace = true
|
||||
@ -31,6 +32,7 @@ logos-blockchain-core.workspace = true
|
||||
rand.workspace = true
|
||||
borsh.workspace = true
|
||||
bytesize.workspace = true
|
||||
hex.workspace = true
|
||||
url.workspace = true
|
||||
|
||||
[features]
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use std::{sync::Arc, time::Duration};
|
||||
use std::{pin::Pin, sync::Arc, time::Duration};
|
||||
|
||||
use anyhow::{Context as _, Result, anyhow};
|
||||
use anyhow::{Context as _, Result};
|
||||
use common::block::Block;
|
||||
use log::warn;
|
||||
pub use logos_blockchain_core::mantle::ops::channel::MsgId;
|
||||
@ -10,7 +10,7 @@ use logos_blockchain_zone_sdk::{
|
||||
CommonHttpClient,
|
||||
adapter::NodeHttpClient,
|
||||
sequencer::{Event, SequencerConfig as ZoneSdkSequencerConfig, SequencerHandle, ZoneSequencer},
|
||||
state::InscriptionInfo,
|
||||
state::{DepositInfo, FinalizedOp, InscriptionInfo},
|
||||
};
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
@ -18,12 +18,16 @@ use crate::config::BedrockConfig;
|
||||
|
||||
/// Sink for `Event::Published` checkpoints emitted by the drive task.
|
||||
/// Caller is responsible for persistence (e.g. writing to rocksdb).
|
||||
pub type CheckpointSink = Box<dyn Fn(SequencerCheckpoint) + Send + Sync + 'static>;
|
||||
pub type CheckpointSink = Box<dyn Fn(SequencerCheckpoint) + Send + 'static>;
|
||||
|
||||
/// Sink for finalized L2 block ids derived from `Event::TxsFinalized` and
|
||||
/// `Event::FinalizedInscriptions`. Caller is responsible for cleanup
|
||||
/// (e.g. marking pending blocks as finalized in storage).
|
||||
pub type FinalizedBlockSink = Box<dyn Fn(u64) + Send + Sync + 'static>;
|
||||
pub type FinalizedBlockSink = Box<dyn Fn(u64) + Send + 'static>;
|
||||
|
||||
/// Sink for finalized Bedrock deposit events.
|
||||
pub type OnDepositEventSink =
|
||||
Box<dyn Fn(DepositInfo) -> Pin<Box<dyn Future<Output = ()> + Send>> + Send + 'static>;
|
||||
|
||||
#[expect(async_fn_in_trait, reason = "We don't care about Send/Sync here")]
|
||||
pub trait BlockPublisherTrait: Clone {
|
||||
@ -34,6 +38,7 @@ pub trait BlockPublisherTrait: Clone {
|
||||
initial_checkpoint: Option<SequencerCheckpoint>,
|
||||
on_checkpoint: CheckpointSink,
|
||||
on_finalized_block: FinalizedBlockSink,
|
||||
on_deposit_event: OnDepositEventSink,
|
||||
) -> Result<Self>;
|
||||
|
||||
/// Fire-and-forget publish. Zone-sdk drives the actual submission and
|
||||
@ -65,6 +70,7 @@ impl BlockPublisherTrait for ZoneSdkPublisher {
|
||||
initial_checkpoint: Option<SequencerCheckpoint>,
|
||||
on_checkpoint: CheckpointSink,
|
||||
on_finalized_block: FinalizedBlockSink,
|
||||
on_deposit_event: OnDepositEventSink,
|
||||
) -> Result<Self> {
|
||||
let basic_auth = config.auth.clone().map(Into::into);
|
||||
let node = NodeHttpClient::new(CommonHttpClient::new(basic_auth), config.node_url.clone());
|
||||
@ -89,10 +95,20 @@ impl BlockPublisherTrait for ZoneSdkPublisher {
|
||||
};
|
||||
match event {
|
||||
Event::Published { checkpoint, .. } => on_checkpoint(checkpoint),
|
||||
Event::TxsFinalized { inscriptions, .. }
|
||||
| Event::FinalizedInscriptions { inscriptions } => {
|
||||
if let Some(max_block_id) = max_block_id_from_inscriptions(&inscriptions) {
|
||||
on_finalized_block(max_block_id);
|
||||
Event::TxsFinalized { items } => {
|
||||
for op in items.into_iter().flat_map(|item| item.ops) {
|
||||
match op {
|
||||
FinalizedOp::Inscription(inscription) => {
|
||||
if let Some(block_id) = block_id_from_inscription(&inscription)
|
||||
{
|
||||
on_finalized_block(block_id);
|
||||
}
|
||||
}
|
||||
FinalizedOp::Deposit(deposit) => {
|
||||
on_deposit_event(deposit).await;
|
||||
}
|
||||
FinalizedOp::Withdraw(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
Event::ChannelUpdate { .. } | Event::Ready => {}
|
||||
@ -110,27 +126,26 @@ impl BlockPublisherTrait for ZoneSdkPublisher {
|
||||
|
||||
async fn publish_block(&self, block: &Block) -> Result<()> {
|
||||
let data = borsh::to_vec(block).context("Failed to serialize block")?;
|
||||
let data_bounded = data
|
||||
.try_into()
|
||||
.context("Block data exceeds maximum allowed size")?;
|
||||
|
||||
self.handle
|
||||
.publish_message(data)
|
||||
.publish_message(data_bounded)
|
||||
.await
|
||||
.map_err(|e| anyhow!("zone-sdk publish failed: {e}"))?;
|
||||
.context("Failed to publish block")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Deserialize each inscription payload as a `Block` and return the highest
|
||||
/// `block_id`. Bad payloads are logged and skipped.
|
||||
fn max_block_id_from_inscriptions(inscriptions: &[InscriptionInfo]) -> Option<u64> {
|
||||
inscriptions
|
||||
.iter()
|
||||
.filter_map(
|
||||
|inscription| match borsh::from_slice::<Block>(&inscription.payload) {
|
||||
Ok(block) => Some(block.header.block_id),
|
||||
Err(err) => {
|
||||
warn!("Failed to deserialize finalized inscription as Block: {err:#}");
|
||||
None
|
||||
}
|
||||
},
|
||||
)
|
||||
.max()
|
||||
/// Deserialize inscription payload as a `Block` and return it's`block_id`.
|
||||
/// Bad payloads are logged and skipped.
|
||||
fn block_id_from_inscription(inscription: &InscriptionInfo) -> Option<u64> {
|
||||
borsh::from_slice::<Block>(&inscription.payload)
|
||||
.inspect_err(|err| {
|
||||
warn!("Failed to deserialize block from inscription: {err:?}");
|
||||
})
|
||||
.ok()
|
||||
.map(|block| block.header.block_id)
|
||||
}
|
||||
|
||||
@ -22,6 +22,9 @@ pub enum GenesisAction {
|
||||
account_id: AccountId,
|
||||
balance: u128,
|
||||
},
|
||||
SupplyBridgeAccount {
|
||||
balance: u128,
|
||||
},
|
||||
}
|
||||
|
||||
// TODO: Provide default values
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use std::{path::Path, time::Instant};
|
||||
|
||||
use anyhow::{Context as _, Result, anyhow};
|
||||
use borsh::BorshDeserialize;
|
||||
use common::{
|
||||
HashType,
|
||||
block::{BedrockStatus, Block, HashableBlockData},
|
||||
@ -28,10 +29,29 @@ pub mod config;
|
||||
#[cfg(feature = "mock")]
|
||||
pub mod mock;
|
||||
|
||||
/// The origin of a transaction.
|
||||
pub enum TransactionOrigin {
|
||||
/// Basic transactions submitted by users via RPC.
|
||||
User,
|
||||
/// Transactions generated by the sequencer itself.
|
||||
Sequencer,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, BorshDeserialize)]
|
||||
struct DepositMetadata {
|
||||
recipient_id: nssa::AccountId,
|
||||
}
|
||||
|
||||
impl DepositMetadata {
|
||||
fn decode(bytes: &[u8]) -> Result<Self, std::io::Error> {
|
||||
Self::try_from_slice(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SequencerCore<BP: BlockPublisherTrait = ZoneSdkPublisher> {
|
||||
state: nssa::V03State,
|
||||
store: SequencerStore,
|
||||
mempool: MemPool<NSSATransaction>,
|
||||
mempool: MemPool<(TransactionOrigin, NSSATransaction)>,
|
||||
sequencer_config: SequencerConfig,
|
||||
chain_height: u64,
|
||||
block_publisher: BP,
|
||||
@ -45,7 +65,7 @@ impl<BP: BlockPublisherTrait> SequencerCore<BP> {
|
||||
/// initializing its state with the accounts defined in the configuration file.
|
||||
pub async fn start_from_config(
|
||||
config: SequencerConfig,
|
||||
) -> (Self, MemPoolHandle<NSSATransaction>) {
|
||||
) -> (Self, MemPoolHandle<(TransactionOrigin, NSSATransaction)>) {
|
||||
let signing_key = nssa::PrivateKey::try_new(config.signing_key).unwrap();
|
||||
|
||||
let bedrock_signing_key =
|
||||
@ -132,6 +152,37 @@ impl<BP: BlockPublisherTrait> SequencerCore<BP> {
|
||||
}
|
||||
});
|
||||
|
||||
let (mempool, mempool_handle) = MemPool::new(config.mempool_max_size);
|
||||
|
||||
let mempool_handle_for_deposit = mempool_handle.clone();
|
||||
let on_deposit_event: block_publisher::OnDepositEventSink = Box::new(move |deposit| {
|
||||
let mempool_handle_for_deposit = mempool_handle_for_deposit.clone();
|
||||
Box::pin(async move {
|
||||
info!(
|
||||
"Observed Bedrock Deposit event with id: {:?}",
|
||||
hex::encode(deposit.op_id)
|
||||
);
|
||||
let tx = match build_bridge_deposit_tx(&deposit) {
|
||||
Ok(tx) => tx,
|
||||
Err(err) => {
|
||||
warn!(
|
||||
"Skipping finalized Bedrock deposit event due to tx build failure: {err:#}"
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(err) = mempool_handle_for_deposit
|
||||
.push((TransactionOrigin::Sequencer, tx))
|
||||
.await
|
||||
{
|
||||
error!(
|
||||
"Failed to queue sequencer transaction built from finalized Bedrock event: {err:#}"
|
||||
);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
let block_publisher = BP::new(
|
||||
&config.bedrock_config,
|
||||
bedrock_signing_key,
|
||||
@ -139,6 +190,7 @@ impl<BP: BlockPublisherTrait> SequencerCore<BP> {
|
||||
initial_checkpoint,
|
||||
on_checkpoint,
|
||||
on_finalized_block,
|
||||
on_deposit_event,
|
||||
)
|
||||
.await
|
||||
.expect("Failed to initialize Block Publisher");
|
||||
@ -151,8 +203,6 @@ impl<BP: BlockPublisherTrait> SequencerCore<BP> {
|
||||
error!("Failed to publish genesis block: {err:#}");
|
||||
}
|
||||
|
||||
let (mempool, mempool_handle) = MemPool::new(config.mempool_max_size);
|
||||
|
||||
let sequencer_core = Self {
|
||||
state,
|
||||
store,
|
||||
@ -207,7 +257,7 @@ impl<BP: BlockPublisherTrait> SequencerCore<BP> {
|
||||
let clock_tx = clock_invocation(new_block_timestamp);
|
||||
let clock_nssa_tx = NSSATransaction::Public(clock_tx.clone());
|
||||
|
||||
while let Some(tx) = self.mempool.pop() {
|
||||
while let Some((origin, tx)) = self.mempool.pop() {
|
||||
let tx_hash = tx.hash();
|
||||
|
||||
// Check if block size exceeds limit (including the mandatory clock tx).
|
||||
@ -235,25 +285,41 @@ impl<BP: BlockPublisherTrait> SequencerCore<BP> {
|
||||
block size {block_size} bytes would exceed limit of {max_block_size} bytes",
|
||||
);
|
||||
|
||||
self.mempool.push_front(tx);
|
||||
self.mempool.push_front((origin, tx));
|
||||
break;
|
||||
}
|
||||
|
||||
let validated_diff = match tx.validate_on_state(
|
||||
&self.state,
|
||||
new_block_height,
|
||||
new_block_timestamp,
|
||||
) {
|
||||
Ok(diff) => diff,
|
||||
Err(err) => {
|
||||
error!(
|
||||
"Transaction with hash {tx_hash} failed execution check with error: {err:#?}, skipping it",
|
||||
);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
match origin {
|
||||
TransactionOrigin::User => {
|
||||
let validated_diff = match tx.validate_on_state(
|
||||
&self.state,
|
||||
new_block_height,
|
||||
new_block_timestamp,
|
||||
) {
|
||||
Ok(diff) => diff,
|
||||
Err(err) => {
|
||||
error!(
|
||||
"Transaction with hash {tx_hash} failed execution check with error: {err:#?}, skipping it",
|
||||
);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
self.state.apply_state_diff(validated_diff);
|
||||
self.state.apply_state_diff(validated_diff);
|
||||
}
|
||||
TransactionOrigin::Sequencer => {
|
||||
let NSSATransaction::Public(public_tx) = &tx else {
|
||||
panic!("Sequencer may only generate Public transactions, found {tx:#?}");
|
||||
};
|
||||
self.state
|
||||
.transition_from_public_transaction(
|
||||
public_tx,
|
||||
new_block_height,
|
||||
new_block_timestamp,
|
||||
)
|
||||
.context("Failed to execute sequencer-generated transaction")?;
|
||||
}
|
||||
}
|
||||
|
||||
valid_transactions.push(tx);
|
||||
info!("Validated transaction with hash {tx_hash}, including it in block");
|
||||
@ -363,6 +429,9 @@ fn build_genesis_state(config: &SequencerConfig) -> (nssa::V03State, Vec<NSSATra
|
||||
account_id,
|
||||
balance,
|
||||
} => build_supply_account_genesis_transaction(account_id, *balance),
|
||||
GenesisAction::SupplyBridgeAccount { balance } => {
|
||||
build_supply_bridge_account_genesis_transaction(*balance)
|
||||
}
|
||||
})
|
||||
.chain(std::iter::once(clock_invocation(0)))
|
||||
.inspect(|tx| {
|
||||
@ -388,7 +457,7 @@ fn build_supply_account_genesis_transaction(
|
||||
faucet_program_id,
|
||||
vec![nssa::system_faucet_account_id(), recipient_vault_id],
|
||||
vec![],
|
||||
faucet_core::Instruction::Transfer {
|
||||
faucet_core::Instruction::GenesisTransferVault {
|
||||
vault_program_id,
|
||||
recipient_id: *account_id,
|
||||
amount: balance,
|
||||
@ -400,6 +469,52 @@ fn build_supply_account_genesis_transaction(
|
||||
PublicTransaction::new(message, witness_set)
|
||||
}
|
||||
|
||||
fn build_supply_bridge_account_genesis_transaction(balance: u128) -> PublicTransaction {
|
||||
let faucet_program_id = Program::faucet().id();
|
||||
let bridge_account_id = nssa::system_bridge_account_id();
|
||||
|
||||
let message = Message::try_new(
|
||||
faucet_program_id,
|
||||
vec![nssa::system_faucet_account_id(), bridge_account_id],
|
||||
vec![],
|
||||
faucet_core::Instruction::GenesisTransferDirect { amount: balance },
|
||||
)
|
||||
.expect("Failed to serialize bridge genesis transfer instruction");
|
||||
let witness_set = nssa::public_transaction::WitnessSet::from_raw_parts(vec![]);
|
||||
|
||||
PublicTransaction::new(message, witness_set)
|
||||
}
|
||||
|
||||
fn build_bridge_deposit_tx(
|
||||
deposit: &logos_blockchain_zone_sdk::state::DepositInfo,
|
||||
) -> Result<NSSATransaction> {
|
||||
let metadata = DepositMetadata::decode(&deposit.metadata)
|
||||
.context("Failed to decode finalized Bedrock deposit metadata")?;
|
||||
|
||||
let bridge_program_id = Program::bridge().id();
|
||||
let vault_program_id = Program::vault().id();
|
||||
let recipient_vault_id =
|
||||
vault_core::compute_vault_account_id(vault_program_id, metadata.recipient_id);
|
||||
|
||||
let message = Message::try_new(
|
||||
bridge_program_id,
|
||||
vec![nssa::system_bridge_account_id(), recipient_vault_id],
|
||||
vec![],
|
||||
bridge_core::Instruction::Deposit {
|
||||
vault_program_id,
|
||||
recipient_id: metadata.recipient_id,
|
||||
amount: u128::from(deposit.amount),
|
||||
},
|
||||
)
|
||||
.context("Failed to build bridge deposit message")?;
|
||||
|
||||
let witness_set = nssa::public_transaction::WitnessSet::from_raw_parts(vec![]);
|
||||
Ok(NSSATransaction::Public(PublicTransaction::new(
|
||||
message,
|
||||
witness_set,
|
||||
)))
|
||||
}
|
||||
|
||||
/// Load signing key from file or generate a new one if it doesn't exist.
|
||||
fn load_or_create_signing_key(path: &Path) -> Result<Ed25519Key> {
|
||||
if path.exists() {
|
||||
@ -441,6 +556,7 @@ mod tests {
|
||||
use testnet_initial_state::{initial_accounts, initial_pub_accounts_private_keys};
|
||||
|
||||
use crate::{
|
||||
TransactionOrigin,
|
||||
block_store::SequencerStore,
|
||||
build_genesis_state,
|
||||
config::{BedrockConfig, SequencerConfig},
|
||||
@ -476,19 +592,28 @@ mod tests {
|
||||
initial_pub_accounts_private_keys()[1].pub_sign_key.clone()
|
||||
}
|
||||
|
||||
async fn common_setup() -> (SequencerCoreWithMockClients, MemPoolHandle<NSSATransaction>) {
|
||||
async fn common_setup() -> (
|
||||
SequencerCoreWithMockClients,
|
||||
MemPoolHandle<(TransactionOrigin, NSSATransaction)>,
|
||||
) {
|
||||
let config = setup_sequencer_config();
|
||||
common_setup_with_config(config).await
|
||||
}
|
||||
|
||||
async fn common_setup_with_config(
|
||||
config: SequencerConfig,
|
||||
) -> (SequencerCoreWithMockClients, MemPoolHandle<NSSATransaction>) {
|
||||
) -> (
|
||||
SequencerCoreWithMockClients,
|
||||
MemPoolHandle<(TransactionOrigin, NSSATransaction)>,
|
||||
) {
|
||||
let (mut sequencer, mempool_handle) =
|
||||
SequencerCoreWithMockClients::start_from_config(config).await;
|
||||
|
||||
let tx = common::test_utils::produce_dummy_empty_transaction();
|
||||
mempool_handle.push(tx).await.unwrap();
|
||||
mempool_handle
|
||||
.push((TransactionOrigin::User, tx))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
sequencer.produce_new_block().await.unwrap();
|
||||
|
||||
@ -678,10 +803,13 @@ mod tests {
|
||||
let tx = common::test_utils::produce_dummy_empty_transaction();
|
||||
|
||||
// Fill the mempool
|
||||
mempool_handle.push(tx.clone()).await.unwrap();
|
||||
mempool_handle
|
||||
.push((TransactionOrigin::User, tx.clone()))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Check that pushing another transaction will block
|
||||
let mut push_fut = pin!(mempool_handle.push(tx.clone()));
|
||||
let mut push_fut = pin!(mempool_handle.push((TransactionOrigin::User, tx.clone())));
|
||||
let poll = futures::poll!(push_fut.as_mut());
|
||||
assert!(poll.is_pending());
|
||||
|
||||
@ -698,7 +826,10 @@ mod tests {
|
||||
let genesis_height = sequencer.chain_height;
|
||||
|
||||
let tx = common::test_utils::produce_dummy_empty_transaction();
|
||||
mempool_handle.push(tx).await.unwrap();
|
||||
mempool_handle
|
||||
.push((TransactionOrigin::User, tx))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let result = sequencer.build_block_from_mempool();
|
||||
assert!(result.is_ok());
|
||||
@ -721,8 +852,14 @@ mod tests {
|
||||
let tx_original = tx.clone();
|
||||
let tx_replay = tx.clone();
|
||||
// Pushing two copies of the same tx to the mempool
|
||||
mempool_handle.push(tx_original).await.unwrap();
|
||||
mempool_handle.push(tx_replay).await.unwrap();
|
||||
mempool_handle
|
||||
.push((TransactionOrigin::User, tx_original))
|
||||
.await
|
||||
.unwrap();
|
||||
mempool_handle
|
||||
.push((TransactionOrigin::User, tx_replay))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Create block
|
||||
sequencer.produce_new_block().await.unwrap();
|
||||
@ -756,7 +893,10 @@ mod tests {
|
||||
);
|
||||
|
||||
// The transaction should be included the first time
|
||||
mempool_handle.push(tx.clone()).await.unwrap();
|
||||
mempool_handle
|
||||
.push((TransactionOrigin::User, tx.clone()))
|
||||
.await
|
||||
.unwrap();
|
||||
sequencer.produce_new_block().await.unwrap();
|
||||
let block = sequencer
|
||||
.store
|
||||
@ -772,7 +912,10 @@ mod tests {
|
||||
);
|
||||
|
||||
// Add same transaction should fail
|
||||
mempool_handle.push(tx.clone()).await.unwrap();
|
||||
mempool_handle
|
||||
.push((TransactionOrigin::User, tx.clone()))
|
||||
.await
|
||||
.unwrap();
|
||||
sequencer.produce_new_block().await.unwrap();
|
||||
let block = sequencer
|
||||
.store
|
||||
@ -811,7 +954,10 @@ mod tests {
|
||||
&signing_key,
|
||||
);
|
||||
|
||||
mempool_handle.push(tx.clone()).await.unwrap();
|
||||
mempool_handle
|
||||
.push((TransactionOrigin::User, tx.clone()))
|
||||
.await
|
||||
.unwrap();
|
||||
sequencer.produce_new_block().await.unwrap();
|
||||
let block = sequencer
|
||||
.store
|
||||
@ -895,7 +1041,10 @@ mod tests {
|
||||
&signing_key,
|
||||
);
|
||||
|
||||
mempool_handle.push(tx).await.unwrap();
|
||||
mempool_handle
|
||||
.push((TransactionOrigin::User, tx))
|
||||
.await
|
||||
.unwrap();
|
||||
sequencer.produce_new_block().await.unwrap();
|
||||
|
||||
// Get the metadata of the last block produced
|
||||
@ -916,7 +1065,10 @@ mod tests {
|
||||
&signing_key,
|
||||
);
|
||||
|
||||
mempool_handle.push(tx.clone()).await.unwrap();
|
||||
mempool_handle
|
||||
.push((TransactionOrigin::User, tx.clone()))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Step 4: Produce new block
|
||||
sequencer.produce_new_block().await.unwrap();
|
||||
@ -962,10 +1114,16 @@ mod tests {
|
||||
))
|
||||
};
|
||||
mempool_handle
|
||||
.push(NSSATransaction::Public(clock_invocation(0)))
|
||||
.push((
|
||||
TransactionOrigin::User,
|
||||
NSSATransaction::Public(clock_invocation(0)),
|
||||
))
|
||||
.await
|
||||
.unwrap();
|
||||
mempool_handle
|
||||
.push((TransactionOrigin::User, crafted_clock_tx))
|
||||
.await
|
||||
.unwrap();
|
||||
mempool_handle.push(crafted_clock_tx).await.unwrap();
|
||||
sequencer.produce_new_block().await.unwrap();
|
||||
|
||||
let block = sequencer
|
||||
@ -994,7 +1152,10 @@ mod tests {
|
||||
test_program_methods::CLOCK_CHAIN_CALLER_ELF.to_vec(),
|
||||
),
|
||||
));
|
||||
mempool_handle.push(deploy_tx).await.unwrap();
|
||||
mempool_handle
|
||||
.push((TransactionOrigin::User, deploy_tx))
|
||||
.await
|
||||
.unwrap();
|
||||
sequencer.produce_new_block().await.unwrap();
|
||||
|
||||
// Build a user transaction that invokes clock_chain_caller, which in turn chain-calls the
|
||||
@ -1019,7 +1180,10 @@ mod tests {
|
||||
nssa::public_transaction::WitnessSet::from_raw_parts(vec![]),
|
||||
));
|
||||
|
||||
mempool_handle.push(user_tx).await.unwrap();
|
||||
mempool_handle
|
||||
.push((TransactionOrigin::User, user_tx))
|
||||
.await
|
||||
.unwrap();
|
||||
sequencer.produce_new_block().await.unwrap();
|
||||
|
||||
let block = sequencer
|
||||
@ -1051,7 +1215,10 @@ mod tests {
|
||||
|
||||
// Push a dummy transaction so the mempool is non-empty.
|
||||
let tx = common::test_utils::produce_dummy_empty_transaction();
|
||||
mempool_handle.push(tx).await.unwrap();
|
||||
mempool_handle
|
||||
.push((TransactionOrigin::User, tx))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Block production must fail because the appended clock tx cannot execute.
|
||||
let result = sequencer.produce_new_block().await;
|
||||
|
||||
@ -6,7 +6,8 @@ use logos_blockchain_key_management_system_service::keys::Ed25519Key;
|
||||
|
||||
use crate::{
|
||||
block_publisher::{
|
||||
BlockPublisherTrait, CheckpointSink, FinalizedBlockSink, SequencerCheckpoint,
|
||||
BlockPublisherTrait, CheckpointSink, FinalizedBlockSink, OnDepositEventSink,
|
||||
SequencerCheckpoint,
|
||||
},
|
||||
config::BedrockConfig,
|
||||
};
|
||||
@ -24,6 +25,7 @@ impl BlockPublisherTrait for MockBlockPublisher {
|
||||
_initial_checkpoint: Option<SequencerCheckpoint>,
|
||||
_on_checkpoint: CheckpointSink,
|
||||
_on_finalized_block: FinalizedBlockSink,
|
||||
_on_deposit_event: OnDepositEventSink,
|
||||
) -> Result<Self> {
|
||||
Ok(Self)
|
||||
}
|
||||
|
||||
@ -15,6 +15,11 @@
|
||||
},
|
||||
"indexer_rpc_url": "ws://localhost:8779",
|
||||
"genesis": [
|
||||
{
|
||||
"supply_bridge_account": {
|
||||
"balance": 1000000
|
||||
}
|
||||
},
|
||||
{
|
||||
"supply_account": {
|
||||
"account_id": "CbgR6tj5kWx5oziiFptM7jMvrQeYY3Mzaao6ciuhSr2r",
|
||||
|
||||
@ -15,6 +15,11 @@
|
||||
},
|
||||
"indexer_rpc_url": "ws://localhost:8779",
|
||||
"genesis": [
|
||||
{
|
||||
"supply_bridge_account": {
|
||||
"balance": 1000000
|
||||
}
|
||||
},
|
||||
{
|
||||
"supply_account": {
|
||||
"account_id": "CbgR6tj5kWx5oziiFptM7jMvrQeYY3Mzaao6ciuhSr2r",
|
||||
|
||||
@ -11,6 +11,7 @@ use mempool::MemPoolHandle;
|
||||
use sequencer_core::SequencerCore;
|
||||
#[cfg(feature = "standalone")]
|
||||
use sequencer_core::SequencerCoreWithMockClients as SequencerCore;
|
||||
use sequencer_core::TransactionOrigin;
|
||||
pub use sequencer_core::config::*;
|
||||
use sequencer_service_rpc::RpcServer as _;
|
||||
use tokio::{sync::Mutex, task::JoinHandle};
|
||||
@ -55,15 +56,14 @@ impl SequencerHandle {
|
||||
} = &mut self;
|
||||
|
||||
let server_handle = server_handle.take().expect("Server handle is set");
|
||||
|
||||
tokio::select! {
|
||||
() = server_handle.stopped() => {
|
||||
Err(anyhow!("RPC Server stopped"))
|
||||
}
|
||||
res = main_loop_handle => {
|
||||
res
|
||||
.context("Main loop task panicked")?
|
||||
.context("Main loop exited unexpectedly")
|
||||
.context("Main loop task panicked")?
|
||||
.context("Main loop exited unexpectedly")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -120,10 +120,11 @@ pub async fn run(config: SequencerConfig, port: u16) -> Result<SequencerHandle>
|
||||
info!("Sequencer core set up");
|
||||
|
||||
let seq_core_wrapped = Arc::new(Mutex::new(sequencer_core));
|
||||
let mempool_handle_for_server = mempool_handle.clone();
|
||||
|
||||
let (server_handle, addr) = run_server(
|
||||
Arc::clone(&seq_core_wrapped),
|
||||
mempool_handle,
|
||||
mempool_handle_for_server,
|
||||
port,
|
||||
max_block_size.as_u64(),
|
||||
)
|
||||
@ -133,12 +134,14 @@ pub async fn run(config: SequencerConfig, port: u16) -> Result<SequencerHandle>
|
||||
info!("Starting main sequencer loop");
|
||||
let main_loop_handle = tokio::spawn(main_loop(seq_core_wrapped, block_timeout));
|
||||
|
||||
let _ = mempool_handle;
|
||||
|
||||
Ok(SequencerHandle::new(addr, server_handle, main_loop_handle))
|
||||
}
|
||||
|
||||
async fn run_server(
|
||||
sequencer: Arc<Mutex<SequencerCore>>,
|
||||
mempool_handle: MemPoolHandle<NSSATransaction>,
|
||||
mempool_handle: MemPoolHandle<(TransactionOrigin, NSSATransaction)>,
|
||||
port: u16,
|
||||
max_block_size: u64,
|
||||
) -> Result<(ServerHandle, SocketAddr)> {
|
||||
|
||||
@ -8,7 +8,9 @@ use jsonrpsee::{
|
||||
use log::warn;
|
||||
use mempool::MemPoolHandle;
|
||||
use nssa::{self, program::Program};
|
||||
use sequencer_core::{DbError, SequencerCore, block_publisher::BlockPublisherTrait};
|
||||
use sequencer_core::{
|
||||
DbError, SequencerCore, TransactionOrigin, block_publisher::BlockPublisherTrait,
|
||||
};
|
||||
use sequencer_service_protocol::{
|
||||
Account, AccountId, Block, BlockId, Commitment, HashType, MembershipProof, Nonce, ProgramId,
|
||||
};
|
||||
@ -18,14 +20,14 @@ const NOT_FOUND_ERROR_CODE: i32 = -31999;
|
||||
|
||||
pub struct SequencerService<BC: BlockPublisherTrait> {
|
||||
sequencer: Arc<Mutex<SequencerCore<BC>>>,
|
||||
mempool_handle: MemPoolHandle<NSSATransaction>,
|
||||
mempool_handle: MemPoolHandle<(TransactionOrigin, NSSATransaction)>,
|
||||
max_block_size: u64,
|
||||
}
|
||||
|
||||
impl<BC: BlockPublisherTrait> SequencerService<BC> {
|
||||
pub const fn new(
|
||||
sequencer: Arc<Mutex<SequencerCore<BC>>>,
|
||||
mempool_handle: MemPoolHandle<NSSATransaction>,
|
||||
mempool_handle: MemPoolHandle<(TransactionOrigin, NSSATransaction)>,
|
||||
max_block_size: u64,
|
||||
) -> Self {
|
||||
Self {
|
||||
@ -72,7 +74,7 @@ impl<BC: BlockPublisherTrait + Send + 'static> sequencer_service_rpc::RpcServer
|
||||
})?;
|
||||
|
||||
self.mempool_handle
|
||||
.push(authenticated_tx)
|
||||
.push((TransactionOrigin::User, authenticated_tx))
|
||||
.await
|
||||
.expect("Mempool is closed, this is a bug");
|
||||
|
||||
|
||||
@ -143,7 +143,12 @@ pub fn genesis_from_accounts(
|
||||
balance: account.balance,
|
||||
});
|
||||
|
||||
public_genesis.chain(private_genesis).collect()
|
||||
let supply_bridge_account = GenesisAction::SupplyBridgeAccount { balance: 1_000_000 };
|
||||
|
||||
public_genesis
|
||||
.chain(private_genesis)
|
||||
.chain(std::iter::once(supply_bridge_account))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn wallet_config(sequencer_addr: SocketAddr) -> Result<WalletConfig> {
|
||||
@ -184,7 +189,8 @@ pub fn addr_to_url(protocol: UrlProtocol, addr: SocketAddr) -> Result<Url> {
|
||||
url_string.parse().map_err(Into::into)
|
||||
}
|
||||
|
||||
fn bedrock_channel_id() -> ChannelId {
|
||||
#[must_use]
|
||||
pub fn bedrock_channel_id() -> ChannelId {
|
||||
let channel_id: [u8; 32] = [0_u8, 1]
|
||||
.repeat(16)
|
||||
.try_into()
|
||||
|
||||
@ -30,7 +30,7 @@ fn main() {
|
||||
|
||||
let chained_calls = vec![ChainedCall {
|
||||
program_id: faucet_program_id,
|
||||
instruction_data: to_vec(&faucet_core::Instruction::Transfer {
|
||||
instruction_data: to_vec(&faucet_core::Instruction::GenesisTransferVault {
|
||||
vault_program_id,
|
||||
recipient_id,
|
||||
amount,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user