mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-08-01 12:33:24 +00:00
Merge pull request #654 from logos-blockchain/arjentix/bump-bedrock-and-sdk
feat(zone_sdk): update to a new bedrock & zone sdk
This commit is contained in:
commit
7132a899ce
373
Cargo.lock
generated
373
Cargo.lock
generated
@ -499,7 +499,7 @@ dependencies = [
|
||||
"asn1-rs-derive",
|
||||
"asn1-rs-impl",
|
||||
"displaydoc",
|
||||
"nom 7.1.3",
|
||||
"nom",
|
||||
"num-traits",
|
||||
"rusticata-macros",
|
||||
"thiserror 2.0.18",
|
||||
@ -1220,7 +1220,6 @@ dependencies = [
|
||||
name = "bridge_program"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"authenticated_transfer_core",
|
||||
"bridge_core",
|
||||
"lee_core",
|
||||
"vault_core",
|
||||
@ -1405,7 +1404,7 @@ version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
||||
dependencies = [
|
||||
"nom 7.1.3",
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2315,7 +2314,7 @@ checksum = "07da5016415d5a3c4dd39b11ed26f915f52fc4e0dc197d87908bc916e51bc1a6"
|
||||
dependencies = [
|
||||
"asn1-rs",
|
||||
"displaydoc",
|
||||
"nom 7.1.3",
|
||||
"nom",
|
||||
"num-bigint 0.4.6",
|
||||
"num-traits",
|
||||
"rusticata-macros",
|
||||
@ -3037,15 +3036,6 @@ 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"
|
||||
@ -3053,7 +3043,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965"
|
||||
dependencies = [
|
||||
"foreign-types-macros",
|
||||
"foreign-types-shared 0.3.1",
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3067,12 +3057,6 @@ 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"
|
||||
@ -3852,22 +3836,6 @@ 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"
|
||||
@ -3886,11 +3854,9 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"socket2 0.6.4",
|
||||
"system-configuration 0.7.0",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
"windows-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4304,7 +4270,6 @@ dependencies = [
|
||||
"anyhow",
|
||||
"associated_token_account_core",
|
||||
"authenticated_transfer_core",
|
||||
"borsh",
|
||||
"bridge_core",
|
||||
"bridge_lock_core",
|
||||
"bytesize",
|
||||
@ -4312,7 +4277,6 @@ dependencies = [
|
||||
"cross_zone_inbox_core",
|
||||
"cross_zone_outbox_core",
|
||||
"faucet_core",
|
||||
"futures",
|
||||
"hex",
|
||||
"indexer_ffi",
|
||||
"indexer_service_protocol",
|
||||
@ -4322,13 +4286,9 @@ dependencies = [
|
||||
"lee_core",
|
||||
"log",
|
||||
"logos-blockchain-core",
|
||||
"logos-blockchain-http-api-common",
|
||||
"logos-blockchain-key-management-system-service",
|
||||
"logos-blockchain-zone-sdk",
|
||||
"num-bigint 0.4.6",
|
||||
"ping_core",
|
||||
"programs",
|
||||
"reqwest",
|
||||
"risc0-zkvm",
|
||||
"sequencer_core",
|
||||
"sequencer_service_rpc",
|
||||
@ -5671,10 +5631,20 @@ version = "0.4.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "113b30b4cd05f7c06868fdb2854f66a7b9fece9a48425351cd532e810d74024f"
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-blake2btree"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"blake2",
|
||||
"logos-blockchain-dynamic-merkle",
|
||||
"logos-blockchain-merkle-tree",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-blend-crypto"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"blake2",
|
||||
"logos-blockchain-groth16",
|
||||
@ -5687,8 +5657,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-blend-message"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"blake2",
|
||||
"derivative",
|
||||
@ -5696,6 +5666,7 @@ dependencies = [
|
||||
"itertools 0.14.0",
|
||||
"logos-blockchain-blend-crypto",
|
||||
"logos-blockchain-blend-proofs",
|
||||
"logos-blockchain-codec",
|
||||
"logos-blockchain-core",
|
||||
"logos-blockchain-cryptarchia-engine",
|
||||
"logos-blockchain-groth16",
|
||||
@ -5711,13 +5682,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-blend-proofs"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"ed25519-dalek",
|
||||
"generic-array 1.4.3",
|
||||
"hex",
|
||||
"logos-blockchain-blend-crypto",
|
||||
"logos-blockchain-codec",
|
||||
"logos-blockchain-groth16",
|
||||
"logos-blockchain-pol",
|
||||
"logos-blockchain-poq",
|
||||
@ -5731,8 +5703,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-chain-broadcast-service"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"derivative",
|
||||
@ -5745,8 +5717,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-chain-service"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
@ -5826,8 +5798,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-circuits-prover"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"rust-rapidsnark",
|
||||
]
|
||||
@ -5851,10 +5823,33 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-codec"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"hex",
|
||||
"logos-blockchain-codec-macros",
|
||||
"logos-blockchain-groth16",
|
||||
"logos-blockchain-utils",
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-codec-macros"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"hex",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-common-http-client"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"hex",
|
||||
@ -5876,17 +5871,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-core"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"ark-ff",
|
||||
"bincode",
|
||||
"blake2",
|
||||
"bytes",
|
||||
"const-hex",
|
||||
"futures",
|
||||
"hex",
|
||||
"logos-blockchain-blake2btree",
|
||||
"logos-blockchain-blend-proofs",
|
||||
"logos-blockchain-codec",
|
||||
"logos-blockchain-cryptarchia-engine",
|
||||
"logos-blockchain-groth16",
|
||||
"logos-blockchain-key-management-system-keys",
|
||||
@ -5898,9 +5894,7 @@ dependencies = [
|
||||
"logos-blockchain-utils",
|
||||
"logos-blockchain-utxotree",
|
||||
"multiaddr",
|
||||
"nom 8.0.0",
|
||||
"num-bigint 0.4.6",
|
||||
"rpds",
|
||||
"serde",
|
||||
"strum",
|
||||
"thiserror 2.0.18",
|
||||
@ -5910,11 +5904,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-cryptarchia-engine"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"logos-blockchain-codec",
|
||||
"logos-blockchain-pol",
|
||||
"logos-blockchain-utils",
|
||||
"rpds",
|
||||
"serde",
|
||||
"serde_with",
|
||||
"thiserror 2.0.18",
|
||||
@ -5925,8 +5921,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-cryptarchia-sync"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures",
|
||||
@ -5942,10 +5938,19 @@ dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-dynamic-merkle"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"rpds",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-groth16"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"ark-bn254",
|
||||
"ark-ec",
|
||||
@ -5955,6 +5960,7 @@ dependencies = [
|
||||
"generic-array 1.4.3",
|
||||
"hex",
|
||||
"num-bigint 0.4.6",
|
||||
"rand 0.8.6",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.18",
|
||||
@ -5962,8 +5968,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-http-api-common"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"axum 0.7.9",
|
||||
"logos-blockchain-core",
|
||||
@ -5983,14 +5989,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-key-management-system-keys"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"ed25519-dalek",
|
||||
"generic-array 1.4.3",
|
||||
"hex",
|
||||
"logos-blockchain-codec",
|
||||
"logos-blockchain-groth16",
|
||||
"logos-blockchain-key-management-system-macros",
|
||||
"logos-blockchain-log-targets",
|
||||
@ -6010,8 +6017,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-key-management-system-macros"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -6020,8 +6027,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-key-management-system-operators"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"logos-blockchain-blend-proofs",
|
||||
@ -6030,6 +6037,7 @@ dependencies = [
|
||||
"logos-blockchain-key-management-system-keys",
|
||||
"logos-blockchain-log-targets",
|
||||
"logos-blockchain-poseidon2",
|
||||
"logos-blockchain-utils",
|
||||
"logos-blockchain-utxotree",
|
||||
"tokio",
|
||||
"tracing",
|
||||
@ -6037,8 +6045,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-key-management-system-service"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"logos-blockchain-key-management-system-keys",
|
||||
@ -6054,8 +6062,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-ledger"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"derivative",
|
||||
"logos-blockchain-blend-crypto",
|
||||
@ -6080,8 +6088,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-libp2p"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"backon",
|
||||
@ -6109,30 +6117,42 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-log-targets"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
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=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-merkle-tree"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"logos-blockchain-dynamic-merkle",
|
||||
"rpds",
|
||||
"serde",
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-mmr"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"ark-ff",
|
||||
"logos-blockchain-groth16",
|
||||
"logos-blockchain-poseidon2",
|
||||
"logos-blockchain-utils",
|
||||
"rpds",
|
||||
"serde",
|
||||
"thiserror 2.0.18",
|
||||
@ -6140,8 +6160,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-network-service"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"futures",
|
||||
@ -6150,6 +6170,7 @@ dependencies = [
|
||||
"logos-blockchain-libp2p",
|
||||
"logos-blockchain-log-targets",
|
||||
"logos-blockchain-tracing",
|
||||
"logos-blockchain-utils",
|
||||
"overwatch",
|
||||
"rand 0.8.6",
|
||||
"rand_chacha 0.3.1",
|
||||
@ -6161,8 +6182,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-poc"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"logos-blockchain-circuits-poc-sys",
|
||||
"logos-blockchain-circuits-prover",
|
||||
@ -6178,8 +6199,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-pol"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"astro-float",
|
||||
"logos-blockchain-circuits-pol-sys",
|
||||
@ -6198,8 +6219,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-poq"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"logos-blockchain-circuits-poq-sys",
|
||||
"logos-blockchain-circuits-prover",
|
||||
@ -6217,8 +6238,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-poseidon2"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"ark-bn254",
|
||||
"ark-ff",
|
||||
@ -6228,8 +6249,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-proofs-error"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"logos-blockchain-circuits-types",
|
||||
"logos-blockchain-groth16",
|
||||
@ -6239,24 +6260,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-services-utils"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"futures",
|
||||
"log",
|
||||
"logos-blockchain-log-targets",
|
||||
"overwatch",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"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=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
@ -6264,7 +6285,9 @@ dependencies = [
|
||||
"logos-blockchain-core",
|
||||
"logos-blockchain-cryptarchia-engine",
|
||||
"logos-blockchain-log-targets",
|
||||
"logos-blockchain-services-utils",
|
||||
"logos-blockchain-tracing",
|
||||
"logos-blockchain-utils",
|
||||
"overwatch",
|
||||
"serde",
|
||||
"thiserror 2.0.18",
|
||||
@ -6274,8 +6297,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-time-service"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"futures",
|
||||
@ -6297,8 +6320,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-tracing"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"flate2",
|
||||
"logos-blockchain-log-targets",
|
||||
@ -6323,15 +6346,17 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-utils"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"blake2",
|
||||
"cipher 0.4.4",
|
||||
"const-hex",
|
||||
"futures",
|
||||
"humantime",
|
||||
"logos-blockchain-log-targets",
|
||||
"multiaddr",
|
||||
"overwatch",
|
||||
"rand 0.8.6",
|
||||
"serde",
|
||||
@ -6340,27 +6365,27 @@ dependencies = [
|
||||
"serde_yaml",
|
||||
"thiserror 2.0.18",
|
||||
"time",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-utxotree"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"ark-ff",
|
||||
"logos-blockchain-groth16",
|
||||
"logos-blockchain-dynamic-merkle",
|
||||
"logos-blockchain-merkle-tree",
|
||||
"logos-blockchain-poseidon2",
|
||||
"num-bigint 0.4.6",
|
||||
"rpds",
|
||||
"serde",
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-zksign"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"logos-blockchain-circuits-prover",
|
||||
"logos-blockchain-circuits-signature-sys",
|
||||
@ -6371,6 +6396,7 @@ dependencies = [
|
||||
"logos-blockchain-proofs-error",
|
||||
"num-bigint 0.4.6",
|
||||
"serde",
|
||||
"serde-big-array",
|
||||
"serde_json",
|
||||
"thiserror 2.0.18",
|
||||
"tracing",
|
||||
@ -6378,8 +6404,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-zone-sdk"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=d8711bbc3d43d3ef9755ef9b73af32fd0f703160#d8711bbc3d43d3ef9755ef9b73af32fd0f703160"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=0dc34e2c5a6e2ff772140378659489a602ee06bc#0dc34e2c5a6e2ff772140378659489a602ee06bc"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"futures",
|
||||
@ -6611,7 +6637,7 @@ dependencies = [
|
||||
"bitflags 2.12.1",
|
||||
"block",
|
||||
"core-graphics-types",
|
||||
"foreign-types 0.5.0",
|
||||
"foreign-types",
|
||||
"log",
|
||||
"objc",
|
||||
"paste",
|
||||
@ -6774,23 +6800,6 @@ 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"
|
||||
@ -6955,15 +6964,6 @@ dependencies = [
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "8.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.50.3"
|
||||
@ -7184,49 +7184,12 @@ 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.12.1",
|
||||
"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"
|
||||
@ -7345,7 +7308,7 @@ checksum = "8c04f5d74368e4d0dfe06c45c8627c81bd7c317d52762d118fb9b3076f6420fd"
|
||||
[[package]]
|
||||
name = "overwatch"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/logos-co/Overwatch?rev=448c192#448c192895b8311c742b1726a1bb12ee314ad95c"
|
||||
source = "git+https://github.com/logos-co/Overwatch?rev=ae887f41f5a626c341179026ad7f03953ff2072e#ae887f41f5a626c341179026ad7f03953ff2072e"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"futures",
|
||||
@ -7360,10 +7323,10 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "overwatch-derive"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/logos-co/Overwatch?rev=448c192#448c192895b8311c742b1726a1bb12ee314ad95c"
|
||||
source = "git+https://github.com/logos-co/Overwatch?rev=ae887f41f5a626c341179026ad7f03953ff2072e#ae887f41f5a626c341179026ad7f03953ff2072e"
|
||||
dependencies = [
|
||||
"convert_case 0.8.0",
|
||||
"proc-macro-error2",
|
||||
"manyhow",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.117",
|
||||
@ -8384,7 +8347,7 @@ checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"encoding_rs",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
@ -8393,12 +8356,9 @@ dependencies = [
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-rustls",
|
||||
"hyper-tls",
|
||||
"hyper-util",
|
||||
"js-sys",
|
||||
"log",
|
||||
"mime",
|
||||
"native-tls",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"quinn",
|
||||
@ -8409,7 +8369,6 @@ dependencies = [
|
||||
"serde_urlencoded",
|
||||
"sync_wrapper",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tokio-rustls",
|
||||
"tokio-util",
|
||||
"tower",
|
||||
@ -8997,7 +8956,7 @@ version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632"
|
||||
dependencies = [
|
||||
"nom 7.1.3",
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -9303,6 +9262,7 @@ dependencies = [
|
||||
"lee_core",
|
||||
"log",
|
||||
"logos-blockchain-core",
|
||||
"logos-blockchain-http-api-common",
|
||||
"logos-blockchain-key-management-system-service",
|
||||
"logos-blockchain-zone-sdk",
|
||||
"mempool",
|
||||
@ -9378,6 +9338,15 @@ dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-big-array"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11fc7cc2c76d73e0f27ee52abbd64eec84d46f370c88371120433196934e4b7f"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_arrays"
|
||||
version = "0.2.0"
|
||||
@ -10189,12 +10158,15 @@ dependencies = [
|
||||
"common",
|
||||
"env_logger",
|
||||
"futures",
|
||||
"hex",
|
||||
"indexer_service",
|
||||
"jsonrpsee",
|
||||
"key_protocol",
|
||||
"lee",
|
||||
"lee_core",
|
||||
"log",
|
||||
"logos-blockchain-key-management-system-service",
|
||||
"num-bigint 0.4.6",
|
||||
"programs",
|
||||
"sequencer_core",
|
||||
"sequencer_service",
|
||||
@ -10203,6 +10175,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"tempfile",
|
||||
"testcontainers",
|
||||
"time",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"url",
|
||||
@ -10467,16 +10440,6 @@ 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"
|
||||
@ -12058,7 +12021,7 @@ dependencies = [
|
||||
"data-encoding",
|
||||
"der-parser",
|
||||
"lazy_static",
|
||||
"nom 7.1.3",
|
||||
"nom",
|
||||
"oid-registry",
|
||||
"rusticata-macros",
|
||||
"thiserror 2.0.18",
|
||||
|
||||
17
Cargo.toml
17
Cargo.toml
@ -132,6 +132,7 @@ openssl = { version = "0.10", features = ["vendored"] }
|
||||
openssl-probe = { version = "0.1.2" }
|
||||
serde = { version = "1.0.60", default-features = false, features = ["derive"] }
|
||||
serde_json = "1.0.81"
|
||||
serde_yaml = "0.9.34"
|
||||
serde_with = "3.16.1"
|
||||
actix = "0.13.0"
|
||||
actix-cors = "0.7.1"
|
||||
@ -162,6 +163,7 @@ base64 = "0.22.1"
|
||||
bip39 = "2.2.0"
|
||||
hmac-sha512 = "1.1.7"
|
||||
chrono = "0.4.41"
|
||||
time = "0.3"
|
||||
borsh = "1.5.7"
|
||||
zstd = "0.13"
|
||||
base58 = "0.2.0"
|
||||
@ -172,13 +174,14 @@ tokio-retry = "0.3.0"
|
||||
schemars = "1.2"
|
||||
async-stream = "0.3.6"
|
||||
|
||||
logos-blockchain-common-http-client = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "d8711bbc3d43d3ef9755ef9b73af32fd0f703160" }
|
||||
logos-blockchain-key-management-system-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "d8711bbc3d43d3ef9755ef9b73af32fd0f703160" }
|
||||
logos-blockchain-core = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "d8711bbc3d43d3ef9755ef9b73af32fd0f703160" }
|
||||
logos-blockchain-chain-broadcast-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "d8711bbc3d43d3ef9755ef9b73af32fd0f703160" }
|
||||
logos-blockchain-chain-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "d8711bbc3d43d3ef9755ef9b73af32fd0f703160" }
|
||||
logos-blockchain-zone-sdk = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "d8711bbc3d43d3ef9755ef9b73af32fd0f703160" }
|
||||
logos-blockchain-http-api-common = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "d8711bbc3d43d3ef9755ef9b73af32fd0f703160" }
|
||||
logos-blockchain-common-http-client = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "0dc34e2c5a6e2ff772140378659489a602ee06bc" }
|
||||
logos-blockchain-key-management-system-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "0dc34e2c5a6e2ff772140378659489a602ee06bc" }
|
||||
logos-blockchain-codec = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "0dc34e2c5a6e2ff772140378659489a602ee06bc" }
|
||||
logos-blockchain-core = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "0dc34e2c5a6e2ff772140378659489a602ee06bc" }
|
||||
logos-blockchain-chain-broadcast-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "0dc34e2c5a6e2ff772140378659489a602ee06bc" }
|
||||
logos-blockchain-chain-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "0dc34e2c5a6e2ff772140378659489a602ee06bc" }
|
||||
logos-blockchain-zone-sdk = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "0dc34e2c5a6e2ff772140378659489a602ee06bc" }
|
||||
logos-blockchain-http-api-common = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "0dc34e2c5a6e2ff772140378659489a602ee06bc" }
|
||||
|
||||
keycard-rs = { git = "https://github.com/keycard-tech/keycard-rs", rev = "9535a657ba04b1e6916de51777e22b4837c1a84d" }
|
||||
|
||||
|
||||
2
Justfile
2
Justfile
@ -24,7 +24,7 @@ build-artifacts:
|
||||
just regenerate-test-fixture; \
|
||||
fi
|
||||
|
||||
RISC0_DOCKER_CONTAINER_TAG := "r0.1.97.0"
|
||||
RISC0_DOCKER_CONTAINER_TAG := "r0.1.91.1"
|
||||
|
||||
build-artifact methods_path features="":
|
||||
@echo "Building artifacts for {{methods_path}}"
|
||||
|
||||
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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,48 +1,47 @@
|
||||
blend:
|
||||
common:
|
||||
num_blend_layers: 3
|
||||
num_blend_layers: 1
|
||||
minimum_network_size: 30
|
||||
protocol_name: /blend/integration-tests
|
||||
data_replication_factor: 0
|
||||
protocol_name: /logos-blockchain-LEZ-DEV/blend/1.0.0
|
||||
data_replication_factor: 1
|
||||
core:
|
||||
scheduler:
|
||||
cover:
|
||||
message_frequency_per_round: 1.0
|
||||
delayer:
|
||||
maximum_release_delay_in_rounds: 3
|
||||
maximum_release_delay_in_rounds: 1
|
||||
minimum_messages_coefficient: 1
|
||||
normalization_constant: 1.03
|
||||
activity_threshold_sensitivity: 1
|
||||
network:
|
||||
kademlia_protocol_name: /integration/logos-blockchain/kad/1.0.0
|
||||
identify_protocol_name: /integration/logos-blockchain/identify/1.0.0
|
||||
chain_sync_protocol_name: /integration/logos-blockchain/chainsync/1.0.0
|
||||
kademlia_protocol_name: /logos-blockchain-LEZ-DEV/kad/1.0.0
|
||||
identify_protocol_name: /logos-blockchain-LEZ-DEV/identify/1.0.0
|
||||
chain_sync_protocol_name: /logos-blockchain-LEZ-DEV/chainsync/1.0.0
|
||||
cryptarchia:
|
||||
epoch_config:
|
||||
epoch_stake_distribution_stabilization: 3
|
||||
epoch_period_nonce_buffer: 3
|
||||
epoch_period_nonce_stabilization: 4
|
||||
security_param: 10
|
||||
security_param: 5
|
||||
slot_activation_coeff:
|
||||
numerator: 1
|
||||
denominator: 2
|
||||
learning_rate: 0.1
|
||||
learning_rate: 0.5
|
||||
sdp_config:
|
||||
service_params:
|
||||
BN:
|
||||
inactivity_period: 1
|
||||
retention_period: 1
|
||||
inactivity_period: 2
|
||||
epoch: 0
|
||||
min_stake:
|
||||
threshold: 1
|
||||
timestamp: 0
|
||||
gossipsub_protocol: /integration/logos-blockchain/cryptarchia/proto/1.0.0
|
||||
gossipsub_protocol: /logos-blockchain-LEZ-DEV/cryptarchia/1.0.0
|
||||
genesis_block:
|
||||
header:
|
||||
version: Bedrock
|
||||
parent_block: '0000000000000000000000000000000000000000000000000000000000000000'
|
||||
slot: 0
|
||||
block_root: b5f8787ac23674822414c70eea15d842da38f2e806ede1a73cf7b5cf0277da07
|
||||
block_root: cb5951ac1ffa1aa5d0e585fb54e784bd9c025b28d752324e98b3837f34648692
|
||||
proof_of_leadership:
|
||||
proof: '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
|
||||
entropy_contribution: '0000000000000000000000000000000000000000000000000000000000000000'
|
||||
@ -56,24 +55,134 @@ cryptarchia:
|
||||
payload:
|
||||
inputs: []
|
||||
outputs:
|
||||
- value: 1
|
||||
pk: d204000000000000000000000000000000000000000000000000000000000000
|
||||
- value: 100
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1
|
||||
pk: ed266e6e887b9b97059dc1aa1b7b2e19b934291753c6336a163fe4ebaa28e717
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 1000000
|
||||
pk: '2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26'
|
||||
- value: 100000
|
||||
pk: '6b2bcd3029fba573cff0c332dc4de7430faf5e261383d693d8dbb5b97665660a'
|
||||
- value: 18446744073709551615
|
||||
pk: c2a6a4a0981d5bdcf8ddeb8d7934fd8c5510efeb1053f613b45871670b6f7b19
|
||||
- opcode: 17
|
||||
payload:
|
||||
channel_id: '0000000000000000000000000000000000000000000000000000000000000000'
|
||||
# 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'
|
||||
inscription: '05302e322e3123766c6a2d2ddf918544bca603c5a291c7dd1b902d6769ff4b00021506780e075c06051a'
|
||||
parent: '0000000000000000000000000000000000000000000000000000000000000000'
|
||||
signer: '0000000000000000000000000000000000000000000000000000000000000000'
|
||||
- opcode: 32
|
||||
payload:
|
||||
service_type: BN
|
||||
locators:
|
||||
- /ip4/65.109.51.37/udp/3400/quic-v1
|
||||
provider_id: '59c662860b737f4e2515599adb3434856db8070b373a449ff66955ad3da6b473'
|
||||
zk_id: '6b2bcd3029fba573cff0c332dc4de7430faf5e261383d693d8dbb5b97665660a'
|
||||
locked_note_id: '7e449a14172fc90679f6fca7b49a2d58c305ebf7ac42ef20202e533c31115222'
|
||||
ops_proofs:
|
||||
- !ZkSig
|
||||
pi_a: '0000000000000000000000000000000000000000000000000000000000000000'
|
||||
pi_b: '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
|
||||
pi_c: '0000000000000000000000000000000000000000000000000000000000000000'
|
||||
- !Ed25519Sig '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
|
||||
- !Ed25519Sig '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
|
||||
- !ZkAndEd25519Sigs
|
||||
zk_sig:
|
||||
pi_a: '0000000000000000000000000000000000000000000000000000000000000000'
|
||||
pi_b: '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
|
||||
pi_c: '0000000000000000000000000000000000000000000000000000000000000000'
|
||||
ed25519_sig: '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
|
||||
faucet_pk: c2a6a4a0981d5bdcf8ddeb8d7934fd8c5510efeb1053f613b45871670b6f7b19
|
||||
time:
|
||||
slot_duration: '1.0'
|
||||
slot_duration: '1.000000000'
|
||||
mempool:
|
||||
pubsub_topic: mantle_e2e_tests
|
||||
pubsub_topic: /logos-blockchain-LEZ-DEV/mempool/1.0.0
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
services:
|
||||
|
||||
logos-blockchain-node-0:
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain@sha256:91d6c5bf07e07fcfba5e7cf07d21ee686a6bc4b9f6210f2d28bffbcad9a3729f
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:0.2.1-lssa
|
||||
ports:
|
||||
- "${PORT:-18080}:18080/tcp"
|
||||
volumes:
|
||||
|
||||
@ -7,14 +7,6 @@ export POL_PROOF_DEV_MODE=true
|
||||
# Use static configs mounted from host. Both node-config.yaml and
|
||||
# deployment-settings.yaml have matching validator keys so the node
|
||||
# can produce blocks as a single-validator network.
|
||||
# Copy deployment-settings to a writable path because sed -i can't
|
||||
# rename on a bind-mounted file.
|
||||
cp /etc/logos-blockchain/deployment-settings.yaml /deployment-settings.yaml
|
||||
|
||||
# Set chain_start_time to "now" so the chain starts immediately.
|
||||
sed -i "s/PLACEHOLDER_CHAIN_START_TIME/$(date -u '+%Y-%m-%d %H:%M:%S.000000 +00:00:00')/" \
|
||||
/deployment-settings.yaml
|
||||
|
||||
exec /usr/bin/logos-blockchain-node \
|
||||
/etc/logos-blockchain/node-config.yaml \
|
||||
--deployment /deployment-settings.yaml
|
||||
--deployment /etc/logos-blockchain/deployment-settings.yaml
|
||||
|
||||
@ -38,17 +38,11 @@ programs.workspace = true
|
||||
test_programs.workspace = true
|
||||
testnet_initial_state.workspace = true
|
||||
|
||||
logos-blockchain-http-api-common.workspace = true
|
||||
logos-blockchain-core.workspace = true
|
||||
logos-blockchain-zone-sdk.workspace = true
|
||||
logos-blockchain-key-management-system-service.workspace = true
|
||||
anyhow.workspace = true
|
||||
log.workspace = true
|
||||
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
|
||||
futures.workspace = true
|
||||
hex.workspace = true
|
||||
tempfile.workspace = true
|
||||
bytesize.workspace = true
|
||||
reqwest.workspace = true
|
||||
borsh.workspace = true
|
||||
num-bigint.workspace = true
|
||||
|
||||
@ -1,43 +1,23 @@
|
||||
#![expect(
|
||||
clippy::tests_outside_test_module,
|
||||
clippy::arithmetic_side_effects,
|
||||
reason = "We don't care about these in tests"
|
||||
)]
|
||||
|
||||
use std::{ops::Deref as _, time::Duration};
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::Context as _;
|
||||
use borsh::BorshSerialize;
|
||||
use common::transaction::LeeTransaction;
|
||||
use futures::StreamExt as _;
|
||||
use integration_tests::{
|
||||
TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext, account_balance, get_account,
|
||||
wait_for_indexer_to_catch_up,
|
||||
};
|
||||
use lee::{
|
||||
AccountId, execute_and_prove, privacy_preserving_transaction, program::Program,
|
||||
public_transaction,
|
||||
execute_and_prove, privacy_preserving_transaction, program::Program, public_transaction,
|
||||
};
|
||||
use lee_core::{InputAccountIdentity, account::AccountWithMetadata};
|
||||
use log::info;
|
||||
use logos_blockchain_core::mantle::{ledger::Inputs, ops::channel::deposit::DepositOp};
|
||||
use logos_blockchain_http_api_common::bodies::{
|
||||
channel::ChannelDepositRequestBody,
|
||||
wallet::{
|
||||
balance::WalletBalanceResponseBody,
|
||||
transfer_funds::{WalletTransferFundsRequestBody, WalletTransferFundsResponseBody},
|
||||
},
|
||||
};
|
||||
use logos_blockchain_zone_sdk::{
|
||||
CommonHttpClient, ZoneMessage, adapter::NodeHttpClient, indexer::ZoneIndexer,
|
||||
};
|
||||
use num_bigint::BigUint;
|
||||
use sequencer_service_rpc::RpcClient as _;
|
||||
use test_fixtures::public_mention;
|
||||
use tokio::test;
|
||||
use wallet::cli::{Command, execute_subcommand, programs::bridge::BridgeSubcommand};
|
||||
|
||||
const TIME_TO_FINALIZE_DEPOSIT_EVENT_ON_BEDROCK: Duration = Duration::from_mins(2);
|
||||
// const TIME_TO_FINALIZE_DEPOSIT_EVENT_ON_BEDROCK: Duration = Duration::from_mins(2);
|
||||
|
||||
#[test]
|
||||
async fn public_bridge_deposit_invocation_is_dropped() -> anyhow::Result<()> {
|
||||
@ -249,377 +229,386 @@ async fn private_bridge_deposit_invocation_is_dropped() -> anyhow::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn submit_bedrock_deposit(
|
||||
bedrock_addr: std::net::SocketAddr,
|
||||
bedrock_account_pk: &str,
|
||||
recipient_id: AccountId,
|
||||
amount: u64,
|
||||
) -> anyhow::Result<()> {
|
||||
#[derive(BorshSerialize)]
|
||||
struct DepositMetadata {
|
||||
recipient_id: AccountId,
|
||||
}
|
||||
// async fn submit_bedrock_deposit(
|
||||
// bedrock_addr: std::net::SocketAddr,
|
||||
// bedrock_account_pk: &str,
|
||||
// recipient_id: AccountId,
|
||||
// amount: u64,
|
||||
// ) -> 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")?
|
||||
.try_into()
|
||||
.context("Encoded metadata is too big")?;
|
||||
// // Encode deposit metadata
|
||||
// let metadata = borsh::to_vec(&DepositMetadata { recipient_id })
|
||||
// .context("Failed to encode deposit metadata")?
|
||||
// .try_into()
|
||||
// .context("Encoded metadata is too big")?;
|
||||
|
||||
let channel_id = integration_tests::config::bedrock_channel_id();
|
||||
let client = reqwest::Client::new();
|
||||
// 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/{bedrock_account_pk}/balance"
|
||||
))
|
||||
.send()
|
||||
.await
|
||||
.context("Failed to query Bedrock wallet balance")?;
|
||||
// let mut balance = bedrock_wallet_balance(bedrock_addr, bedrock_account_pk).await?;
|
||||
|
||||
let balance_response = check_response_success(balance_response).await?;
|
||||
// info!(
|
||||
// "Queried Bedrock balance for key {bedrock_account_pk}: {:?}",
|
||||
// balance.balance
|
||||
// );
|
||||
|
||||
balance_response
|
||||
.json::<WalletBalanceResponseBody>()
|
||||
.await
|
||||
.context("Failed to decode Bedrock balance response")
|
||||
};
|
||||
// if balance.balance < amount {
|
||||
// anyhow::bail!(
|
||||
// "Bedrock wallet with key {bedrock_account_pk} has insufficient balance {:?} for
|
||||
// deposit amount {:?}", balance.balance,
|
||||
// amount
|
||||
// );
|
||||
// }
|
||||
|
||||
let mut balance = query_balance().await?;
|
||||
// let mut selected_note_id = balance
|
||||
// .notes
|
||||
// .iter()
|
||||
// .find_map(|(note_id, value)| (*value == amount).then_some(*note_id));
|
||||
|
||||
info!(
|
||||
"Queried Bedrock balance for key {bedrock_account_pk}: {:?}",
|
||||
balance.balance
|
||||
);
|
||||
// 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,
|
||||
// };
|
||||
|
||||
if balance.balance < amount {
|
||||
anyhow::bail!(
|
||||
"Bedrock wallet with key {bedrock_account_pk} has insufficient balance {:?} for deposit amount {:?}",
|
||||
balance.balance,
|
||||
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 mut selected_note_id = balance
|
||||
.notes
|
||||
.iter()
|
||||
.find_map(|(note_id, value)| (*value == amount).then_some(*note_id));
|
||||
// let transfer: WalletTransferFundsResponseBody = transfer_response
|
||||
// .json()
|
||||
// .await
|
||||
// .context("Failed to decode Bedrock transfer-funds response")?;
|
||||
|
||||
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,
|
||||
};
|
||||
// info!(
|
||||
// "Submitted transfer-funds to create exact deposit note, tx hash {:?}",
|
||||
// transfer.hash
|
||||
// );
|
||||
|
||||
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 mut found_note = None;
|
||||
// for _ in 0..20 {
|
||||
// tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
// balance = bedrock_wallet_balance(bedrock_addr, bedrock_account_pk).await?;
|
||||
// found_note = balance
|
||||
// .notes
|
||||
// .iter()
|
||||
// .find_map(|(note_id, value)| (*value == amount).then_some(*note_id));
|
||||
// if found_note.is_some() {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
let transfer: WalletTransferFundsResponseBody = transfer_response
|
||||
.json()
|
||||
.await
|
||||
.context("Failed to decode Bedrock transfer-funds response")?;
|
||||
// selected_note_id = found_note;
|
||||
// }
|
||||
|
||||
info!(
|
||||
"Submitted transfer-funds to create exact deposit note, tx hash {:?}",
|
||||
transfer.hash
|
||||
);
|
||||
// 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 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;
|
||||
}
|
||||
}
|
||||
// let body = ChannelDepositRequestBody {
|
||||
// tip: None,
|
||||
// deposit: DepositOp {
|
||||
// channel_id,
|
||||
// inputs: Inputs::new(selected_note_id),
|
||||
// metadata,
|
||||
// },
|
||||
// change_public_key: balance.address,
|
||||
// funding_public_keys: vec![balance.address],
|
||||
// max_tx_fee: u64::MAX.into(),
|
||||
// };
|
||||
|
||||
selected_note_id = found_note;
|
||||
}
|
||||
// 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 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_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}", );
|
||||
|
||||
let body = ChannelDepositRequestBody {
|
||||
tip: None,
|
||||
deposit: DepositOp {
|
||||
channel_id,
|
||||
inputs: Inputs::new(selected_note_id),
|
||||
metadata,
|
||||
},
|
||||
change_public_key: balance.address,
|
||||
funding_public_keys: vec![balance.address],
|
||||
max_tx_fee: 1_000_u64.into(),
|
||||
};
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
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?;
|
||||
// /// The Bedrock wallet state of `bedrock_account_pk`: its total balance and the
|
||||
// /// notes it owns, keyed by note id.
|
||||
// async fn bedrock_wallet_balance(
|
||||
// bedrock_addr: std::net::SocketAddr,
|
||||
// bedrock_account_pk: &str,
|
||||
// ) -> anyhow::Result<WalletBalanceResponseBody> {
|
||||
// let response = reqwest::Client::new()
|
||||
// .get(format!(
|
||||
// "http://{bedrock_addr}/wallet/{bedrock_account_pk}/balance"
|
||||
// ))
|
||||
// .send()
|
||||
// .await
|
||||
// .context("Failed to query Bedrock wallet balance")?;
|
||||
|
||||
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}",
|
||||
);
|
||||
// check_response_success(response)
|
||||
// .await?
|
||||
// .json::<WalletBalanceResponseBody>()
|
||||
// .await
|
||||
// .context("Failed to decode Bedrock balance response")
|
||||
// }
|
||||
|
||||
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 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 = account_balance(ctx, 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}")
|
||||
// })?
|
||||
// }
|
||||
|
||||
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 = account_balance(ctx, 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 deposit and withdraw round trip.
|
||||
// ///
|
||||
// /// Implemented as one test instead of two separate tests for deposit and withdraw, because the
|
||||
// /// withdraw test depends on the deposit to set up the necessary state (funds in vault) for
|
||||
// testing /// withdraw functionality.
|
||||
// #[test]
|
||||
// async fn bedrock_deposit_claim_and_withdraw_round_trip_succeeds() -> anyhow::Result<()> {
|
||||
// let mut ctx = TestContext::new().await?;
|
||||
|
||||
/// Test deposit and withdraw round trip.
|
||||
///
|
||||
/// Implemented as one test instead of two separate tests for deposit and withdraw, because the
|
||||
/// withdraw test depends on the deposit to set up the necessary state (funds in vault) for testing
|
||||
/// withdraw functionality.
|
||||
#[test]
|
||||
async fn bedrock_deposit_claim_and_withdraw_round_trip_succeeds() -> anyhow::Result<()> {
|
||||
let mut ctx = TestContext::new().await?;
|
||||
// let bedrock_account_pk = "2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26";
|
||||
// let recipient_id = ctx.existing_public_accounts()[0];
|
||||
// let amount = 1_u64;
|
||||
// let vault_program_id = programs::vault().id();
|
||||
// let recipient_vault_id = vault_core::compute_vault_account_id(vault_program_id,
|
||||
// recipient_id);
|
||||
|
||||
let bedrock_account_pk = "2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26";
|
||||
let recipient_id = ctx.existing_public_accounts()[0];
|
||||
let amount = 1_u64;
|
||||
let vault_program_id = programs::vault().id();
|
||||
let recipient_vault_id = vault_core::compute_vault_account_id(vault_program_id, recipient_id);
|
||||
// let vault_balance_before = account_balance(&ctx, recipient_vault_id).await?;
|
||||
// let recipient_balance_before = account_balance(&ctx, recipient_id).await?;
|
||||
|
||||
let vault_balance_before = account_balance(&ctx, recipient_vault_id).await?;
|
||||
let recipient_balance_before = account_balance(&ctx, recipient_id).await?;
|
||||
// // Submit deposit to Bedrock
|
||||
// submit_bedrock_deposit(ctx.bedrock_addr(), bedrock_account_pk, recipient_id, amount)
|
||||
// .await
|
||||
// .context("Failed to submit Bedrock deposit for round-trip setup")?;
|
||||
|
||||
// Submit deposit to Bedrock
|
||||
submit_bedrock_deposit(ctx.bedrock_addr(), bedrock_account_pk, recipient_id, amount)
|
||||
.await
|
||||
.context("Failed to submit Bedrock deposit for round-trip setup")?;
|
||||
// // Wait for vault to receive the deposit (minted from bridge to vault)
|
||||
// wait_for_vault_balance(
|
||||
// &ctx,
|
||||
// recipient_vault_id,
|
||||
// vault_balance_before + u128::from(amount),
|
||||
// )
|
||||
// .await?;
|
||||
|
||||
// Wait for vault to receive the deposit (minted from bridge to vault)
|
||||
wait_for_vault_balance(
|
||||
&ctx,
|
||||
recipient_vault_id,
|
||||
vault_balance_before + u128::from(amount),
|
||||
)
|
||||
.await?;
|
||||
// // Now claim funds from vault back to recipient
|
||||
// let nonces = ctx
|
||||
// .wallet()
|
||||
// .get_accounts_nonces(&[recipient_id])
|
||||
// .await
|
||||
// .context("Failed to get nonce for vault claim")?;
|
||||
|
||||
// Now claim funds from vault back to recipient
|
||||
let nonces = ctx
|
||||
.wallet()
|
||||
.get_accounts_nonces(&[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 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: u128::from(amount),
|
||||
// },
|
||||
// )
|
||||
// .context("Failed to build vault claim message")?;
|
||||
|
||||
let claim_message = public_transaction::Message::try_new(
|
||||
vault_program_id,
|
||||
vec![recipient_id, recipient_vault_id],
|
||||
nonces,
|
||||
vault_core::Instruction::Claim {
|
||||
amount: u128::from(amount),
|
||||
},
|
||||
)
|
||||
.context("Failed to build vault claim message")?;
|
||||
// let claim_witness_set =
|
||||
// public_transaction::WitnessSet::for_message(&claim_message, &[signing_key]);
|
||||
// let claim_tx = LeeTransaction::Public(lee::PublicTransaction::new(
|
||||
// claim_message,
|
||||
// claim_witness_set,
|
||||
// ));
|
||||
|
||||
let claim_witness_set =
|
||||
public_transaction::WitnessSet::for_message(&claim_message, &[signing_key]);
|
||||
let claim_tx = LeeTransaction::Public(lee::PublicTransaction::new(
|
||||
claim_message,
|
||||
claim_witness_set,
|
||||
));
|
||||
// let claim_hash = ctx.sequencer_client().send_transaction(claim_tx).await?;
|
||||
|
||||
let claim_hash = ctx.sequencer_client().send_transaction(claim_tx).await?;
|
||||
// tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).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 = account_balance(&ctx, recipient_vault_id).await?;
|
||||
// let recipient_balance_after_claim = account_balance(&ctx, recipient_id).await?;
|
||||
|
||||
let claim_on_chain = ctx.sequencer_client().get_transaction(claim_hash).await?;
|
||||
let vault_balance_after_claim = account_balance(&ctx, recipient_vault_id).await?;
|
||||
let recipient_balance_after_claim = account_balance(&ctx, 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 + u128::from(amount),
|
||||
// "Recipient balance should increase by claimed amount"
|
||||
// );
|
||||
|
||||
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 + u128::from(amount),
|
||||
"Recipient balance should increase by claimed amount"
|
||||
);
|
||||
// // The indexer must replay the deposit and claim blocks and reach the same
|
||||
// // state as the sequencer — including the bridge system account the deposit
|
||||
// // modifies, which is the case the hot fix unblocks.
|
||||
// wait_for_indexer_to_catch_up(&ctx).await?;
|
||||
// let bridge_account_id = system_accounts::bridge_account_id();
|
||||
// for account_id in [recipient_id, recipient_vault_id, bridge_account_id] {
|
||||
// let indexer_account = indexer_service_rpc::RpcClient::get_account(
|
||||
// // `deref` is needed for correct trait resolution
|
||||
// // of the async `get_account` method on `RpcClient`
|
||||
// ctx.indexer_client().deref(),
|
||||
// account_id.into(),
|
||||
// )
|
||||
// .await?;
|
||||
// let sequencer_account = get_account(&ctx, account_id).await?;
|
||||
// assert_eq!(
|
||||
// indexer_account,
|
||||
// sequencer_account.into(),
|
||||
// "Indexer and sequencer diverged for account {account_id} after deposit"
|
||||
// );
|
||||
// }
|
||||
|
||||
// The indexer must replay the deposit and claim blocks and reach the same
|
||||
// state as the sequencer — including the bridge system account the deposit
|
||||
// modifies, which is the case the hot fix unblocks.
|
||||
wait_for_indexer_to_catch_up(&ctx).await?;
|
||||
let bridge_account_id = system_accounts::bridge_account_id();
|
||||
for account_id in [recipient_id, recipient_vault_id, bridge_account_id] {
|
||||
let indexer_account = indexer_service_rpc::RpcClient::get_account(
|
||||
// `deref` is needed for correct trait resolution
|
||||
// of the async `get_account` method on `RpcClient`
|
||||
ctx.indexer_client().deref(),
|
||||
account_id.into(),
|
||||
)
|
||||
.await?;
|
||||
let sequencer_account = get_account(&ctx, account_id).await?;
|
||||
assert_eq!(
|
||||
indexer_account,
|
||||
sequencer_account.into(),
|
||||
"Indexer and sequencer diverged for account {account_id} after deposit"
|
||||
);
|
||||
}
|
||||
// // Withdraw back to Bedrock and wait for finalized withdraw event.
|
||||
// let sender_id = recipient_id;
|
||||
|
||||
// Withdraw back to Bedrock and wait for finalized withdraw event.
|
||||
let sender_id = recipient_id;
|
||||
// let observer = create_zone_indexer_observer(ctx.bedrock_addr())?;
|
||||
// let observe_fut =
|
||||
// wait_for_finalized_withdraw_op(&observer, ctx.bedrock_addr(), amount,
|
||||
// bedrock_account_pk);
|
||||
|
||||
let observer = create_zone_indexer_observer(ctx.bedrock_addr())?;
|
||||
let observe_fut = wait_for_finalized_withdraw_op(&observer, amount, bedrock_account_pk);
|
||||
// let withdraw_fut = execute_subcommand(
|
||||
// ctx.wallet_mut(),
|
||||
// Command::Bridge(BridgeSubcommand::Withdraw {
|
||||
// from: public_mention(sender_id),
|
||||
// amount,
|
||||
// bedrock_account_pk: bedrock_account_pk.to_owned(),
|
||||
// }),
|
||||
// );
|
||||
|
||||
let withdraw_fut = execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Bridge(BridgeSubcommand::Withdraw {
|
||||
from: public_mention(sender_id),
|
||||
amount,
|
||||
bedrock_account_pk: bedrock_account_pk.to_owned(),
|
||||
}),
|
||||
);
|
||||
// let (observe_result, withdraw_result) = tokio::join!(observe_fut, withdraw_fut);
|
||||
|
||||
let (observe_result, withdraw_result) = tokio::join!(observe_fut, withdraw_fut);
|
||||
// withdraw_result.context("Failed to execute wallet bridge withdraw command")?;
|
||||
|
||||
withdraw_result.context("Failed to execute wallet bridge withdraw command")?;
|
||||
// observe_result
|
||||
// .context("Failed while waiting for finalized withdraw event from zone indexer")?;
|
||||
|
||||
observe_result
|
||||
.context("Failed while waiting for finalized withdraw event from zone indexer")?;
|
||||
// // Sleep to observe sequencer log about validated withdraw event
|
||||
// tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
|
||||
// Sleep to observe sequencer log about validated withdraw event
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
Ok(())
|
||||
}
|
||||
// fn create_zone_indexer_observer(
|
||||
// bedrock_addr: std::net::SocketAddr,
|
||||
// ) -> anyhow::Result<ZoneIndexer<NodeHttpClient>> {
|
||||
// let bedrock_url = integration_tests::config::addr_to_url(
|
||||
// integration_tests::config::UrlProtocol::Http,
|
||||
// bedrock_addr,
|
||||
// )
|
||||
// .context("Failed to convert Bedrock addr to URL for zone indexer observer")?;
|
||||
|
||||
fn create_zone_indexer_observer(
|
||||
bedrock_addr: std::net::SocketAddr,
|
||||
) -> anyhow::Result<ZoneIndexer<NodeHttpClient>> {
|
||||
let bedrock_url = integration_tests::config::addr_to_url(
|
||||
integration_tests::config::UrlProtocol::Http,
|
||||
bedrock_addr,
|
||||
)
|
||||
.context("Failed to convert Bedrock addr to URL for zone indexer observer")?;
|
||||
// let node = NodeHttpClient::new(CommonHttpClient::new(None), bedrock_url);
|
||||
|
||||
let node = NodeHttpClient::new(CommonHttpClient::new(None), bedrock_url);
|
||||
// Ok(ZoneIndexer::new(
|
||||
// integration_tests::config::bedrock_channel_id(),
|
||||
// node,
|
||||
// ))
|
||||
// }
|
||||
|
||||
Ok(ZoneIndexer::new(
|
||||
integration_tests::config::bedrock_channel_id(),
|
||||
node,
|
||||
))
|
||||
}
|
||||
// /// Waits for a finalized withdraw that pays `expected_amount` to `receiver_pk`.
|
||||
// ///
|
||||
// /// A withdraw op releases channel-owned notes and carries nothing but their
|
||||
// /// ids — the value and recipient live in the note itself. A released note keeps
|
||||
// /// its id, value and public key, so the pairing is checked on the receiver's
|
||||
// /// Bedrock wallet: one of the released notes must land there with the expected
|
||||
// /// value.
|
||||
// async fn wait_for_finalized_withdraw_op(
|
||||
// observer: &ZoneIndexer<NodeHttpClient>,
|
||||
// bedrock_addr: std::net::SocketAddr,
|
||||
// expected_amount: u64,
|
||||
// receiver_pk: &str,
|
||||
// ) -> anyhow::Result<()> {
|
||||
// let timeout = TIME_TO_FINALIZE_DEPOSIT_EVENT_ON_BEDROCK
|
||||
// + Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS);
|
||||
|
||||
async fn wait_for_finalized_withdraw_op(
|
||||
observer: &ZoneIndexer<NodeHttpClient>,
|
||||
expected_amount: u64,
|
||||
receiver_pk: &str,
|
||||
) -> 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 {
|
||||
// // The wallet can trail the channel event, so released notes accumulate
|
||||
// // across polls instead of being checked once when first observed.
|
||||
// let mut released_notes = HashSet::new();
|
||||
|
||||
let bedrock_account_pk_bytes = hex::decode(receiver_pk)
|
||||
.context("Failed to decode expected receiver public key from hex")?;
|
||||
let expected_receiver_pk =
|
||||
logos_blockchain_key_management_system_service::keys::ZkPublicKey::from(
|
||||
BigUint::from_bytes_le(&bedrock_account_pk_bytes),
|
||||
);
|
||||
// loop {
|
||||
// let stream = observer
|
||||
// .follow()
|
||||
// .await
|
||||
// .context("Failed to read zone indexer message batch")?;
|
||||
// let mut stream = std::pin::pin!(stream);
|
||||
|
||||
tokio::time::timeout(timeout, async {
|
||||
loop {
|
||||
let stream = observer
|
||||
.follow()
|
||||
.await
|
||||
.context("Failed to read zone indexer message batch")?;
|
||||
let mut stream = std::pin::pin!(stream);
|
||||
// while let Some(message) = stream.next().await {
|
||||
// info!("Observed zone message {message:?}");
|
||||
|
||||
while let Some(message) = stream.next().await {
|
||||
info!("Observed zone message {message:?}");
|
||||
// if let ZoneMessage::Withdraw(withdraw) = message {
|
||||
// released_notes.extend(withdraw.inputs.iter().copied());
|
||||
// }
|
||||
// }
|
||||
|
||||
let ZoneMessage::Withdraw(withdraw) = message else {
|
||||
continue;
|
||||
};
|
||||
// if !released_notes.is_empty() {
|
||||
// let balance = bedrock_wallet_balance(bedrock_addr, receiver_pk).await?;
|
||||
// if released_notes
|
||||
// .iter()
|
||||
// .any(|note_id| balance.notes.get(note_id) == Some(&expected_amount))
|
||||
// {
|
||||
// return Ok(());
|
||||
// }
|
||||
// }
|
||||
|
||||
let mut iter = withdraw.outputs.iter();
|
||||
let Some(note) = iter.next() else {
|
||||
continue;
|
||||
};
|
||||
if iter.next().is_some() {
|
||||
// Withdraw op should only have one output
|
||||
continue;
|
||||
}
|
||||
|
||||
if note.value == expected_amount && note.pk == expected_receiver_pk {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
}
|
||||
})
|
||||
.await
|
||||
.with_context(|| {
|
||||
format!("Timed out waiting for finalized withdraw message with amount {expected_amount}")
|
||||
})?
|
||||
}
|
||||
// tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
// }
|
||||
// })
|
||||
// .await
|
||||
// .with_context(|| {
|
||||
// format!("Timed out waiting for finalized withdraw message with amount {expected_amount}")
|
||||
// })?
|
||||
// }
|
||||
|
||||
@ -70,6 +70,7 @@ async fn multi_sequencer_committee_converges() -> Result<()> {
|
||||
&BedrockConfig {
|
||||
channel_id: config::bedrock_channel_id(),
|
||||
node_url: config::addr_to_url(config::UrlProtocol::Http, bedrock_addr)?,
|
||||
funding_key: config::bedrock_funding_key(),
|
||||
auth: None,
|
||||
},
|
||||
&Ed25519Key::from_bytes(&key_a),
|
||||
|
||||
@ -170,13 +170,13 @@ unsafe extern "C" {
|
||||
|
||||
fn wallet_ffi_free_transfer_result(result: *mut FfiTransferResult);
|
||||
|
||||
fn wallet_ffi_bridge_withdraw(
|
||||
handle: *mut WalletHandle,
|
||||
from: *const FfiBytes32,
|
||||
amount: u64,
|
||||
bedrock_account_pk: *const FfiBytes32,
|
||||
out_result: *mut FfiTransferResult,
|
||||
) -> error::WalletFfiError;
|
||||
// fn wallet_ffi_bridge_withdraw(
|
||||
// handle: *mut WalletHandle,
|
||||
// from: *const FfiBytes32,
|
||||
// amount: u64,
|
||||
// bedrock_account_pk: *const FfiBytes32,
|
||||
// out_result: *mut FfiTransferResult,
|
||||
// ) -> error::WalletFfiError;
|
||||
|
||||
fn wallet_ffi_get_vault_balance(
|
||||
handle: *mut WalletHandle,
|
||||
@ -1521,68 +1521,68 @@ fn restore_keys_from_seed_ffi() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wallet_ffi_bridge_withdraw() -> Result<()> {
|
||||
let ctx = BlockingTestContext::new()?;
|
||||
let home = tempfile::tempdir()?;
|
||||
let FfiCreateWalletOutput {
|
||||
wallet: wallet_ffi_handle,
|
||||
mnemonic: _,
|
||||
} = new_wallet_ffi_with_test_context_config(&ctx, home.path())?;
|
||||
let from: FfiBytes32 = ctx.ctx().existing_public_accounts()[0].into();
|
||||
let bridge_account: FfiBytes32 = system_accounts::bridge_account_id().into();
|
||||
let bedrock_account_pk = FfiBytes32::from_bytes([0x42; 32]);
|
||||
let amount = 100_u64;
|
||||
// #[test]
|
||||
// fn test_wallet_ffi_bridge_withdraw() -> Result<()> {
|
||||
// let ctx = BlockingTestContext::new()?;
|
||||
// let home = tempfile::tempdir()?;
|
||||
// let FfiCreateWalletOutput {
|
||||
// wallet: wallet_ffi_handle,
|
||||
// mnemonic: _,
|
||||
// } = new_wallet_ffi_with_test_context_config(&ctx, home.path())?;
|
||||
// let from: FfiBytes32 = ctx.ctx().existing_public_accounts()[0].into();
|
||||
// let bridge_account: FfiBytes32 = system_accounts::bridge_account_id().into();
|
||||
// let bedrock_account_pk = FfiBytes32::from_bytes([0x42; 32]);
|
||||
// let amount = 100_u64;
|
||||
|
||||
let mut transfer_result = FfiTransferResult::default();
|
||||
unsafe {
|
||||
wallet_ffi_bridge_withdraw(
|
||||
wallet_ffi_handle,
|
||||
&raw const from,
|
||||
amount,
|
||||
&raw const bedrock_account_pk,
|
||||
&raw mut transfer_result,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
// let mut transfer_result = FfiTransferResult::default();
|
||||
// unsafe {
|
||||
// wallet_ffi_bridge_withdraw(
|
||||
// wallet_ffi_handle,
|
||||
// &raw const from,
|
||||
// amount,
|
||||
// &raw const bedrock_account_pk,
|
||||
// &raw mut transfer_result,
|
||||
// )
|
||||
// .unwrap();
|
||||
// }
|
||||
|
||||
info!("Waiting for next block creation");
|
||||
std::thread::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS));
|
||||
// info!("Waiting for next block creation");
|
||||
// std::thread::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS));
|
||||
|
||||
let from_balance = unsafe {
|
||||
let mut out_balance: [u8; 16] = [0; 16];
|
||||
wallet_ffi_get_balance(
|
||||
wallet_ffi_handle,
|
||||
&raw const from,
|
||||
true,
|
||||
&raw mut out_balance,
|
||||
)
|
||||
.unwrap();
|
||||
u128::from_le_bytes(out_balance)
|
||||
};
|
||||
// let from_balance = unsafe {
|
||||
// let mut out_balance: [u8; 16] = [0; 16];
|
||||
// wallet_ffi_get_balance(
|
||||
// wallet_ffi_handle,
|
||||
// &raw const from,
|
||||
// true,
|
||||
// &raw mut out_balance,
|
||||
// )
|
||||
// .unwrap();
|
||||
// u128::from_le_bytes(out_balance)
|
||||
// };
|
||||
|
||||
let bridge_balance = unsafe {
|
||||
let mut out_balance: [u8; 16] = [0; 16];
|
||||
wallet_ffi_get_balance(
|
||||
wallet_ffi_handle,
|
||||
&raw const bridge_account,
|
||||
true,
|
||||
&raw mut out_balance,
|
||||
)
|
||||
.unwrap();
|
||||
u128::from_le_bytes(out_balance)
|
||||
};
|
||||
// let bridge_balance = unsafe {
|
||||
// let mut out_balance: [u8; 16] = [0; 16];
|
||||
// wallet_ffi_get_balance(
|
||||
// wallet_ffi_handle,
|
||||
// &raw const bridge_account,
|
||||
// true,
|
||||
// &raw mut out_balance,
|
||||
// )
|
||||
// .unwrap();
|
||||
// u128::from_le_bytes(out_balance)
|
||||
// };
|
||||
|
||||
assert_eq!(from_balance, 9900);
|
||||
assert_eq!(bridge_balance, 1_000_100);
|
||||
// assert_eq!(from_balance, 9900);
|
||||
// assert_eq!(bridge_balance, 1_000_100);
|
||||
|
||||
unsafe {
|
||||
wallet_ffi_free_transfer_result(&raw mut transfer_result);
|
||||
wallet_ffi_destroy(wallet_ffi_handle);
|
||||
}
|
||||
// unsafe {
|
||||
// wallet_ffi_free_transfer_result(&raw mut transfer_result);
|
||||
// wallet_ffi_destroy(wallet_ffi_handle);
|
||||
// }
|
||||
|
||||
Ok(())
|
||||
}
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
#[test]
|
||||
fn test_wallet_ffi_transfer_generic_public() -> Result<()> {
|
||||
|
||||
@ -11,7 +11,8 @@
|
||||
"max_retries": 5
|
||||
},
|
||||
"channel_id": "0101010101010101010101010101010101010101010101010101010101010101",
|
||||
"node_url": "http://logos-blockchain-node-0:18080"
|
||||
"node_url": "http://logos-blockchain-node-0:18080",
|
||||
"funding_key": "2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26"
|
||||
},
|
||||
"genesis": [
|
||||
{
|
||||
|
||||
@ -7,5 +7,4 @@ license = { workspace = true }
|
||||
[dependencies]
|
||||
bridge_core.workspace = true
|
||||
vault_core.workspace = true
|
||||
authenticated_transfer_core.workspace = true
|
||||
lee_core.workspace = true
|
||||
|
||||
@ -104,33 +104,35 @@ fn main() {
|
||||
}
|
||||
}
|
||||
Instruction::Withdraw {
|
||||
amount,
|
||||
amount: _,
|
||||
bedrock_account_pk: _,
|
||||
} => {
|
||||
let [sender, bridge] = pre_states
|
||||
.try_into()
|
||||
.expect("Withdraw requires exactly 2 accounts");
|
||||
panic!("Withdraws are disabled in the current version of LEZ");
|
||||
|
||||
assert_eq!(
|
||||
bridge.account_id,
|
||||
bridge_core::compute_bridge_account_id(self_program_id),
|
||||
"Second account must be bridge PDA"
|
||||
);
|
||||
// let [sender, bridge] = pre_states
|
||||
// .try_into()
|
||||
// .expect("Withdraw requires exactly 2 accounts");
|
||||
|
||||
let auth_transfer_program_id = bridge.account.program_owner;
|
||||
assert_eq!(
|
||||
sender.account.program_owner, auth_transfer_program_id,
|
||||
"Sender account must be owned by the authenticated transfer program"
|
||||
);
|
||||
// assert_eq!(
|
||||
// bridge.account_id,
|
||||
// bridge_core::compute_bridge_account_id(self_program_id),
|
||||
// "Second account must be bridge PDA"
|
||||
// );
|
||||
|
||||
let chained_calls = vec![ChainedCall::new(
|
||||
auth_transfer_program_id,
|
||||
vec![sender, bridge],
|
||||
&authenticated_transfer_core::Instruction::Transfer {
|
||||
amount: u128::from(amount),
|
||||
},
|
||||
)];
|
||||
(unchanged_post_states(&pre_states_clone), chained_calls)
|
||||
// let auth_transfer_program_id = bridge.account.program_owner;
|
||||
// assert_eq!(
|
||||
// sender.account.program_owner, auth_transfer_program_id,
|
||||
// "Sender account must be owned by the authenticated transfer program"
|
||||
// );
|
||||
|
||||
// let chained_calls = vec![ChainedCall::new(
|
||||
// auth_transfer_program_id,
|
||||
// vec![sender, bridge],
|
||||
// &authenticated_transfer_core::Instruction::Transfer {
|
||||
// amount: u128::from(amount),
|
||||
// },
|
||||
// )];
|
||||
// (unchanged_post_states(&pre_states_clone), chained_calls)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@ cross_zone_inbox_core.workspace = true
|
||||
|
||||
logos-blockchain-key-management-system-service.workspace = true
|
||||
logos-blockchain-core.workspace = true
|
||||
logos-blockchain-http-api-common.workspace = true
|
||||
anyhow.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
|
||||
@ -4,11 +4,15 @@ use anyhow::{Context as _, Result, anyhow, ensure};
|
||||
use common::block::Block;
|
||||
use futures::Stream;
|
||||
use log::{info, warn};
|
||||
pub use logos_blockchain_core::mantle::ops::channel::{Ed25519PublicKey, MsgId};
|
||||
pub use logos_blockchain_core::mantle::{
|
||||
ledger::NoteId,
|
||||
ops::channel::{Ed25519PublicKey, MsgId},
|
||||
};
|
||||
use logos_blockchain_core::{
|
||||
mantle::{
|
||||
MantleTx, SignedMantleTx, Transaction as _,
|
||||
SignedMantleTx,
|
||||
channel::{SlotTimeframe, SlotTimeout},
|
||||
gas::GasCost,
|
||||
ops::{
|
||||
Op, OpProof,
|
||||
channel::{
|
||||
@ -17,9 +21,12 @@ use logos_blockchain_core::{
|
||||
inscribe::Inscription,
|
||||
},
|
||||
},
|
||||
traits::Hashable as _,
|
||||
transactions::{MantleTxBuilder, OpsProofs},
|
||||
},
|
||||
proofs::channel_multi_sig_proof::{ChannelMultiSigProof, IndexedSignature},
|
||||
};
|
||||
use logos_blockchain_http_api_common::bodies::wallet::fund::WalletFundRequestBody;
|
||||
pub use logos_blockchain_key_management_system_service::keys::{
|
||||
ED25519_SECRET_KEY_SIZE, Ed25519Key, ZkKey,
|
||||
};
|
||||
@ -29,9 +36,9 @@ use logos_blockchain_zone_sdk::{
|
||||
adapter::{Node as _, NodeHttpClient},
|
||||
indexer::ZoneIndexer,
|
||||
sequencer::{
|
||||
DepositInfo, Event, FinalizedOp, InscriptionInfo, OrphanedTx,
|
||||
SequencerConfig as ZoneSdkSequencerConfig, TurnNotification, WithdrawArg, WithdrawInfo,
|
||||
ZoneSequencer,
|
||||
ChannelUpdateTx, DepositInfo, Event, FinalizedOp, FundingConfig, InscriptionInfo,
|
||||
PendingTx, SequencerConfig as ZoneSdkSequencerConfig, TurnNotification, WithdrawArg,
|
||||
WithdrawInfo, ZoneSequencer,
|
||||
},
|
||||
};
|
||||
use tokio::sync::{mpsc, oneshot, watch};
|
||||
@ -72,14 +79,29 @@ pub struct FollowUpdate {
|
||||
/// persist the whole event in one write.
|
||||
pub type OnFollowSink = Box<dyn Fn(FollowUpdate) + Send + 'static>;
|
||||
|
||||
/// What one publish produced.
|
||||
pub struct PublishOutcome {
|
||||
/// The `MsgId` zone-sdk assigned the published inscription.
|
||||
pub this_msg: MsgId,
|
||||
/// The checkpoint that now holds the inscription as pending.
|
||||
pub checkpoint: SequencerCheckpoint,
|
||||
/// Channel notes the bundled withdrawals release, empty for a plain
|
||||
/// publish.
|
||||
/// A [`ChannelWithdrawOp`](logos_blockchain_core::mantle::ops::channel::withdraw::ChannelWithdrawOp)
|
||||
/// carries nothing but the note ids it releases, so these are the only
|
||||
/// handle the local withdraw intent shares with the Bedrock Withdraw event
|
||||
/// that later reports it.
|
||||
pub released_notes: Vec<NoteId>,
|
||||
}
|
||||
|
||||
/// Commands the drive task executes with `&mut sequencer`.
|
||||
enum Command {
|
||||
/// Publish an inscription (+ atomic withdrawals); responds with the assigned
|
||||
/// `MsgId` and the checkpoint that now includes it as pending.
|
||||
/// Publish an inscription (+ atomic withdrawals); responds with the
|
||||
/// [`PublishOutcome`].
|
||||
Publish {
|
||||
inscription: Inscription,
|
||||
withdrawals: Vec<WithdrawArg>,
|
||||
resp: oneshot::Sender<Result<(MsgId, SequencerCheckpoint)>>,
|
||||
resp: oneshot::Sender<Result<PublishOutcome>>,
|
||||
},
|
||||
}
|
||||
|
||||
@ -95,9 +117,8 @@ pub trait BlockPublisherTrait: Sized {
|
||||
on_follow: OnFollowSink,
|
||||
) -> Result<Self>;
|
||||
|
||||
/// Publish a block and return the `MsgId` zone-sdk assigned its inscription
|
||||
/// together with the checkpoint that now holds it as pending. Zone-sdk
|
||||
/// drives the actual submission and retries internally.
|
||||
/// Publish a block and return what zone-sdk made of it. Zone-sdk drives the
|
||||
/// actual submission and retries internally.
|
||||
///
|
||||
/// The checkpoint must be persisted with the block — restoring an older one
|
||||
/// drops the inscription from the pending set, and it is never resubmitted.
|
||||
@ -105,7 +126,7 @@ pub trait BlockPublisherTrait: Sized {
|
||||
&self,
|
||||
block: &Block,
|
||||
withdrawals: Vec<WithdrawArg>,
|
||||
) -> Result<(MsgId, SequencerCheckpoint)>;
|
||||
) -> Result<PublishOutcome>;
|
||||
|
||||
fn channel_id(&self) -> ChannelId;
|
||||
|
||||
@ -167,6 +188,11 @@ impl BlockPublisherTrait for ZoneSdkPublisher {
|
||||
|
||||
let zone_sdk_config = ZoneSdkSequencerConfig {
|
||||
resubmit_interval,
|
||||
funding: Some(FundingConfig {
|
||||
funding_pk: config.funding_key,
|
||||
max_tx_fee: GasCost::new(logos_blockchain_core::mantle::Value::MAX),
|
||||
priority_fee: FundingConfig::DEFAULT_PRIORITY_FEE,
|
||||
}),
|
||||
..ZoneSdkSequencerConfig::default()
|
||||
};
|
||||
|
||||
@ -209,15 +235,20 @@ impl BlockPublisherTrait for ZoneSdkPublisher {
|
||||
let published = if withdrawals.is_empty() {
|
||||
sequencer.handle()
|
||||
.publish(data_bounded)
|
||||
.await
|
||||
.context("Failed to publish block")
|
||||
} else {
|
||||
sequencer.handle()
|
||||
.publish_atomic_withdraw(data_bounded, withdrawals)
|
||||
.await
|
||||
.context("Failed to publish block with withdrawals")
|
||||
};
|
||||
|
||||
let msg_result = published
|
||||
.map(|(result, checkpoint)| (result.tx.inscription().this_msg, checkpoint));
|
||||
let msg_result = published.map(|(result, checkpoint)| PublishOutcome {
|
||||
this_msg: result.tx.inscription().this_msg,
|
||||
checkpoint,
|
||||
released_notes: released_notes(&result.tx),
|
||||
});
|
||||
match &msg_result {
|
||||
Ok(_) if withdraw_count == 0 => {
|
||||
info!("Published block with the size of {data_byte_size} bytes");
|
||||
@ -233,9 +264,6 @@ impl BlockPublisherTrait for ZoneSdkPublisher {
|
||||
}
|
||||
},
|
||||
event = sequencer.next_event() => {
|
||||
let Some(event) = event else {
|
||||
continue;
|
||||
};
|
||||
match event {
|
||||
Event::BlocksProcessed {
|
||||
checkpoint,
|
||||
@ -245,12 +273,13 @@ impl BlockPublisherTrait for ZoneSdkPublisher {
|
||||
let adopted = channel_update
|
||||
.adopted
|
||||
.iter()
|
||||
.filter_map(channel_update_inscription)
|
||||
.filter_map(block_from_inscription)
|
||||
.collect();
|
||||
let orphaned = channel_update
|
||||
.orphaned
|
||||
.iter()
|
||||
.map(orphan_inscription)
|
||||
.filter_map(channel_update_inscription)
|
||||
.filter_map(block_from_inscription)
|
||||
.collect();
|
||||
|
||||
@ -295,6 +324,7 @@ impl BlockPublisherTrait for ZoneSdkPublisher {
|
||||
notification.ends_at_slot
|
||||
);
|
||||
}
|
||||
Event::MempoolPending(_tx_hash) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -324,7 +354,7 @@ impl BlockPublisherTrait for ZoneSdkPublisher {
|
||||
&self,
|
||||
block: &Block,
|
||||
withdrawals: Vec<WithdrawArg>,
|
||||
) -> Result<(MsgId, SequencerCheckpoint)> {
|
||||
) -> Result<PublishOutcome> {
|
||||
let data = borsh::to_vec(block).context("Failed to serialize block")?;
|
||||
let data_bounded: Inscription = data
|
||||
.try_into()
|
||||
@ -394,16 +424,31 @@ fn block_from_inscription(inscription: &InscriptionInfo) -> Option<(MsgId, Block
|
||||
.map(|block| (inscription.this_msg, block))
|
||||
}
|
||||
|
||||
/// Channel notes the withdraws bundled with a published tx release; empty for a
|
||||
/// plain inscription. See [`PublishOutcome::released_notes`].
|
||||
fn released_notes(tx: &PendingTx) -> Vec<NoteId> {
|
||||
match tx {
|
||||
PendingTx::Inscription(_) => Vec::new(),
|
||||
PendingTx::AtomicWithdraw(bundle) => bundle
|
||||
.withdraws
|
||||
.iter()
|
||||
.flat_map(|withdraw| withdraw.op.inputs.iter().copied())
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
/// The inscription carried by an orphaned tx (plain or atomic-withdraw bundle).
|
||||
const fn orphan_inscription(orphan: &OrphanedTx) -> &InscriptionInfo {
|
||||
const fn channel_update_inscription(orphan: &ChannelUpdateTx) -> Option<&InscriptionInfo> {
|
||||
match orphan {
|
||||
OrphanedTx::Inscription(info) => info,
|
||||
OrphanedTx::AtomicWithdraw(bundle) => &bundle.inscription,
|
||||
ChannelUpdateTx::Inscription(info) => Some(info),
|
||||
ChannelUpdateTx::AtomicWithdraw(bundle) => Some(&bundle.inscription),
|
||||
ChannelUpdateTx::Custom(_signed_mantle_tx) => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Signs a `ChannelConfig` op (accredited keys + rotation params) with
|
||||
/// `signing_key` and posts it straight to the bedrock node.
|
||||
/// `signing_key`, funds it from `config.funding_key` via the node's wallet,
|
||||
/// and posts it straight to the bedrock node.
|
||||
///
|
||||
/// A standalone one-shot — no running sequencer involved, so authorization is
|
||||
/// holding the admin key: the L1 rejects non-admin signers. `Ok(())` means the
|
||||
@ -416,12 +461,12 @@ pub async fn post_channel_config(
|
||||
posting_timeframe: u32,
|
||||
posting_timeout: u32,
|
||||
configuration_threshold: u16,
|
||||
withdraw_threshold: u16,
|
||||
transfer_threshold: u16,
|
||||
) -> Result<()> {
|
||||
ensure!(!keys.is_empty(), "Channel key list must not be empty");
|
||||
for (name, threshold) in [
|
||||
("configuration_threshold", configuration_threshold),
|
||||
("withdraw_threshold", withdraw_threshold),
|
||||
("transfer_threshold", transfer_threshold),
|
||||
] {
|
||||
ensure!(
|
||||
threshold >= 1 && usize::from(threshold) <= keys.len(),
|
||||
@ -442,27 +487,51 @@ pub async fn post_channel_config(
|
||||
posting_timeframe: SlotTimeframe::from(posting_timeframe),
|
||||
posting_timeout: SlotTimeout::from(posting_timeout),
|
||||
configuration_threshold,
|
||||
withdraw_threshold,
|
||||
};
|
||||
|
||||
let mantle_tx = MantleTx([Op::ChannelConfig(config_op)].into());
|
||||
let tx_hash = mantle_tx.hash();
|
||||
// The admin key is `keys[0]`, hence signature index 0.
|
||||
let signature = IndexedSignature::new(
|
||||
0,
|
||||
signing_key.sign_payload(tx_hash.as_signing_bytes().as_ref()),
|
||||
);
|
||||
let proof = ChannelMultiSigProof::new(vec![signature])
|
||||
.map_err(|err| anyhow!("Failed to assemble channel multi-sig proof: {err:?}"))?;
|
||||
let signed_tx = SignedMantleTx {
|
||||
ops_proofs: vec![OpProof::ChannelMultiSigProof(proof)],
|
||||
mantle_tx,
|
||||
transfer_threshold,
|
||||
};
|
||||
|
||||
let node = NodeHttpClient::new(
|
||||
CommonHttpClient::new(config.auth.clone().map(Into::into)),
|
||||
config.node_url.clone(),
|
||||
);
|
||||
|
||||
// Fund the op from the node's wallet: the node appends a fee transfer
|
||||
// (paid from `funding_key`, change back to it) and returns its proof.
|
||||
let tx_builder = MantleTxBuilder::new()
|
||||
.extend_ops([Op::ChannelConfig(config_op)])
|
||||
.map_err(|err| anyhow!("Too many ops in channel config transaction: {err:?}"))?;
|
||||
let funded = node
|
||||
.fund_tx(WalletFundRequestBody {
|
||||
tip: None,
|
||||
tx_builder,
|
||||
change_public_key: config.funding_key,
|
||||
funding_public_keys: vec![config.funding_key],
|
||||
max_tx_fee: GasCost::new(logos_blockchain_core::mantle::Value::MAX),
|
||||
priority_fee: FundingConfig::DEFAULT_PRIORITY_FEE,
|
||||
})
|
||||
.await
|
||||
.context("Failed to fund channel config transaction")?;
|
||||
let mantle_tx = funded.funded_tx;
|
||||
|
||||
// Sign the funded tx: the appended fee transfer changes the hash.
|
||||
let tx_hash = mantle_tx.hash();
|
||||
// The admin key is `keys[0]`, hence signature index 0.
|
||||
let signature = IndexedSignature::new(
|
||||
0,
|
||||
signing_key.sign_payload(tx_hash.as_signing_bytes().as_ref()),
|
||||
);
|
||||
let proof = ChannelMultiSigProof::try_new(signature.into())
|
||||
.map_err(|err| anyhow!("Failed to assemble channel multi-sig proof: {err:?}"))?;
|
||||
|
||||
// Proofs follow op order; funding appends the transfer as the last op.
|
||||
let mut ops_proofs: OpsProofs = OpProof::ChannelMultiSigProof(proof).into();
|
||||
if let Some(transfer_proof) = funded.transfer_proof {
|
||||
ops_proofs
|
||||
.try_push(transfer_proof)
|
||||
.map_err(|err| anyhow!("Too many operation proofs: {err:?}"))?;
|
||||
}
|
||||
let signed_tx = SignedMantleTx::new(mantle_tx, ops_proofs);
|
||||
|
||||
node.post_transaction(signed_tx)
|
||||
.await
|
||||
.context("Failed to post channel config transaction")
|
||||
|
||||
@ -12,6 +12,7 @@ pub use cross_zone_inbox_core::{CrossZoneConfig, CrossZonePeer};
|
||||
use humantime_serde;
|
||||
use lee::{AccountId, Balance};
|
||||
use logos_blockchain_core::mantle::ops::channel::ChannelId;
|
||||
use logos_blockchain_key_management_system_service::keys::ZkPublicKey;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
@ -72,6 +73,7 @@ pub struct BedrockConfig {
|
||||
pub node_url: Url,
|
||||
/// Bedrock auth.
|
||||
pub auth: Option<BasicAuth>,
|
||||
pub funding_key: ZkPublicKey,
|
||||
}
|
||||
|
||||
impl SequencerConfig {
|
||||
|
||||
@ -41,7 +41,7 @@ use storage::sequencer::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
block_publisher::{BlockPublisherTrait, MsgId, ZoneSdkPublisher},
|
||||
block_publisher::{BlockPublisherTrait, MsgId, NoteId, ZoneSdkPublisher},
|
||||
block_store::SequencerStore,
|
||||
task_group::{StoreRelease, TaskGroup},
|
||||
};
|
||||
@ -268,7 +268,7 @@ impl<BP: BlockPublisherTrait> SequencerCore<BP> {
|
||||
|
||||
let mut last_checkpoint = None;
|
||||
for block in &pending_blocks {
|
||||
let (_msg, checkpoint) = block_publisher
|
||||
let outcome = block_publisher
|
||||
.publish_block(block, vec![])
|
||||
.await
|
||||
.unwrap_or_else(|err| {
|
||||
@ -277,7 +277,7 @@ impl<BP: BlockPublisherTrait> SequencerCore<BP> {
|
||||
block.header.block_id
|
||||
)
|
||||
});
|
||||
last_checkpoint = Some(checkpoint);
|
||||
last_checkpoint = Some(outcome.checkpoint);
|
||||
}
|
||||
|
||||
// These blocks are already stored, so only the sdk's pending set
|
||||
@ -542,18 +542,21 @@ impl<BP: BlockPublisherTrait> SequencerCore<BP> {
|
||||
.build_block_from_mempool()
|
||||
.context("Failed to build block from mempool transactions")?;
|
||||
|
||||
let withdrawal_reconciliation_keys: Vec<_> = withdrawals
|
||||
.iter()
|
||||
.map(|withdraw| withdraw_event_reconciliation_key(&withdraw.outputs))
|
||||
.collect::<Result<Vec<_>>>()
|
||||
.context("Failed to build reconciliation keys for block withdrawals")?;
|
||||
|
||||
let (this_msg, checkpoint) = self
|
||||
let block_publisher::PublishOutcome {
|
||||
this_msg,
|
||||
checkpoint,
|
||||
released_notes,
|
||||
} = self
|
||||
.block_publisher
|
||||
.publish_block(&block, withdrawals)
|
||||
.await
|
||||
.context("Failed to publish block to Bedrock")?;
|
||||
|
||||
let withdrawal_reconciliation_keys: Vec<_> = released_notes
|
||||
.iter()
|
||||
.map(withdrawal_reconciliation_key)
|
||||
.collect();
|
||||
|
||||
self.record_produced_block(
|
||||
this_msg,
|
||||
&block,
|
||||
@ -1146,20 +1149,12 @@ fn apply_follow_update(
|
||||
let deposit_records: Vec<PendingDepositEventRecord> =
|
||||
deposits.iter().map(pending_deposit_event_record).collect();
|
||||
|
||||
// A withdraw whose outputs we cannot read has no counter to reconcile
|
||||
// against; log and drop it rather than fail the whole update.
|
||||
// One reconciliation unit per released note, matching how the intents were
|
||||
// recorded at publish time.
|
||||
let consumed_withdrawals: Vec<WithdrawalReconciliationKey> = withdrawals
|
||||
.iter()
|
||||
.filter_map(|withdraw| {
|
||||
withdraw_event_reconciliation_key(&withdraw.op.outputs)
|
||||
.inspect_err(|err| {
|
||||
error!(
|
||||
"Failed to build reconciliation key for Bedrock Withdraw event with tx_hash {}: {err:#}",
|
||||
hex::encode(withdraw.tx_hash.as_ref())
|
||||
);
|
||||
})
|
||||
.ok()
|
||||
})
|
||||
.flat_map(|withdraw| withdraw.op.inputs.iter())
|
||||
.map(withdrawal_reconciliation_key)
|
||||
.collect();
|
||||
|
||||
// The lock is held across the persist below so disk writes land in apply
|
||||
@ -1167,12 +1162,6 @@ fn apply_follow_update(
|
||||
let (resubmit_txs, outcome) = {
|
||||
let mut chain = chain.lock().expect("chain state mutex poisoned");
|
||||
|
||||
// User txs of orphaned blocks, returned to the mempool below.
|
||||
let resubmit_txs: Vec<LeeTransaction> = orphaned
|
||||
.iter()
|
||||
.flat_map(|(_, block)| resubmittable_txs(block))
|
||||
.collect();
|
||||
|
||||
// Outcomes align with `adopted`.
|
||||
let outcomes = chain.apply_channel_update(&orphaned, &adopted);
|
||||
let mut to_persist: Vec<(&Block, bool)> = adopted
|
||||
@ -1206,6 +1195,22 @@ fn apply_follow_update(
|
||||
AcceptOutcome::Parked(_) | AcceptOutcome::RetryableFailure(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
// User txs of orphaned blocks, returned to the mempool below.
|
||||
//
|
||||
// Computed after the finalized tier has advanced, and only for blocks
|
||||
// above it: the zone-sdk reports a block as orphaned once LIB pruning
|
||||
// drops its inscription from the channel lineage, so every block of
|
||||
// ours is orphaned a poll or two after it finalizes. Those transactions
|
||||
// are irreversibly included, and returning them to the mempool puts
|
||||
// them back in every block we produce from then on.
|
||||
let final_height = chain.final_tip().map(|tip| tip.block_id);
|
||||
let resubmit_txs: Vec<LeeTransaction> = orphaned
|
||||
.iter()
|
||||
.filter(|(_, block)| final_height.is_none_or(|id| block.header.block_id > id))
|
||||
.flat_map(|(_, block)| resubmittable_txs(block))
|
||||
.collect();
|
||||
|
||||
// Snapshot the advanced final tier so a restart re-anchors on it.
|
||||
let final_meta = final_advanced.then(|| {
|
||||
let tip = chain.final_tip().expect("advanced final tier has a tip");
|
||||
@ -1265,9 +1270,8 @@ fn apply_follow_update(
|
||||
}
|
||||
for withdrawal in &outcome.unmatched_withdrawals {
|
||||
warn!(
|
||||
"Unexpected Bedrock Withdraw event of {} to {}: no matching unseen withdraw found",
|
||||
withdrawal.amount,
|
||||
hex::encode(withdrawal.bedrock_account_pk)
|
||||
"Unexpected Bedrock Withdraw event releasing channel note {}: no matching unseen withdraw found",
|
||||
hex::encode(withdrawal.released_note_id)
|
||||
);
|
||||
}
|
||||
|
||||
@ -1643,35 +1647,21 @@ fn extract_bridge_withdraw_data(tx: &LeeTransaction) -> Option<WithdrawArg> {
|
||||
})
|
||||
}
|
||||
|
||||
fn withdraw_event_reconciliation_key(
|
||||
outputs: &logos_blockchain_core::mantle::ledger::Outputs,
|
||||
) -> Result<WithdrawalReconciliationKey> {
|
||||
let [note] = outputs.as_ref().as_slice() else {
|
||||
return Err(anyhow!(
|
||||
"Unsupported withdraw output count for reconciliation: {}",
|
||||
outputs.len()
|
||||
));
|
||||
};
|
||||
|
||||
// `extract_bridge_withdraw_data` maps [u8;32] LE -> BigUint -> ZkPublicKey.
|
||||
// Reconcile by reversing that direction here.
|
||||
let mut bedrock_account_pk = BigUint::from(note.pk.into_inner()).to_bytes_le();
|
||||
if bedrock_account_pk.len() > 32 {
|
||||
return Err(anyhow!(
|
||||
"Withdraw recipient public key is too large: {} bytes",
|
||||
bedrock_account_pk.len()
|
||||
));
|
||||
}
|
||||
bedrock_account_pk.resize(32, 0);
|
||||
|
||||
let bedrock_account_pk: [u8; 32] = bedrock_account_pk
|
||||
/// The reconciliation identity of one released channel note.
|
||||
///
|
||||
/// A `ChannelWithdrawOp` releases notes the channel already owns and carries
|
||||
/// only their ids — the recipient key and value live in the note itself, which
|
||||
/// neither the op nor the Bedrock Withdraw event reports. The note id is
|
||||
/// therefore the one handle both sides share, and it is unique: a note is spent
|
||||
/// once.
|
||||
fn withdrawal_reconciliation_key(note_id: &NoteId) -> WithdrawalReconciliationKey {
|
||||
let released_note_id: [u8; 32] = note_id
|
||||
.as_bytes()
|
||||
.as_ref()
|
||||
.try_into()
|
||||
.expect("Public key bytes were padded/truncated to 32 bytes");
|
||||
.expect("`NoteId` is a 32-byte field element");
|
||||
|
||||
Ok(WithdrawalReconciliationKey {
|
||||
amount: note.value,
|
||||
bedrock_account_pk,
|
||||
})
|
||||
WithdrawalReconciliationKey { released_note_id }
|
||||
}
|
||||
|
||||
/// Load signing key from file or generate a new one if it doesn't exist.
|
||||
|
||||
@ -5,14 +5,17 @@ use common::block::Block;
|
||||
use futures::Stream;
|
||||
use logos_blockchain_core::{
|
||||
header::HeaderId,
|
||||
mantle::ops::channel::{ChannelId, MsgId},
|
||||
mantle::{
|
||||
ledger::{NoteId, Utxo},
|
||||
ops::channel::{ChannelId, MsgId},
|
||||
},
|
||||
};
|
||||
use logos_blockchain_key_management_system_service::keys::Ed25519Key;
|
||||
use logos_blockchain_zone_sdk::{Slot, ZoneMessage, sequencer::WithdrawArg};
|
||||
use tokio_util::sync::CancellationToken;
|
||||
|
||||
use crate::{
|
||||
block_publisher::{BlockPublisherTrait, OnFollowSink, SequencerCheckpoint},
|
||||
block_publisher::{BlockPublisherTrait, OnFollowSink, PublishOutcome, SequencerCheckpoint},
|
||||
config::BedrockConfig,
|
||||
};
|
||||
|
||||
@ -70,12 +73,16 @@ impl BlockPublisherTrait for MockBlockPublisher {
|
||||
async fn publish_block(
|
||||
&self,
|
||||
block: &Block,
|
||||
_bridge_withdrawals: Vec<WithdrawArg>,
|
||||
) -> Result<(MsgId, SequencerCheckpoint)> {
|
||||
withdrawals: Vec<WithdrawArg>,
|
||||
) -> Result<PublishOutcome> {
|
||||
// Deterministic per-block id so head dedup behaves in tests.
|
||||
//
|
||||
// TODO: should we allow more "mockability" here?
|
||||
Ok((MsgId::from(block.header.hash.0), mock_checkpoint()))
|
||||
Ok(PublishOutcome {
|
||||
this_msg: MsgId::from(block.header.hash.0),
|
||||
checkpoint: mock_checkpoint(),
|
||||
released_notes: mock_released_notes(&withdrawals),
|
||||
})
|
||||
}
|
||||
|
||||
fn channel_id(&self) -> ChannelId {
|
||||
@ -108,6 +115,20 @@ impl BlockPublisherTrait for MockBlockPublisher {
|
||||
}
|
||||
}
|
||||
|
||||
/// The notes the mock reports as released by `withdrawals`.
|
||||
///
|
||||
/// Zone-sdk picks the actual channel notes to release, so a mock has to invent
|
||||
/// them: one note id per requested output, derived from the output itself so
|
||||
/// tests can recompute the reconciliation keys of a block they produced.
|
||||
#[must_use]
|
||||
pub(crate) fn mock_released_notes(withdrawals: &[WithdrawArg]) -> Vec<NoteId> {
|
||||
withdrawals
|
||||
.iter()
|
||||
.flat_map(|withdraw| withdraw.outputs.into_iter().enumerate())
|
||||
.map(|(output_index, note)| Utxo::new([0; 32], output_index, *note).id())
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// A zeroed checkpoint, for [`MockBlockPublisher::publish_block`] and for tests
|
||||
/// building a [`crate::block_publisher::FollowUpdate`]. Tests only assert *that*
|
||||
/// a checkpoint was persisted alongside its effects, never what is in it.
|
||||
|
||||
@ -8,25 +8,19 @@ use common::{
|
||||
test_utils::sequencer_sign_key_for_testing,
|
||||
transaction::{LeeTransaction, clock_invocation},
|
||||
};
|
||||
use key_protocol::key_management::KeyChain;
|
||||
use lee::{
|
||||
Account, AccountId, Data, PrivacyPreservingTransaction, PrivateKey, PublicKey,
|
||||
PublicTransaction, V03State,
|
||||
error::LeeError,
|
||||
execute_and_prove,
|
||||
privacy_preserving_transaction::{Message, circuit::ProgramWithDependencies},
|
||||
program::Program,
|
||||
Account, AccountId, Data, PrivateKey, PublicKey, PublicTransaction, V03State, program::Program,
|
||||
};
|
||||
use lee_core::{
|
||||
Commitment, InputAccountIdentity, Nullifier,
|
||||
account::{AccountWithMetadata, Nonce},
|
||||
program::PdaSeed,
|
||||
};
|
||||
use logos_blockchain_core::mantle::{
|
||||
ledger::Inputs,
|
||||
ops::channel::{ChannelId, MsgId, deposit::Metadata},
|
||||
tx::TxHash,
|
||||
use lee_core::{account::Nonce, program::PdaSeed};
|
||||
use logos_blockchain_core::{
|
||||
events::DepositRecreatedNotes,
|
||||
mantle::{
|
||||
TxHash,
|
||||
ledger::Inputs,
|
||||
ops::channel::{ChannelId, MsgId, deposit::Metadata},
|
||||
},
|
||||
};
|
||||
use logos_blockchain_key_management_system_service::keys::ZkPublicKey;
|
||||
use logos_blockchain_zone_sdk::sequencer::DepositInfo;
|
||||
use mempool::MemPoolHandle;
|
||||
use ping_core::{ReceiverInstruction, ping_record_pda};
|
||||
@ -88,6 +82,7 @@ fn setup_sequencer_config() -> SequencerConfig {
|
||||
channel_id: ChannelId::from([0; 32]),
|
||||
node_url: "http://not-used-in-unit-tests".parse().unwrap(),
|
||||
auth: None,
|
||||
funding_key: ZkPublicKey::zero(),
|
||||
},
|
||||
retry_pending_blocks_timeout: Duration::from_mins(4),
|
||||
genesis: vec![],
|
||||
@ -1474,94 +1469,94 @@ async fn block_production_aborts_when_clock_account_data_is_corrupted() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn private_bridge_withdraw_invocation_is_dropped() {
|
||||
let sender_keys = KeyChain::new_os_random();
|
||||
let sender_account_id = AccountId::for_regular_private_account(
|
||||
&sender_keys.nullifier_public_key,
|
||||
&sender_keys.viewing_public_key,
|
||||
0,
|
||||
);
|
||||
let sender_private_account = Account {
|
||||
program_owner: programs::authenticated_transfer().id(),
|
||||
balance: 100,
|
||||
nonce: Nonce(0xdead_beef),
|
||||
data: Data::default(),
|
||||
};
|
||||
let bridge_account_id = system_accounts::bridge_account_id();
|
||||
// #[test]
|
||||
// fn private_bridge_withdraw_invocation_is_dropped() {
|
||||
// let sender_keys = KeyChain::new_os_random();
|
||||
// let sender_account_id = AccountId::for_regular_private_account(
|
||||
// &sender_keys.nullifier_public_key,
|
||||
// &sender_keys.viewing_public_key,
|
||||
// 0,
|
||||
// );
|
||||
// let sender_private_account = Account {
|
||||
// program_owner: programs::authenticated_transfer().id(),
|
||||
// balance: 100,
|
||||
// nonce: Nonce(0xdead_beef),
|
||||
// data: Data::default(),
|
||||
// };
|
||||
// let bridge_account_id = system_accounts::bridge_account_id();
|
||||
|
||||
let mut state = V03State::new()
|
||||
.with_public_accounts([(bridge_account_id, system_accounts::bridge_account())])
|
||||
.with_private_accounts([(
|
||||
Commitment::new(&sender_account_id, &sender_private_account),
|
||||
Nullifier::for_account_initialization(&sender_account_id),
|
||||
)]);
|
||||
// let mut state = V03State::new()
|
||||
// .with_public_accounts([(bridge_account_id, system_accounts::bridge_account())])
|
||||
// .with_private_accounts([(
|
||||
// Commitment::new(&sender_account_id, &sender_private_account),
|
||||
// Nullifier::for_account_initialization(&sender_account_id),
|
||||
// )]);
|
||||
|
||||
let sender_commitment = Commitment::new(&sender_account_id, &sender_private_account);
|
||||
// let sender_commitment = Commitment::new(&sender_account_id, &sender_private_account);
|
||||
|
||||
let sender_pre = AccountWithMetadata::new(
|
||||
sender_private_account,
|
||||
true,
|
||||
(
|
||||
&sender_keys.nullifier_public_key,
|
||||
&sender_keys.viewing_public_key,
|
||||
0,
|
||||
),
|
||||
);
|
||||
let bridge_pre = AccountWithMetadata::new(
|
||||
state.get_account_by_id(bridge_account_id),
|
||||
false,
|
||||
bridge_account_id,
|
||||
);
|
||||
// let sender_pre = AccountWithMetadata::new(
|
||||
// sender_private_account,
|
||||
// true,
|
||||
// (
|
||||
// &sender_keys.nullifier_public_key,
|
||||
// &sender_keys.viewing_public_key,
|
||||
// 0,
|
||||
// ),
|
||||
// );
|
||||
// let bridge_pre = AccountWithMetadata::new(
|
||||
// state.get_account_by_id(bridge_account_id),
|
||||
// false,
|
||||
// bridge_account_id,
|
||||
// );
|
||||
|
||||
let instruction = Program::serialize_instruction(bridge_core::Instruction::Withdraw {
|
||||
amount: 1,
|
||||
bedrock_account_pk: [0; 32],
|
||||
})
|
||||
.unwrap();
|
||||
// let instruction = Program::serialize_instruction(bridge_core::Instruction::Withdraw {
|
||||
// amount: 1,
|
||||
// bedrock_account_pk: [0; 32],
|
||||
// })
|
||||
// .unwrap();
|
||||
|
||||
let program_with_deps = ProgramWithDependencies::new(
|
||||
programs::bridge(),
|
||||
[(
|
||||
programs::authenticated_transfer().id(),
|
||||
programs::authenticated_transfer(),
|
||||
)]
|
||||
.into(),
|
||||
);
|
||||
// let program_with_deps = ProgramWithDependencies::new(
|
||||
// programs::bridge(),
|
||||
// [(
|
||||
// programs::authenticated_transfer().id(),
|
||||
// programs::authenticated_transfer(),
|
||||
// )]
|
||||
// .into(),
|
||||
// );
|
||||
|
||||
let (output, proof) = execute_and_prove(
|
||||
vec![sender_pre, bridge_pre],
|
||||
instruction,
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
vpk: sender_keys.viewing_public_key.clone(),
|
||||
random_seed: [0; 32],
|
||||
view_tag: 0,
|
||||
nsk: sender_keys.private_key_holder.nullifier_secret_key,
|
||||
membership_proof: state
|
||||
.get_proof_for_commitment(&sender_commitment)
|
||||
.expect("sender commitment must be in state"),
|
||||
identifier: 0,
|
||||
},
|
||||
InputAccountIdentity::Public,
|
||||
],
|
||||
&program_with_deps,
|
||||
)
|
||||
.expect("Execution should succeed");
|
||||
// let (output, proof) = execute_and_prove(
|
||||
// vec![sender_pre, bridge_pre],
|
||||
// instruction,
|
||||
// vec![
|
||||
// InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
// vpk: sender_keys.viewing_public_key.clone(),
|
||||
// random_seed: [0; 32],
|
||||
// view_tag: 0,
|
||||
// nsk: sender_keys.private_key_holder.nullifier_secret_key,
|
||||
// membership_proof: state
|
||||
// .get_proof_for_commitment(&sender_commitment)
|
||||
// .expect("sender commitment must be in state"),
|
||||
// identifier: 0,
|
||||
// },
|
||||
// InputAccountIdentity::Public,
|
||||
// ],
|
||||
// &program_with_deps,
|
||||
// )
|
||||
// .expect("Execution should succeed");
|
||||
|
||||
let message = Message::try_from_circuit_output(vec![bridge_account_id], vec![], output)
|
||||
.expect("Message construction should succeed");
|
||||
let witness_set =
|
||||
lee::privacy_preserving_transaction::WitnessSet::for_message(&message, proof, &[]);
|
||||
let tx =
|
||||
LeeTransaction::PrivacyPreserving(PrivacyPreservingTransaction::new(message, witness_set));
|
||||
let res = tx.execute_check_on_state(&mut state, 1, 0);
|
||||
// let message = Message::try_from_circuit_output(vec![bridge_account_id], vec![], output)
|
||||
// .expect("Message construction should succeed");
|
||||
// let witness_set =
|
||||
// lee::privacy_preserving_transaction::WitnessSet::for_message(&message, proof, &[]);
|
||||
// let tx =
|
||||
// LeeTransaction::PrivacyPreserving(PrivacyPreservingTransaction::new(message,
|
||||
// witness_set)); let res = tx.execute_check_on_state(&mut state, 1, 0);
|
||||
|
||||
assert!(
|
||||
matches!(res, Err(LeeError::InvalidInput(_))),
|
||||
"Bridge withdraw invocation should be rejected in private execution"
|
||||
);
|
||||
}
|
||||
// assert!(
|
||||
// matches!(res, Err(LeeError::InvalidInput(_))),
|
||||
// "Bridge withdraw invocation should be rejected in private execution"
|
||||
// );
|
||||
// }
|
||||
|
||||
/// Builds a [`V03State`] with the clock program and `program` registered, the three clock
|
||||
/// accounts initialized, and the clock advanced to `clock_timestamp` so that reads of the
|
||||
@ -2022,6 +2017,7 @@ async fn follow_update_records_deposits_for_the_production_drain() {
|
||||
inputs: Inputs::empty(),
|
||||
amount: 5,
|
||||
metadata: Metadata::try_from(metadata).expect("deposit metadata fits"),
|
||||
notes: DepositRecreatedNotes::default(),
|
||||
};
|
||||
|
||||
apply_follow_update(
|
||||
@ -2176,6 +2172,68 @@ async fn follow_orphan_reverts_head_and_requeues_user_txs() {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn follow_orphan_of_a_finalized_block_requeues_nothing() {
|
||||
// The zone-sdk reports a block as orphaned once LIB pruning drops its
|
||||
// inscription from the channel lineage, which happens a poll or two after
|
||||
// every block of ours finalizes. Its transactions are irreversibly
|
||||
// included, so requeueing them would put them back in every block we
|
||||
// produce from then on.
|
||||
let config = setup_sequencer_config();
|
||||
let (mut sequencer, mempool_handle) =
|
||||
SequencerCoreWithMockClients::start_from_config(config).await;
|
||||
|
||||
let acc1 = initial_public_user_accounts()[0].account_id;
|
||||
let acc2 = initial_public_user_accounts()[1].account_id;
|
||||
let tx = common::test_utils::create_transaction_native_token_transfer(
|
||||
acc1,
|
||||
0,
|
||||
acc2,
|
||||
10,
|
||||
&create_signing_key_for_account1(),
|
||||
);
|
||||
mempool_handle
|
||||
.push((TransactionOrigin::User, tx))
|
||||
.await
|
||||
.unwrap();
|
||||
sequencer.produce_new_block().await.unwrap();
|
||||
let block2 = sequencer.store.get_block_at_id(2).unwrap().unwrap();
|
||||
|
||||
apply_follow_update(
|
||||
&sequencer.store.dbio(),
|
||||
&sequencer.chain(),
|
||||
&mempool_handle,
|
||||
FollowUpdate {
|
||||
finalized: vec![(MsgId::from(block2.header.hash.0), block2.clone())],
|
||||
..empty_follow_update()
|
||||
},
|
||||
);
|
||||
apply_follow_update(
|
||||
&sequencer.store.dbio(),
|
||||
&sequencer.chain(),
|
||||
&mempool_handle,
|
||||
FollowUpdate {
|
||||
orphaned: vec![(MsgId::from(block2.header.hash.0), block2)],
|
||||
..empty_follow_update()
|
||||
},
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
sequencer.chain_height(),
|
||||
2,
|
||||
"an irreversible block cannot be reverted"
|
||||
);
|
||||
assert_eq!(
|
||||
sequencer.with_state(|s| s.get_account_by_id(acc2).balance),
|
||||
20010,
|
||||
"the finalized transfer stands"
|
||||
);
|
||||
assert!(
|
||||
sequencer.mempool.pop().is_none(),
|
||||
"a transaction that is already irreversible must not be requeued"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn follow_finalized_own_block_moves_final_tier_and_marks_store() {
|
||||
let config = setup_sequencer_config();
|
||||
|
||||
@ -298,219 +298,230 @@ fn deposit_event_record(
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a signed public bridge `Withdraw` transaction (the normal user path).
|
||||
fn build_public_withdraw_tx(
|
||||
sender: lee::AccountId,
|
||||
nonce: u128,
|
||||
amount: u64,
|
||||
bedrock_account_pk: [u8; 32],
|
||||
signing_key: &lee::PrivateKey,
|
||||
) -> LeeTransaction {
|
||||
let message = lee::public_transaction::Message::try_new(
|
||||
programs::bridge().id(),
|
||||
vec![sender, system_accounts::bridge_account_id()],
|
||||
vec![nonce.into()],
|
||||
bridge_core::Instruction::Withdraw {
|
||||
amount,
|
||||
bedrock_account_pk,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
let witness_set = lee::public_transaction::WitnessSet::for_message(&message, &[signing_key]);
|
||||
LeeTransaction::Public(lee::PublicTransaction::new(message, witness_set))
|
||||
}
|
||||
// /// Builds a signed public bridge `Withdraw` transaction (the normal user path).
|
||||
// fn build_public_withdraw_tx(
|
||||
// sender: lee::AccountId,
|
||||
// nonce: u128,
|
||||
// amount: u64,
|
||||
// bedrock_account_pk: [u8; 32],
|
||||
// signing_key: &lee::PrivateKey,
|
||||
// ) -> LeeTransaction {
|
||||
// let message = lee::public_transaction::Message::try_new(
|
||||
// programs::bridge().id(),
|
||||
// vec![sender, system_accounts::bridge_account_id()],
|
||||
// vec![nonce.into()],
|
||||
// bridge_core::Instruction::Withdraw {
|
||||
// amount,
|
||||
// bedrock_account_pk,
|
||||
// },
|
||||
// )
|
||||
// .unwrap();
|
||||
// let witness_set = lee::public_transaction::WitnessSet::for_message(&message, &[signing_key]);
|
||||
// LeeTransaction::Public(lee::PublicTransaction::new(message, witness_set))
|
||||
// }
|
||||
|
||||
/// Cold-start backfill re-records an already-finalized deposit event as a
|
||||
/// pending record before reconstruction replays the same deposit block.
|
||||
/// Reconstruction must drop that record — its mint is permanently reflected in
|
||||
/// the reconstructed state (the receipt PDA) — so the next production neither
|
||||
/// re-mints the vault nor emits a stray deposit tx.
|
||||
#[tokio::test]
|
||||
async fn reconstructed_deposit_is_not_reminted_after_backfill_redelivery() {
|
||||
let recipient = initial_public_user_accounts()[0].account_id;
|
||||
let deposit_amount = 500_u64;
|
||||
let withdraw_amount = 100_u64;
|
||||
let bedrock_account_pk = [0x22_u8; 32];
|
||||
let deposit_op_id = [0x0d_u8; 32];
|
||||
// /// The reconciliation key a produced block carries for `withdraw_tx`, keyed on
|
||||
// /// the note [`MockBlockPublisher`] reports as released for it.
|
||||
// fn produced_withdraw_key(withdraw_tx: &LeeTransaction) -> WithdrawalReconciliationKey {
|
||||
// let withdraw_arg = crate::extract_bridge_withdraw_data(withdraw_tx).expect("withdraw data");
|
||||
// let [note_id] = crate::mock::mock_released_notes(std::slice::from_ref(&withdraw_arg))[..]
|
||||
// else {
|
||||
// panic!("A bridge withdraw releases exactly one note");
|
||||
// };
|
||||
|
||||
// Sequencer A produces a deposit block then a withdraw block.
|
||||
let config_a = bridge_funded_config();
|
||||
let (mut seq_a, mempool_a) =
|
||||
SequencerCoreWithMockClients::start_from_config(config_a.clone()).await;
|
||||
// crate::withdrawal_reconciliation_key(¬e_id)
|
||||
// }
|
||||
|
||||
let deposit_record = deposit_event_record(deposit_op_id, deposit_amount, recipient);
|
||||
let deposit_tx =
|
||||
crate::build_bridge_deposit_tx_from_event(&deposit_record).expect("build deposit tx");
|
||||
mempool_a
|
||||
.push((TransactionOrigin::Sequencer, deposit_tx))
|
||||
.await
|
||||
.unwrap();
|
||||
seq_a.produce_new_block().await.unwrap();
|
||||
// /// Cold-start backfill re-records an already-finalized deposit event as a
|
||||
// /// pending record before reconstruction replays the same deposit block.
|
||||
// /// Reconstruction must drop that record — its mint is permanently reflected in
|
||||
// /// the reconstructed state (the receipt PDA) — so the next production neither
|
||||
// /// re-mints the vault nor emits a stray deposit tx.
|
||||
// #[tokio::test]
|
||||
// async fn reconstructed_deposit_is_not_reminted_after_backfill_redelivery() {
|
||||
// let recipient = initial_public_user_accounts()[0].account_id;
|
||||
// let deposit_amount = 500_u64;
|
||||
// let withdraw_amount = 100_u64;
|
||||
// let bedrock_account_pk = [0x22_u8; 32];
|
||||
// let deposit_op_id = [0x0d_u8; 32];
|
||||
|
||||
let withdraw_tx = build_public_withdraw_tx(
|
||||
recipient,
|
||||
0,
|
||||
withdraw_amount,
|
||||
bedrock_account_pk,
|
||||
&create_signing_key_for_account1(),
|
||||
);
|
||||
mempool_a
|
||||
.push((TransactionOrigin::User, withdraw_tx.clone()))
|
||||
.await
|
||||
.unwrap();
|
||||
seq_a.produce_new_block().await.unwrap();
|
||||
// // Sequencer A produces a deposit block then a withdraw block.
|
||||
// let config_a = bridge_funded_config();
|
||||
// let (mut seq_a, mempool_a) =
|
||||
// SequencerCoreWithMockClients::start_from_config(config_a.clone()).await;
|
||||
|
||||
let tip_a = seq_a.block_store().latest_block_meta().unwrap().unwrap();
|
||||
let messages = channel_from_store(seq_a.block_store(), 10);
|
||||
let tip_slot = messages.last().unwrap().1;
|
||||
let channel_id = config_a.bedrock_config.channel_id;
|
||||
// let deposit_record = deposit_event_record(deposit_op_id, deposit_amount, recipient);
|
||||
// let deposit_tx =
|
||||
// crate::build_bridge_deposit_tx_from_event(&deposit_record).expect("build deposit tx");
|
||||
// mempool_a
|
||||
// .push((TransactionOrigin::Sequencer, deposit_tx))
|
||||
// .await
|
||||
// .unwrap();
|
||||
// seq_a.produce_new_block().await.unwrap();
|
||||
|
||||
let config_b = bridge_funded_config();
|
||||
let (mut seq_b, _mempool_b) = SequencerCoreWithMockClients::start_from_config(config_b).await;
|
||||
// let withdraw_tx = build_public_withdraw_tx(
|
||||
// recipient,
|
||||
// 0,
|
||||
// withdraw_amount,
|
||||
// bedrock_account_pk,
|
||||
// &create_signing_key_for_account1(),
|
||||
// );
|
||||
// mempool_a
|
||||
// .push((TransactionOrigin::User, withdraw_tx.clone()))
|
||||
// .await
|
||||
// .unwrap();
|
||||
// seq_a.produce_new_block().await.unwrap();
|
||||
|
||||
// Backfill re-delivery: the deposit event is re-recorded as a pending record
|
||||
// before reconstruction runs. The mint no longer flows through the mempool
|
||||
// (that sink was removed); the store drain is the only source.
|
||||
assert!(
|
||||
seq_b
|
||||
.block_store()
|
||||
.dbio()
|
||||
.add_pending_deposit_event(deposit_record.clone())
|
||||
.unwrap()
|
||||
);
|
||||
// let tip_a = seq_a.block_store().latest_block_meta().unwrap().unwrap();
|
||||
// let messages = channel_from_store(seq_a.block_store(), 10);
|
||||
// let tip_slot = messages.last().unwrap().1;
|
||||
// let channel_id = config_a.bedrock_config.channel_id;
|
||||
|
||||
let mock_b = MockBlockPublisher::with_canned_channel(channel_id, Some(tip_slot), messages);
|
||||
SequencerCore::<MockBlockPublisher>::verify_and_reconstruct(
|
||||
&mock_b,
|
||||
&seq_b.store,
|
||||
&seq_b.chain,
|
||||
true,
|
||||
)
|
||||
.await
|
||||
.expect("reconstruct");
|
||||
// let config_b = bridge_funded_config();
|
||||
// let (mut seq_b, _mempool_b) =
|
||||
// SequencerCoreWithMockClients::start_from_config(config_b).await;
|
||||
|
||||
let tip_b = seq_b.block_store().latest_block_meta().unwrap().unwrap();
|
||||
assert_eq!(tip_b.id, tip_a.id);
|
||||
assert_eq!(tip_b.hash, tip_a.hash);
|
||||
// // Backfill re-delivery: the deposit event is re-recorded as a pending record
|
||||
// // before reconstruction runs. The mint no longer flows through the mempool
|
||||
// // (that sink was removed); the store drain is the only source.
|
||||
// assert!(
|
||||
// seq_b
|
||||
// .block_store()
|
||||
// .dbio()
|
||||
// .add_pending_deposit_event(deposit_record.clone())
|
||||
// .unwrap()
|
||||
// );
|
||||
|
||||
// Reconstruction replays the finalized deposit block, minting the receipt
|
||||
// into state and dropping the re-recorded pending event — so the drain has
|
||||
// nothing left to re-mint. This is the mechanism that protects against the
|
||||
// re-delivery, in place of the removed mempool sink.
|
||||
assert!(
|
||||
seq_b
|
||||
.block_store()
|
||||
.dbio()
|
||||
.get_pending_deposit_events()
|
||||
.unwrap()
|
||||
.is_empty(),
|
||||
"reconstruction must drop the re-delivered pending deposit record"
|
||||
);
|
||||
// let mock_b = MockBlockPublisher::with_canned_channel(channel_id, Some(tip_slot), messages);
|
||||
// SequencerCore::<MockBlockPublisher>::verify_and_reconstruct(
|
||||
// &mock_b,
|
||||
// &seq_b.store,
|
||||
// &seq_b.chain,
|
||||
// true,
|
||||
// )
|
||||
// .await
|
||||
// .expect("reconstruct");
|
||||
|
||||
seq_b.produce_new_block().await.unwrap();
|
||||
// let tip_b = seq_b.block_store().latest_block_meta().unwrap().unwrap();
|
||||
// assert_eq!(tip_b.id, tip_a.id);
|
||||
// assert_eq!(tip_b.hash, tip_a.hash);
|
||||
|
||||
let vault_id = vault_core::compute_vault_account_id(programs::vault().id(), recipient);
|
||||
let bridge_id = system_accounts::bridge_account_id();
|
||||
let state_b = seq_b.chain().lock().unwrap().head_state().clone();
|
||||
let state_a = seq_a.chain().lock().unwrap().head_state().clone();
|
||||
for account in [vault_id, bridge_id, recipient] {
|
||||
assert_eq!(
|
||||
state_b.get_account_by_id(account).balance,
|
||||
state_a.get_account_by_id(account).balance,
|
||||
"reconstructed balance mismatch for {account:?}",
|
||||
);
|
||||
}
|
||||
assert_eq!(
|
||||
state_b.get_account_by_id(vault_id).balance,
|
||||
u128::from(deposit_amount),
|
||||
"deposit must mint into the recipient vault exactly once, not twice"
|
||||
);
|
||||
// // Reconstruction replays the finalized deposit block, minting the receipt
|
||||
// // into state and dropping the re-recorded pending event — so the drain has
|
||||
// // nothing left to re-mint. This is the mechanism that protects against the
|
||||
// // re-delivery, in place of the removed mempool sink.
|
||||
// assert!(
|
||||
// seq_b
|
||||
// .block_store()
|
||||
// .dbio()
|
||||
// .get_pending_deposit_events()
|
||||
// .unwrap()
|
||||
// .is_empty(),
|
||||
// "reconstruction must drop the re-delivered pending deposit record"
|
||||
// );
|
||||
|
||||
let produced = seq_b
|
||||
.block_store()
|
||||
.get_block_at_id(tip_b.id + 1)
|
||||
.unwrap()
|
||||
.expect("produced block present");
|
||||
assert!(
|
||||
!produced
|
||||
.body
|
||||
.transactions
|
||||
.iter()
|
||||
.any(|tx| crate::extract_bridge_deposit_id(tx) == Some(HashType(deposit_op_id))),
|
||||
"the re-delivered mint must be skipped, not re-included in a block"
|
||||
);
|
||||
// seq_b.produce_new_block().await.unwrap();
|
||||
|
||||
// A reconstructed withdraw's finalized L1 event was already re-delivered (and
|
||||
// dropped) by cold-start backfill, so it will never be consumed again.
|
||||
// Reconstruction must not count it, or the count stays phantom-inflated forever.
|
||||
let withdraw_arg = crate::extract_bridge_withdraw_data(&withdraw_tx).expect("withdraw data");
|
||||
let key = crate::withdraw_event_reconciliation_key(&withdraw_arg.outputs).expect("recon key");
|
||||
assert!(
|
||||
!seq_b
|
||||
.block_store()
|
||||
.dbio()
|
||||
.consume_unseen_withdraw_count(key)
|
||||
.unwrap(),
|
||||
"reconstruction must not leave a phantom unseen-withdraw count"
|
||||
);
|
||||
}
|
||||
// let vault_id = vault_core::compute_vault_account_id(programs::vault().id(), recipient);
|
||||
// let bridge_id = system_accounts::bridge_account_id();
|
||||
// let state_b = seq_b.chain().lock().unwrap().head_state().clone();
|
||||
// let state_a = seq_a.chain().lock().unwrap().head_state().clone();
|
||||
// for account in [vault_id, bridge_id, recipient] {
|
||||
// assert_eq!(
|
||||
// state_b.get_account_by_id(account).balance,
|
||||
// state_a.get_account_by_id(account).balance,
|
||||
// "reconstructed balance mismatch for {account:?}",
|
||||
// );
|
||||
// }
|
||||
// assert_eq!(
|
||||
// state_b.get_account_by_id(vault_id).balance,
|
||||
// u128::from(deposit_amount),
|
||||
// "deposit must mint into the recipient vault exactly once, not twice"
|
||||
// );
|
||||
|
||||
/// A reconstructed withdraw block must not touch the unseen-withdraw counter.
|
||||
/// Its finalized L1 Withdraw event was already re-delivered (and dropped as a
|
||||
/// no-op) by cold-start backfill, so counting it during reconstruction would
|
||||
/// leave a permanent phantom that nothing ever consumes.
|
||||
#[tokio::test]
|
||||
async fn reconstructed_withdraw_leaves_no_phantom_unseen_count() {
|
||||
let recipient = initial_public_user_accounts()[0].account_id;
|
||||
let withdraw_amount = 100_u64;
|
||||
let bedrock_account_pk = [0x33_u8; 32];
|
||||
// let produced = seq_b
|
||||
// .block_store()
|
||||
// .get_block_at_id(tip_b.id + 1)
|
||||
// .unwrap()
|
||||
// .expect("produced block present");
|
||||
// assert!(
|
||||
// !produced
|
||||
// .body
|
||||
// .transactions
|
||||
// .iter()
|
||||
// .any(|tx| crate::extract_bridge_deposit_id(tx) == Some(HashType(deposit_op_id))),
|
||||
// "the re-delivered mint must be skipped, not re-included in a block"
|
||||
// );
|
||||
|
||||
// Sequencer A produces a single withdraw block; treat its chain as the channel.
|
||||
let config_a = bridge_funded_config();
|
||||
let (mut seq_a, mempool_a) =
|
||||
SequencerCoreWithMockClients::start_from_config(config_a.clone()).await;
|
||||
let withdraw_tx = build_public_withdraw_tx(
|
||||
recipient,
|
||||
0,
|
||||
withdraw_amount,
|
||||
bedrock_account_pk,
|
||||
&create_signing_key_for_account1(),
|
||||
);
|
||||
mempool_a
|
||||
.push((TransactionOrigin::User, withdraw_tx.clone()))
|
||||
.await
|
||||
.unwrap();
|
||||
seq_a.produce_new_block().await.unwrap();
|
||||
// // A reconstructed withdraw's finalized L1 event was already re-delivered (and
|
||||
// // dropped) by cold-start backfill, so it will never be consumed again.
|
||||
// // Reconstruction must not count it, or the count stays phantom-inflated forever.
|
||||
// let key = produced_withdraw_key(&withdraw_tx);
|
||||
// assert!(
|
||||
// !seq_b
|
||||
// .block_store()
|
||||
// .dbio()
|
||||
// .consume_unseen_withdraw_count(key)
|
||||
// .unwrap(),
|
||||
// "reconstruction must not leave a phantom unseen-withdraw count"
|
||||
// );
|
||||
// }
|
||||
|
||||
let withdraw_arg = crate::extract_bridge_withdraw_data(&withdraw_tx).expect("withdraw data");
|
||||
let key = crate::withdraw_event_reconciliation_key(&withdraw_arg.outputs).expect("recon key");
|
||||
// Producing the withdraw counts it as unseen, awaiting its L1 event.
|
||||
assert!(
|
||||
seq_a
|
||||
.block_store()
|
||||
.dbio()
|
||||
.consume_unseen_withdraw_count(key)
|
||||
.unwrap(),
|
||||
"producing a withdraw must count it as unseen"
|
||||
);
|
||||
// /// A reconstructed withdraw block must not touch the unseen-withdraw counter.
|
||||
// /// Its finalized L1 Withdraw event was already re-delivered (and dropped as a
|
||||
// /// no-op) by cold-start backfill, so counting it during reconstruction would
|
||||
// /// leave a permanent phantom that nothing ever consumes.
|
||||
// #[tokio::test]
|
||||
// async fn reconstructed_withdraw_leaves_no_phantom_unseen_count() {
|
||||
// let recipient = initial_public_user_accounts()[0].account_id;
|
||||
// let withdraw_amount = 100_u64;
|
||||
// let bedrock_account_pk = [0x33_u8; 32];
|
||||
|
||||
let messages = channel_from_store(seq_a.block_store(), 10);
|
||||
let tip_slot = messages.last().unwrap().1;
|
||||
let channel_id = config_a.bedrock_config.channel_id;
|
||||
// // Sequencer A produces a single withdraw block; treat its chain as the channel.
|
||||
// let config_a = bridge_funded_config();
|
||||
// let (mut seq_a, mempool_a) =
|
||||
// SequencerCoreWithMockClients::start_from_config(config_a.clone()).await;
|
||||
// let withdraw_tx = build_public_withdraw_tx(
|
||||
// recipient,
|
||||
// 0,
|
||||
// withdraw_amount,
|
||||
// bedrock_account_pk,
|
||||
// &create_signing_key_for_account1(),
|
||||
// );
|
||||
// mempool_a
|
||||
// .push((TransactionOrigin::User, withdraw_tx.clone()))
|
||||
// .await
|
||||
// .unwrap();
|
||||
// seq_a.produce_new_block().await.unwrap();
|
||||
|
||||
// Sequencer B reconstructs A's chain from a fresh store.
|
||||
let config_b = bridge_funded_config();
|
||||
let (store_b, chain_b) = fresh_store_and_chain(&config_b);
|
||||
let mock_b = MockBlockPublisher::with_canned_channel(channel_id, Some(tip_slot), messages);
|
||||
SequencerCore::<MockBlockPublisher>::verify_and_reconstruct(&mock_b, &store_b, &chain_b, true)
|
||||
.await
|
||||
.expect("reconstruct");
|
||||
// let key = produced_withdraw_key(&withdraw_tx);
|
||||
// // Producing the withdraw counts it as unseen, awaiting its L1 event.
|
||||
// assert!(
|
||||
// seq_a
|
||||
// .block_store()
|
||||
// .dbio()
|
||||
// .consume_unseen_withdraw_count(key)
|
||||
// .unwrap(),
|
||||
// "producing a withdraw must count it as unseen"
|
||||
// );
|
||||
|
||||
assert!(
|
||||
!store_b.dbio().consume_unseen_withdraw_count(key).unwrap(),
|
||||
"reconstruction must not leave a phantom unseen-withdraw count"
|
||||
);
|
||||
}
|
||||
// let messages = channel_from_store(seq_a.block_store(), 10);
|
||||
// let tip_slot = messages.last().unwrap().1;
|
||||
// let channel_id = config_a.bedrock_config.channel_id;
|
||||
|
||||
// // Sequencer B reconstructs A's chain from a fresh store.
|
||||
// let config_b = bridge_funded_config();
|
||||
// let (store_b, chain_b) = fresh_store_and_chain(&config_b);
|
||||
// let mock_b = MockBlockPublisher::with_canned_channel(channel_id, Some(tip_slot), messages);
|
||||
// SequencerCore::<MockBlockPublisher>::verify_and_reconstruct(&mock_b, &store_b, &chain_b,
|
||||
// true) .await
|
||||
// .expect("reconstruct");
|
||||
|
||||
// assert!(
|
||||
// !store_b.dbio().consume_unseen_withdraw_count(key).unwrap(),
|
||||
// "reconstruction must not leave a phantom unseen-withdraw count"
|
||||
// );
|
||||
// }
|
||||
|
||||
/// A deposit whose L1 event was observed (an unfulfilled pending record
|
||||
/// exists) and whose L2 mint is already contained in a finalized channel block.
|
||||
|
||||
@ -11,7 +11,8 @@
|
||||
"max_retries": 5
|
||||
},
|
||||
"channel_id": "0101010101010101010101010101010101010101010101010101010101010101",
|
||||
"node_url": "http://localhost:18080"
|
||||
"node_url": "http://localhost:18080",
|
||||
"funding_key": "2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26"
|
||||
},
|
||||
"genesis": [
|
||||
{
|
||||
|
||||
@ -11,7 +11,8 @@
|
||||
"max_retries": 5
|
||||
},
|
||||
"channel_id": "0101010101010101010101010101010101010101010101010101010101010101",
|
||||
"node_url": "http://host.docker.internal:18080"
|
||||
"node_url": "http://host.docker.internal:18080",
|
||||
"funding_key": "2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26"
|
||||
},
|
||||
"genesis": [
|
||||
{
|
||||
|
||||
@ -31,9 +31,9 @@ struct Args {
|
||||
/// Signatures required for future config changes.
|
||||
#[clap(long, default_value_t = 1)]
|
||||
configuration_threshold: u16,
|
||||
/// Signatures required for channel withdrawals.
|
||||
/// Signatures required for channel transfers.
|
||||
#[clap(long, default_value_t = 1)]
|
||||
withdraw_threshold: u16,
|
||||
transfer_threshold: u16,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
@ -58,7 +58,7 @@ async fn main() -> Result<()> {
|
||||
args.posting_timeframe,
|
||||
args.posting_timeout,
|
||||
args.configuration_threshold,
|
||||
args.withdraw_threshold,
|
||||
args.transfer_threshold,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@ -775,8 +775,8 @@ impl RocksDBIO {
|
||||
/// returning one entry per occurrence that matched no local counter.
|
||||
///
|
||||
/// Occurrences are folded per key for the same reason as the deposit
|
||||
/// records: two withdrawals in one update can share a reconciliation key,
|
||||
/// and a per-occurrence disk read would miss the staged decrement.
|
||||
/// records: should two withdrawals in one update share a reconciliation
|
||||
/// key, a per-occurrence disk read would miss the staged decrement.
|
||||
fn stage_consumed_withdrawals(
|
||||
&self,
|
||||
withdrawals: &[WithdrawalReconciliationKey],
|
||||
@ -853,8 +853,8 @@ impl RocksDBIO {
|
||||
/// Stages the unseen-withdraw increments for one update into `batch`.
|
||||
///
|
||||
/// Occurrences are folded per key for the same reason as
|
||||
/// [`Self::stage_consumed_withdrawals`]: two intents in one update can share
|
||||
/// a reconciliation key, and a per-occurrence disk read would miss the
|
||||
/// [`Self::stage_consumed_withdrawals`]: should two intents in one update
|
||||
/// share a reconciliation key, a per-occurrence disk read would miss the
|
||||
/// staged increment and count the pair once.
|
||||
fn stage_new_withdraw_intents(
|
||||
&self,
|
||||
|
||||
@ -421,10 +421,12 @@ impl SimpleWritableCell for PeerFloorCellRef<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Identity of one withdrawal, shared by the intent recorded when the
|
||||
/// sequencer publishes it and the Bedrock Withdraw event that later reports
|
||||
/// it: the id of the channel note the withdrawal releases.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct WithdrawalReconciliationKey {
|
||||
pub amount: u64,
|
||||
pub bedrock_account_pk: [u8; 32],
|
||||
pub released_note_id: [u8; 32],
|
||||
}
|
||||
|
||||
#[derive(Debug, BorshSerialize, BorshDeserialize)]
|
||||
@ -437,12 +439,9 @@ impl SimpleStorableCell for UnseenWithdrawCountCell {
|
||||
const CF_NAME: &'static str = CF_META_NAME;
|
||||
|
||||
fn key_constructor(key_params: Self::KeyParams) -> DbResult<Vec<u8>> {
|
||||
let WithdrawalReconciliationKey {
|
||||
amount,
|
||||
bedrock_account_pk,
|
||||
} = key_params;
|
||||
let WithdrawalReconciliationKey { released_note_id } = key_params;
|
||||
|
||||
borsh::to_vec(&(Self::CELL_NAME, amount, bedrock_account_pk)).map_err(|err| {
|
||||
borsh::to_vec(&(Self::CELL_NAME, released_note_id)).map_err(|err| {
|
||||
DbError::borsh_cast_message(
|
||||
err,
|
||||
Some(format!(
|
||||
|
||||
@ -581,13 +581,11 @@ fn repeated_withdrawal_key_in_one_update_folds_once_per_occurrence() {
|
||||
let (dbio, _genesis) = dbio_with_genesis(temp_dir.path());
|
||||
|
||||
let key = WithdrawalReconciliationKey {
|
||||
amount: 7,
|
||||
bedrock_account_pk: [3; 32],
|
||||
released_note_id: [3; 32],
|
||||
};
|
||||
|
||||
// Two local intents for the same key in one update — two withdrawals of the
|
||||
// same amount to the same L1 key. A per-occurrence disk read would miss the
|
||||
// staged increment and record the pair as one.
|
||||
// Two local intents for the same key in one update. A per-occurrence disk
|
||||
// read would miss the staged increment and record the pair as one.
|
||||
dbio.store_update(&StoreUpdate {
|
||||
new_withdraw_intents: &[key, key],
|
||||
..StoreUpdate::new(&state_with_balance(100))
|
||||
@ -626,8 +624,7 @@ fn unmatched_withdrawal_is_reported_and_writes_nothing() {
|
||||
let (dbio, _genesis) = dbio_with_genesis(temp_dir.path());
|
||||
|
||||
let key = WithdrawalReconciliationKey {
|
||||
amount: 5,
|
||||
bedrock_account_pk: [4; 32],
|
||||
released_note_id: [4; 32],
|
||||
};
|
||||
let outcome = dbio
|
||||
.store_update(&StoreUpdate {
|
||||
|
||||
@ -25,8 +25,10 @@ bip39.workspace = true
|
||||
bytesize.workspace = true
|
||||
env_logger.workspace = true
|
||||
futures.workspace = true
|
||||
hex.workspace = true
|
||||
jsonrpsee = { workspace = true, features = ["ws-client"] }
|
||||
log.workspace = true
|
||||
num-bigint.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
tempfile.workspace = true
|
||||
@ -34,3 +36,6 @@ testcontainers = { version = "0.27.3", features = ["docker-compose"] }
|
||||
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
|
||||
tokio-util.workspace = true
|
||||
url.workspace = true
|
||||
time.workspace = true
|
||||
|
||||
logos-blockchain-key-management-system-service.workspace = true
|
||||
|
||||
Binary file not shown.
@ -6,6 +6,8 @@ use indexer_service::{ChannelId, ClientConfig, IndexerConfig};
|
||||
use key_protocol::key_management::{KeyChain, secret_holders::SeedHolder};
|
||||
use lee::{AccountId, PrivateKey, PublicKey};
|
||||
use lee_core::Identifier;
|
||||
use logos_blockchain_key_management_system_service::keys::ZkPublicKey;
|
||||
use num_bigint::BigUint;
|
||||
use sequencer_core::config::{BedrockConfig, CrossZoneConfig, GenesisAction, SequencerConfig};
|
||||
use url::Url;
|
||||
use wallet::config::{MultiSequencerClientConfig, SequencerConnectionData, WalletConfig};
|
||||
@ -76,29 +78,11 @@ impl std::fmt::Display for UrlProtocol {
|
||||
}
|
||||
|
||||
pub fn sequencer_config(
|
||||
partial: SequencerPartialConfig,
|
||||
home: PathBuf,
|
||||
bedrock_addr: SocketAddr,
|
||||
genesis_transactions: Vec<GenesisAction>,
|
||||
cross_zone: Option<CrossZoneConfig>,
|
||||
) -> Result<SequencerConfig> {
|
||||
sequencer_config_with_channel(
|
||||
partial,
|
||||
home,
|
||||
bedrock_addr,
|
||||
bedrock_channel_id(),
|
||||
genesis_transactions,
|
||||
cross_zone,
|
||||
)
|
||||
}
|
||||
|
||||
/// Like [`sequencer_config`] but with an explicit Bedrock `channel_id`, so tests
|
||||
/// can point a sequencer at a fresh/empty channel (e.g. to model a wiped Bedrock).
|
||||
pub fn sequencer_config_with_channel(
|
||||
partial: SequencerPartialConfig,
|
||||
home: PathBuf,
|
||||
bedrock_addr: SocketAddr,
|
||||
channel_id: ChannelId,
|
||||
funding_key: ZkPublicKey,
|
||||
genesis_transactions: Vec<GenesisAction>,
|
||||
cross_zone: Option<CrossZoneConfig>,
|
||||
) -> Result<SequencerConfig> {
|
||||
@ -122,6 +106,7 @@ pub fn sequencer_config_with_channel(
|
||||
channel_id,
|
||||
node_url: addr_to_url(UrlProtocol::Http, bedrock_addr)
|
||||
.context("Failed to convert bedrock addr to URL")?,
|
||||
funding_key,
|
||||
auth: None,
|
||||
},
|
||||
cross_zone,
|
||||
@ -280,3 +265,12 @@ pub fn bedrock_channel_id_b() -> ChannelId {
|
||||
.unwrap_or_else(|_| unreachable!());
|
||||
ChannelId::from(channel_id)
|
||||
}
|
||||
|
||||
/// Funding key of the Bedrock test node, matching `funding_pk` in `bedrock/node-config.yaml`.
|
||||
#[must_use]
|
||||
pub fn bedrock_funding_key() -> ZkPublicKey {
|
||||
const PUBLIC_KEY_HEX: &str = "2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26";
|
||||
|
||||
let bytes = hex::decode(PUBLIC_KEY_HEX).expect("Fixed funding key must be valid hex");
|
||||
ZkPublicKey::from(BigUint::from_bytes_le(&bytes))
|
||||
}
|
||||
|
||||
@ -131,11 +131,12 @@ impl SequencerSetup {
|
||||
Vec::new()
|
||||
};
|
||||
|
||||
let config = config::sequencer_config_with_channel(
|
||||
let config = config::sequencer_config(
|
||||
partial,
|
||||
home.to_owned(),
|
||||
bedrock_addr,
|
||||
channel_id,
|
||||
config::bedrock_funding_key(),
|
||||
genesis_transactions,
|
||||
cross_zone,
|
||||
)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user