refactor(testing-framework): scaffold source-orchestrated runtime model

This commit is contained in:
andrussal 2026-02-19 06:30:43 +01:00
parent 6c52dc6e31
commit ad8381ab68
25 changed files with 1246 additions and 208 deletions

309
Cargo.lock generated
View File

@ -483,6 +483,40 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "155a5a185e42c6b77ac7b88a15143d930a9e9727a5b7b77eed417404ab15c247"
[[package]]
name = "astro-float"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96034cc871c05bb65ad7fb77e6a8bebf45d8b055ed0311769e2f83a1d373c1ec"
dependencies = [
"astro-float-macro",
"astro-float-num",
]
[[package]]
name = "astro-float-macro"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05cfe0f6df5a74fb25b9e713470ad77e091f35f798730673c8772f26ed438963"
dependencies = [
"astro-float-num",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "astro-float-num"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86887daca11d02e0b04f37a9cb81888aae881397fb48ff66494e356aea97554a"
dependencies = [
"itertools 0.10.5",
"lazy_static",
"rand 0.8.5",
"serde",
]
[[package]]
name = "async-channel"
version = "2.5.0"
@ -533,28 +567,6 @@ dependencies = [
"syn 2.0.114",
]
[[package]]
name = "async-stream"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476"
dependencies = [
"async-stream-impl",
"futures-core",
"pin-project-lite",
]
[[package]]
name = "async-stream-impl"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.114",
]
[[package]]
name = "async-trait"
version = "0.1.89"
@ -1952,19 +1964,13 @@ dependencies = [
"futures-core",
"futures-sink",
"http 1.4.0",
"indexmap 2.13.0",
"indexmap",
"slab",
"tokio",
"tokio-util",
"tracing",
]
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "hashbrown"
version = "0.13.2"
@ -2579,16 +2585,6 @@ version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5"
[[package]]
name = "indexmap"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
"hashbrown 0.12.3",
]
[[package]]
name = "indexmap"
version = "2.13.0"
@ -3421,7 +3417,7 @@ checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
name = "logos-blockchain-api-service"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"async-trait",
"bytes",
@ -3448,7 +3444,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-blend"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"logos-blockchain-blend-crypto",
"logos-blockchain-blend-message",
@ -3460,7 +3456,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-blend-crypto"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"blake2",
"logos-blockchain-groth16",
@ -3474,7 +3470,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-blend-message"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"blake2",
"derivative",
@ -3496,7 +3492,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-blend-network"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"either",
"futures",
@ -3514,13 +3510,15 @@ dependencies = [
[[package]]
name = "logos-blockchain-blend-proofs"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"ed25519-dalek",
"generic-array 1.3.5",
"logos-blockchain-blend-crypto",
"logos-blockchain-groth16",
"logos-blockchain-pol",
"logos-blockchain-poq",
"logos-blockchain-utils",
"num-bigint",
"serde",
"thiserror 1.0.69",
@ -3529,7 +3527,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-blend-scheduling"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"async-trait",
"derivative",
@ -3553,7 +3551,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-blend-service"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"async-trait",
"fork_stream",
@ -3588,7 +3586,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-chain-broadcast-service"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"async-trait",
"derivative",
@ -3604,7 +3602,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-chain-leader-service"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"async-trait",
"futures",
@ -3632,7 +3630,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-chain-network-service"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"async-trait",
"futures",
@ -3660,7 +3658,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-chain-service"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"async-trait",
"bytes",
@ -3690,7 +3688,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-chain-service-common"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"logos-blockchain-core",
"serde",
@ -3699,7 +3697,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-circuits-prover"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"logos-blockchain-circuits-utils",
"tempfile",
@ -3708,7 +3706,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-circuits-utils"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"dirs",
]
@ -3716,7 +3714,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-common-http-client"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"futures",
"hex",
@ -3736,7 +3734,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-core"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"ark-ff 0.4.2",
"bincode",
@ -3766,9 +3764,10 @@ dependencies = [
[[package]]
name = "logos-blockchain-cryptarchia-engine"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"cfg_eval",
"logos-blockchain-pol",
"logos-blockchain-utils",
"serde",
"serde_with",
@ -3781,7 +3780,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-cryptarchia-sync"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"bytes",
"futures",
@ -3800,7 +3799,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-groth16"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"ark-bn254 0.4.0",
"ark-ec 0.4.2",
@ -3818,7 +3817,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-http-api-common"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"axum",
"logos-blockchain-core",
@ -3832,7 +3831,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-key-management-system-keys"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"async-trait",
"bytes",
@ -3857,7 +3856,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-key-management-system-macros"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"proc-macro2",
"quote",
@ -3867,7 +3866,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-key-management-system-operators"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"async-trait",
"logos-blockchain-blend-proofs",
@ -3883,7 +3882,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-key-management-system-service"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"async-trait",
"log",
@ -3899,7 +3898,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-ledger"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"derivative",
"logos-blockchain-blend-crypto",
@ -3923,7 +3922,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-libp2p"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"async-trait",
"backon",
@ -3952,7 +3951,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-network-service"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"async-trait",
"futures",
@ -3971,7 +3970,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-node"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"async-trait",
"axum",
@ -4033,7 +4032,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-poc"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"logos-blockchain-circuits-prover",
"logos-blockchain-circuits-utils",
@ -4049,11 +4048,13 @@ dependencies = [
[[package]]
name = "logos-blockchain-pol"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"astro-float",
"logos-blockchain-circuits-prover",
"logos-blockchain-circuits-utils",
"logos-blockchain-groth16",
"logos-blockchain-utils",
"logos-blockchain-witness-generator",
"num-bigint",
"num-traits",
@ -4066,7 +4067,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-poq"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"logos-blockchain-circuits-prover",
"logos-blockchain-circuits-utils",
@ -4083,7 +4084,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-poseidon2"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"ark-bn254 0.4.0",
"ark-ff 0.4.2",
@ -4094,7 +4095,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-sdp-service"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"async-trait",
"futures",
@ -4110,7 +4111,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-services-utils"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"async-trait",
"futures",
@ -4125,7 +4126,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-storage-service"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"async-trait",
"bytes",
@ -4143,7 +4144,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-system-sig-service"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"async-ctrlc",
"async-trait",
@ -4154,7 +4155,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-time-service"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"async-trait",
"cfg_eval",
@ -4176,15 +4177,15 @@ dependencies = [
[[package]]
name = "logos-blockchain-tracing"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"opentelemetry",
"opentelemetry-appender-tracing",
"opentelemetry-http",
"opentelemetry-otlp",
"opentelemetry-semantic-conventions",
"opentelemetry_sdk",
"rand 0.8.5",
"reqwest",
"serde",
"tokio",
"tracing",
@ -4199,7 +4200,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-tracing-service"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"async-trait",
"logos-blockchain-tracing",
@ -4213,7 +4214,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-tui-zone"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"clap",
"hex",
@ -4230,7 +4231,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-tx-service"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"async-trait",
"futures",
@ -4252,7 +4253,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-utils"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"async-trait",
"blake2",
@ -4269,7 +4270,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-utxotree"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"ark-ff 0.4.2",
"logos-blockchain-groth16",
@ -4283,7 +4284,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-wallet"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"logos-blockchain-core",
"logos-blockchain-key-management-system-keys",
@ -4298,7 +4299,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-wallet-service"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"async-trait",
"bytes",
@ -4323,7 +4324,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-witness-generator"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"tempfile",
]
@ -4331,7 +4332,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-zksign"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"logos-blockchain-circuits-prover",
"logos-blockchain-circuits-utils",
@ -4348,7 +4349,7 @@ dependencies = [
[[package]]
name = "logos-blockchain-zone-sdk"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"futures",
"logos-blockchain-common-http-client",
@ -4368,7 +4369,7 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdc38a304f59a03e6efa3876766a48c70a766a93f88341c3fff4212834b8e327"
dependencies = [
"prost",
"prost 0.13.5",
"prost-types",
]
@ -4909,23 +4910,34 @@ dependencies = [
[[package]]
name = "opentelemetry"
version = "0.26.0"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "570074cc999d1a58184080966e5bd3bf3a9a4af650c3b05047c2621e7405cd17"
checksum = "b84bcd6ae87133e903af7ef497404dda70c60d0ea14895fc8a5e6722754fc2a0"
dependencies = [
"futures-core",
"futures-sink",
"js-sys",
"once_cell",
"pin-project-lite",
"thiserror 1.0.69",
"thiserror 2.0.18",
]
[[package]]
name = "opentelemetry-appender-tracing"
version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef6a1ac5ca3accf562b8c306fa8483c85f4390f768185ab775f242f7fe8fdcc2"
dependencies = [
"opentelemetry",
"tracing",
"tracing-core",
"tracing-subscriber 0.3.22",
]
[[package]]
name = "opentelemetry-http"
version = "0.26.0"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6351496aeaa49d7c267fb480678d85d1cd30c5edb20b497c48c56f62a8c14b99"
checksum = "d7a6d09a73194e6b66df7c8f1b680f156d916a1a942abf2de06823dd02b7855d"
dependencies = [
"async-trait",
"bytes",
@ -4936,57 +4948,53 @@ dependencies = [
[[package]]
name = "opentelemetry-otlp"
version = "0.26.0"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29e1f9c8b032d4f635c730c0efcf731d5e2530ea13fa8bef7939ddc8420696bd"
checksum = "7a2366db2dca4d2ad033cad11e6ee42844fd727007af5ad04a1730f4cb8163bf"
dependencies = [
"async-trait",
"futures-core",
"http 1.4.0",
"opentelemetry",
"opentelemetry-http",
"opentelemetry-proto",
"opentelemetry_sdk",
"prost",
"thiserror 1.0.69",
"prost 0.14.3",
"thiserror 2.0.18",
"tokio",
"tonic",
]
[[package]]
name = "opentelemetry-proto"
version = "0.26.1"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9d3968ce3aefdcca5c27e3c4ea4391b37547726a70893aab52d3de95d5f8b34"
checksum = "a7175df06de5eaee9909d4805a3d07e28bb752c34cab57fa9cff549da596b30f"
dependencies = [
"opentelemetry",
"opentelemetry_sdk",
"prost",
"prost 0.14.3",
"tonic",
"tonic-prost",
]
[[package]]
name = "opentelemetry-semantic-conventions"
version = "0.26.0"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db945c1eaea8ac6a9677185357480d215bb6999faa9f691d0c4d4d641eab7a09"
checksum = "e62e29dfe041afb8ed2a6c9737ab57db4907285d999ef8ad3a59092a36bdc846"
[[package]]
name = "opentelemetry_sdk"
version = "0.26.0"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2c627d9f4c9cdc1f21a29ee4bfbd6028fcb8bcf2a857b43f3abdf72c9c862f3"
checksum = "e14ae4f5991976fd48df6d843de219ca6d31b01daaab2dad5af2badeded372bd"
dependencies = [
"async-trait",
"futures-channel",
"futures-executor",
"futures-util",
"glob",
"once_cell",
"opentelemetry",
"percent-encoding",
"rand 0.8.5",
"thiserror 1.0.69",
"rand 0.9.2",
"thiserror 2.0.18",
"tokio",
"tokio-stream",
]
@ -5394,7 +5402,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5"
dependencies = [
"bytes",
"prost-derive",
"prost-derive 0.13.5",
]
[[package]]
name = "prost"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568"
dependencies = [
"bytes",
"prost-derive 0.14.3",
]
[[package]]
@ -5410,13 +5428,26 @@ dependencies = [
"syn 2.0.114",
]
[[package]]
name = "prost-derive"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b"
dependencies = [
"anyhow",
"itertools 0.10.5",
"proc-macro2",
"quote",
"syn 2.0.114",
]
[[package]]
name = "prost-types"
version = "0.13.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16"
dependencies = [
"prost",
"prost 0.13.5",
]
[[package]]
@ -6184,7 +6215,7 @@ version = "0.9.34+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
dependencies = [
"indexmap 2.13.0",
"indexmap",
"itoa",
"ryu",
"serde",
@ -6562,7 +6593,7 @@ dependencies = [
[[package]]
name = "testing_framework"
version = "0.1.0"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=a4275d00eb3041ed6bfb394e0913cd1ad172224c#a4275d00eb3041ed6bfb394e0913cd1ad172224c"
source = "git+https://github.com/logos-blockchain/logos-blockchain.git?rev=41ea1e3082526bb271e655cddb95a5b448e7de20#41ea1e3082526bb271e655cddb95a5b448e7de20"
dependencies = [
"anyhow",
"async-trait",
@ -6834,7 +6865,7 @@ version = "0.23.10+spec-1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269"
dependencies = [
"indexmap 2.13.0",
"indexmap",
"toml_datetime",
"toml_parser",
"winnow",
@ -6851,16 +6882,13 @@ dependencies = [
[[package]]
name = "tonic"
version = "0.12.3"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52"
checksum = "7f32a6f80051a4111560201420c7885d0082ba9efe2ab61875c587bb6b18b9a0"
dependencies = [
"async-stream",
"async-trait",
"axum",
"base64 0.22.1",
"bytes",
"h2",
"http 1.4.0",
"http-body 1.0.1",
"http-body-util",
@ -6869,16 +6897,26 @@ dependencies = [
"hyper-util",
"percent-encoding",
"pin-project",
"prost",
"socket2 0.5.10",
"sync_wrapper",
"tokio",
"tokio-stream",
"tower 0.4.13",
"tower 0.5.3",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tonic-prost"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f86539c0089bfd09b1f8c0ab0239d80392af74c21bc9e0f15e1b4aca4c1647f"
dependencies = [
"bytes",
"prost 0.14.3",
"tonic",
]
[[package]]
name = "tower"
version = "0.4.13"
@ -6887,11 +6925,8 @@ checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
dependencies = [
"futures-core",
"futures-util",
"indexmap 1.9.3",
"pin-project",
"pin-project-lite",
"rand 0.8.5",
"slab",
"tokio",
"tokio-util",
"tower-layer",
@ -6907,11 +6942,15 @@ checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4"
dependencies = [
"futures-core",
"futures-util",
"indexmap",
"pin-project-lite",
"slab",
"sync_wrapper",
"tokio",
"tokio-util",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
@ -7091,14 +7130,12 @@ dependencies = [
[[package]]
name = "tracing-opentelemetry"
version = "0.27.0"
version = "0.32.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc58af5d3f6c5811462cabb3289aec0093f7338e367e5a33d28c0433b3c7360b"
checksum = "1ac28f2d093c6c477eaa76b23525478f38de514fa9aeb1285738d4b97a9552fc"
dependencies = [
"js-sys",
"once_cell",
"opentelemetry",
"opentelemetry_sdk",
"smallvec",
"tracing",
"tracing-core",
@ -7258,7 +7295,7 @@ version = "4.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5afb1a60e207dca502682537fefcfd9921e71d0b83e9576060f09abc6efab23"
dependencies = [
"indexmap 2.13.0",
"indexmap",
"serde",
"serde_json",
"utoipa-gen",
@ -8066,7 +8103,7 @@ dependencies = [
"crossbeam-utils",
"displaydoc",
"flate2",
"indexmap 2.13.0",
"indexmap",
"num_enum",
"thiserror 1.0.69",
]

View File

@ -33,7 +33,7 @@ all = "allow"
# Local testing framework crates
cfgsync-core = { default-features = false, path = "testing-framework/tools/cfgsync-core" }
lb-ext = { default-features = false, path = "logos/runtime/ext" }
lb-framework = { default-features = false, package = "testing_framework", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
lb-framework = { default-features = false, package = "testing_framework", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
lb-workloads = { default-features = false, path = "logos/runtime/workloads" }
testing-framework-core = { default-features = false, path = "testing-framework/core" }
testing-framework-env = { default-features = false, path = "logos/runtime/env" }
@ -42,44 +42,44 @@ testing-framework-runner-k8s = { default-features = false, path = "testing-f
testing-framework-runner-local = { default-features = false, path = "testing-framework/deployers/local" }
# Logos dependencies (from logos-blockchain master @ deccbb2d2)
broadcast-service = { default-features = false, package = "logos-blockchain-chain-broadcast-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
broadcast-service = { default-features = false, package = "logos-blockchain-chain-broadcast-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
cfgsync_runtime = { default-features = false, package = "cfgsync-runtime", path = "testing-framework/tools/cfgsync-runtime" }
chain-leader = { default-features = false, features = [
"pol-dev-mode",
], package = "logos-blockchain-chain-leader-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
chain-network = { default-features = false, package = "logos-blockchain-chain-network-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
chain-service = { default-features = false, package = "logos-blockchain-chain-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
common-http-client = { default-features = false, package = "logos-blockchain-common-http-client", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
cryptarchia-engine = { default-features = false, package = "logos-blockchain-cryptarchia-engine", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
cryptarchia-sync = { default-features = false, package = "logos-blockchain-cryptarchia-sync", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
groth16 = { default-features = false, package = "logos-blockchain-groth16", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
key-management-system-service = { default-features = false, package = "logos-blockchain-key-management-system-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
nomos-api = { default-features = false, package = "logos-blockchain-api-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
nomos-blend-message = { default-features = false, package = "logos-blockchain-blend-message", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
nomos-blend-service = { default-features = false, package = "logos-blockchain-blend-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
nomos-core = { default-features = false, package = "logos-blockchain-core", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
nomos-http-api-common = { default-features = false, package = "logos-blockchain-http-api-common", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
nomos-ledger = { default-features = false, package = "logos-blockchain-ledger", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
nomos-libp2p = { default-features = false, package = "logos-blockchain-libp2p", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
nomos-network = { default-features = false, package = "logos-blockchain-network-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
], package = "logos-blockchain-chain-leader-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
chain-network = { default-features = false, package = "logos-blockchain-chain-network-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
chain-service = { default-features = false, package = "logos-blockchain-chain-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
common-http-client = { default-features = false, package = "logos-blockchain-common-http-client", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
cryptarchia-engine = { default-features = false, package = "logos-blockchain-cryptarchia-engine", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
cryptarchia-sync = { default-features = false, package = "logos-blockchain-cryptarchia-sync", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
groth16 = { default-features = false, package = "logos-blockchain-groth16", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
key-management-system-service = { default-features = false, package = "logos-blockchain-key-management-system-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
nomos-api = { default-features = false, package = "logos-blockchain-api-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
nomos-blend-message = { default-features = false, package = "logos-blockchain-blend-message", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
nomos-blend-service = { default-features = false, package = "logos-blockchain-blend-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
nomos-core = { default-features = false, package = "logos-blockchain-core", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
nomos-http-api-common = { default-features = false, package = "logos-blockchain-http-api-common", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
nomos-ledger = { default-features = false, package = "logos-blockchain-ledger", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
nomos-libp2p = { default-features = false, package = "logos-blockchain-libp2p", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
nomos-network = { default-features = false, package = "logos-blockchain-network-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
nomos-node = { default-features = false, features = [
"testing",
], package = "logos-blockchain-node", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
nomos-sdp = { default-features = false, package = "logos-blockchain-sdp-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
nomos-time = { default-features = false, package = "logos-blockchain-time-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
nomos-tracing = { default-features = false, package = "logos-blockchain-tracing", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
nomos-tracing-service = { default-features = false, package = "logos-blockchain-tracing-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
nomos-utils = { default-features = false, package = "logos-blockchain-utils", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
nomos-wallet = { default-features = false, package = "logos-blockchain-wallet-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
poc = { default-features = false, package = "logos-blockchain-poc", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
pol = { default-features = false, package = "logos-blockchain-pol", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
tx-service = { default-features = false, package = "logos-blockchain-tx-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
wallet = { default-features = false, package = "logos-blockchain-wallet", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
zksign = { default-features = false, package = "logos-blockchain-zksign", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
], package = "logos-blockchain-node", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
nomos-sdp = { default-features = false, package = "logos-blockchain-sdp-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
nomos-time = { default-features = false, package = "logos-blockchain-time-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
nomos-tracing = { default-features = false, package = "logos-blockchain-tracing", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
nomos-tracing-service = { default-features = false, package = "logos-blockchain-tracing-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
nomos-utils = { default-features = false, package = "logos-blockchain-utils", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
nomos-wallet = { default-features = false, package = "logos-blockchain-wallet-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
poc = { default-features = false, package = "logos-blockchain-poc", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
pol = { default-features = false, package = "logos-blockchain-pol", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
tx-service = { default-features = false, package = "logos-blockchain-tx-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
wallet = { default-features = false, package = "logos-blockchain-wallet", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
zksign = { default-features = false, package = "logos-blockchain-zksign", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
# lb_* aliases (nomos-node repo naming)
lb_http_api_common = { default-features = false, package = "logos-blockchain-http-api-common", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
lb_tracing = { default-features = false, package = "logos-blockchain-tracing", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
lb_tracing_service = { default-features = false, package = "logos-blockchain-tracing-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "a4275d00eb3041ed6bfb394e0913cd1ad172224c" }
lb_http_api_common = { default-features = false, package = "logos-blockchain-http-api-common", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
lb_tracing = { default-features = false, package = "logos-blockchain-tracing", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
lb_tracing_service = { default-features = false, package = "logos-blockchain-tracing-service", git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "41ea1e3082526bb271e655cddb95a5b448e7de20" }
# External crates
async-trait = { default-features = false, version = "0.1" }
bytes = { default-features = false, version = "1.3" }

View File

@ -17,11 +17,11 @@ flowchart TD
BO[Bootstrap Orchestrator]
A --> B[Managed Nodes Spec\ncount/config/patches]
A --> C[Attach Spec\nprovider + selector]
A --> C[Attach Spec\ntyped k8s/compose source]
A --> D[External Nodes Spec\nstatic endpoints]
B --> E[Deployer\nlocal/docker/k8s]
C --> F[AttachProvider\nstatic/k8s/compose/...]
C --> F[AttachProvider\nk8s/compose/...]
D --> BO
E --> G[Managed Node Handles\norigin=Managed, ownership=Owned]
@ -147,7 +147,7 @@ This keeps scenario logic reusable while preserving explicit safety boundaries.
- **Node identity**: use `peer_id` as canonical key; fallback to `(host, port)` only when peer id is unavailable.
- **Dedup merge**: if same canonical identity appears from multiple sources, keep one handle and record all origins for diagnostics.
- **Bootstrap peers**: every managed node gets at least 2 seed peers from distinct origins when possible.
- **Readiness gate**: default to quorum (`>= 2` or `>= 50%`, whichever is greater); allow strict-all via scenario override.
- **Readiness gate**: phase 1 default is `AllReady` (all known nodes must pass readiness). Keep policy extensible for `Quorum` and future `SourceAware` readiness.
- **Borrowed node safety**: lifecycle and config patch disabled by default for borrowed nodes; explicit opt-in required.
- **Compatibility preflight**: enforce matching chain/network id + protocol version before scenario start.
- **Failure handling**:
@ -156,6 +156,20 @@ This keeps scenario logic reusable while preserving explicit safety boundaries.
- partial attach discovery: warn + continue only if readiness quorum still satisfiable
- **Cleanup**: delete owned artifacts only; never mutate or delete borrowed node resources.
## Source Combination Modes
Use a typed source enum so invalid combinations are unrepresentable:
- `Managed { external }`: deployer-managed nodes with optional external overlays.
- `Attached { attach, external }`: attached cluster with optional external overlays.
- `ExternalOnly { external }`: explicit external-only mode.
Validation rules:
- `Managed` requires managed deployment to produce nodes (`managed_count > 0`).
- `Attached` requires managed deployment to produce zero nodes (`managed + attached` is disallowed).
- `ExternalOnly` requires non-empty `external` and zero managed nodes.
## Clean Codebase Layout (Recommended)
Use a layered module structure so responsibilities stay isolated.
@ -220,3 +234,17 @@ These changes help future external-network support while preserving current publ
- Add internal node metadata (`origin`, `ownership`, `capabilities`) defaulted to managed semantics.
- Standardize node identity and dedup helpers (`peer_id` preferred, endpoint fallback).
- Keep current env vars/flags intact, but parse via a single typed config layer.
- Add a single source-orchestration match path (`ScenarioSources`) inside deployers; unsupported source modes fail fast with typed errors until attach/external registration lands.
## Open Risks and Required Clarifications
Before full rollout, lock these semantics explicitly:
- **Source enum precedence**: typed `ScenarioSources` variants are the primary control plane. Runtime counts validate, but never redefine, source intent.
- **Ownership conflict resolution**: define behavior when a deduped node appears from multiple sources with different ownership (for example, fail-fast by default; optional override if needed).
- **Source-aware readiness**: avoid quorum rules that can hide managed deployment failures. Require per-source readiness constraints (for example, minimum managed-ready + global quorum).
- **Readiness rollout**: phase 1 uses `AllReady`; later rollout can add `SourceAware` constraints once mixed-source behavior is validated.
- **Bootstrap mutation boundary**: peer/bootstrap policy mutates managed nodes only unless an attach provider explicitly supports controlled mutation.
- **Compatibility contract expansion**: preflight checks should include API/auth/genesis compatibility class, not only network/protocol identifiers.
- **Deterministic membership policy**: define strict vs degradable attach behavior so partial discovery does not silently change scenario semantics.
- **Step migration boundary**: after `NodeInventory` handoff, scenario steps must not read deployer-specific state directly.

View File

@ -16,6 +16,18 @@ pub trait Application: Send + Sync + 'static {
type FeedRuntime: FeedRuntime;
/// Optional stable node identity (for example a peer id) used for
/// deduplication when nodes are discovered from multiple sources.
fn node_peer_identity(_client: &Self::NodeClient) -> Option<String> {
None
}
/// Optional endpoint identity used as a dedup fallback when no peer id is
/// available.
fn node_endpoint_identity(_client: &Self::NodeClient) -> Option<String> {
None
}
async fn prepare_feed(
client: Self::NodeClient,
) -> Result<(<Self::FeedRuntime as FeedRuntime>::Feed, Self::FeedRuntime), DynError>;

View File

@ -4,9 +4,16 @@ use thiserror::Error;
use tracing::{debug, info};
use super::{
Application, DeploymentPolicy, DynError, HttpReadinessRequirement, NodeControlCapability,
ObservabilityCapability, builder_ops::CoreBuilderAccess, expectation::Expectation,
runtime::context::RunMetrics, workload::Workload,
Application, AttachSource, DeploymentPolicy, DynError, ExternalNodeSource,
HttpReadinessRequirement, NodeControlCapability, ObservabilityCapability, ScenarioSources,
SourceReadinessPolicy,
builder_ops::CoreBuilderAccess,
expectation::Expectation,
runtime::{
context::RunMetrics,
orchestration::{SourceModeName, SourceOrchestrationPlan, SourceOrchestrationPlanError},
},
workload::Workload,
};
use crate::topology::{DeploymentDescriptor, DeploymentProvider, DeploymentSeed, DynTopologyError};
@ -21,6 +28,10 @@ pub enum ScenarioBuildError {
WorkloadInit { name: String, source: DynError },
#[error("expectation '{name}' failed to initialize")]
ExpectationInit { name: String, source: DynError },
#[error("invalid scenario source configuration: {message}")]
SourceConfiguration { message: String },
#[error("scenario source mode '{mode}' is not wired into deployers yet")]
SourceModeNotWiredYet { mode: &'static str },
}
/// Immutable scenario definition used by the runner, workloads, and
@ -32,6 +43,8 @@ pub struct Scenario<E: Application, Caps = ()> {
duration: Duration,
expectation_cooldown: Duration,
deployment_policy: DeploymentPolicy,
sources: ScenarioSources,
source_readiness_policy: SourceReadinessPolicy,
capabilities: Caps,
}
@ -43,6 +56,8 @@ impl<E: Application, Caps> Scenario<E, Caps> {
duration: Duration,
expectation_cooldown: Duration,
deployment_policy: DeploymentPolicy,
sources: ScenarioSources,
source_readiness_policy: SourceReadinessPolicy,
capabilities: Caps,
) -> Self {
Self {
@ -52,6 +67,8 @@ impl<E: Application, Caps> Scenario<E, Caps> {
duration,
expectation_cooldown,
deployment_policy,
sources,
source_readiness_policy,
capabilities,
}
}
@ -96,6 +113,20 @@ impl<E: Application, Caps> Scenario<E, Caps> {
self.deployment_policy
}
#[must_use]
/// Selected source readiness policy.
///
/// This is currently reserved for future mixed-source orchestration and
/// does not change runtime behavior yet.
pub const fn source_readiness_policy(&self) -> SourceReadinessPolicy {
self.source_readiness_policy
}
#[must_use]
pub fn sources(&self) -> &ScenarioSources {
&self.sources
}
#[must_use]
pub const fn capabilities(&self) -> &Caps {
&self.capabilities
@ -111,6 +142,8 @@ pub struct Builder<E: Application, Caps = ()> {
duration: Duration,
expectation_cooldown: Option<Duration>,
deployment_policy: DeploymentPolicy,
sources: ScenarioSources,
source_readiness_policy: SourceReadinessPolicy,
capabilities: Caps,
}
@ -205,6 +238,26 @@ macro_rules! impl_common_builder_methods {
self.map_core_builder(|builder| builder.with_deployment_policy(policy))
}
#[must_use]
pub fn with_attach_source(self, attach: AttachSource) -> Self {
self.map_core_builder(|builder| builder.with_attach_source(attach))
}
#[must_use]
pub fn with_external_node(self, node: ExternalNodeSource) -> Self {
self.map_core_builder(|builder| builder.with_external_node(node))
}
#[must_use]
pub fn with_source_readiness_policy(self, policy: SourceReadinessPolicy) -> Self {
self.map_core_builder(|builder| builder.with_source_readiness_policy(policy))
}
#[must_use]
pub fn with_external_only_sources(self) -> Self {
self.map_core_builder(|builder| builder.with_external_only_sources())
}
#[must_use]
pub fn run_duration(&self) -> Duration {
self.core_builder_ref().run_duration()
@ -288,6 +341,8 @@ impl<E: Application, Caps: Default> Builder<E, Caps> {
duration: Duration::ZERO,
expectation_cooldown: None,
deployment_policy: DeploymentPolicy::default(),
sources: ScenarioSources::default(),
source_readiness_policy: SourceReadinessPolicy::default(),
capabilities: Caps::default(),
}
}
@ -389,6 +444,8 @@ impl<E: Application, Caps> Builder<E, Caps> {
duration,
expectation_cooldown,
deployment_policy,
sources,
source_readiness_policy,
..
} = self;
@ -400,6 +457,8 @@ impl<E: Application, Caps> Builder<E, Caps> {
duration,
expectation_cooldown,
deployment_policy,
sources,
source_readiness_policy,
capabilities,
}
}
@ -500,6 +559,34 @@ impl<E: Application, Caps> Builder<E, Caps> {
self
}
#[must_use]
pub fn with_attach_source(mut self, attach: AttachSource) -> Self {
self.sources.set_attach(attach);
self
}
#[must_use]
pub fn with_external_node(mut self, node: ExternalNodeSource) -> Self {
self.sources.add_external_node(node);
self
}
#[must_use]
/// Configure source readiness policy metadata.
///
/// This is currently reserved for future mixed-source orchestration and
/// does not change runtime behavior yet.
pub fn with_source_readiness_policy(mut self, policy: SourceReadinessPolicy) -> Self {
self.source_readiness_policy = policy;
self
}
#[must_use]
pub fn with_external_only_sources(mut self) -> Self {
self.sources.set_external_only();
self
}
fn add_workload(&mut self, workload: Box<dyn Workload<E>>) {
self.expectations.extend(workload.expectations());
self.workloads.push(workload);
@ -517,6 +604,11 @@ impl<E: Application, Caps> Builder<E, Caps> {
let descriptors = parts.resolve_deployment()?;
let run_plan = parts.run_plan();
let run_metrics = RunMetrics::new(run_plan.duration);
let _source_plan = build_source_orchestration_plan(
parts.sources(),
descriptors.node_count(),
parts.source_readiness_policy,
)?;
initialize_components(
&descriptors,
@ -542,6 +634,8 @@ impl<E: Application, Caps> Builder<E, Caps> {
run_plan.duration,
run_plan.expectation_cooldown,
parts.deployment_policy,
parts.sources,
parts.source_readiness_policy,
parts.capabilities,
))
}
@ -560,6 +654,8 @@ struct BuilderParts<E: Application, Caps> {
duration: Duration,
expectation_cooldown: Option<Duration>,
deployment_policy: DeploymentPolicy,
sources: ScenarioSources,
source_readiness_policy: SourceReadinessPolicy,
capabilities: Caps,
}
@ -573,6 +669,8 @@ impl<E: Application, Caps> BuilderParts<E, Caps> {
duration,
expectation_cooldown,
deployment_policy,
sources,
source_readiness_policy,
capabilities,
..
} = builder;
@ -585,6 +683,8 @@ impl<E: Application, Caps> BuilderParts<E, Caps> {
duration,
expectation_cooldown,
deployment_policy,
sources,
source_readiness_policy,
capabilities,
}
}
@ -601,6 +701,40 @@ impl<E: Application, Caps> BuilderParts<E, Caps> {
expectation_cooldown: expectation_cooldown_for(self.expectation_cooldown),
}
}
fn sources(&self) -> &ScenarioSources {
&self.sources
}
}
fn build_source_orchestration_plan(
sources: &ScenarioSources,
managed_node_count: usize,
readiness_policy: SourceReadinessPolicy,
) -> Result<SourceOrchestrationPlan, ScenarioBuildError> {
SourceOrchestrationPlan::try_from_sources(sources, managed_node_count, readiness_policy)
.map_err(source_plan_error_to_build_error)
}
fn source_plan_error_to_build_error(error: SourceOrchestrationPlanError) -> ScenarioBuildError {
match error {
SourceOrchestrationPlanError::ManagedNodesMissing => ScenarioBuildError::SourceConfiguration {
message:
"managed source selected but deployment produced 0 managed nodes; choose a deployment provider/configuration that yields managed nodes".to_string(),
},
SourceOrchestrationPlanError::SourceModeNotWiredYet { mode } => {
ScenarioBuildError::SourceModeNotWiredYet {
mode: source_mode_name(mode),
}
}
}
}
const fn source_mode_name(mode: SourceModeName) -> &'static str {
match mode {
SourceModeName::Attached => "Attached",
SourceModeName::ExternalOnly => "ExternalOnly",
}
}
impl<E: Application> Builder<E, ()> {

View File

@ -12,6 +12,7 @@ mod deployment_policy;
mod expectation;
mod observability;
mod runtime;
mod sources;
mod workload;
pub type DynError = Box<dyn Error + Send + Sync + 'static>;
@ -36,8 +37,9 @@ pub use deployment_policy::{CleanupPolicy, DeploymentPolicy, RetryPolicy};
pub use expectation::Expectation;
pub use observability::{ObservabilityCapabilityProvider, ObservabilityInputs};
pub use runtime::{
CleanupGuard, Deployer, Feed, FeedHandle, FeedRuntime, HttpReadinessRequirement, NodeClients,
ReadinessError, RunContext, RunHandle, RunMetrics, Runner, ScenarioError, StabilizationConfig,
BorrowedNode, BorrowedOrigin, CleanupGuard, Deployer, Feed, FeedHandle, FeedRuntime,
HttpReadinessRequirement, ManagedNode, NodeClients, NodeHandle, NodeInventory, ReadinessError,
RunContext, RunHandle, RunMetrics, Runner, ScenarioError, StabilizationConfig,
metrics::{
CONSENSUS_PROCESSED_BLOCKS, CONSENSUS_TRANSACTIONS_TOTAL, Metrics, MetricsError,
PrometheusEndpoint, PrometheusInstantSample,
@ -46,6 +48,7 @@ pub use runtime::{
wait_for_http_ports_with_host_and_requirement, wait_for_http_ports_with_requirement,
wait_http_readiness, wait_until_stable,
};
pub use sources::{AttachSource, ExternalNodeSource, ScenarioSources, SourceReadinessPolicy};
pub use workload::Workload;
pub use crate::env::Application;

View File

@ -1,7 +1,7 @@
use std::{sync::Arc, time::Duration};
use super::{metrics::Metrics, node_clients::ClusterClient};
use crate::scenario::{Application, NodeClients, NodeControlHandle};
use crate::scenario::{Application, BorrowedNode, ManagedNode, NodeClients, NodeControlHandle};
/// Shared runtime context available to workloads and expectations.
pub struct RunContext<E: Application> {
@ -54,6 +54,26 @@ impl<E: Application> RunContext<E> {
self.node_clients.random_client()
}
#[must_use]
pub fn managed_nodes(&self) -> Vec<ManagedNode<E>> {
self.node_clients.managed_nodes()
}
#[must_use]
pub fn borrowed_nodes(&self) -> Vec<BorrowedNode<E>> {
self.node_clients.borrowed_nodes()
}
#[must_use]
pub fn find_managed_node(&self, identity: &str) -> Option<ManagedNode<E>> {
self.node_clients.find_managed(identity)
}
#[must_use]
pub fn find_borrowed_node(&self, identity: &str) -> Option<BorrowedNode<E>> {
self.node_clients.find_borrowed(identity)
}
#[must_use]
pub fn feed(&self) -> <E::FeedRuntime as super::FeedRuntime>::Feed {
self.feed.clone()

View File

@ -0,0 +1,3 @@
mod node_inventory;
pub use node_inventory::{BorrowedNode, BorrowedOrigin, ManagedNode, NodeHandle, NodeInventory};

View File

@ -0,0 +1,342 @@
use std::{collections::HashMap, sync::Arc};
use parking_lot::RwLock;
use crate::scenario::{Application, DynError, NodeControlHandle, StartNodeOptions, StartedNode};
/// Origin for borrowed (non-managed) nodes in the runtime inventory.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum BorrowedOrigin {
/// Node discovered from an attached cluster provider.
Attached,
/// Node provided explicitly as an external endpoint.
External,
}
/// Managed node handle with full lifecycle capabilities.
pub struct ManagedNode<E: Application> {
/// Canonical node identity used for deduplication and lookups.
pub identity: String,
/// Application-specific API client for this node.
pub client: E::NodeClient,
}
/// Borrowed node handle (attached or external), query-only by default.
pub struct BorrowedNode<E: Application> {
/// Canonical node identity used for deduplication and lookups.
pub identity: String,
/// Application-specific API client for this node.
pub client: E::NodeClient,
/// Borrowed source kind used for diagnostics and selection.
pub origin: BorrowedOrigin,
}
/// Unified node handle variant used by runtime inventory snapshots.
pub enum NodeHandle<E: Application> {
/// Managed node variant.
Managed(ManagedNode<E>),
/// Borrowed node variant.
Borrowed(BorrowedNode<E>),
}
impl<E: Application> Clone for ManagedNode<E> {
fn clone(&self) -> Self {
Self {
identity: self.identity.clone(),
client: self.client.clone(),
}
}
}
impl<E: Application> Clone for BorrowedNode<E> {
fn clone(&self) -> Self {
Self {
identity: self.identity.clone(),
client: self.client.clone(),
origin: self.origin,
}
}
}
impl<E: Application> Clone for NodeHandle<E> {
fn clone(&self) -> Self {
match self {
Self::Managed(node) => Self::Managed(node.clone()),
Self::Borrowed(node) => Self::Borrowed(node.clone()),
}
}
}
/// Thread-safe node inventory with identity-based upsert semantics.
pub struct NodeInventory<E: Application> {
inner: Arc<RwLock<NodeInventoryInner<E>>>,
}
struct NodeInventoryInner<E: Application> {
nodes: Vec<NodeHandle<E>>,
indices_by_identity: HashMap<String, usize>,
next_synthetic_id: usize,
}
impl<E: Application> Default for NodeInventory<E> {
fn default() -> Self {
Self {
inner: Arc::new(RwLock::new(NodeInventoryInner {
nodes: Vec::new(),
indices_by_identity: HashMap::new(),
next_synthetic_id: 0,
})),
}
}
}
impl<E: Application> Clone for NodeInventory<E> {
fn clone(&self) -> Self {
Self {
inner: Arc::clone(&self.inner),
}
}
}
impl<E: Application> NodeInventory<E> {
#[must_use]
/// Builds an inventory from managed clients.
pub fn from_managed_clients(clients: Vec<E::NodeClient>) -> Self {
let inventory = Self::default();
for client in clients {
inventory.add_managed_node(client, None);
}
inventory
}
#[must_use]
/// Returns a cloned snapshot of all node clients.
pub fn snapshot_clients(&self) -> Vec<E::NodeClient> {
self.inner.read().nodes.iter().map(clone_client).collect()
}
#[must_use]
/// Returns cloned managed node handles from the current inventory.
pub fn managed_nodes(&self) -> Vec<ManagedNode<E>> {
self.inner
.read()
.nodes
.iter()
.filter_map(|handle| match handle {
NodeHandle::Managed(node) => Some(node.clone()),
NodeHandle::Borrowed(_) => None,
})
.collect()
}
#[must_use]
/// Returns cloned borrowed node handles from the current inventory.
pub fn borrowed_nodes(&self) -> Vec<BorrowedNode<E>> {
self.inner
.read()
.nodes
.iter()
.filter_map(|handle| match handle {
NodeHandle::Managed(_) => None,
NodeHandle::Borrowed(node) => Some(node.clone()),
})
.collect()
}
#[must_use]
/// Finds a managed node by canonical identity.
pub fn find_managed(&self, identity: &str) -> Option<ManagedNode<E>> {
let guard = self.inner.read();
match node_by_identity(&guard, identity)? {
NodeHandle::Managed(node) => Some(node.clone()),
NodeHandle::Borrowed(_) => None,
}
}
#[must_use]
/// Finds a borrowed node by canonical identity.
pub fn find_borrowed(&self, identity: &str) -> Option<BorrowedNode<E>> {
let guard = self.inner.read();
match node_by_identity(&guard, identity)? {
NodeHandle::Managed(_) => None,
NodeHandle::Borrowed(node) => Some(node.clone()),
}
}
#[must_use]
/// Finds any node handle by canonical identity.
pub fn find_node(&self, identity: &str) -> Option<NodeHandle<E>> {
let guard = self.inner.read();
node_by_identity(&guard, identity).cloned()
}
#[must_use]
/// Returns current number of nodes in inventory.
pub fn len(&self) -> usize {
self.inner.read().nodes.len()
}
#[must_use]
/// Returns true when no nodes are registered.
pub fn is_empty(&self) -> bool {
self.len() == 0
}
/// Clears all nodes and identity indexes.
pub fn clear(&self) {
let mut guard = self.inner.write();
guard.nodes.clear();
guard.indices_by_identity.clear();
guard.next_synthetic_id = 0;
}
/// Adds or replaces a managed node entry using canonical identity
/// resolution. Re-adding the same node identity updates the stored handle.
pub fn add_managed_node(&self, client: E::NodeClient, identity_hint: Option<String>) {
let mut guard = self.inner.write();
let identity = canonical_identity::<E>(&client, identity_hint, &mut guard);
let handle = NodeHandle::Managed(ManagedNode {
identity: identity.clone(),
client,
});
upsert_node(&mut guard, identity, handle);
}
/// Adds or replaces an attached node entry.
pub fn add_attached_node(&self, client: E::NodeClient, identity_hint: Option<String>) {
self.add_borrowed_node(client, BorrowedOrigin::Attached, identity_hint);
}
/// Adds or replaces an external static node entry.
pub fn add_external_node(&self, client: E::NodeClient, identity_hint: Option<String>) {
self.add_borrowed_node(client, BorrowedOrigin::External, identity_hint);
}
/// Executes a synchronous read over a cloned client slice.
pub fn with_clients<R>(&self, f: impl FnOnce(&[E::NodeClient]) -> R) -> R {
let guard = self.inner.read();
let clients = guard.nodes.iter().map(clone_client).collect::<Vec<_>>();
f(&clients)
}
fn add_borrowed_node(
&self,
client: E::NodeClient,
origin: BorrowedOrigin,
identity_hint: Option<String>,
) {
let mut guard = self.inner.write();
let identity = canonical_identity::<E>(&client, identity_hint, &mut guard);
let handle = NodeHandle::Borrowed(BorrowedNode {
identity: identity.clone(),
client,
origin,
});
upsert_node(&mut guard, identity, handle);
}
}
impl<E: Application> ManagedNode<E> {
#[must_use]
/// Returns the node client.
pub const fn client(&self) -> &E::NodeClient {
&self.client
}
/// Delegates restart to the deployer's control surface for this node name.
pub async fn restart(
&self,
control: &dyn NodeControlHandle<E>,
node_name: &str,
) -> Result<(), DynError> {
control.restart_node(node_name).await
}
/// Delegates stop to the deployer's control surface for this node name.
pub async fn stop(
&self,
control: &dyn NodeControlHandle<E>,
node_name: &str,
) -> Result<(), DynError> {
control.stop_node(node_name).await
}
/// Delegates dynamic node start with options to the control surface.
pub async fn start_with(
&self,
control: &dyn NodeControlHandle<E>,
node_name: &str,
options: StartNodeOptions<E>,
) -> Result<StartedNode<E>, DynError> {
control.start_node_with(node_name, options).await
}
#[must_use]
/// Returns process id if the backend can expose it for this node name.
pub fn pid(&self, control: &dyn NodeControlHandle<E>, node_name: &str) -> Option<u32> {
control.node_pid(node_name)
}
}
impl<E: Application> BorrowedNode<E> {
#[must_use]
/// Returns the node client.
pub const fn client(&self) -> &E::NodeClient {
&self.client
}
}
fn upsert_node<E: Application>(
inner: &mut NodeInventoryInner<E>,
identity: String,
handle: NodeHandle<E>,
) {
if let Some(existing_index) = inner.indices_by_identity.get(&identity).copied() {
inner.nodes[existing_index] = handle;
return;
}
let index = inner.nodes.len();
inner.nodes.push(handle);
inner.indices_by_identity.insert(identity, index);
}
fn canonical_identity<E: Application>(
client: &E::NodeClient,
identity_hint: Option<String>,
inner: &mut NodeInventoryInner<E>,
) -> String {
// Priority: explicit hint -> app-provided peer id -> endpoint -> synthetic.
if let Some(identity) = identity_hint.filter(|value| !value.trim().is_empty()) {
return identity;
}
if let Some(identity) = E::node_peer_identity(client) {
return format!("peer:{identity}");
}
if let Some(identity) = E::node_endpoint_identity(client) {
return format!("endpoint:{identity}");
}
let synthetic = format!("node:{}", inner.next_synthetic_id);
inner.next_synthetic_id += 1;
synthetic
}
fn clone_client<E: Application>(handle: &NodeHandle<E>) -> E::NodeClient {
match handle {
NodeHandle::Managed(node) => node.client.clone(),
NodeHandle::Borrowed(node) => node.client.clone(),
}
}
fn node_by_identity<'a, E: Application>(
inner: &'a NodeInventoryInner<E>,
identity: &str,
) -> Option<&'a NodeHandle<E>> {
let index = *inner.indices_by_identity.get(identity)?;
inner.nodes.get(index)
}

View File

@ -77,7 +77,7 @@ impl Metrics {
fn require_prometheus(&self) -> Result<Arc<PrometheusEndpoint>, MetricsError> {
self.prometheus()
.ok_or_else(|| MetricsError::new("prometheus endpoint unavailable"))
.ok_or_else(|| MetricsError::new("prometheus endpoint unavailable".to_string()))
}
}
@ -122,8 +122,8 @@ pub enum MetricsError {
impl MetricsError {
#[must_use]
pub fn new(message: impl Into<String>) -> Self {
Self::Store(message.into())
pub fn new(message: String) -> Self {
Self::Store(message)
}
}
@ -188,7 +188,7 @@ fn query_prometheus(client: PrometheusClient, query: String) -> Result<PromqlRes
.map_err(|error| MetricsError::new(format!("prometheus query failed: {error}")))
})
.join()
.map_err(|_| MetricsError::new("prometheus query thread panicked"))?
.map_err(|_| MetricsError::new("prometheus query thread panicked".to_string()))?
}
fn samples_from_prometheus_data(data: &PrometheusData) -> Vec<PrometheusInstantSample> {

View File

@ -1,13 +1,17 @@
pub mod context;
mod deployer;
pub mod inventory;
pub mod metrics;
mod node_clients;
pub(crate) mod orchestration;
pub(crate) mod providers;
pub mod readiness;
mod runner;
use async_trait::async_trait;
pub use context::{CleanupGuard, RunContext, RunHandle, RunMetrics};
pub use deployer::{Deployer, ScenarioError};
pub use inventory::{BorrowedNode, BorrowedOrigin, ManagedNode, NodeHandle, NodeInventory};
pub use node_clients::NodeClients;
pub use readiness::{
HttpReadinessRequirement, ReadinessError, StabilizationConfig, wait_for_http_ports,

View File

@ -1,23 +1,17 @@
use std::sync::Arc;
use parking_lot::RwLock;
use rand::{seq::SliceRandom as _, thread_rng};
use super::inventory::{BorrowedNode, ManagedNode, NodeInventory};
use crate::scenario::{Application, DynError};
/// Collection of API clients for the node set.
pub struct NodeClients<E: Application> {
inner: Arc<RwLock<NodeClientsInner<E>>>,
}
struct NodeClientsInner<E: Application> {
nodes: Vec<E::NodeClient>,
inventory: NodeInventory<E>,
}
impl<E: Application> Default for NodeClients<E> {
fn default() -> Self {
Self {
inner: Arc::new(RwLock::new(NodeClientsInner { nodes: Vec::new() })),
inventory: NodeInventory::default(),
}
}
}
@ -25,7 +19,7 @@ impl<E: Application> Default for NodeClients<E> {
impl<E: Application> Clone for NodeClients<E> {
fn clone(&self) -> Self {
Self {
inner: Arc::clone(&self.inner),
inventory: self.inventory.clone(),
}
}
}
@ -35,7 +29,7 @@ impl<E: Application> NodeClients<E> {
/// Build clients from preconstructed vectors.
pub fn new(nodes: Vec<E::NodeClient>) -> Self {
Self {
inner: Arc::new(RwLock::new(NodeClientsInner { nodes })),
inventory: NodeInventory::from_managed_clients(nodes),
}
}
@ -45,15 +39,14 @@ impl<E: Application> NodeClients<E> {
/// This clones the current vector so callers can iterate across `.await`
/// boundaries without holding the internal lock.
pub fn snapshot(&self) -> Vec<E::NodeClient> {
self.inner.read().nodes.clone()
self.inventory.snapshot_clients()
}
/// Execute a synchronous read against the current client slice.
///
/// Prefer this over `snapshot()` when no async boundary is involved.
pub fn with_clients<R>(&self, f: impl FnOnce(&[E::NodeClient]) -> R) -> R {
let guard = self.inner.read();
f(&guard.nodes)
self.inventory.with_clients(f)
}
#[must_use]
@ -64,12 +57,12 @@ impl<E: Application> NodeClients<E> {
#[must_use]
pub fn len(&self) -> usize {
self.inner.read().nodes.len()
self.inventory.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.len() == 0
self.inventory.is_empty()
}
#[must_use]
@ -79,13 +72,35 @@ impl<E: Application> NodeClients<E> {
}
pub fn add_node(&self, client: E::NodeClient) {
let mut guard = self.inner.write();
guard.nodes.push(client);
self.inventory.add_managed_node(client, None);
}
pub fn clear(&self) {
let mut guard = self.inner.write();
guard.nodes.clear();
self.inventory.clear();
}
#[must_use]
/// Returns a cloned snapshot of managed node handles.
pub fn managed_nodes(&self) -> Vec<ManagedNode<E>> {
self.inventory.managed_nodes()
}
#[must_use]
/// Returns a cloned snapshot of borrowed node handles.
pub fn borrowed_nodes(&self) -> Vec<BorrowedNode<E>> {
self.inventory.borrowed_nodes()
}
#[must_use]
/// Finds a managed node by canonical identity.
pub fn find_managed(&self, identity: &str) -> Option<ManagedNode<E>> {
self.inventory.find_managed(identity)
}
#[must_use]
/// Finds a borrowed node by canonical identity.
pub fn find_borrowed(&self, identity: &str) -> Option<BorrowedNode<E>> {
self.inventory.find_borrowed(identity)
}
fn shuffled_snapshot(&self) -> Vec<E::NodeClient> {

View File

@ -0,0 +1,6 @@
#[allow(dead_code)]
mod source_orchestration_plan;
pub(crate) use source_orchestration_plan::{
SourceModeName, SourceOrchestrationPlan, SourceOrchestrationPlanError,
};

View File

@ -0,0 +1,130 @@
use std::fmt;
use crate::scenario::{AttachSource, ExternalNodeSource, ScenarioSources, SourceReadinessPolicy};
/// Explicit descriptor for managed node sourcing.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ManagedSource {
/// Nodes are provisioned by the configured deployer.
DeployerManaged,
}
/// Internal source-orchestration mode derived from scenario source
/// configuration.
///
/// This is scaffolding-only and is intentionally not executed by deployers
/// yet.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum SourceOrchestrationMode {
Managed {
managed: ManagedSource,
external: Vec<ExternalNodeSource>,
},
Attached {
attach: AttachSource,
external: Vec<ExternalNodeSource>,
},
ExternalOnly {
external: Vec<ExternalNodeSource>,
},
}
/// Internal source-orchestration plan used to prepare future deployer wiring.
///
/// This captures only mapping-time source intent and readiness policy.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SourceOrchestrationPlan {
pub mode: SourceOrchestrationMode,
pub readiness_policy: SourceReadinessPolicy,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum SourceModeName {
Attached,
ExternalOnly,
}
impl fmt::Display for SourceModeName {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Attached => f.write_str("Attached"),
Self::ExternalOnly => f.write_str("ExternalOnly"),
}
}
}
/// Validation failure while building orchestration plan from sources.
#[derive(Debug, thiserror::Error)]
pub enum SourceOrchestrationPlanError {
#[error("managed source selected but deployment produced 0 managed nodes")]
ManagedNodesMissing,
#[error("source mode '{mode}' is not wired into deployers yet")]
SourceModeNotWiredYet { mode: SourceModeName },
}
impl SourceOrchestrationPlan {
pub fn try_from_sources(
sources: &ScenarioSources,
managed_node_count: usize,
readiness_policy: SourceReadinessPolicy,
) -> Result<Self, SourceOrchestrationPlanError> {
ensure_managed_sources_have_nodes(sources, managed_node_count)?;
let mode = mode_from_sources(sources);
let plan = Self {
mode,
readiness_policy,
};
plan.ensure_currently_wired()?;
Ok(plan)
}
#[must_use]
pub fn external_sources(&self) -> &[ExternalNodeSource] {
match &self.mode {
SourceOrchestrationMode::Managed { external, .. }
| SourceOrchestrationMode::Attached { external, .. }
| SourceOrchestrationMode::ExternalOnly { external } => external,
}
}
fn ensure_currently_wired(&self) -> Result<(), SourceOrchestrationPlanError> {
match self.mode {
SourceOrchestrationMode::Managed { .. } => Ok(()),
SourceOrchestrationMode::Attached { .. } => not_wired(SourceModeName::Attached),
SourceOrchestrationMode::ExternalOnly { .. } => not_wired(SourceModeName::ExternalOnly),
}
}
}
fn ensure_managed_sources_have_nodes(
sources: &ScenarioSources,
managed_node_count: usize,
) -> Result<(), SourceOrchestrationPlanError> {
if matches!(sources, ScenarioSources::Managed { .. }) && managed_node_count == 0 {
return Err(SourceOrchestrationPlanError::ManagedNodesMissing);
}
Ok(())
}
fn mode_from_sources(sources: &ScenarioSources) -> SourceOrchestrationMode {
match sources {
ScenarioSources::Managed { external } => SourceOrchestrationMode::Managed {
managed: ManagedSource::DeployerManaged,
external: external.clone(),
},
ScenarioSources::Attached { attach, external } => SourceOrchestrationMode::Attached {
attach: attach.clone(),
external: external.clone(),
},
ScenarioSources::ExternalOnly { external } => SourceOrchestrationMode::ExternalOnly {
external: external.clone(),
},
}
}
fn not_wired(mode: SourceModeName) -> Result<(), SourceOrchestrationPlanError> {
Err(SourceOrchestrationPlanError::SourceModeNotWiredYet { mode })
}

View File

@ -0,0 +1,53 @@
use async_trait::async_trait;
use crate::scenario::{Application, AttachSource, DynError};
/// Attached node discovered from an existing external cluster source.
#[derive(Clone, Debug)]
pub struct AttachedNode<E: Application> {
/// Optional stable identity hint used by runtime inventory dedup logic.
pub identity_hint: Option<String>,
/// Application-specific client for the discovered node.
pub client: E::NodeClient,
}
/// Errors returned by attach providers while discovering attached nodes.
#[derive(Debug, thiserror::Error)]
pub enum AttachProviderError {
#[error("attach source is not supported by this provider: {attach_source:?}")]
UnsupportedSource { attach_source: AttachSource },
#[error("attach discovery failed: {source}")]
Discovery {
#[source]
source: DynError,
},
}
/// Internal adapter interface for discovering pre-existing nodes.
///
/// This is scaffolding-only in phase 1 and is intentionally not wired into
/// deployer runtime orchestration yet.
#[async_trait]
pub trait AttachProvider<E: Application>: Send + Sync {
/// Discovers node clients for the requested attach source.
async fn discover(
&self,
source: &AttachSource,
) -> Result<Vec<AttachedNode<E>>, AttachProviderError>;
}
/// Default attach provider stub used while attach wiring is not implemented.
#[derive(Clone, Copy, Debug, Default)]
pub struct NoopAttachProvider;
#[async_trait]
impl<E: Application> AttachProvider<E> for NoopAttachProvider {
async fn discover(
&self,
source: &AttachSource,
) -> Result<Vec<AttachedNode<E>>, AttachProviderError> {
Err(AttachProviderError::UnsupportedSource {
attach_source: source.clone(),
})
}
}

View File

@ -0,0 +1,52 @@
use crate::scenario::{Application, DynError, ExternalNodeSource};
/// External node client prepared from a static external source endpoint.
#[derive(Clone, Debug)]
pub struct ExternalNode<E: Application> {
/// Optional stable identity hint used by runtime inventory dedup logic.
pub identity_hint: Option<String>,
/// Application-specific client for the external node endpoint.
pub client: E::NodeClient,
}
/// Errors returned while constructing node clients from external sources.
#[derive(Debug, thiserror::Error)]
pub enum ExternalProviderError {
#[error("external source is not supported by this provider: {external_source:?}")]
UnsupportedSource { external_source: ExternalNodeSource },
#[error("failed to build external node from source {source_label}: {source}")]
Build {
source_label: String,
#[source]
source: DynError,
},
}
/// Internal adapter interface for constructing node clients from static
/// external endpoint sources.
///
/// This is scaffolding-only in phase 1 and is intentionally not wired into
/// deployer runtime orchestration yet.
pub trait ExternalProvider<E: Application>: Send + Sync {
/// Builds one external node handle from one external source descriptor.
fn build_node(
&self,
source: &ExternalNodeSource,
) -> Result<ExternalNode<E>, ExternalProviderError>;
}
/// Default external provider stub used while external wiring is not
/// implemented.
#[derive(Clone, Copy, Debug, Default)]
pub struct NoopExternalProvider;
impl<E: Application> ExternalProvider<E> for NoopExternalProvider {
fn build_node(
&self,
source: &ExternalNodeSource,
) -> Result<ExternalNode<E>, ExternalProviderError> {
Err(ExternalProviderError::UnsupportedSource {
external_source: source.clone(),
})
}
}

View File

@ -0,0 +1,4 @@
#[allow(dead_code)]
mod attach_provider;
#[allow(dead_code)]
mod external_provider;

View File

@ -0,0 +1,3 @@
mod model;
pub use model::{AttachSource, ExternalNodeSource, ScenarioSources, SourceReadinessPolicy};

View File

@ -0,0 +1,168 @@
/// Typed attach source for existing clusters.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum AttachSource {
K8s {
namespace: Option<String>,
label_selector: String,
},
Compose {
project: Option<String>,
services: Vec<String>,
},
}
impl AttachSource {
#[must_use]
pub fn k8s(label_selector: String) -> Self {
Self::K8s {
namespace: None,
label_selector,
}
}
#[must_use]
pub fn with_namespace(self, namespace: String) -> Self {
match self {
Self::K8s { label_selector, .. } => Self::K8s {
namespace: Some(namespace),
label_selector,
},
other => other,
}
}
#[must_use]
pub fn compose(services: Vec<String>) -> Self {
Self::Compose {
project: None,
services,
}
}
#[must_use]
pub fn with_project(self, project: String) -> Self {
match self {
Self::Compose { services, .. } => Self::Compose {
project: Some(project),
services,
},
other => other,
}
}
}
/// Static external node endpoint that should be included in the runtime
/// inventory.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ExternalNodeSource {
pub label: String,
pub endpoint: String,
}
impl ExternalNodeSource {
#[must_use]
pub fn new(label: String, endpoint: String) -> Self {
Self { label, endpoint }
}
}
/// Planned readiness strategy for mixed managed/attached/external sources.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Default)]
pub enum SourceReadinessPolicy {
/// Phase 1 default: require every known node to pass readiness checks.
#[default]
AllReady,
/// Optional relaxed policy for large/partial environments.
Quorum,
/// Future policy for per-source constraints (for example managed minimum
/// plus overall quorum).
SourceAware,
}
/// Source model that makes invalid managed+attached combinations
/// unrepresentable by type.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ScenarioSources {
Managed {
external: Vec<ExternalNodeSource>,
},
Attached {
attach: AttachSource,
external: Vec<ExternalNodeSource>,
},
ExternalOnly {
external: Vec<ExternalNodeSource>,
},
}
impl Default for ScenarioSources {
fn default() -> Self {
Self::Managed {
external: Vec::new(),
}
}
}
impl ScenarioSources {
#[must_use]
pub const fn managed() -> Self {
Self::Managed {
external: Vec::new(),
}
}
#[must_use]
pub fn attached(attach: AttachSource) -> Self {
Self::Attached {
attach,
external: Vec::new(),
}
}
#[must_use]
pub fn external_only(external: Vec<ExternalNodeSource>) -> Self {
Self::ExternalOnly { external }
}
pub fn add_external_node(&mut self, node: ExternalNodeSource) {
match self {
Self::Managed { external }
| Self::Attached { external, .. }
| Self::ExternalOnly { external } => external.push(node),
}
}
pub fn set_attach(&mut self, attach: AttachSource) {
let external = self.external_nodes().to_vec();
*self = Self::Attached { attach, external };
}
pub fn set_external_only(&mut self) {
let external = self.external_nodes().to_vec();
*self = Self::ExternalOnly { external };
}
#[must_use]
pub fn external_nodes(&self) -> &[ExternalNodeSource] {
match self {
Self::Managed { external }
| Self::Attached { external, .. }
| Self::ExternalOnly { external } => external,
}
}
#[must_use]
pub const fn is_managed(&self) -> bool {
matches!(self, Self::Managed { .. })
}
#[must_use]
pub const fn is_attached(&self) -> bool {
matches!(self, Self::Attached { .. })
}
#[must_use]
pub const fn is_external_only(&self) -> bool {
matches!(self, Self::ExternalOnly { .. })
}
}

View File

@ -222,6 +222,10 @@ async fn build_compose_runtime<E: ComposeDeployEnv>(
input: RuntimeBuildInput<'_, E>,
) -> Result<ComposeRuntime<E>, ComposeRunnerError> {
let node_clients = input.deployed.node_clients.clone();
if node_clients.is_empty() {
return Err(ComposeRunnerError::RuntimePreflight);
}
let (feed, feed_task) = input
.deployed
.client_builder

View File

@ -33,6 +33,8 @@ pub enum ComposeRunnerError {
Telemetry(#[from] MetricsError),
#[error("feed requires at least one node client")]
BlockFeedMissing,
#[error("runtime preflight failed: no node clients available")]
RuntimePreflight,
#[error("failed to start feed: {source}")]
BlockFeed {
#[source]

View File

@ -92,6 +92,8 @@ pub enum K8sRunnerError {
InternalInvariant { message: String },
#[error("k8s runner requires at least one node client for feed data")]
BlockFeedMissing,
#[error("runtime preflight failed: no node clients available")]
RuntimePreflight,
#[error("failed to initialize feed: {source}")]
BlockFeed {
#[source]
@ -344,6 +346,15 @@ async fn build_runtime_artifacts<E: K8sDeployEnv>(
) -> Result<RuntimeArtifacts<E>, K8sRunnerError> {
info!("building node clients");
let node_clients = build_node_clients_or_fail::<E>(cluster).await?;
if node_clients.is_empty() {
fail_cluster(
cluster,
"runtime preflight failed: no node clients available",
)
.await;
return Err(K8sRunnerError::RuntimePreflight);
}
let telemetry = build_telemetry_or_fail(cluster, observability).await?;
let (feed, feed_task) = spawn_block_feed_or_fail::<E>(cluster, &node_clients).await?;

View File

@ -0,0 +1,3 @@
mod orchestrator;
pub use orchestrator::{ProcessDeployer, ProcessDeployerError};

View File

@ -84,6 +84,8 @@ pub enum ProcessDeployerError {
#[source]
source: DynError,
},
#[error("runtime preflight failed: no node clients available")]
RuntimePreflight,
#[error("expectations failed: {source}")]
ExpectationsFailed {
#[source]
@ -421,10 +423,8 @@ async fn spawn_feed_with<E: Application>(
.map_err(workload_error)
}
fn workload_error(source: impl Into<DynError>) -> ProcessDeployerError {
ProcessDeployerError::WorkloadFailed {
source: source.into(),
}
fn workload_error(source: DynError) -> ProcessDeployerError {
ProcessDeployerError::WorkloadFailed { source }
}
fn log_local_deploy_start(node_count: usize, policy: DeploymentPolicy, has_node_control: bool) {
@ -449,6 +449,10 @@ async fn run_context_for<E: Application>(
expectation_cooldown: Duration,
node_control: Option<Arc<dyn NodeControlHandle<E>>>,
) -> Result<RuntimeContext<E>, ProcessDeployerError> {
if node_clients.is_empty() {
return Err(ProcessDeployerError::RuntimePreflight);
}
let (feed, feed_task) = spawn_feed_with::<E>(&node_clients).await?;
let context = RunContext::new(
descriptors,

View File

@ -1,7 +1,7 @@
VERSION=v0.4.1
LOGOS_BLOCKCHAIN_BUNDLE_VERSION=v4
# Pinned logos-blockchain-node revision used for CI builds and binary bundles.
LOGOS_BLOCKCHAIN_NODE_REV=a4275d00eb3041ed6bfb394e0913cd1ad172224c
LOGOS_BLOCKCHAIN_NODE_REV=41ea1e3082526bb271e655cddb95a5b448e7de20
# Local logos-blockchain-node checkout override.
# LOGOS_BLOCKCHAIN_NODE_PATH=/path/to/local/nomos-node
# LOGOS_BLOCKCHAIN_NODE_PATH=