diff --git a/CLAUDE.md b/CLAUDE.md index e02bfc9..0369160 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,7 @@ Full-stack integration test infrastructure and coordination repo for the Source ## Hot path: ACP Light Client (#18) -The primary workstream is building a shared proof-validated ACP cache consumed by both DefraDB (query gate) and Orbis (signing gate). This is the critical path to making `tests/full_stack.rs` pass end-to-end with hub.rs as the SourceHub backend. +The primary workstream is building a shared proof-validated ACP cache consumed by both DefraDB (query gate) and Orbis (signing gate). This is the critical path to making `tests/full_stack.rs` pass end-to-end with hub.rs as the Vera backend. ### Trust chain (every document write is cryptographically verified) @@ -46,7 +46,7 @@ See `docs/architecture.md` for the full security architecture. backbone/ ├── crates/ │ ├── test-infra/ # Shared primitives (ManagedProcess, ports, log tracking, run dirs) -│ ├── sourcehub-harness/ # Go sourcehubd manager (legacy, being replaced by hub-harness) +│ ├── vera-harness/ # Go verad manager (legacy, being replaced by hub-harness) │ ├── defra-harness/ # DefraDB node manager + CLI client + test fixtures │ ├── hub-harness/ # Hub.rs node manager + cluster builder + observability │ └── orbis-harness/ # Orbis ring builder + DKG fixtures + event subscriptions @@ -84,7 +84,7 @@ cargo fmt --all # Format ## Running the canonical test ```bash -# Requires sourcehubd, defra, and orbis-node binaries on PATH +# Requires verad, defra, and orbis-node binaries on PATH cargo test --test full_stack -- --ignored --nocapture ``` diff --git a/Cargo.lock b/Cargo.lock index 5c4ef72..930ebdf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1985,10 +1985,10 @@ dependencies = [ "reqwest 0.12.28", "serde", "serde_json", - "sourcehub-harness", "test-infra", "tokio", "tracing", + "vera-harness", ] [[package]] @@ -3689,12 +3689,12 @@ dependencies = [ "reqwest 0.12.28", "serde", "serde_json", - "sourcehub-harness", "test-infra", "tokio", "tokio-tungstenite", "tracing", "tracing-subscriber", + "vera-harness", ] [[package]] @@ -5069,21 +5069,6 @@ dependencies = [ "windows-sys 0.60.2", ] -[[package]] -name = "sourcehub-harness" -version = "0.1.0" -dependencies = [ - "cosmrs", - "eyre", - "hex", - "regex", - "reqwest 0.12.28", - "serde_json", - "test-infra", - "tokio", - "tracing", -] - [[package]] name = "spin" version = "0.10.0" @@ -6004,6 +5989,21 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "vera-harness" +version = "0.1.0" +dependencies = [ + "cosmrs", + "eyre", + "hex", + "regex", + "reqwest 0.12.28", + "serde_json", + "test-infra", + "tokio", + "tracing", +] + [[package]] name = "version_check" version = "0.9.5" diff --git a/Cargo.toml b/Cargo.toml index 3cc4e18..b181b52 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ publish = false resolver = "2" members = [ "crates/test-infra", - "crates/sourcehub-harness", + "crates/vera-harness", "crates/defra-harness", "crates/hub-harness", "crates/orbis-harness", diff --git a/README.md b/README.md index 6f1dcfb..eed06d9 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ Everything needed to start and observe Hub.rs validator clusters: Everything needed to orchestrate Orbis DKG rings: - `OrbisRingBuilder` — multi-node ring setup with threshold configuration -- `DkgFixture` — complete SourceHub + Orbis ring with DKG ceremony +- `DkgFixture` — complete Vera + Orbis ring with DKG ceremony - Event-based synchronization — WebSocket subscriptions for DKG completion ## How Component Repos Use Backbone diff --git a/crates/defra-harness/Cargo.toml b/crates/defra-harness/Cargo.toml index 9938de8..3eaf650 100644 --- a/crates/defra-harness/Cargo.toml +++ b/crates/defra-harness/Cargo.toml @@ -7,7 +7,7 @@ license.workspace = true [dependencies] test-infra = { path = "../test-infra" } -sourcehub-harness = { path = "../sourcehub-harness" } +vera-harness = { path = "../vera-harness" } tokio.workspace = true reqwest.workspace = true serde.workspace = true diff --git a/crates/defra-harness/src/cluster/builder.rs b/crates/defra-harness/src/cluster/builder.rs index 108dd3c..ef790ab 100644 --- a/crates/defra-harness/src/cluster/builder.rs +++ b/crates/defra-harness/src/cluster/builder.rs @@ -10,7 +10,7 @@ use crate::node::{ start_node, BinarySource, GoNode, KeyringBackend, NodeConfig, PortConflict, RustNode, }; use crate::ports::allocate_node_ports; -use sourcehub_harness::{allocate_source_hub_ports, SourceHubConfig, SourceHubNode}; +use vera_harness::{allocate_vera_ports, VeraConfig, VeraNode}; use super::health::health_check_all; use super::runtime::TestCluster; @@ -57,7 +57,7 @@ pub struct TestClusterBuilder { encryption_enabled: bool, signing_enabled: bool, nac_enabled: bool, - source_hub_enabled: bool, + vera_enabled: bool, development: bool, store: Option, query_timeout: Option, @@ -95,7 +95,7 @@ impl TestClusterBuilder { encryption_enabled: false, signing_enabled: false, nac_enabled: false, - source_hub_enabled: false, + vera_enabled: false, development: false, store: None, query_timeout: None, @@ -232,9 +232,9 @@ impl TestClusterBuilder { self } - pub fn with_source_hub(mut self) -> Self { - self.source_hub_enabled = true; - self.acp_document_type = Some("source-hub".to_string()); + pub fn with_vera(mut self) -> Self { + self.vera_enabled = true; + self.acp_document_type = Some("vera".to_string()); self } @@ -369,8 +369,8 @@ impl TestClusterBuilder { None }; - // Source Hub or NAC requires an identity at startup. - if (self.nac_enabled || self.source_hub_enabled) && self.node_identity.is_none() { + // Vera or NAC requires an identity at startup. + if (self.nac_enabled || self.vera_enabled) && self.node_identity.is_none() { let binary = if let Some(ref p) = go_binary_path { p.clone() } else if let Some(ref p) = rust_binary_path { @@ -379,7 +379,7 @@ impl TestClusterBuilder { eyre::bail!("no binary available for identity generation"); }; let id = crate::identity::generate_identity(&binary) - .wrap_err("auto-generating identity for NAC/SourceHub")?; + .wrap_err("auto-generating identity for NAC/Vera")?; self.node_identity = Some(id.private_key_hex); } @@ -398,17 +398,17 @@ impl TestClusterBuilder { "DEFRA_E2E_KEEP", )?; - // Start Source Hub if enabled - let source_hub = if self.source_hub_enabled { - let sh_ports = allocate_source_hub_ports().wrap_err("allocating source hub ports")?; + // Start Vera if enabled + let vera = if self.vera_enabled { + let sh_ports = allocate_vera_ports().wrap_err("allocating Vera ports")?; - let sh_home = run_dir.node_dir("sourcehub")?; + let sh_home = run_dir.node_dir("vera")?; let sh_log_dir = sh_home.join("logs"); std::fs::create_dir_all(&sh_log_dir)?; let identity_keys: Vec = self.node_identity.iter().cloned().collect(); - let sh_node = SourceHubNode::start( + let sh_node = VeraNode::start( sh_home, sh_log_dir, &sh_ports, @@ -416,14 +416,14 @@ impl TestClusterBuilder { Duration::from_secs(60), ) .await - .wrap_err("failed to start source hub node")?; + .wrap_err("failed to start Vera node")?; Some(sh_node) } else { None }; - let sh_config: Option = source_hub.as_ref().map(SourceHubConfig::from); + let sh_config: Option = vera.as_ref().map(VeraConfig::from); let mut nodes = Vec::with_capacity(total); @@ -468,7 +468,7 @@ impl TestClusterBuilder { encryption_enabled: self.encryption_enabled, signing_enabled: self.signing_enabled, nac_enabled: self.nac_enabled, - source_hub: sh_config.clone(), + vera: sh_config.clone(), hub_rs_address: None, orbis_signer: None, keyring, @@ -568,7 +568,7 @@ impl TestClusterBuilder { encryption_enabled: self.encryption_enabled, signing_enabled: self.signing_enabled, nac_enabled: self.nac_enabled, - source_hub: sh_config.clone(), + vera: sh_config.clone(), hub_rs_address: None, orbis_signer: None, keyring, @@ -649,7 +649,7 @@ impl TestClusterBuilder { run_dir, self.node_identity, effective_identities, - source_hub, + vera, )) } } diff --git a/crates/defra-harness/src/cluster/runtime.rs b/crates/defra-harness/src/cluster/runtime.rs index 720ece9..33ac71b 100644 --- a/crates/defra-harness/src/cluster/runtime.rs +++ b/crates/defra-harness/src/cluster/runtime.rs @@ -9,7 +9,7 @@ use crate::divergences::NodeKind; use crate::node::{start_node, DefraNode, NodeConfig, PortConflict, RunningNode, RustNode}; use crate::observe::LogTracker; use crate::ports::{multiaddr_ports, reserve_ports, ReservedPorts}; -use sourcehub_harness::SourceHubNode; +use vera_harness::VeraNode; use super::health::health_check; @@ -94,11 +94,11 @@ async fn reserve_until_free( /// A cluster of running DefraDB nodes. /// -/// Field order matters: `nodes` and `source_hub` are dropped before `run_dir`, +/// Field order matters: `nodes` and `vera` are dropped before `run_dir`, /// ensuring processes are killed before their data directories are removed. pub struct TestCluster { pub nodes: Vec, - source_hub: Option, + vera: Option, #[allow(dead_code)] run_dir: test_infra::TestRunDir, startup_identity: Option, @@ -111,11 +111,11 @@ impl TestCluster { run_dir: test_infra::TestRunDir, startup_identity: Option, node_identities: Vec>, - source_hub: Option, + vera: Option, ) -> Self { Self { nodes, - source_hub, + vera, run_dir, startup_identity, node_identities, @@ -157,16 +157,16 @@ impl TestCluster { self.nodes.is_empty() } - pub fn source_hub(&self) -> Option<&SourceHubNode> { - self.source_hub.as_ref() + pub fn vera(&self) -> Option<&VeraNode> { + self.vera.as_ref() } - /// Stop the SourceHub process. Drops the node, sending SIGTERM. - pub fn stop_source_hub(&mut self) -> Result<()> { - if self.source_hub.take().is_some() { + /// Stop the Vera process. Drops the node, sending SIGTERM. + pub fn stop_vera(&mut self) -> Result<()> { + if self.vera.take().is_some() { Ok(()) } else { - eyre::bail!("no SourceHub node to stop") + eyre::bail!("no Vera node to stop") } } diff --git a/crates/defra-harness/src/divergences.rs b/crates/defra-harness/src/divergences.rs index 7e2dc48..228cb1e 100644 --- a/crates/defra-harness/src/divergences.rs +++ b/crates/defra-harness/src/divergences.rs @@ -86,11 +86,11 @@ pub fn p2p_listening_pattern(_kind: NodeKind) -> &'static str { r"Created LibP2P host" } -// -- SourceHub support -- +// -- Vera support -- -/// Whether the node supports `--source-hub-*` start flags. +/// Whether the node supports `--vera-*` start flags. /// Rust: yes, Go: not yet -pub fn supports_source_hub_flags(kind: NodeKind) -> bool { +pub fn supports_vera_flags(kind: NodeKind) -> bool { match kind { NodeKind::Rust => true, NodeKind::Go => false, diff --git a/crates/defra-harness/src/node/go_node.rs b/crates/defra-harness/src/node/go_node.rs index 502eca2..c492904 100644 --- a/crates/defra-harness/src/node/go_node.rs +++ b/crates/defra-harness/src/node/go_node.rs @@ -142,16 +142,21 @@ impl DefraNode for GoNode { if let Some(ref acp_type) = config.acp_document_type { args.push("--document-acp-type".to_string()); - args.push(acp_type.clone()); + // Go still exposes the legacy selector. + args.push(if acp_type == "vera" { + "source-hub".to_string() + } else { + acp_type.clone() + }); } if config.nac_enabled { args.push("--node-acp-enable".to_string()); } - // DIVERGENCE: Go does not support --source-hub-* flags - if config.source_hub.is_some() && divergences::supports_source_hub_flags(NodeKind::Go) { - unreachable!("Go node does not support SourceHub flags"); + // DIVERGENCE: Go does not support --vera-* flags + if config.vera.is_some() && divergences::supports_vera_flags(NodeKind::Go) { + unreachable!("Go node does not support Vera flags"); } if config.development { diff --git a/crates/defra-harness/src/node/mod.rs b/crates/defra-harness/src/node/mod.rs index 7c68918..5517a46 100644 --- a/crates/defra-harness/src/node/mod.rs +++ b/crates/defra-harness/src/node/mod.rs @@ -198,7 +198,7 @@ pub struct NodeConfig { pub encryption_enabled: bool, pub signing_enabled: bool, pub nac_enabled: bool, - pub source_hub: Option, + pub vera: Option, pub hub_rs_address: Option, pub orbis_signer: Option, pub keyring: KeyringBackend, @@ -244,7 +244,7 @@ impl NodeConfig { encryption_enabled: false, signing_enabled: false, nac_enabled: false, - source_hub: None, + vera: None, hub_rs_address: None, orbis_signer: None, keyring: KeyringBackend::None, diff --git a/crates/defra-harness/src/node/rust_node.rs b/crates/defra-harness/src/node/rust_node.rs index 82fdb77..dcfe43a 100644 --- a/crates/defra-harness/src/node/rust_node.rs +++ b/crates/defra-harness/src/node/rust_node.rs @@ -166,17 +166,17 @@ impl DefraNode for RustNode { args.push("--node-acp-enable".to_string()); } - // DIVERGENCE: Only Rust supports --source-hub-* flags - if divergences::supports_source_hub_flags(NodeKind::Rust) { - if let Some(ref sh) = config.source_hub { + // DIVERGENCE: Only Rust supports --vera-* flags + if divergences::supports_vera_flags(NodeKind::Rust) { + if let Some(ref sh) = config.vera { args.extend([ - "--source-hub-address".into(), + "--vera-address".into(), sh.lcd_url.clone(), - "--source-hub-grpc-address".into(), + "--vera-grpc-address".into(), sh.grpc_url.clone(), - "--source-hub-comet-address".into(), + "--vera-comet-address".into(), sh.comet_rpc_url.clone(), - "--source-hub-chain-id".into(), + "--vera-chain-id".into(), sh.chain_id.clone(), ]); } @@ -268,26 +268,26 @@ mod tests { } #[test] - fn source_hub_passes_distinct_lcd_and_grpc_addresses() { + fn vera_passes_distinct_lcd_and_grpc_addresses() { let node = RustNode::from_binary("/nonexistent/defra"); let mut config = test_config(); - config.source_hub = Some(sourcehub_harness::SourceHubConfig { + config.vera = Some(vera_harness::VeraConfig { lcd_url: "http://127.0.0.1:1317".to_string(), comet_rpc_url: "http://127.0.0.1:26657".to_string(), grpc_url: "http://127.0.0.1:9090".to_string(), - chain_id: "sourcehub-test".to_string(), + chain_id: "vera-test".to_string(), }); let (_binary, args, _envs) = node.command_parts(&config); let grpc_flag = args .iter() - .position(|argument| argument == "--source-hub-grpc-address") + .position(|argument| argument == "--vera-grpc-address") .expect("gRPC address flag should be present"); assert_eq!(args[grpc_flag + 1], "http://127.0.0.1:9090"); let lcd_flag = args .iter() - .position(|argument| argument == "--source-hub-address") + .position(|argument| argument == "--vera-address") .expect("LCD address flag should be present"); assert_eq!(args[lcd_flag + 1], "http://127.0.0.1:1317"); } diff --git a/crates/defra-harness/tests/sourcehub.rs b/crates/defra-harness/tests/sourcehub.rs deleted file mode 100644 index 01fc38b..0000000 --- a/crates/defra-harness/tests/sourcehub.rs +++ /dev/null @@ -1,10 +0,0 @@ -#[path = "sourcehub/compartments.rs"] -mod compartments; -#[path = "sourcehub/p2p_acp.rs"] -mod p2p_acp; -#[path = "sourcehub/policy_lifecycle.rs"] -mod policy_lifecycle; -#[path = "sourcehub/resilience.rs"] -mod resilience; -#[path = "sourcehub/smoke.rs"] -mod smoke; diff --git a/crates/defra-harness/tests/vera.rs b/crates/defra-harness/tests/vera.rs new file mode 100644 index 0000000..7620999 --- /dev/null +++ b/crates/defra-harness/tests/vera.rs @@ -0,0 +1,10 @@ +#[path = "vera/compartments.rs"] +mod compartments; +#[path = "vera/p2p_acp.rs"] +mod p2p_acp; +#[path = "vera/policy_lifecycle.rs"] +mod policy_lifecycle; +#[path = "vera/resilience.rs"] +mod resilience; +#[path = "vera/smoke.rs"] +mod smoke; diff --git a/crates/defra-harness/tests/sourcehub/compartments.rs b/crates/defra-harness/tests/vera/compartments.rs similarity index 96% rename from crates/defra-harness/tests/sourcehub/compartments.rs rename to crates/defra-harness/tests/vera/compartments.rs index 063f90f..77f2181 100644 --- a/crates/defra-harness/tests/sourcehub/compartments.rs +++ b/crates/defra-harness/tests/vera/compartments.rs @@ -29,9 +29,9 @@ fn add_policy(node: &defra_harness::DefraClient, policy: &str, identity: &str) - /// Jack (owner), Agent-XArchive (writer), Agent-Hiking (writer), /// Vanessa (reader), Outsider (none) /// -/// The node is started with Jack's identity so SourceHub transactions work. +/// The node is started with Jack's identity so Vera transactions work. #[tokio::test] -async fn rust_sourcehub_compartments() { +async fn rust_vera_compartments() { let binary = RustNode::from_workspace().binary_path().to_path_buf(); RustNode::build().expect("build rust binary"); let jack = generate_identity(&binary).expect("Jack identity"); @@ -39,11 +39,11 @@ async fn rust_sourcehub_compartments() { let cluster = TestCluster::builder() .rust_nodes(1) .skip_build() - .with_source_hub() + .with_vera() .with_identity(&jack.private_key_hex) .build() .await - .expect("failed to build source hub cluster"); + .expect("failed to build Vera cluster"); let node = cluster.client(0); @@ -53,7 +53,7 @@ async fn rust_sourcehub_compartments() { let vanessa = generate_identity(&binary).expect("Vanessa identity"); let outsider = generate_identity(&binary).expect("Outsider identity"); - // Create policies on Source Hub (one at a time to avoid account sequence issues) + // Create policies on Vera (one at a time to avoid account sequence issues) let xarchive_policy_id = add_policy(&node, XARCHIVE_ACP_POLICY, &jack.private_key_hex); tokio::time::sleep(Duration::from_secs(2)).await; let hiking_policy_id = add_policy(&node, HIKING_ACP_POLICY, &jack.private_key_hex); diff --git a/crates/defra-harness/tests/sourcehub/p2p_acp.rs b/crates/defra-harness/tests/vera/p2p_acp.rs similarity index 87% rename from crates/defra-harness/tests/sourcehub/p2p_acp.rs rename to crates/defra-harness/tests/vera/p2p_acp.rs index 199be63..081277d 100644 --- a/crates/defra-harness/tests/sourcehub/p2p_acp.rs +++ b/crates/defra-harness/tests/vera/p2p_acp.rs @@ -3,15 +3,15 @@ use std::time::Duration; use defra_harness::node::{DefraNode, RustNode}; use defra_harness::{generate_identity, users_schema_with_policy, TestCluster, USER_ACP_POLICY}; -/// P2P replication preserving Source Hub ACP. +/// P2P replication preserving Vera ACP. /// -/// Two Rust DefraDB nodes connected to the same Source Hub. +/// Two Rust DefraDB nodes connected to the same Vera. /// A document created on node 0 replicates to node 1. /// The owner can read on both nodes; anonymous cannot read on either. /// -/// The cluster is started with Jack's identity so SourceHub transactions work. +/// The cluster is started with Jack's identity so Vera transactions work. #[tokio::test] -async fn rust_sourcehub_p2p_acp() { +async fn rust_vera_p2p_acp() { let binary = RustNode::from_workspace().binary_path().to_path_buf(); RustNode::build().expect("build rust binary"); let jack = generate_identity(&binary).expect("Jack identity"); @@ -19,17 +19,17 @@ async fn rust_sourcehub_p2p_acp() { let cluster = TestCluster::builder() .rust_nodes(2) .skip_build() - .with_source_hub() + .with_vera() .with_identity(&jack.private_key_hex) .with_p2p() .build() .await - .expect("failed to build source hub p2p cluster"); + .expect("failed to build Vera p2p cluster"); let node0 = cluster.client(0); let node1 = cluster.client(1); - // Add policy on Source Hub via node 0 + // Add policy on Vera via node 0 let policy_result = node0 .acp_policy_add(USER_ACP_POLICY, &jack.private_key_hex) .expect("add policy"); @@ -86,7 +86,7 @@ async fn rust_sourcehub_p2p_acp() { // Wait for replication tokio::time::sleep(Duration::from_secs(5)).await; - // Jack can read on node 1 (same DID, same policy on Source Hub) + // Jack can read on node 1 (same DID, same policy on Vera) let jack_on_node1 = node1 .query_with_identity("query { User { _docID name } }", &jack.private_key_hex) .expect("Jack query on node1"); @@ -94,7 +94,7 @@ async fn rust_sourcehub_p2p_acp() { assert_eq!(users.len(), 1, "Jack should see replicated doc on node 1"); assert_eq!(users[0]["name"], "Jack"); - // Anonymous cannot read on node 1 (Source Hub ACP enforced) + // Anonymous cannot read on node 1 (Vera ACP enforced) let anon_on_node1 = node1 .query("query { User { _docID name } }") .expect("anon query on node1"); diff --git a/crates/defra-harness/tests/sourcehub/policy_lifecycle.rs b/crates/defra-harness/tests/vera/policy_lifecycle.rs similarity index 88% rename from crates/defra-harness/tests/sourcehub/policy_lifecycle.rs rename to crates/defra-harness/tests/vera/policy_lifecycle.rs index 8dd315e..966ddbf 100644 --- a/crates/defra-harness/tests/sourcehub/policy_lifecycle.rs +++ b/crates/defra-harness/tests/vera/policy_lifecycle.rs @@ -3,16 +3,16 @@ use defra_harness::{generate_identity, users_schema_with_policy, TestCluster, US /// Full on-chain policy lifecycle test. /// -/// 1. Create policy on Source Hub -> get policy ID +/// 1. Create policy on Vera -> get policy ID /// 2. Verify policy exists on-chain via LCD query /// 3. Use policy ID in DefraDB schema /// 4. Create documents governed by policy /// 5. Grant/revoke relationships (on-chain transactions) /// 6. Verify access changes propagate /// -/// The node is started with Alice's identity so SourceHub transactions work. +/// The node is started with Alice's identity so Vera transactions work. #[tokio::test] -async fn rust_sourcehub_policy_lifecycle() { +async fn rust_vera_policy_lifecycle() { let binary = RustNode::from_workspace().binary_path().to_path_buf(); RustNode::build().expect("build rust binary"); let alice = generate_identity(&binary).expect("Alice identity"); @@ -20,14 +20,14 @@ async fn rust_sourcehub_policy_lifecycle() { let cluster = TestCluster::builder() .rust_nodes(1) .skip_build() - .with_source_hub() + .with_vera() .with_identity(&alice.private_key_hex) .build() .await .expect("failed to build cluster"); let node = cluster.client(0); - let sh = cluster.source_hub().expect("source hub not available"); + let sh = cluster.vera().expect("Vera not available"); let bob = generate_identity(&binary).expect("Bob identity"); @@ -41,12 +41,9 @@ async fn rust_sourcehub_policy_lifecycle() { .expect("PolicyID") .to_string(); - // Step 2: Verify policy exists on Source Hub via LCD + // Step 2: Verify policy exists on Vera via LCD let client = reqwest::Client::new(); - let policy_url = format!( - "{}/sourcenetwork/sourcehub/acp/policy/{}", - sh.lcd_url, policy_id - ); + let policy_url = format!("{}/sourcenetwork/vera/acp/policy/{}", sh.lcd_url, policy_id); let resp = client .get(&policy_url) .send() diff --git a/crates/defra-harness/tests/sourcehub/resilience.rs b/crates/defra-harness/tests/vera/resilience.rs similarity index 89% rename from crates/defra-harness/tests/sourcehub/resilience.rs rename to crates/defra-harness/tests/vera/resilience.rs index 369e6a3..066a687 100644 --- a/crates/defra-harness/tests/sourcehub/resilience.rs +++ b/crates/defra-harness/tests/vera/resilience.rs @@ -3,13 +3,13 @@ use std::time::Duration; use defra_harness::node::{DefraNode, RustNode}; use defra_harness::{generate_identity, users_schema_with_policy, TestCluster, USER_ACP_POLICY}; -/// Circuit breaker fail-closed: when SourceHub becomes unreachable after +/// Circuit breaker fail-closed: when Vera becomes unreachable after /// initial setup, ACP-protected queries deny ALL access (including owner). /// /// Sequence: -/// 1. Start cluster with SourceHub, create policy + protected doc +/// 1. Start cluster with Vera, create policy + protected doc /// 2. Verify Jack (owner) can read during normal operation -/// 3. Stop the SourceHub process (simulates network partition) +/// 3. Stop the Vera process (simulates network partition) /// 4. Verify Jack is DENIED (node can't verify ACP -> fail-closed) /// 5. Verify anonymous is also denied #[tokio::test] @@ -21,7 +21,7 @@ async fn rust_circuit_breaker_trip_recovery() { let mut cluster = TestCluster::builder() .rust_nodes(1) .skip_build() - .with_source_hub() + .with_vera() .with_identity(&jack.private_key_hex) .build() .await @@ -58,23 +58,21 @@ async fn rust_circuit_breaker_trip_recovery() { "Jack should see 1 doc during normal operation" ); - // Phase 2: Stop SourceHub — kill the devnet process - cluster - .stop_source_hub() - .expect("failed to stop source hub"); + // Phase 2: Stop Vera — kill the devnet process + cluster.stop_vera().expect("failed to stop Vera"); // Give time for connections to notice the shutdown tokio::time::sleep(Duration::from_secs(2)).await; - // Phase 3: Fail-closed — even the owner is denied when SourceHub is unreachable. - // The node cannot verify ACP permissions without SourceHub, so it denies all access. + // Phase 3: Fail-closed — even the owner is denied when Vera is unreachable. + // The node cannot verify ACP permissions without Vera, so it denies all access. let jack_after_stop = node .query_with_identity("query { User { _docID name } }", &jack.private_key_hex) - .expect("Jack read after SourceHub stop"); + .expect("Jack read after Vera stop"); assert_eq!( jack_after_stop["User"].as_array().unwrap().len(), 0, - "Jack should be denied when SourceHub is down (fail-closed)" + "Jack should be denied when Vera is down (fail-closed)" ); // Anonymous is also denied @@ -84,11 +82,11 @@ async fn rust_circuit_breaker_trip_recovery() { assert_eq!( anon_after_stop["User"].as_array().unwrap().len(), 0, - "anonymous must be denied with SourceHub down (fail-closed)" + "anonymous must be denied with Vera down (fail-closed)" ); } -/// Policy cache verification: after creating a policy on SourceHub, +/// Policy cache verification: after creating a policy on Vera, /// subsequent ACP operations use the cached policy without hitting /// the chain for every request. /// @@ -105,7 +103,7 @@ async fn rust_policy_cache_ttl_expiry() { let cluster = TestCluster::builder() .rust_nodes(1) .skip_build() - .with_source_hub() + .with_vera() .with_identity(&alice.private_key_hex) .build() .await @@ -178,7 +176,7 @@ async fn rust_policy_cache_ttl_expiry() { /// Go runtime variant — circuit breaker behavior #[tokio::test] -#[ignore = "Go node with SourceHub not yet supported"] +#[ignore = "Go node with Vera not yet supported"] async fn go_circuit_breaker_trip_recovery() { let binary = RustNode::from_workspace().binary_path().to_path_buf(); RustNode::build().expect("build rust binary"); @@ -186,7 +184,7 @@ async fn go_circuit_breaker_trip_recovery() { let cluster = TestCluster::builder() .go_nodes(1) - .with_source_hub() + .with_vera() .with_identity(&jack.private_key_hex) .build() .await @@ -220,7 +218,7 @@ async fn go_circuit_breaker_trip_recovery() { /// Go runtime variant — policy cache behavior #[tokio::test] -#[ignore = "Go node with SourceHub not yet supported"] +#[ignore = "Go node with Vera not yet supported"] async fn go_policy_cache_ttl_expiry() { let binary = RustNode::from_workspace().binary_path().to_path_buf(); RustNode::build().expect("build rust binary"); @@ -228,7 +226,7 @@ async fn go_policy_cache_ttl_expiry() { let cluster = TestCluster::builder() .go_nodes(1) - .with_source_hub() + .with_vera() .with_identity(&alice.private_key_hex) .build() .await diff --git a/crates/defra-harness/tests/sourcehub/smoke.rs b/crates/defra-harness/tests/vera/smoke.rs similarity index 79% rename from crates/defra-harness/tests/sourcehub/smoke.rs rename to crates/defra-harness/tests/vera/smoke.rs index 11ee321..2953863 100644 --- a/crates/defra-harness/tests/sourcehub/smoke.rs +++ b/crates/defra-harness/tests/vera/smoke.rs @@ -1,17 +1,17 @@ use defra_harness::node::{DefraNode, RustNode}; use defra_harness::{generate_identity, users_schema_with_policy, TestCluster, USER_ACP_POLICY}; -/// Smoke test proving DefraDB -> Source Hub ACP pipeline works end-to-end. +/// Smoke test proving DefraDB -> Vera ACP pipeline works end-to-end. /// -/// 1. Starts a Source Hub devnet + 1 Rust DefraDB node connected to it +/// 1. Starts a Vera devnet + 1 Rust DefraDB node connected to it /// 2. Creates an ACP policy (on-chain via MsgCreatePolicy) /// 3. Creates a protected document as Jack (owner) /// 4. Jack sees the document, anonymous sees nothing /// -/// The node must be started with Jack's identity so the SourceHub TxSigner +/// The node must be started with Jack's identity so the Vera TxSigner /// can create bearer tokens for Jack's DID. #[tokio::test] -async fn rust_sourcehub_smoke() { +async fn rust_vera_smoke() { let binary = RustNode::from_workspace().binary_path().to_path_buf(); RustNode::build().expect("build rust binary"); let jack = generate_identity(&binary).expect("failed to generate Jack identity"); @@ -19,18 +19,18 @@ async fn rust_sourcehub_smoke() { let cluster = TestCluster::builder() .rust_nodes(1) .skip_build() - .with_source_hub() + .with_vera() .with_identity(&jack.private_key_hex) .build() .await - .expect("failed to build source hub cluster"); + .expect("failed to build Vera cluster"); let node = cluster.client(0); - // Add ACP policy — this submits MsgCreatePolicy on Source Hub + // Add ACP policy — this submits MsgCreatePolicy on Vera let policy_result = node .acp_policy_add(USER_ACP_POLICY, &jack.private_key_hex) - .expect("failed to add ACP policy via Source Hub"); + .expect("failed to add ACP policy via Vera"); let policy_id = policy_result["PolicyID"] .as_str() @@ -65,7 +65,7 @@ async fn rust_sourcehub_smoke() { assert_eq!(jack_users.len(), 1, "Jack should see 1 document"); assert_eq!(jack_users[0]["name"], "Jack"); - // Anonymous query -> sees 0 documents (ACP enforced via Source Hub) + // Anonymous query -> sees 0 documents (ACP enforced via Vera) let anon_result = node .query("query { User { _docID name age } }") .expect("anonymous query failed"); @@ -76,6 +76,6 @@ async fn rust_sourcehub_smoke() { assert_eq!( anon_users.len(), 0, - "anonymous should see 0 documents (Source Hub ACP)" + "anonymous should see 0 documents (Vera ACP)" ); } diff --git a/crates/orbis-harness/Cargo.toml b/crates/orbis-harness/Cargo.toml index 67dde57..94dddea 100644 --- a/crates/orbis-harness/Cargo.toml +++ b/crates/orbis-harness/Cargo.toml @@ -7,7 +7,7 @@ license.workspace = true [dependencies] test-infra = { path = "../test-infra" } -sourcehub-harness = { path = "../sourcehub-harness" } +sourcehub-harness = { package = "vera-harness", path = "../vera-harness" } defra-harness = { path = "../defra-harness" } tokio.workspace = true reqwest.workspace = true diff --git a/crates/orbis-harness/tests/three_component_smoke.rs b/crates/orbis-harness/tests/three_component_smoke.rs index 6bb7780..10a8212 100644 --- a/crates/orbis-harness/tests/three_component_smoke.rs +++ b/crates/orbis-harness/tests/three_component_smoke.rs @@ -100,7 +100,7 @@ async fn three_component_smoke() { ); config.p2p_enabled = true; config.p2p_addr = Some(format!("/ip4/127.0.0.1/tcp/{}", ports[1])); - config.source_hub = Some(SourceHubConfig::from(&sourcehub)); + config.vera = Some(SourceHubConfig::from(&sourcehub)); config.acp_document_type = Some("source-hub".to_string()); config.identity = Some(defra_key.clone()); config.keyring = KeyringBackend::File { diff --git a/crates/test-infra/src/binary.rs b/crates/test-infra/src/binary.rs index 4a52208..82fb6ef 100644 --- a/crates/test-infra/src/binary.rs +++ b/crates/test-infra/src/binary.rs @@ -1,6 +1,6 @@ //! Version-aware binary resolution for integration test dependencies. //! -//! Each component in the stack (defra, hubd, orbis-node, sourcehubd) needs to be +//! Each component in the stack (defra, hubd, orbis-node, verad) needs to be //! resolved at test time. The resolution order supports both local development //! (dirty working tree) and CI (pinned versions): //! diff --git a/crates/sourcehub-harness/Cargo.toml b/crates/vera-harness/Cargo.toml similarity index 79% rename from crates/sourcehub-harness/Cargo.toml rename to crates/vera-harness/Cargo.toml index d94b6f0..5af1129 100644 --- a/crates/sourcehub-harness/Cargo.toml +++ b/crates/vera-harness/Cargo.toml @@ -1,7 +1,7 @@ [package] -name = "sourcehub-harness" +name = "vera-harness" version = "0.1.0" -description = "SourceHub devnet manager for integration tests" +description = "Vera devnet manager for integration tests" edition.workspace = true license.workspace = true diff --git a/crates/sourcehub-harness/src/genesis.rs b/crates/vera-harness/src/genesis.rs similarity index 91% rename from crates/sourcehub-harness/src/genesis.rs rename to crates/vera-harness/src/genesis.rs index ff68c15..afe8082 100644 --- a/crates/sourcehub-harness/src/genesis.rs +++ b/crates/vera-harness/src/genesis.rs @@ -3,14 +3,14 @@ use std::process::Command; use eyre::{Result, WrapErr}; -use crate::SourceHubPorts; +use crate::VeraPorts; const VALIDATOR_STAKE: &str = "100000000000uopen"; const VALIDATOR_BALANCE: &str = "1000000000000uopen"; const IDENTITY_BALANCE: &str = "100000000uopen"; const FAUCET_BALANCE: &str = "100000000000uopen"; -/// Provision a single-node SourceHub devnet genesis. +/// Provision a single-node Vera devnet genesis. /// /// Follows the standard Cosmos SDK pattern: /// init -> keys add -> add-genesis-account (validator + funded addrs + faucet) -> @@ -21,7 +21,7 @@ pub fn provision_genesis( chain_id: &str, funded_addresses: &[String], faucet_address: Option<&str>, - ports: &SourceHubPorts, + ports: &VeraPorts, ) -> Result<()> { let home_str = home_dir.display().to_string(); @@ -36,7 +36,7 @@ pub fn provision_genesis( &home_str, ], ) - .wrap_err("sourcehubd init failed")?; + .wrap_err("verad init failed")?; let validator_output = run_cmd( binary, @@ -52,7 +52,7 @@ pub fn provision_genesis( "json", ], ) - .wrap_err("sourcehubd keys add failed")?; + .wrap_err("verad keys add failed")?; let addr_json: serde_json::Value = serde_json::from_str(&validator_output).wrap_err("failed to parse validator key output")?; @@ -119,10 +119,10 @@ pub fn provision_genesis( &home_str, ], ) - .wrap_err("sourcehubd gentx failed")?; + .wrap_err("verad gentx failed")?; run_cmd(binary, &["genesis", "collect-gentxs", "--home", &home_str]) - .wrap_err("sourcehubd collect-gentxs failed")?; + .wrap_err("verad collect-gentxs failed")?; patch_config_toml(home_dir, ports)?; patch_app_toml(home_dir, ports)?; @@ -131,7 +131,7 @@ pub fn provision_genesis( } /// Patch config.toml to bind CometBFT RPC and P2P to allocated ports. -fn patch_config_toml(home_dir: &Path, ports: &SourceHubPorts) -> Result<()> { +fn patch_config_toml(home_dir: &Path, ports: &VeraPorts) -> Result<()> { let config_path = home_dir.join("config/config.toml"); let content = std::fs::read_to_string(&config_path).wrap_err("read config.toml")?; @@ -151,7 +151,7 @@ fn patch_config_toml(home_dir: &Path, ports: &SourceHubPorts) -> Result<()> { } /// Patch app.toml to bind gRPC and LCD/API to allocated ports. -fn patch_app_toml(home_dir: &Path, ports: &SourceHubPorts) -> Result<()> { +fn patch_app_toml(home_dir: &Path, ports: &VeraPorts) -> Result<()> { let app_path = home_dir.join("config/app.toml"); let content = std::fs::read_to_string(&app_path).wrap_err("read app.toml")?; diff --git a/crates/sourcehub-harness/src/identity.rs b/crates/vera-harness/src/identity.rs similarity index 55% rename from crates/sourcehub-harness/src/identity.rs rename to crates/vera-harness/src/identity.rs index 64eb5d6..9e2f813 100644 --- a/crates/sourcehub-harness/src/identity.rs +++ b/crates/vera-harness/src/identity.rs @@ -1,18 +1,18 @@ use cosmrs::crypto::secp256k1::SigningKey; -/// Derive a `source1...` bech32 address from a secp256k1 private key hex string. +/// Derive a `vera1...` bech32 address from a secp256k1 private key hex string. /// /// Uses the standard Cosmos SDK derivation: -/// secp256k1 pubkey -> SHA256 -> RIPEMD160 -> bech32("source", ...) -pub fn source_hub_address(private_key_hex: &str) -> eyre::Result { +/// secp256k1 pubkey -> SHA256 -> RIPEMD160 -> bech32("vera", ...) +pub fn vera_address(private_key_hex: &str) -> eyre::Result { let key_bytes = hex::decode(private_key_hex).map_err(|e| eyre::eyre!("invalid hex key: {}", e))?; let signing_key = SigningKey::from_slice(&key_bytes) .map_err(|e| eyre::eyre!("invalid secp256k1 private key: {}", e))?; let public_key = signing_key.public_key(); let account_id = public_key - .account_id("source") - .map_err(|e| eyre::eyre!("failed to derive source address: {}", e))?; + .account_id("vera") + .map_err(|e| eyre::eyre!("failed to derive Vera address: {}", e))?; Ok(account_id.to_string()) } @@ -21,12 +21,12 @@ mod tests { use super::*; #[test] - fn derives_source_address() { + fn derives_vera_address() { let key_hex = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; - let addr = source_hub_address(key_hex).unwrap(); + let addr = vera_address(key_hex).unwrap(); assert!( - addr.starts_with("source1"), - "expected source1... prefix, got: {}", + addr.starts_with("vera1"), + "expected vera1... prefix, got: {}", addr ); } diff --git a/crates/sourcehub-harness/src/lib.rs b/crates/vera-harness/src/lib.rs similarity index 50% rename from crates/sourcehub-harness/src/lib.rs rename to crates/vera-harness/src/lib.rs index dc31ab9..51d5fa7 100644 --- a/crates/sourcehub-harness/src/lib.rs +++ b/crates/vera-harness/src/lib.rs @@ -2,23 +2,30 @@ pub mod genesis; pub mod identity; mod node; -pub use identity::source_hub_address; -pub use node::SourceHubNode; +pub use identity::vera_address; +pub use node::VeraNode; -/// Connection info for a SourceHub node. +// Keep existing Orbis harness consumers source-compatible. +pub use allocate_vera_ports as allocate_source_hub_ports; +pub use identity::vera_address as source_hub_address; +pub use VeraConfig as SourceHubConfig; +pub use VeraNode as SourceHubNode; +pub use VeraPorts as SourceHubPorts; + +/// Connection info for a Vera node. /// /// A lightweight data carrier that can be passed to DefraDB or Orbis config -/// without coupling to the full `SourceHubNode` process handle. +/// without coupling to the full `VeraNode` process handle. #[derive(Clone, Debug)] -pub struct SourceHubConfig { +pub struct VeraConfig { pub lcd_url: String, pub comet_rpc_url: String, pub grpc_url: String, pub chain_id: String, } -impl From<&SourceHubNode> for SourceHubConfig { - fn from(node: &SourceHubNode) -> Self { +impl From<&VeraNode> for VeraConfig { + fn from(node: &VeraNode) -> Self { Self { lcd_url: node.lcd_url.clone(), comet_rpc_url: node.comet_rpc_url.clone(), @@ -28,8 +35,8 @@ impl From<&SourceHubNode> for SourceHubConfig { } } -/// Ports assigned to a SourceHub node. -pub struct SourceHubPorts { +/// Ports assigned to a Vera node. +pub struct VeraPorts { /// Cosmos LCD/REST API port (default 1317). pub lcd: u16, /// CometBFT RPC port (default 26657). @@ -40,10 +47,10 @@ pub struct SourceHubPorts { pub p2p: u16, } -/// Allocate ports for a single SourceHub instance. -pub fn allocate_source_hub_ports() -> eyre::Result { +/// Allocate ports for a single Vera instance. +pub fn allocate_vera_ports() -> eyre::Result { let ports = test_infra::allocate_ports(4)?; - Ok(SourceHubPorts { + Ok(VeraPorts { lcd: ports[0], comet_rpc: ports[1], grpc: ports[2], @@ -51,11 +58,11 @@ pub fn allocate_source_hub_ports() -> eyre::Result { }) } -/// Resolve the sourcehubd binary. +/// Resolve the verad binary. /// -/// Uses `BinaryResolver` with the `SOURCEHUB` prefix. Set `SOURCEHUB_BINARY` -/// to an explicit path, or ensure `sourcehubd` is on PATH. +/// Uses `BinaryResolver` with the `VERA` prefix. Set `VERA_BINARY` +/// to an explicit path, or ensure `verad` is on PATH. pub fn resolve_binary() -> eyre::Result { - let resolved = test_infra::BinaryResolver::new("SOURCEHUB", "sourcehubd").resolve()?; + let resolved = test_infra::BinaryResolver::new("VERA", "verad").resolve()?; Ok(resolved.path) } diff --git a/crates/sourcehub-harness/src/node.rs b/crates/vera-harness/src/node.rs similarity index 78% rename from crates/sourcehub-harness/src/node.rs rename to crates/vera-harness/src/node.rs index 9d7a253..c40828e 100644 --- a/crates/sourcehub-harness/src/node.rs +++ b/crates/vera-harness/src/node.rs @@ -4,20 +4,20 @@ use std::time::Duration; use eyre::{Result, WrapErr}; use crate::genesis; -use crate::identity::source_hub_address; -use crate::SourceHubPorts; +use crate::identity::vera_address; +use crate::VeraPorts; -const DEFAULT_CHAIN_ID: &str = "sourcehub-localnet"; +const DEFAULT_CHAIN_ID: &str = "vera-localnet"; /// Well-known test account private key (the "abandon" mnemonic, Cosmos HD path m/44'/118'/0'/0/0). const TEST_ACCOUNT_HEX_KEY: &str = "c4a48e2fce1481cd3294b4490f6678090ea98d3d0e5cd984558ab0968741b104"; -/// A running SourceHub single-node devnet. +/// A running Vera single-node devnet. /// /// Provisions genesis, starts the chain, and waits for the first block. /// Killed on drop via ManagedProcess. -pub struct SourceHubNode { +pub struct VeraNode { #[allow(dead_code)] process: test_infra::ManagedProcess, #[allow(dead_code)] @@ -30,20 +30,20 @@ pub struct SourceHubNode { pub grpc_url: String, /// Chain ID. pub chain_id: String, - /// SourceHub home directory. + /// Vera home directory. #[allow(dead_code)] pub home_dir: PathBuf, } -impl SourceHubNode { - /// Provision and start a SourceHub devnet node. +impl VeraNode { + /// Provision and start a Vera devnet node. /// /// `identity_keys` are hex-encoded secp256k1 private keys whose derived - /// `source1...` addresses will be funded in genesis. + /// `vera1...` addresses will be funded in genesis. pub async fn start( home_dir: PathBuf, log_dir: PathBuf, - ports: &SourceHubPorts, + ports: &VeraPorts, identity_keys: &[String], ready_timeout: Duration, ) -> Result { @@ -52,11 +52,11 @@ impl SourceHubNode { let funded_addresses: Vec = identity_keys .iter() - .map(|key| source_hub_address(key)) + .map(|key| vera_address(key)) .collect::>() - .wrap_err("deriving source hub addresses from identity keys")?; + .wrap_err("deriving Vera addresses from identity keys")?; - let faucet_address = source_hub_address(TEST_ACCOUNT_HEX_KEY)?; + let faucet_address = vera_address(TEST_ACCOUNT_HEX_KEY)?; genesis::provision_genesis( &binary, @@ -66,7 +66,7 @@ impl SourceHubNode { Some(&faucet_address), ports, ) - .wrap_err("provisioning source hub genesis")?; + .wrap_err("provisioning Vera genesis")?; let home_str = home_dir.display().to_string(); let comet_rpc_addr = format!("tcp://0.0.0.0:{}", ports.comet_rpc); @@ -94,15 +94,15 @@ impl SourceHubNode { let stdout_path = log_dir.join("stdout.log"); let log_tracker = - test_infra::LogTracker::start(stdout_path, "committed state", sourcehub_patterns()); + test_infra::LogTracker::start(stdout_path, "committed state", vera_patterns()); - let process = test_infra::ManagedProcess::spawn("sourcehub", &binary, &args, &[], &log_dir) - .wrap_err("failed to spawn sourcehubd")?; + let process = test_infra::ManagedProcess::spawn("vera", &binary, &args, &[], &log_dir) + .wrap_err("failed to spawn verad")?; let _first_block: String = log_tracker .wait_for_pattern("first_block", ready_timeout) .await - .wrap_err("sourcehubd did not produce first block")?; + .wrap_err("verad did not produce first block")?; let lcd_url = format!("http://127.0.0.1:{}", ports.lcd); @@ -116,7 +116,7 @@ impl SourceHubNode { _ => {} } if tokio::time::Instant::now() >= deadline { - eyre::bail!("sourcehubd LCD health check timed out at {}", health_url); + eyre::bail!("verad LCD health check timed out at {}", health_url); } tokio::time::sleep(Duration::from_millis(200)).await; } @@ -128,7 +128,7 @@ impl SourceHubNode { lcd = %lcd_url, comet_rpc = %comet_rpc_url, grpc = %grpc_url, - "SourceHub devnet ready" + "Vera devnet ready" ); Ok(Self { @@ -143,7 +143,7 @@ impl SourceHubNode { } } -fn sourcehub_patterns() -> Vec { +fn vera_patterns() -> Vec { vec![test_infra::NamedPattern { name: "first_block", regex: regex::Regex::new(r"committed state.*height=1\b").unwrap(),