diff --git a/Cargo.lock b/Cargo.lock index 1b3fa017..f3ea5b2e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -486,6 +486,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + [[package]] name = "hmac" version = "0.12.1" @@ -579,6 +585,7 @@ dependencies = [ "drand-common", "drand-verify", "hex", + "hex-literal", "nois", "serde", "sha2 0.10.8", diff --git a/Cargo.toml b/Cargo.toml index 29a5833e..9cc39b4a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ resolver = "2" # nois = { git = "https://github.com/noislabs/nois", branch = "add-published-time" } nois = "0.7.0" cw2 = "1.1.1" +hex-literal = "0.4.1" [profile.release.package.nois-protocol] codegen-units = 1 diff --git a/contracts/nois-drand/Cargo.toml b/contracts/nois-drand/Cargo.toml index 429919a2..7d1ed150 100644 --- a/contracts/nois-drand/Cargo.toml +++ b/contracts/nois-drand/Cargo.toml @@ -32,3 +32,6 @@ sha2 = "0.10.6" # Drand dependencies hex = { version = "0.4" } drand-verify = "0.6.2" + +[dev-dependencies] +hex-literal = { workspace = true } diff --git a/contracts/nois-drand/src/contract.rs b/contracts/nois-drand/src/contract.rs index c015c324..ea030b45 100644 --- a/contracts/nois-drand/src/contract.rs +++ b/contracts/nois-drand/src/contract.rs @@ -1,3 +1,5 @@ +use std::str::FromStr; + use cosmwasm_std::{ ensure_eq, to_json_binary, Addr, Attribute, BankMsg, Coin, CosmosMsg, Deps, DepsMut, Empty, Env, HexBinary, MessageInfo, Order, QueryResponse, Response, StdError, StdResult, Uint128, @@ -5,8 +7,8 @@ use cosmwasm_std::{ }; use cw2::set_contract_version; use cw_storage_plus::Bound; -use drand_common::DRAND_MAINNET2_PUBKEY; -use drand_verify::{derive_randomness, G2PubkeyFastnet, Pubkey}; +use drand_common::DrandNetwork; +use drand_verify::{derive_randomness, G2PubkeyFastnet, G2PubkeyRfc, Pubkey}; use crate::attributes::{ ATTR_BOT, ATTR_RANDOMNESS, ATTR_REWARD_PAYOUT, ATTR_REWARD_POINTS, ATTR_ROUND, @@ -20,8 +22,8 @@ use crate::msg::{ }; use crate::state::{ Bot, Config, QueriedBeacon, QueriedBot, StoredSubmission, VerifiedBeacon, ALLOWLIST, BEACONS, - BOTS, CONFIG, INCENTIVIZED_BY_GATEWAY, INCENTIVIZED_BY_GATEWAY_MARKER, SUBMISSIONS, - SUBMISSIONS_COUNT, + BOTS, CONFIG, FASTNET_SUBMISSIONS_COUNT, INCENTIVIZED_BY_GATEWAY, + INCENTIVIZED_BY_GATEWAY_MARKER, QUICKNET_SUBMISSIONS_COUNT, SUBMISSIONS, }; /// Constant defining how many submissions per round will be rewarded @@ -80,9 +82,11 @@ pub fn execute( msg: ExecuteMsg, ) -> Result { match msg { - ExecuteMsg::AddRound { round, signature } => { - execute_add_round(deps, env, info, round, signature) - } + ExecuteMsg::AddRound { + network, + round, + signature, + } => execute_add_round(deps, env, info, network, round, signature), ExecuteMsg::RegisterBot { moniker } => execute_register_bot(deps, env, info, moniker), ExecuteMsg::SetIncentivized { round } => execute_set_incentivized(deps, env, info, round), ExecuteMsg::UpdateAllowlistBots { add, remove } => { @@ -307,6 +311,7 @@ fn execute_add_round( deps: DepsMut, env: Env, info: MessageInfo, + network: Option, round: u64, signature: HexBinary, ) -> Result { @@ -322,13 +327,20 @@ fn execute_add_round( return Err(ContractError::RoundTooLow { round, min_round }); } + let network = DrandNetwork::from_str(network.as_deref().unwrap_or("fastnet"))?; + // Initialise the incentive to 0 let mut reward_points = 0u64; // Get the number of submission before this one. - let submissions_count = SUBMISSIONS_COUNT - .may_load(deps.storage, round)? - .unwrap_or_default(); + let submissions_count = match network { + DrandNetwork::Fastnet => FASTNET_SUBMISSIONS_COUNT + .may_load(deps.storage, round)? + .unwrap_or_default(), + DrandNetwork::Quicknet => QUICKNET_SUBMISSIONS_COUNT + .may_load(deps.storage, round)? + .unwrap_or_default(), + }; let randomness: HexBinary = derive_randomness(signature.as_slice()).into(); // Check if we need to verify the submission or we just compare it to the registered randomness from the first submission of this round @@ -336,13 +348,28 @@ fn execute_add_round( if submissions_count < NUMBER_OF_SUBMISSION_VERIFICATION_PER_ROUND { is_verifying_tx = true; - // Since we have a static pubkey, it is safe to use the unchecked method - let pk = G2PubkeyFastnet::from_fixed_unchecked(DRAND_MAINNET2_PUBKEY) - .map_err(|_| ContractError::InvalidPubkey {})?; - // Verify BLS - if !pk.verify(round, b"", &signature).unwrap_or(false) { - return Err(ContractError::InvalidSignature {}); + + match network { + DrandNetwork::Fastnet => { + // Since we have a static pubkey, it is safe to use the unchecked method + let pk = G2PubkeyFastnet::from_fixed_unchecked(DrandNetwork::Fastnet.pubkey()) + .map_err(|_| ContractError::InvalidPubkey {})?; + // Verify BLS + if !pk.verify(round, b"", &signature).unwrap_or(false) { + return Err(ContractError::InvalidSignature {}); + } + } + DrandNetwork::Quicknet => { + // Since we have a static pubkey, it is safe to use the unchecked method + let pk = G2PubkeyRfc::from_fixed_unchecked(DrandNetwork::Quicknet.pubkey()) + .map_err(|_| ContractError::InvalidPubkey {})?; + // Verify BLS + if !pk.verify(round, b"", &signature).unwrap_or(false) { + return Err(ContractError::InvalidSignature {}); + } + } } + // Send verification reward reward_points += INCENTIVE_POINTS_FOR_VERIFICATION; } else { @@ -394,7 +421,7 @@ fn execute_add_round( }, )?; - SUBMISSIONS_COUNT.save(deps.storage, round, &new_count)?; + FASTNET_SUBMISSIONS_COUNT.save(deps.storage, round, &new_count)?; let mut attributes = vec![ Attribute::new(ATTR_ROUND, round.to_string()), @@ -557,7 +584,9 @@ mod tests { mock_dependencies, mock_dependencies_with_balance, mock_env, mock_info, }; use cosmwasm_std::{coins, from_json, Addr, Timestamp, Uint128}; - use drand_common::testing::testing_signature; + use drand_common::testing::{testing_signature_fastnet, testing_signature_quicknet}; + use drand_common::DrandNetwork::*; + use hex_literal::hex; const TESTING_MANAGER: &str = "mngr"; const GATEWAY: &str = "thegateway"; @@ -567,18 +596,26 @@ mod tests { const DEFAULT_HEIGHT: u64 = 12345; const DEFAULT_TX_INDEX: Option = Some(3); - fn make_add_round_msg(round: u64) -> ExecuteMsg { - if let Some(signature) = testing_signature(round) { - ExecuteMsg::AddRound { round, signature } - } else { - panic!("Test round {round} not set"); + fn make_add_round_msg(network: DrandNetwork, round: u64) -> ExecuteMsg { + let signature = match network { + Fastnet => testing_signature_fastnet(round), + Quicknet => testing_signature_quicknet(round), + }; + let Some(signature) = signature else { + panic!("Test round {round} not set for {network}"); + }; + + ExecuteMsg::AddRound { + network: Some(network.to_string()), + round, + signature, } } /// Adds round 72750, 72775, 72800, 72825 fn add_test_rounds(mut deps: DepsMut, bot_addr: &str) { for round in [72750, 72775, 72800, 72825] { - let msg = make_add_round_msg(round); + let msg = make_add_round_msg(Fastnet, round); execute(deps.branch(), mock_env(), mock_info(bot_addr, &[]), msg).unwrap(); } } @@ -661,7 +698,7 @@ mod tests { register_bot(deps.as_mut(), "anyone"); - let msg = make_add_round_msg(72780); + let msg = make_add_round_msg(Fastnet, 72780); let info = mock_info("anyone", &[]); execute(deps.as_mut(), mock_env(), info, msg).unwrap(); @@ -674,6 +711,44 @@ mod tests { ); } + #[test] + fn add_round_works_for_quicknet() { + let mut deps = mock_dependencies(); + + let info = mock_info("creator", &[]); + let msg = InstantiateMsg { + manager: TESTING_MANAGER.to_string(), + min_round: TESTING_MIN_ROUND, + incentive_point_price: Uint128::new(20_000), + incentive_denom: "unois".to_string(), + }; + instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); + + register_bot(deps.as_mut(), "anyone"); + + // https://api3.drand.sh/52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971/public/7307065 + let msg = ExecuteMsg::AddRound { + network: Some("quicknet".to_string()), + round: 7307065, + signature: HexBinary::from_hex("a8f51ba7ab91c937aa8c54f58da04172a4a9a8af2d7c95502e99c1dc29e574968b4b832446a18c251e07f7abc16a362f").unwrap(), + }; + let expected_randomness = + hex!("41155d35838a37100a908a4a713c593573d7ab6e845189fb24f7e31d72fc05e3"); + let info = mock_info("anyone", &[]); + execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + + let BeaconResponse { beacon } = from_json( + query( + deps.as_ref(), + mock_env(), + QueryMsg::Beacon { round: 7307065 }, + ) + .unwrap(), + ) + .unwrap(); + assert_eq!(beacon.unwrap().randomness, &expected_randomness); + } + #[test] fn add_round_not_divisible_by_15_succeeds() { let mut deps = mock_dependencies_with_balance(&[Coin::new(9999999, "unois")]); @@ -700,7 +775,7 @@ mod tests { allowlist_bot(deps.as_mut(), BOT2); // succeeds but not incentivized - let msg: ExecuteMsg = make_add_round_msg(ROUND); + let msg = make_add_round_msg(Fastnet, ROUND); let response: Response = execute(deps.as_mut(), mock_env(), mock_info(BOT1, &[]), msg).unwrap(); assert_eq!(response.messages.len(), 0); @@ -732,7 +807,7 @@ mod tests { execute(deps.as_mut(), mock_env(), mock_info(GATEWAY, &[]), msg).unwrap(); // succeeds and incentivized - let msg: ExecuteMsg = make_add_round_msg(ROUND); + let msg = make_add_round_msg(Fastnet, ROUND); let response: Response = execute(deps.as_mut(), mock_env(), mock_info(BOT2, &[]), msg).unwrap(); assert_eq!(response.messages.len(), 2); @@ -769,7 +844,7 @@ mod tests { from_json(query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap()).unwrap(); assert_eq!(min_round, TESTING_MIN_ROUND); - let msg = make_add_round_msg(10); + let msg = make_add_round_msg(Fastnet, 10); let err = execute(deps.as_mut(), mock_env(), mock_info("anyone", &[]), msg).unwrap_err(); assert!(matches!( err, @@ -809,7 +884,7 @@ mod tests { const EXPECTED_RANDOMNESS: &str = "2f3a6976baf6847d75b5eae60c0e460bb55ab6034ee28aef2f0d10b0b5cc57c1"; - let msg = make_add_round_msg(ROUND); + let msg = make_add_round_msg(Fastnet, ROUND); let info = mock_info("unregistered_bot", &[]); let response = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); let attrs = response.attributes; @@ -1087,7 +1162,7 @@ mod tests { const EXPECTED_RANDOMNESS: &str = "b84506d4342f4ec2506baa60a6b611ab006cf45e870d069ebb1b6a051c9e9acf"; - let msg = make_add_round_msg(ROUND); + let msg = make_add_round_msg(Fastnet, ROUND); let info = mock_info(MYBOT, &[]); let response = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); assert_eq!(response.messages.len(), 0); @@ -1158,7 +1233,7 @@ mod tests { // Same msg for all submissions const ROUND: u64 = 72775; - let msg = make_add_round_msg(ROUND); + let msg = make_add_round_msg(Fastnet, ROUND); // 1st let info = mock_info(bot1, &[]); @@ -1251,7 +1326,7 @@ mod tests { }; instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); - let msg = make_add_round_msg(72780); + let msg = make_add_round_msg(Fastnet, 72780); let info = mock_info("unregistered_bot", &[]); let response = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); let randomness = first_attr(response.attributes, "randomness").unwrap(); @@ -1277,6 +1352,7 @@ mod tests { register_bot(deps.as_mut(), "anyone"); let info = mock_info("anyone", &[]); let msg = ExecuteMsg::AddRound { + network: Some("fastnet".to_string()), round: 72780, signature: hex::decode("3cc6f6cdf59e95526d5a5d82aaa84fa6f181e4") .unwrap() @@ -1303,8 +1379,9 @@ mod tests { instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); let msg = ExecuteMsg::AddRound { + network: Some("fastnet".to_string()), round: 72790, // wrong round - signature: testing_signature(72780).unwrap(), + signature: testing_signature_fastnet(72780).unwrap(), }; let result = execute(deps.as_mut(), mock_env(), mock_info("anon", &[]), msg); match result.unwrap_err() { @@ -1314,6 +1391,7 @@ mod tests { let msg = ExecuteMsg::AddRound { // curl -sS https://drand.cloudflare.com/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/public/72780 + network: Some("fastnet".to_string()), round: 72780, // wrong signature (first two bytes swapped) signature: hex::decode("ac86005aaffa5e9de34b558c470a111c862e976922e8da34f9dce1a78507dbd53badd554862bc54bd8e44f44ddd8b100").unwrap().into(), @@ -1340,7 +1418,7 @@ mod tests { }; instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); - let msg = make_add_round_msg(72780); + let msg = make_add_round_msg(Fastnet, 72780); // Execute 1 register_bot(deps.as_mut(), "anyone"); @@ -1378,7 +1456,7 @@ mod tests { }; instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); - let msg = make_add_round_msg(72780); + let msg = make_add_round_msg(Fastnet, 72780); const A: &str = "bot_alice"; const B: &str = "bot_bob"; diff --git a/contracts/nois-drand/src/msg.rs b/contracts/nois-drand/src/msg.rs index 197d2744..ab997776 100644 --- a/contracts/nois-drand/src/msg.rs +++ b/contracts/nois-drand/src/msg.rs @@ -21,7 +21,12 @@ pub struct InstantiateMsg { #[cw_serde] pub enum ExecuteMsg { /// Add drand beacon - AddRound { round: u64, signature: HexBinary }, + AddRound { + /// "fastnet" or "quicknet", defaults to "fastnet" if not set + network: Option, + round: u64, + signature: HexBinary, + }, /// Registers a bot using on the sender address of the message. /// A re-registation updates the information of the bot. RegisterBot { moniker: String }, diff --git a/contracts/nois-drand/src/state.rs b/contracts/nois-drand/src/state.rs index 0eef91c8..1f5a6707 100644 --- a/contracts/nois-drand/src/state.rs +++ b/contracts/nois-drand/src/state.rs @@ -2,7 +2,7 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, HexBinary, Timestamp, Uint128}; use cw_storage_plus::{Item, Map}; -use drand_common::time_of_round; +use drand_common::{time_of_round, DrandNetwork}; /// Top level storage key. Values must not conflict. /// Each key is only one byte long to ensure we use the smallest possible storage keys. @@ -59,7 +59,7 @@ impl QueriedBeacon { pub fn make(beacon: VerifiedBeacon, round: u64) -> Self { Self { round, - published: time_of_round(round), + published: time_of_round(round, DrandNetwork::Fastnet), verified: beacon.verified, randomness: beacon.randomness, } @@ -91,7 +91,10 @@ pub struct StoredSubmission { pub const SUBMISSIONS: Map<(u64, &Addr), StoredSubmission> = Map::new("submissions"); /// The number of submissions done for each round -pub const SUBMISSIONS_COUNT: Map = Map::new("counts"); +pub const FASTNET_SUBMISSIONS_COUNT: Map = Map::new("counts"); + +/// The number of submissions done for each round +pub const QUICKNET_SUBMISSIONS_COUNT: Map = Map::new("qc"); /// Dummy value. Don't rely on the value but just check existence. pub const INCENTIVIZED_BY_GATEWAY_MARKER: u8 = 1; diff --git a/contracts/nois-gateway/README.md b/contracts/nois-gateway/README.md index f63ba498..f13840a6 100644 --- a/contracts/nois-gateway/README.md +++ b/contracts/nois-gateway/README.md @@ -1 +1,41 @@ # Nois Gateway + +The gateway processes incoming job requests and routes them the right backend. + +## Jobs + +TODO: jobs and jobs queue + +## Archive + +If a request comes in for which the corresponding drand beacon was already +verified before, it is looked up and used from the archive. In this case no job +is enqueued by the gateway but instead the beacon delivery packet is sent right +away. + +After the migration to fast randomness, it is unlikely that a beacon is needed +multiple times. So it is important to store very little data per beacon. Right +now the archive is a KV table where the value us a 32 byte randomness (hash of +the signature). The key is 11 bytes long and composed as follows: + +```rust +// fastnet +[ + 7, // BELL + b'd', // drand + b'm', // mainnet aka. fastnet + round[0], round[1], round[2], round[3], round[4], round[5], round[6], round[7], +] + +// quicknet +[ + 7, // BELL + b'd', // drand + b'q', // quicknet + round[0], round[1], round[2], round[3], round[4], round[5], round[6], round[7], +] +``` + +After the migration to quicknet is completed (see +https://github.com/noislabs/nois-contracts/issues/293 and friends), all entries +with prefix `b"\x07dm"` can be deleted as they will never be accessed again. diff --git a/contracts/nois-gateway/src/contract.rs b/contracts/nois-gateway/src/contract.rs index ac16fda9..407a6f7c 100644 --- a/contracts/nois-gateway/src/contract.rs +++ b/contracts/nois-gateway/src/contract.rs @@ -1,3 +1,5 @@ +use std::str::FromStr; + use cosmwasm_std::{ attr, ensure, ensure_eq, entry_point, from_json, instantiate2_address, to_json_binary, Addr, Attribute, Binary, CodeInfoResponse, Coin, Deps, DepsMut, Empty, Env, Event, HexBinary, @@ -9,6 +11,7 @@ use cosmwasm_std::{ }; use cw2::set_contract_version; use cw_storage_plus::Bound; +use drand_common::DrandNetwork; use nois_protocol::{ check_order, check_version, InPacket, InPacketAck, OutPacket, OutPacketAck, BEACON_PRICE_PACKET_LIFETIME, IBC_APP_VERSION, WELCOME_PACKET_LIFETIME, @@ -108,10 +111,13 @@ pub fn execute( ) -> Result { match msg { ExecuteMsg::AddVerifiedRound { + network, round, randomness, is_verifying_tx, - } => execute_add_verified_round(deps, env, info, round, randomness, is_verifying_tx), + } => { + execute_add_verified_round(deps, env, info, network, round, randomness, is_verifying_tx) + } ExecuteMsg::SetConfig { manager, price, @@ -516,6 +522,7 @@ fn execute_add_verified_round( deps: DepsMut, env: Env, info: MessageInfo, + network: Option, round: u64, randomness: HexBinary, is_verifying_tx: bool, @@ -529,12 +536,14 @@ fn execute_add_verified_round( ContractError::UnauthorizedAddVerifiedRound ); + let network = DrandNetwork::from_str(network.as_deref().unwrap_or("fastnet"))?; + let mut attributes = Vec::::new(); let router = RequestRouter::new(); let NewDrand { msgs, jobs_processed, - } = router.new_drand(deps, env, round, &randomness, is_verifying_tx)?; + } = router.new_drand(deps, env, network, round, &randomness, is_verifying_tx)?; attributes.push(Attribute::new("jobs_processed", jobs_processed.to_string())); Ok(Response::new() @@ -681,8 +690,8 @@ mod tests { match round { 9 => ExecuteMsg::AddVerifiedRound { // curl -sS https://drand.cloudflare.com/public/9 + network: Some("fastnet".to_string()), round: 9, - randomness: HexBinary::from_hex( "1b9acda1c43e333bcf02ddce634b18ff79803a904097a5896710c7ae798b47ab", ) @@ -691,6 +700,7 @@ mod tests { }, 810 => ExecuteMsg::AddVerifiedRound { // curl -sS https://drand.cloudflare.com/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/public/810 + network: Some("fastnet".to_string()), round: 810, randomness: HexBinary::from_hex( "192af38cb4e26fd9d15e8b4968fb3df137f3e6d9b4aeb04c7c5b6201091872cc", @@ -700,6 +710,7 @@ mod tests { }, 820 => ExecuteMsg::AddVerifiedRound { // curl -sS https://drand.cloudflare.com/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/public/820 + network: Some("fastnet".to_string()), round: 820, randomness: HexBinary::from_hex( "32f614c72e9a382540f6cdca5f4d58537ea11de9b692bcdef7b10e892690d233", @@ -709,6 +720,7 @@ mod tests { }, 830 => ExecuteMsg::AddVerifiedRound { // curl -sS https://drand.cloudflare.com/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/public/830 + network: Some("fastnet".to_string()), round: 830, randomness: HexBinary::from_hex( "9e8d112e4c9b66e17ca3cd78aca91e6c076a42917a03fe1fe837f7eaf2fa8b86", @@ -718,6 +730,7 @@ mod tests { }, 840 => ExecuteMsg::AddVerifiedRound { // curl -sS https://drand.cloudflare.com/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/public/840 + network: Some("fastnet".to_string()), round: 840, randomness: HexBinary::from_hex( "59b949f6455a6d7319232f8fe085cbba884727cccf79fa5239579078c0a19cd4", @@ -726,7 +739,8 @@ mod tests { is_verifying_tx, }, 72785 => ExecuteMsg::AddVerifiedRound { - // curl -sS https://drand.cloudflare.com/public/72785 + // curl -sS https://drand.cloudflare.com/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/public/72785 + network: Some("fastnet".to_string()), round: 72785, randomness: HexBinary::from_hex( "650be14f6ffd7dcb67df9138c3b7d7d6bca455d0438fc81d3fbb24a4ee038f36", @@ -735,55 +749,61 @@ mod tests { is_verifying_tx, }, 72786 => ExecuteMsg::AddVerifiedRound { - // curl -sS https://drand.cloudflare.com/public/72786 + // curl -sS https://drand.cloudflare.com/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/public/72786 + network: Some("fastnet".to_string()), round: 72786, randomness: HexBinary::from_hex( - "0ed47e6ebc311192000df4469bb5a5a00445a9365e428d61c8c08d78dd1e51a8", + "97a082a640ae98913b076bc3d8d88df8e15d49f57b83cda8e26c9a6b56647d18", ) .unwrap(), is_verifying_tx, }, 72787 => ExecuteMsg::AddVerifiedRound { - // curl -sS https://drand.cloudflare.com/public/72787 + // curl -sS https://drand.cloudflare.com/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/public/72787 + network: Some("fastnet".to_string()), round: 72787, randomness: HexBinary::from_hex( - "d4ea3e5e43bf510c1b086613a9e68257b317202dbe5aab1b9182b65f51f4b82c", + "913cce02caa4e55ce979b7e86a6bfeff545fb19caf1b5c3b99ae740b411a245a", ) .unwrap(), is_verifying_tx, }, 2183668 => ExecuteMsg::AddVerifiedRound { - // curl -sS https://drand.cloudflare.com/public/2183668 + // curl -sS https://drand.cloudflare.com/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/public/2183668 + network: Some("fastnet".to_string()), round: 2183668, randomness: HexBinary::from_hex( - "3436462283a07e695c41854bb953e5964d8737e7e29745afe54a9f4897b6c319", + "3ec104b7145a7a61c7b674a07d1e7dc7774b95f7ed7ba66063554b568ac63314", ) .unwrap(), is_verifying_tx, }, 2183669 => ExecuteMsg::AddVerifiedRound { - // curl -sS https://drand.cloudflare.com/public/2183669 + // curl -sS https://drand.cloudflare.com/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/public/2183669 + network: Some("fastnet".to_string()), round: 2183669, randomness: HexBinary::from_hex( - "408de94b8c7e1972b06a4ab7636eb1ba2a176022a30d018c3b55e89289d41149", + "a47090dd5cde02721cb848271e75a8680bd0d34a254733fe331e824b8d5d2e5d", ) .unwrap(), is_verifying_tx, }, 2183670 => ExecuteMsg::AddVerifiedRound { - // curl -sS https://drand.cloudflare.com/public/2183670 + // curl -sS https://drand.cloudflare.com/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/public/2183670 + network: Some("fastnet".to_string()), round: 2183670, randomness: HexBinary::from_hex( - "e5f7ba655389eee248575dde70cb9f3293c9774c8538136a135601907158d957", + "1c8b6ce9fbf58f06d9fa9d6e22f0b40927eba6a4313efbfde2316afd50212d05", ) .unwrap(), is_verifying_tx, }, 2183671 => ExecuteMsg::AddVerifiedRound { - // curl -sS https://drand.cloudflare.com/public/2183671 + // curl -sS https://drand.cloudflare.com/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/public/2183671 + network: Some("fastnet".to_string()), round: 2183671, randomness: HexBinary::from_hex( - "324e2a196293b42806c12c7bbd1aeba8d5617942f152a16588223f905f60801a", + "0ad508d0ac170b172b6fb9de86c248a1f0373a6744b8feb2dd99ef508e36ad58", ) .unwrap(), is_verifying_tx, diff --git a/contracts/nois-gateway/src/drand_archive.rs b/contracts/nois-gateway/src/drand_archive.rs index 0e5484f6..0073a944 100644 --- a/contracts/nois-gateway/src/drand_archive.rs +++ b/contracts/nois-gateway/src/drand_archive.rs @@ -1,23 +1,36 @@ use cosmwasm_std::{HexBinary, Storage}; +use drand_common::DrandNetwork::{self, *}; -pub fn archive_lookup(storage: &dyn Storage, round: u64) -> Option { - let key = drand_mainnet_randomness_key(round); +pub fn archive_lookup( + storage: &dyn Storage, + network: DrandNetwork, + round: u64, +) -> Option { + let key = drand_randomness_key(network, round); storage.get(&key).map(Into::into) } -pub fn archive_store(storage: &mut dyn Storage, round: u64, randomness: &HexBinary) { - let key = drand_mainnet_randomness_key(round); +pub fn archive_store( + storage: &mut dyn Storage, + network: DrandNetwork, + round: u64, + randomness: &HexBinary, +) { + let key = drand_randomness_key(network, round); storage.set(&key, randomness); } // Use raw storage key to allow storing and querying rounds // without serde -fn drand_mainnet_randomness_key(round: u64) -> [u8; 11] { - let bytes = round.to_be_bytes(); +fn drand_randomness_key(network: DrandNetwork, round: u64) -> [u8; 11] { + let network = match network { + Fastnet => b'm', // mainnet, + Quicknet => b'q', // quicknet, + }; + let round = round.to_be_bytes(); [ 7, // BELL b'd', // drand - b'm', // mainnet - bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], + network, round[0], round[1], round[2], round[3], round[4], round[5], round[6], round[7], ] } diff --git a/contracts/nois-gateway/src/msg.rs b/contracts/nois-gateway/src/msg.rs index 5083671a..d8ef050f 100644 --- a/contracts/nois-gateway/src/msg.rs +++ b/contracts/nois-gateway/src/msg.rs @@ -20,6 +20,8 @@ pub struct InstantiateMsg { pub enum ExecuteMsg { /// Add drand beacon AddVerifiedRound { + /// "fastnet" or "quicknet", defaults to "fastnet" if not set + network: Option, round: u64, randomness: HexBinary, is_verifying_tx: bool, diff --git a/contracts/nois-gateway/src/request_router.rs b/contracts/nois-gateway/src/request_router.rs index d210d160..1ba61dc1 100644 --- a/contracts/nois-gateway/src/request_router.rs +++ b/contracts/nois-gateway/src/request_router.rs @@ -4,7 +4,7 @@ use cosmwasm_std::{ to_json_binary, Binary, CosmosMsg, DepsMut, Env, HexBinary, IbcMsg, StdAck, StdError, StdResult, Timestamp, WasmMsg, }; -use drand_common::{round_after, time_of_round, DRAND_CHAIN_HASH}; +use drand_common::{round_after, time_of_round, DrandNetwork}; use nois_protocol::{InPacketAck, OutPacket, DELIVER_BEACON_PACKET_LIFETIME}; use crate::{ @@ -23,6 +23,8 @@ use crate::{ const MAX_JOBS_PER_SUBMISSION_WITH_VERIFICATION: u32 = 1; const MAX_JOBS_PER_SUBMISSION_WITHOUT_VERIFICATION: u32 = 10; +const NETWORK: DrandNetwork = DrandNetwork::Fastnet; + pub struct RoutingReceipt { pub queued: bool, pub source_id: String, @@ -62,9 +64,7 @@ impl RequestRouter { after: Timestamp, origin: Binary, ) -> StdResult { - let (round, source_id) = commit_to_drand_round(after); - - let existing_randomness = archive_lookup(deps.storage, round); + let (network, round, source_id) = commit_to_drand_round(after); let job = Job { source_id: source_id.clone(), @@ -74,12 +74,18 @@ impl RequestRouter { let mut msgs = Vec::::new(); - let queued = if let Some(randomness) = existing_randomness { - //If the drand round already exists we send it + let queued = if let Some(existing_randomness) = archive_lookup(deps.storage, network, round) + { + // If the drand round already exists we send the deliver beacon packet right away + // without enqueuing the job. increment_processed_drand_jobs(deps.storage, round)?; - let published = time_of_round(round); - let msg = - create_deliver_beacon_ibc_message(env.block.time, job, published, randomness)?; + let published = time_of_round(round, NETWORK); + let msg = create_deliver_beacon_ibc_message( + env.block.time, + job, + published, + existing_randomness, + )?; msgs.push(msg.into()); false } else { @@ -122,11 +128,12 @@ impl RequestRouter { &self, deps: DepsMut, env: Env, + network: DrandNetwork, round: u64, randomness: &HexBinary, is_verifying_tx: bool, ) -> StdResult { - archive_store(deps.storage, round, randomness); + archive_store(deps.storage, network, round, randomness); let max_jobs_per_submission = if is_verifying_tx { MAX_JOBS_PER_SUBMISSION_WITH_VERIFICATION @@ -139,7 +146,7 @@ impl RequestRouter { // let max_jobs_per_submission while let Some(job) = unprocessed_drand_jobs_dequeue(deps.storage, round)? { increment_processed_drand_jobs(deps.storage, round)?; - let published = time_of_round(round); + let published = time_of_round(round, NETWORK); // Use IbcMsg::SendPacket to send packages to the proxies. let msg = create_deliver_beacon_ibc_message( env.block.time, @@ -184,10 +191,11 @@ fn create_deliver_beacon_ibc_message( } /// Calculates the next round in the future, i.e. publish time > base time. -fn commit_to_drand_round(after: Timestamp) -> (u64, String) { - let round = round_after(after); - let source_id = format!("drand:{}:{}", DRAND_CHAIN_HASH, round); - (round, source_id) +fn commit_to_drand_round(after: Timestamp) -> (DrandNetwork, u64, String) { + let network = DrandNetwork::Fastnet; + let round = round_after(after, network); + let source_id = format!("drand:{}:{}", network.chain_hash(), round); + (network, round, source_id) } #[cfg(test)] @@ -197,7 +205,7 @@ mod tests { #[test] fn commit_to_drand_round_works() { // UNIX epoch - let (round, source) = commit_to_drand_round(Timestamp::from_seconds(0)); + let (_network, round, source) = commit_to_drand_round(Timestamp::from_seconds(0)); assert_eq!(round, 1); assert_eq!( source, @@ -205,7 +213,7 @@ mod tests { ); // Before Drand genesis (https://api3.drand.sh/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/info) - let (round, source) = + let (_network, round, source) = commit_to_drand_round(Timestamp::from_seconds(1677685200).minus_nanos(1)); assert_eq!(round, 1); assert_eq!( @@ -214,7 +222,7 @@ mod tests { ); // At Drand genesis (https://api3.drand.sh/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/info) - let (round, source) = commit_to_drand_round(Timestamp::from_seconds(1677685200)); + let (_network, round, source) = commit_to_drand_round(Timestamp::from_seconds(1677685200)); assert_eq!(round, 2); assert_eq!( source, @@ -222,17 +230,18 @@ mod tests { ); // After Drand genesis - let (round, _) = commit_to_drand_round(Timestamp::from_seconds(1677685200).plus_nanos(1)); + let (_network, round, _) = + commit_to_drand_round(Timestamp::from_seconds(1677685200).plus_nanos(1)); assert_eq!(round, 2); // Drand genesis +26s/27s/28s - let (round, _) = + let (_network, round, _) = commit_to_drand_round(Timestamp::from_seconds(1677685200).plus_seconds(26)); assert_eq!(round, 10); - let (round, _) = + let (_network, round, _) = commit_to_drand_round(Timestamp::from_seconds(1677685200).plus_seconds(27)); assert_eq!(round, 11); - let (round, _) = + let (_network, round, _) = commit_to_drand_round(Timestamp::from_seconds(1677685200).plus_seconds(28)); assert_eq!(round, 11); } diff --git a/docs/quicknet-migration.md b/docs/quicknet-migration.md new file mode 100644 index 00000000..55184762 --- /dev/null +++ b/docs/quicknet-migration.md @@ -0,0 +1,55 @@ +## Quicknet genesis + +https://api.drand.sh/52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971/info + +```json +{ + "public_key": "83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a", + "period": 3, + "genesis_time": 1692803367, + "hash": "52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971", + "groupHash": "f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e", + "schemeID": "bls-unchained-g1-rfc9380", + "metadata": { "beaconID": "quicknet" } +} +``` + +## Fastnet genesis + +https://api.drand.sh/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/info + +```json +{ + "public_key": "a0b862a7527fee3a731bcb59280ab6abd62d5c0b6ea03dc4ddf6612fdfc9d01f01c31542541771903475eb1ec6615f8d0df0b8b6dce385811d6dcf8cbefb8759e5e616a3dfd054c928940766d9a5b9db91e3b697e5d70a975181e007f87fca5e", + "period": 3, + "genesis_time": 1677685200, + "hash": "dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493", + "groupHash": "a81e9d63f614ccdb144b8ff79fbd4d5a2d22055c0bfe4ee9a8092003dab1c6c0", + "schemeID": "bls-unchained-on-g1", + "metadata": { "beaconID": "fastnet" } +} +``` + +## Shift + +1692803367-1677685200 = 15118167 seconds = ~175 days + +### Rounds + +Now: + +``` +(curl -sS https://api.drand.sh/52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971/public/latest | jq .round); (curl -sS https://api.drand.sh/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/public/latest | jq .round) +6630929 +11670319 +``` + +| Time | | Fastnet | Quicknet | +| ------------------- | ---------- | -------- | -------- | +| Nois mainnet launch | 1680015600 | 776802 | - | +| Quicknet launch | 1692803367 | 5039391 | 2 | +| Christmas 2023 | 1703430000 | 8581602 | 3542213 | +| New years | 1704067200 | 8794002 | 3754613 | +| Now | 1704236009 | 11670319 | 6630929 | + +If round >= 10_000_000, then verify with fastnet diff --git a/packages/drand-common/src/lib.rs b/packages/drand-common/src/lib.rs index a5e2217b..90ec10e0 100644 --- a/packages/drand-common/src/lib.rs +++ b/packages/drand-common/src/lib.rs @@ -1,27 +1,6 @@ +mod network; mod rounds; pub mod testing; +pub use network::DrandNetwork; pub use rounds::{is_incentivized, round_after, time_of_round}; - -use cosmwasm_std::Timestamp; - -/// The chain hash serves as a drand network identifier. -/// -/// See and -pub const DRAND_CHAIN_HASH: &str = - "dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493"; - -// https://api3.drand.sh/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/info -pub const DRAND_GENESIS: Timestamp = Timestamp::from_seconds(1677685200); -pub const DRAND_ROUND_LENGTH: u64 = 3_000_000_000; // in nanoseconds - -/// The pubkey for fastnet () -pub const DRAND_MAINNET2_PUBKEY: [u8; 96] = [ - // $ node - // > Uint8Array.from(Buffer.from("a0b862a7527fee3a731bcb59280ab6abd62d5c0b6ea03dc4ddf6612fdfc9d01f01c31542541771903475eb1ec6615f8d0df0b8b6dce385811d6dcf8cbefb8759e5e616a3dfd054c928940766d9a5b9db91e3b697e5d70a975181e007f87fca5e", "hex")) - 160, 184, 98, 167, 82, 127, 238, 58, 115, 27, 203, 89, 40, 10, 182, 171, 214, 45, 92, 11, 110, - 160, 61, 196, 221, 246, 97, 47, 223, 201, 208, 31, 1, 195, 21, 66, 84, 23, 113, 144, 52, 117, - 235, 30, 198, 97, 95, 141, 13, 240, 184, 182, 220, 227, 133, 129, 29, 109, 207, 140, 190, 251, - 135, 89, 229, 230, 22, 163, 223, 208, 84, 201, 40, 148, 7, 102, 217, 165, 185, 219, 145, 227, - 182, 151, 229, 215, 10, 151, 81, 129, 224, 7, 248, 127, 202, 94, -]; diff --git a/packages/drand-common/src/network.rs b/packages/drand-common/src/network.rs new file mode 100644 index 00000000..659ffc8d --- /dev/null +++ b/packages/drand-common/src/network.rs @@ -0,0 +1,106 @@ +use core::fmt; +use cosmwasm_std::{StdError, Timestamp}; +use std::str::FromStr; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum DrandNetwork { + Fastnet, + Quicknet, +} + +impl DrandNetwork { + pub fn genesis_time(&self) -> Timestamp { + match self { + // https://api3.drand.sh/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/info + DrandNetwork::Fastnet => Timestamp::from_seconds(1677685200), + DrandNetwork::Quicknet => Timestamp::from_seconds(1692803367), + } + } + + pub fn chain_hash(&self) -> &'static str { + match self { + DrandNetwork::Fastnet => { + "dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493" + } + // https://drand.love/blog/2023/10/16/quicknet-is-live/ + DrandNetwork::Quicknet => { + "52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971" + } + } + } + + pub const fn pubkey(&self) -> [u8; 96] { + match self { + // The pubkey for fastnet () + DrandNetwork::Fastnet => [ + // $ node + // > Uint8Array.from(Buffer.from("a0b862a7527fee3a731bcb59280ab6abd62d5c0b6ea03dc4ddf6612fdfc9d01f01c31542541771903475eb1ec6615f8d0df0b8b6dce385811d6dcf8cbefb8759e5e616a3dfd054c928940766d9a5b9db91e3b697e5d70a975181e007f87fca5e", "hex")) + 160, 184, 98, 167, 82, 127, 238, 58, 115, 27, 203, 89, 40, 10, 182, 171, 214, 45, + 92, 11, 110, 160, 61, 196, 221, 246, 97, 47, 223, 201, 208, 31, 1, 195, 21, 66, 84, + 23, 113, 144, 52, 117, 235, 30, 198, 97, 95, 141, 13, 240, 184, 182, 220, 227, 133, + 129, 29, 109, 207, 140, 190, 251, 135, 89, 229, 230, 22, 163, 223, 208, 84, 201, + 40, 148, 7, 102, 217, 165, 185, 219, 145, 227, 182, 151, 229, 215, 10, 151, 81, + 129, 224, 7, 248, 127, 202, 94, + ], + // The pubkey for quicknet () + DrandNetwork::Quicknet => [ + // $ node + // > Uint8Array.from(Buffer.from("83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a", "hex")) + 131, 207, 15, 40, 150, 173, 238, 126, 184, 181, 240, 31, 202, 211, 145, 34, 18, 196, + 55, 224, 7, 62, 145, 31, 185, 0, 34, 211, 231, 96, 24, 60, 140, 75, 69, 11, 106, + 10, 108, 58, 198, 165, 119, 106, 45, 16, 100, 81, 13, 31, 236, 117, 140, 146, 28, + 194, 43, 14, 23, 230, 58, 175, 75, 203, 94, 214, 99, 4, 222, 156, 248, 9, 189, 39, + 76, 167, 59, 171, 74, 245, 166, 233, 199, 106, 75, 192, 158, 118, 234, 232, 153, + 30, 245, 236, 228, 90, + ], + } + } +} + +impl fmt::Display for DrandNetwork { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + DrandNetwork::Fastnet => f.write_str("fastnet"), + DrandNetwork::Quicknet => f.write_str("quicknet"), + } + } +} + +impl FromStr for DrandNetwork { + type Err = StdError; + + fn from_str(net: &str) -> Result { + match net { + "fastnet" => Ok(DrandNetwork::Fastnet), + "quicknet" => Ok(DrandNetwork::Quicknet), + _ => Err(StdError::generic_err( + "Unknown network identifier. Must be quicknet or fastnet", + )), + } + } +} + +#[cfg(test)] +mod tests { + use super::DrandNetwork::*; + use super::*; + + #[test] + fn to_string_works() { + assert_eq!(Fastnet.to_string(), "fastnet"); + assert_eq!(Quicknet.to_string(), "quicknet"); + } + + #[test] + fn from_str_works() { + assert_eq!(DrandNetwork::from_str("fastnet").unwrap(), Fastnet); + assert_eq!(DrandNetwork::from_str("quicknet").unwrap(), Quicknet); + + DrandNetwork::from_str("Quicknet").unwrap_err(); + DrandNetwork::from_str("FastNet").unwrap_err(); + DrandNetwork::from_str("").unwrap_err(); + DrandNetwork::from_str(" ").unwrap_err(); + DrandNetwork::from_str(" fastnet").unwrap_err(); + DrandNetwork::from_str("fastnet ").unwrap_err(); + } +} diff --git a/packages/drand-common/src/rounds.rs b/packages/drand-common/src/rounds.rs index 9099e361..6174f519 100644 --- a/packages/drand-common/src/rounds.rs +++ b/packages/drand-common/src/rounds.rs @@ -1,18 +1,24 @@ use cosmwasm_std::Timestamp; -use crate::{DRAND_GENESIS, DRAND_ROUND_LENGTH}; +use crate::DrandNetwork; + +// Same for Fastnet and Quicknet +const DRAND_ROUND_LENGTH: u64 = 3_000_000_000; // in nanoseconds // See TimeOfRound implementation: https://github.com/drand/drand/blob/eb36ba81e3f28c966f95bcd602f60e7ff8ef4c35/chain/time.go#L30-L33 -pub fn time_of_round(round: u64) -> Timestamp { - DRAND_GENESIS.plus_nanos((round - 1) * DRAND_ROUND_LENGTH) +pub fn time_of_round(round: u64, network: DrandNetwork) -> Timestamp { + network + .genesis_time() + .plus_nanos((round - 1) * DRAND_ROUND_LENGTH) } -pub fn round_after(base: Timestamp) -> u64 { +pub fn round_after(base: Timestamp, network: DrandNetwork) -> u64 { + let genesis = network.genesis_time(); // Losely ported from https://github.com/drand/drand/blob/eb36ba81e3f28c966f95bcd602f60e7ff8ef4c35/chain/time.go#L49-L63 - if base < DRAND_GENESIS { + if base < genesis { 1 } else { - let from_genesis = base.nanos() - DRAND_GENESIS.nanos(); + let from_genesis = base.nanos() - genesis.nanos(); let periods_since_genesis = from_genesis / DRAND_ROUND_LENGTH; let next_period_index = periods_since_genesis + 1; next_period_index + 1 // Convert 0-based counting to 1-based counting @@ -36,46 +42,84 @@ pub fn is_incentivized(round: u64) -> bool { mod tests { use super::*; + fn time_of_round_fastnet(round: u64) -> Timestamp { + time_of_round(round, DrandNetwork::Fastnet) + } + + fn round_after_fastnet(base: Timestamp) -> u64 { + round_after(base, DrandNetwork::Fastnet) + } + #[test] fn time_of_round_works() { - assert_eq!(time_of_round(1), DRAND_GENESIS); - assert_eq!(time_of_round(2), DRAND_GENESIS.plus_seconds(3)); - assert_eq!(time_of_round(111765), Timestamp::from_seconds(1678020492)); + assert_eq!( + time_of_round_fastnet(1), + DrandNetwork::Fastnet.genesis_time() + ); + assert_eq!( + time_of_round_fastnet(2), + DrandNetwork::Fastnet.genesis_time().plus_seconds(3) + ); + assert_eq!( + time_of_round_fastnet(111765), + Timestamp::from_seconds(1678020492) + ); } #[test] #[should_panic(expected = "overflow")] fn time_of_round_panics_for_round_0() { - time_of_round(0); + time_of_round_fastnet(0); } #[test] fn round_after_works() { // UNIX epoch - let round = round_after(Timestamp::from_seconds(0)); + let round = round_after_fastnet(Timestamp::from_seconds(0)); assert_eq!(round, 1); // Before Drand genesis (https://api3.drand.sh/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/info) - let round = round_after(Timestamp::from_seconds(1677685200).minus_nanos(1)); + let round = round_after_fastnet(Timestamp::from_seconds(1677685200).minus_nanos(1)); assert_eq!(round, 1); // At Drand genesis - let round = round_after(Timestamp::from_seconds(1677685200)); + let round = round_after_fastnet(Timestamp::from_seconds(1677685200)); assert_eq!(round, 2); // After Drand genesis - let round = round_after(Timestamp::from_seconds(1677685200).plus_nanos(1)); + let round = round_after_fastnet(Timestamp::from_seconds(1677685200).plus_nanos(1)); assert_eq!(round, 2); // Drand genesis +2s/3s/4s - let round = round_after(Timestamp::from_seconds(1677685200).plus_seconds(2)); + let round = round_after_fastnet(Timestamp::from_seconds(1677685200).plus_seconds(2)); assert_eq!(round, 2); - let round = round_after(Timestamp::from_seconds(1677685200).plus_seconds(3)); + let round = round_after_fastnet(Timestamp::from_seconds(1677685200).plus_seconds(3)); assert_eq!(round, 3); - let round = round_after(Timestamp::from_seconds(1677685200).plus_seconds(4)); + let round = round_after_fastnet(Timestamp::from_seconds(1677685200).plus_seconds(4)); assert_eq!(round, 3); } + #[test] + fn round_after_impl_can_calculate_round_at_nois_genesis() { + let nois_genesis = Timestamp::from_seconds(1680015600); + let quicknet_launch = Timestamp::from_seconds(1692803367); + let christmas = Timestamp::from_seconds(1703430000); + let ny = Timestamp::from_seconds(1704067200); + + for t in [ + nois_genesis, + quicknet_launch, + christmas, + ny, + Timestamp::from_seconds(1704236009), + ] { + let a = round_after(t, DrandNetwork::Fastnet); + let b = round_after(t, DrandNetwork::Quicknet); + eprintln!("Fastnet round: {a}"); + eprintln!("Quicknet round: {b}"); + } + } + #[test] fn is_incentivised_works() { assert!(!is_incentivized(0)); // no 0 round exists in drand diff --git a/packages/drand-common/src/testing.rs b/packages/drand-common/src/testing.rs index 6dd485c3..0858ee2a 100644 --- a/packages/drand-common/src/testing.rs +++ b/packages/drand-common/src/testing.rs @@ -1,7 +1,7 @@ use cosmwasm_std::HexBinary; -/// Gets a signature from drand mainnet 2 for testing purposes. -pub fn testing_signature(round: u64) -> Option { +/// Gets a signature from fastnet for testing purposes. +pub fn testing_signature_fastnet(round: u64) -> Option { match round { // for r in {1..10}; do echo " $r => Some(HexBinary::from_hex($(curl -sS https://api3.drand.sh/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/public/$r | jq .signature)).unwrap()),"; done 1 => Some(HexBinary::from_hex("9544ddce2fdbe8688d6f5b4f98eed5d63eee3902e7e162050ac0f45905a55657714880adabe3c3096b92767d886567d0").unwrap()), @@ -169,3 +169,162 @@ pub fn testing_signature(round: u64) -> Option { _ => None, } } + +/// Gets a signature from fastnet for testing purposes. +pub fn testing_signature_quicknet(round: u64) -> Option { + match round { + // for r in {72750..72900}; do echo " $r => Some(HexBinary::from_hex($(curl -sS https://api3.drand.sh/52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971/public/$r | jq .signature)).unwrap()),"; done + 72750 => Some(HexBinary::from_hex("85638dfe7f7e877e372e0e08855df32b130e0f58eca1e32a46a8863e32b96934301b8d3b7e2a2946e5b43f7b7ccf9c28").unwrap()), + 72751 => Some(HexBinary::from_hex("8f4e26d95591827021936f91cd053e96e346c9618d5f54c4b2a6f1acfe65897e16e6a349870c5597f8f83f2772b1271d").unwrap()), + 72752 => Some(HexBinary::from_hex("8d926f1873d64aa38873b157af27872b19933d45641559d832c9ae4030f95a4427d06d45255239b94a34d8de96b66714").unwrap()), + 72753 => Some(HexBinary::from_hex("a7f17f5777e37e81e035b5109bf2f108a5893bfbd9f0a745c491679477e043059c2aadf749d5dd6333ce9ea047337b2e").unwrap()), + 72754 => Some(HexBinary::from_hex("8225810a822ec0ee2a36abab1176aa8909c9c3cb06dbf3e9f98023fef597a3bb108a82d947ee5d9c53735ad4a8678a2e").unwrap()), + 72755 => Some(HexBinary::from_hex("91206e7a43d36f990c313bc5aebf83c5c08a51ae287b222a47bef897ecaa4f1e17c25af65960f24e26ecfde7c8d449de").unwrap()), + 72756 => Some(HexBinary::from_hex("b2126354dcc76fa10914d161bddce63ca7d983ff94491a692c897d29fa1baf543320b21f0e7274e3b105e18030b50928").unwrap()), + 72757 => Some(HexBinary::from_hex("b012986838ab6a32ce0df4ad6dc41d00a7b55440e0fb41f8d00bfce9300e857303284e59b3cb5e9449575473d0b0fbf3").unwrap()), + 72758 => Some(HexBinary::from_hex("81eadee1c9ac49aee197c9c69f72cf1e934cc3a92049d671fba8aaebfb86548d28a33b8ed6d59ecb76b2f82c35a8dcc6").unwrap()), + 72759 => Some(HexBinary::from_hex("83d21e3a3ef0e7889c917653e589e74f256e721d492d4044bd265a2830de9d5afd7ddadb26ebb5570aa57df2e6157d26").unwrap()), + 72760 => Some(HexBinary::from_hex("8eee02bb539839c6692e80a9dfb9073341f7b152e5fa10ee3d3e7038217f60651d670017c2fcbbc1a9775abfcdaff3d5").unwrap()), + 72761 => Some(HexBinary::from_hex("935d922a50ef95283521b56014e3e023d3887dc35a5948dc89bababe130eb26f783feb6d5391c29ce5e7abb78cd6e706").unwrap()), + 72762 => Some(HexBinary::from_hex("92ab20ac884c1588705d110e121cedcec687780e78c32b7e4fd38af5870f2e17da655d0bb3fe29219da927b9f1309a20").unwrap()), + 72763 => Some(HexBinary::from_hex("833b3b6943bd4beb238358d7cd6e4ea85b7b045be36755ccb9450f957d8b2ff33dfdb28bf922b7d0b5f5af910e96b2f7").unwrap()), + 72764 => Some(HexBinary::from_hex("ac7347400125f8d2013418c93fad879625738704790039dd6dc76d897150936529fb08fdd78e05f07cfac1e80d90398b").unwrap()), + 72765 => Some(HexBinary::from_hex("94ff76c3323b1621716e9306781859f0bfa5ae98566d5daa836831b08dca2dd9b184efa03c260a8974b4b33256f5f7f0").unwrap()), + 72766 => Some(HexBinary::from_hex("97f7d5478c6203a38798b06c4bbd5935e2882f88677cc4cdb97fe489941aea4126277eb7027b902edd0e6f0062586393").unwrap()), + 72767 => Some(HexBinary::from_hex("8a3ecfca063de3b0d090e454f0b00c57087b0aa6ba27dfff29158ef50e98f6db87e76be7cff77a897f1ee825b7a78c7b").unwrap()), + 72768 => Some(HexBinary::from_hex("878554dd26c730a8e1766389a55aa2ae2ec19d4670bd806663ebbe174862c9efb4fc346d0def8172022323d388fe6629").unwrap()), + 72769 => Some(HexBinary::from_hex("a814719d031c82f2e19d68e90faf10f527c47057b0d2243144f21819aeec7fa62aae4ee61db214225d5002ba59bf298c").unwrap()), + 72770 => Some(HexBinary::from_hex("ac20098698448105db6a7db787e5abc64149ca4933b0b1de299a60f2f05b6bcaa0f3f3c5678f0e954f61fac434d71fc9").unwrap()), + 72771 => Some(HexBinary::from_hex("a0da1b0f65d71e332b20e766770bdbe0cd4e964cec3ac2f83bdd4265e3100054b1d55f5908ad96e6d9351eaf3a109ac4").unwrap()), + 72772 => Some(HexBinary::from_hex("a55e3a39ebba1467c2b6554efc90ccb0ee01066f3845d7f3e3810b3542b3ccc38800b979cd3b5978473b8c6151b9c601").unwrap()), + 72773 => Some(HexBinary::from_hex("9151c497610ad2d56c38048ab003eb0627bf1ce9f08972dfb315137d8b611fef8c8ab460cda603fcd116b55a33df273e").unwrap()), + 72774 => Some(HexBinary::from_hex("b7807d6d54743e9c34d5c45816c5a2a7ab4aa2574f502cf23c886783915685c2827fef9c81069511182cd9d0077c2b7c").unwrap()), + 72775 => Some(HexBinary::from_hex("b5f6f9829ed4e51ec91f1dc6c774c046c6bb5598f4a8796dfebcf5e4317b4ad44b9af67afa8b649ccc6559847e2e2b6f").unwrap()), + 72776 => Some(HexBinary::from_hex("a21bb047b24e979774246c8bcf9791168308ea96954d1ba961d54c8257dfa437d29977a39a093214b249c0855c4a8612").unwrap()), + 72777 => Some(HexBinary::from_hex("8ee97a28414491451247e76ec2c61fbdc9442522ec81409215de92690934c51e6887e51eaac42955fa0af0686bbad851").unwrap()), + 72778 => Some(HexBinary::from_hex("8cc70aa3b6ea98f738b077d42b980b7703168aec3de781d64cfe59af99773e2fc0c577696d67fb8883e560a87465e440").unwrap()), + 72779 => Some(HexBinary::from_hex("8233540728da46c0a35068ee5efb50a6cc42e078fe211c92952ffb6b96717a9a25c709f43ab4822e3916f3ae42598cd4").unwrap()), + 72780 => Some(HexBinary::from_hex("a7a1e62ad5dcc7fc732bc223abc6ab4c00a4c2d04428b69bd365515b881441bbde4b3329e32546be8cce8e70e85070cc").unwrap()), + 72781 => Some(HexBinary::from_hex("8b5cbdc05d038daf51c71eed63c2f5c8bf72e2360b612a9575ed9d45a3ff90f66d12e18578567c0c3dd711e989b8539b").unwrap()), + 72782 => Some(HexBinary::from_hex("990a8a6e635f423ed2605b3d01329a647593a7db3ef3a0cf384f104381b7ec2e4663f10985f885ad6e59334cbbfaaf93").unwrap()), + 72783 => Some(HexBinary::from_hex("a719239e11babe18005a971d397f7119099dad1e7635fde68985a67b85eb28618572d52d2fe371ff40718dcea6af5abb").unwrap()), + 72784 => Some(HexBinary::from_hex("96230c71d747c0db92d122e63e32274776d85121d7df2366bdb0035130a7ec95aa29b43d7c1449459b7c633f65d75f63").unwrap()), + 72785 => Some(HexBinary::from_hex("89ca403495a97bc6ea81233e4e3ded52723594ca9cef7b9f8346e1204e0c488b529e1380dadb25838f7785ccaa762350").unwrap()), + 72786 => Some(HexBinary::from_hex("91419ec23fad8dd559610ce095dd687d09f30fc4d1d34c1ec62a6446c142c76cc32e650a9578efc98e670a2cc2c7c86c").unwrap()), + 72787 => Some(HexBinary::from_hex("ae06b4c06954034462376d074e464908702284398001011530591d16c1b4cfa18f9989aa6e51d216c6e0e747039e7e83").unwrap()), + 72788 => Some(HexBinary::from_hex("8c4e9cbd42fdda1d83e1f00ad1ac7659a2db944596eb2c9bb8122f5ae9252f155a8e283058af90634ce99fe0ff9fe0ac").unwrap()), + 72789 => Some(HexBinary::from_hex("8577003c2e53272cc71607e8899d14b0e68d8326b74124c02705f8b45c87aaf906f9eaf792755fdf0cd9e085d7ebb66a").unwrap()), + 72790 => Some(HexBinary::from_hex("a9fa8a03c1b4eb6881e9b2cfe1629c07667d09d9e5eea9335b1e7a8ed3d38e1c5a8f3d955febf14e6f6957ce01675c94").unwrap()), + 72791 => Some(HexBinary::from_hex("8056ab5a4324344f211a3f243397137c595c9f1f594ad6f0c4bd39830b24d3bf08ca71d8bb796a02fb3a828982324557").unwrap()), + 72792 => Some(HexBinary::from_hex("8d45e96a1f8e22b9c40c2ef9690f54513ea92c3ea26d216a84601de9c8913d06634326d0caa4c822dace1b7d6bc66ad9").unwrap()), + 72793 => Some(HexBinary::from_hex("a18ac7f6e6d5f281246cf4b919d4355701b5b412a31fc758c51a3621eef4f6b5badf9cfe286a3242f3a874fcc7eb21d6").unwrap()), + 72794 => Some(HexBinary::from_hex("99902cb189e8e68efdf26239b76c56d7b5587876fe5f75edc19cb6214b0f8cb60417bd2532368a432312e132bdc2981d").unwrap()), + 72795 => Some(HexBinary::from_hex("a6bf4f24ddbfd9b4c46cca2ec62cfea5a418395a78ce706325df155b765b02775e1a69b6e95d8680a9d33f615b1a6ad3").unwrap()), + 72796 => Some(HexBinary::from_hex("997ccba818886c85d8cac8710084caf197f084fa6da295fdb131d7fc6d83611e60511a0e7579418371642f6d719d321a").unwrap()), + 72797 => Some(HexBinary::from_hex("a78524df2c7f54bb8feee5c6c363472527a7a8ca8d38e61d626d3183660a2f75c725ed93d6c84d9b2b469cb807b92c22").unwrap()), + 72798 => Some(HexBinary::from_hex("a8744de5c129115f3674e1ec12d702d8c73cb4886ce28a8387f0f3d183ca9e24a22ab2179350a55fa8efc6f7b6c666af").unwrap()), + 72799 => Some(HexBinary::from_hex("b82b8429bd439ebe5021e97975b3230ad035f33fc63bcd4056e11c9ee54e369fea633d37d9cb6d17b6abf513ed8f7dbc").unwrap()), + 72800 => Some(HexBinary::from_hex("832939eb2b5860e986454b5f2c7771997f2692d37f5326598c064c632ed4e7dbcd81cbc27f1b2a70a27971df9db724b2").unwrap()), + 72801 => Some(HexBinary::from_hex("b717f5f69096c625ec2ef9d2976995ec2a453a96d965f5a2918a771ae09a6d5e7d301bae12c501adf484625b54282a08").unwrap()), + 72802 => Some(HexBinary::from_hex("b1b52702067f087bdd98fad61adc8456dd36bc8b84ee54f7fc03b36685cf011cae01509cd979c7c999172faedd1cfbc4").unwrap()), + 72803 => Some(HexBinary::from_hex("b19d039350dfbf8a33dc5045a184d7c4063d51d1261266d7e26f2f27470373256a70c84a0f374e44900b4c94cf23bb77").unwrap()), + 72804 => Some(HexBinary::from_hex("8c69c73e0d6c249ff9feb06a4f2491e44393fec7aaec08730269aa617abed5ace5e2df9bdbd1fab12be6b291dff60860").unwrap()), + 72805 => Some(HexBinary::from_hex("ad84be83c1cb7ac243551b8987c7681cf8798e512d2c0f69c98f33c69f5ebc9311efcb5e41913daffa8b130f20f7a6a6").unwrap()), + 72806 => Some(HexBinary::from_hex("846bf0074c5b154c544cc68ca85ede84b6aead5fdb98e7a33b37d07032f1eaf19dc99191950d199954f1832916a53699").unwrap()), + 72807 => Some(HexBinary::from_hex("99b8b008d156e334480d1ca2b68f1be6f80f4a0a640000f716f72698893e62800c26211607219fd2d13580f8244e69f9").unwrap()), + 72808 => Some(HexBinary::from_hex("8f798cdf0cd609a1271b09c54b85d196e370d0569786fbe47524d186c59dea6411a6ae8e7403ba8005c89a4f7a15a6e0").unwrap()), + 72809 => Some(HexBinary::from_hex("89bf0efd4bb186a5815b5eca56b917b2c7cbc6fb87482cef7e974bc93b2534bfdc4e5652e2be81c608c2440035cfc8b2").unwrap()), + 72810 => Some(HexBinary::from_hex("a77370a90972ad07d665a4ccd0927d50e03ce37fe84e1cfacb3bec405c798e6e92bc248e42adf445f12e7b8e5c7c139b").unwrap()), + 72811 => Some(HexBinary::from_hex("a03a7090db4168262ae9c49da3686f3853d02570884bf0a2db870c76dace7d74118276153d599167fb47f0e755ac866c").unwrap()), + 72812 => Some(HexBinary::from_hex("8c1ee2e23d547dd731688aa3305f4c8270b346b04c85b1e8a050f11d9a8cbc52564e2205e737d97df6da207da8ca1408").unwrap()), + 72813 => Some(HexBinary::from_hex("a83adfbafae01bef35b2b7244e5afe08a8f71256067b9a2fa332ea0daaefd5964c3ef5146cd8757749bec228c5e46daf").unwrap()), + 72814 => Some(HexBinary::from_hex("97f728e049b5e18821bd7c8da20d0a417fd99e397e86ab94ee7a555b025a4b898a3f3bc8c84b16d455f72cfdfa6326aa").unwrap()), + 72815 => Some(HexBinary::from_hex("9354e9938245511aa8601f7deaf2dd43863c76cbb77eb4a97ec2548e8bb1f181d12f19dd8717bd4530fc0c429c53befd").unwrap()), + 72816 => Some(HexBinary::from_hex("84abf982c45fe3768bb7fbfc2134531c63638a8a8aa684ea8b0c79de50eae38b76c2645f8194adad7e3665a07fe58f57").unwrap()), + 72817 => Some(HexBinary::from_hex("86d8b0d9c60269c73425daad452745ee0d3cc1ba728e475a657a2a4c93435332c51c7d93b63583771d32d7c1a3ff6272").unwrap()), + 72818 => Some(HexBinary::from_hex("976a8b33332c83d247eff56388fa45cfd0a125f53ec042882d68dd83bdb4b255aa8af3698c537a0a851a718aa96fcf7b").unwrap()), + 72819 => Some(HexBinary::from_hex("a4c74ed60da5067e68bdae1b4c0676f541b304db06ac632bc9de016a13c93106efb44a7ce8cd0a2ac371c08cba7dcb71").unwrap()), + 72820 => Some(HexBinary::from_hex("afa24af003673e74f2eff701fe8f23a22c9e77b359bfea94dc70b8505a0dcc128c8624380b0da4a35724cfa03c3d4ab4").unwrap()), + 72821 => Some(HexBinary::from_hex("8bf4e846f7ff85337a42e46a45384d777f1bc39a02a6e81a7e1bcfc39657aec9866fdd00275137e918782bcdba7cd74c").unwrap()), + 72822 => Some(HexBinary::from_hex("b657aafce2272181fbb66f443a394f12fcb7063f30b8453dcd28a287ee97207f1466abd81e674c460b0d3ed39be3b129").unwrap()), + 72823 => Some(HexBinary::from_hex("ae9162d828ef72aa43e8dedf412632a8caa6634752f40aa3801017967b56b3ced1843ec3997854455ed19dcc052622d5").unwrap()), + 72824 => Some(HexBinary::from_hex("ac04bfa18142b059652332513ed3b98e7c046a45e38b751c078944be7d636ab656d8dcb6a09bc1c653c285b41d5fd668").unwrap()), + 72825 => Some(HexBinary::from_hex("b148e9a2405d0c6e3c2e4ab7257ac73f09bba53bf9c86e1b495414946891aef1bfdfe9111c6ba9eb7d5093cac6f9bd74").unwrap()), + 72826 => Some(HexBinary::from_hex("b6a5365579f3fcce670aee897a8fdbcae48cb3e25f6a1c3b459c23102f2016d06182cfc006bbab47dfce383fbafdd902").unwrap()), + 72827 => Some(HexBinary::from_hex("a46a122fa8a59aa57199441379ee4910df30a46424b171142f27f1d74bfe16830904e264a9d79f6708799f85451e3afc").unwrap()), + 72828 => Some(HexBinary::from_hex("b51bb5a87f1dca711c7dd274968f24f9d147dd7445b347b026b4797a4f817dadb0626282bdcea69ab2c56fa80a1d1687").unwrap()), + 72829 => Some(HexBinary::from_hex("94632c5b182ea793d01843f9543099a1edad125d5cd6976dfaa603ebf1f996a85fa4ad19f55f16ac002186ac2963c167").unwrap()), + 72830 => Some(HexBinary::from_hex("90d1e13c6940fa153d430448b0e8c7244a78d85e54bec943a5ea9b6e18669c8d5dac218b28c4c717412a218bb59c472b").unwrap()), + 72831 => Some(HexBinary::from_hex("aef816957b557503c459c7527f1e4e1a266174646a3dcd0fadcfe8927886c1a44697a00fbf44c232cc9c2ab4cb77ac9c").unwrap()), + 72832 => Some(HexBinary::from_hex("ac141d1080ba10f0f3e67b5fb422bb150768f58d0f2063bc9e1d9cbe2bd3d13ef1844663aff1d631b501e8371536c60f").unwrap()), + 72833 => Some(HexBinary::from_hex("af771d69ee1b53ad284dd4ad06dfb053f48c684d8e6abae56462066d6541e37c8b73d1a75c680f122dde7aaa5edbf48e").unwrap()), + 72834 => Some(HexBinary::from_hex("a010c4e9f142bc08607bbf5162ccf9c5b095472b2dc96f46cb2a38f5b29d41ae452ef66f4a9bc34f9576ebb4d678862b").unwrap()), + 72835 => Some(HexBinary::from_hex("afdf3a64dc7705220e32276f7f0735cd0094c94ce3bd96399b7a121d7b99d2addb463c30014063e37198157ab92aa3b8").unwrap()), + 72836 => Some(HexBinary::from_hex("aad225879d6b49ddb4286187804f03ef8d555b18555922af41cbe4bd159a419271936d4391a9155d445d44e38773484c").unwrap()), + 72837 => Some(HexBinary::from_hex("a73167c6d90f1e02b896ffeaec097090e28ad84151345ae70f8304332a3d3e007048ac95c7418a9419d805c2d6a68c66").unwrap()), + 72838 => Some(HexBinary::from_hex("8a6f14793b44fff353b3f7add79e11a1242f097fb70c79f3733fbbffc74ed4a63b5866c659be53eb32070ee6ebd0a5d8").unwrap()), + 72839 => Some(HexBinary::from_hex("b874580ed9983de51a549c1e229f8287fea919904b8ad8d3228a0e7a72951fbc776535dd000557b16daddf2799050d51").unwrap()), + 72840 => Some(HexBinary::from_hex("a867063df93447726365277509ab4f7a8e0af4fd9c50b8f0b421410aad24661d2d7c80377fbba6226420dab4274c5544").unwrap()), + 72841 => Some(HexBinary::from_hex("8982bf4f48ef4061fe6246ba503f18749e9bdbbd187b8e1320ecc81ffc28d8dd9f402f512af553a6c4a53cd75ca3fc1a").unwrap()), + 72842 => Some(HexBinary::from_hex("b5c118b43845bbcf6efc5cc8eaa7d5eb8f28d43ce880e662c141847bcb2693d07eef01a0ad71466f2afc4d88bd517dbf").unwrap()), + 72843 => Some(HexBinary::from_hex("8b894dfa44523339cef970b26204a477ba670ec0b41212d622be2fe1ed1d8ec5a44ae03f2ca2209fd5e109c11bfc4dca").unwrap()), + 72844 => Some(HexBinary::from_hex("b3c92e851dc0ce3b2c4a07e064e8b29ab159b72b4ad7a8a15d6c1e02c14202740ae5e9bacb5dbc54e43f1faa5672c94f").unwrap()), + 72845 => Some(HexBinary::from_hex("8af73f92b1773c44c38771587071a37011dfa951cc584a58ac73bf1915659b0bd1924cef608442995998d0455944513a").unwrap()), + 72846 => Some(HexBinary::from_hex("a5f596d319c229829af8e6295945d914cd565162ce4919923fee0c15236e1aefc7cd05571659aed86b6ce865c171d864").unwrap()), + 72847 => Some(HexBinary::from_hex("a3b0b9ccb1081fbd89cefecc27cf0e54a73c180ee6978a26df09f9d87ac121d52109f2d4aba830bea3ccb8ed92e8101a").unwrap()), + 72848 => Some(HexBinary::from_hex("b486c9201c440581af4d7f9e954f48ce2c031613ee1fa39c1614428e6dcd53dd7033360bac60d56ccdff5fd094962017").unwrap()), + 72849 => Some(HexBinary::from_hex("b1a8f1cdf3363c7831c11cee99a21240f40e224a203dc78e14c37652b8e3ee31c6c9928cd4adda7278324b4e43ac16d5").unwrap()), + 72850 => Some(HexBinary::from_hex("a7f9ed084cf5bb23801029d45e833e645437fd8121c24e8337aed3d14a36e2ecefa3425ac3b3b87bda80edb2c95803ae").unwrap()), + 72851 => Some(HexBinary::from_hex("968ca20ac4436d6571dea34259ef1ed7841d638be80878e9e58a0199fdd6927c638bca7b05d65c147b98dd22d4c69665").unwrap()), + 72852 => Some(HexBinary::from_hex("838521c08e9e53265df89924bded014716babc2590ee9430390736f4bfdc220246dbcd57bd9152cd7c7a9eb4dd603389").unwrap()), + 72853 => Some(HexBinary::from_hex("a42a95cf71558da6893fe0958b0c0a8e855881e4a51619fc66ddb31fe3c2276236048584fd52563b8c630d4fc0713068").unwrap()), + 72854 => Some(HexBinary::from_hex("ab96330328e9ae74be6faed4836b589ad03cf0c432a37b6e8b4d3ce3004bae91e833e3813118719c0b3386111c11e72e").unwrap()), + 72855 => Some(HexBinary::from_hex("92d560ae39e25dec105c6dcf8db28506224add8e69e3fd0605e46b24352a255867c49307250a034a50e8d2ab3f71d0ca").unwrap()), + 72856 => Some(HexBinary::from_hex("ab6ec7968eb3755c3625c70e66acf33e2d6b6cb9f3bd9303c4b9b68526670c8837b99593ac98d200d6f89c777a2aade2").unwrap()), + 72857 => Some(HexBinary::from_hex("b36e1ed69ca2c4092307abc96a247c7245d4e2d0ef6f0991fd105bd2505ca56795a407a69ebdcfcaa81ce1447530eaf6").unwrap()), + 72858 => Some(HexBinary::from_hex("93525b8f27d3f8d05755f1b3af6a3102b585196b1482ec2460e3e995a27f3cc965e9ca03104cf9777ffbbb8d37937862").unwrap()), + 72859 => Some(HexBinary::from_hex("b6ff444ff5c2f15fed04697d6fbc3bf7fd4468abdf7123c32c89caa2958f8bd22e278150456baed5bd84ef0aba4d517d").unwrap()), + 72860 => Some(HexBinary::from_hex("881e29c74feb7fbee2951ec1d4273537838a5317d8a8cee1b695d202d0f5026d26b9bac87547c29fc8e738aa2e7bfdc5").unwrap()), + 72861 => Some(HexBinary::from_hex("ab0e45babf2db33ce647eaca93b27393ecd5ed645b1e87b814eca8ece3d423d7430c065b2d673d4a0abe2809a1738bea").unwrap()), + 72862 => Some(HexBinary::from_hex("90fafe4b86438a6f78147a35951170b55a00bae7b6f770c7dcad0e592fe827808e61c1cf97faf61fdae7f8961b0d7b79").unwrap()), + 72863 => Some(HexBinary::from_hex("96e6f7628301ffa3b5f773153b12e46c2199926de94b2a3f08c065a551c004092fa1999a7b7fdc9b7b7a70b6e6baea50").unwrap()), + 72864 => Some(HexBinary::from_hex("a31dad7cbeaf1159ce53805b6ae8d60ba9a9e430ec904afcee9d76690f871a8ea1c1f0974b2a9a7eaefd5e052a3881c8").unwrap()), + 72865 => Some(HexBinary::from_hex("98bdeeecf0a78438a17b21081720a2106a5b541818ef9e39eaa2f6c4a72f7193d020b9e2814b0835723d41d190115520").unwrap()), + 72866 => Some(HexBinary::from_hex("90c48ca0f0e22069380067b55d934494d72fa15e4c19def8e1b17a3a3e4855eb03bcb688ed7671bae09cb3400b2a5bf2").unwrap()), + 72867 => Some(HexBinary::from_hex("adcca8b15b4fdade0f27731e48dba3bcd2a2871028233d6357ae2c1575f8dc4cb99753de51f75a3798b9d315132c43dd").unwrap()), + 72868 => Some(HexBinary::from_hex("a8521c436bd9a7c7f5436a0b9ab2b92d963cb25ee1836a56a0029ac0c46bfe8a68cb081331c18ecb47431a8b65d3461f").unwrap()), + 72869 => Some(HexBinary::from_hex("a00585e063672d076dfac5ab31b2e2121c596c9ae47cf2f1217fbf3a19cba1aa88e5dd1901bf4a0543f64e4bf301ce39").unwrap()), + 72870 => Some(HexBinary::from_hex("aba248ed40b05121dfae8758fd62361d74258b52d9b83afabca0344d6173ce43fa3a2b35cb0db2bb7166ee6b83bd5542").unwrap()), + 72871 => Some(HexBinary::from_hex("a790c61a11579b69138b30232e08cc6006c0cf7b1a23e5918a4c3b004566a3204b384c4fc9fa1f4e42f19b623d97ff56").unwrap()), + 72872 => Some(HexBinary::from_hex("a81909447d6c4f2013a8fb3c84f66194b5bbdf56dc26d9b8abb25380d498de1e270008b05a82b7adf32959339d7fe39c").unwrap()), + 72873 => Some(HexBinary::from_hex("af8b4166502c40203b82646b04231c68e2eac1f9616457c0ce6d19768158b2c61aff71aef76c3823c067355be3b8c1b6").unwrap()), + 72874 => Some(HexBinary::from_hex("94e8056b0f25de96cee630f1684262c887bb7ccfd8bed7673ed399ef992c30689ea2ed4e21fbc7eca1d6b63a81987c90").unwrap()), + 72875 => Some(HexBinary::from_hex("a8aa5bee737b2346582e40b749f32c888a6d233b33210ec3c34e0413063fd0c601bb26aac753f3f90b59a712f8beef0d").unwrap()), + 72876 => Some(HexBinary::from_hex("88493818f9356524982bfd91faedd691ef182d52454a5341d4cc51f0d0fd0275be0db679403be0b6411527bf95cc4d7a").unwrap()), + 72877 => Some(HexBinary::from_hex("b8700afa10561f16c5fa62448d5b556841fb6529e05cd0997fd975452ebeda4921a467572eb39ef3010f48109e5d5aba").unwrap()), + 72878 => Some(HexBinary::from_hex("848af264d33ff42fa58a6a5a1059361c93615424237fb90d4e2e4b81775b424fade016252e7a851f9650940a9e4b4c57").unwrap()), + 72879 => Some(HexBinary::from_hex("8973f4b2db8d226391361906ea92eb4e06c481ea06310299d36620284751fbbd75f1bfaf9224ed87e50142048cda3b95").unwrap()), + 72880 => Some(HexBinary::from_hex("a2f012f4b8fb3d55ac418bd9f56e2766d70c8fd047670ac5375097aac066d44d0d7af47d3e32a18ce6e2cabe62e63f5c").unwrap()), + 72881 => Some(HexBinary::from_hex("b6fdb3b7a1dddef07aed014b6d644d945e71014f50039d602606a3af995e1d8dcd21bdb68dc8eeb2c667db7fd36f27aa").unwrap()), + 72882 => Some(HexBinary::from_hex("8511f27c70bde9cf36c190b402e7acd40d61002163cefed03340e38ec5b68bc8d118e775b9fe2fbba8cf05a5e24b2501").unwrap()), + 72883 => Some(HexBinary::from_hex("837b0da961eaf97a778766500f2c15074e207b1b900ca9d666d695f4d18f436c3211281dad9fc477ead57ab81e7c27a8").unwrap()), + 72884 => Some(HexBinary::from_hex("98e00ebab894be0eb9ae05fe3a218109050542859fe8c8a82a68af2f28882466fdf9001690162b9af565a76d108bc705").unwrap()), + 72885 => Some(HexBinary::from_hex("8bd6e3444a068a379080b3da460098fc24f88e423450bcb66043a7ccd19044f9a59dd0712a2c5265040b3afd09c9d7cd").unwrap()), + 72886 => Some(HexBinary::from_hex("8c76086572e587355f28fac437ade17b1fe976d971e83da5f3cfccc0d678f544e4c0ca66d7272f9c2abb8e042406fa1e").unwrap()), + 72887 => Some(HexBinary::from_hex("81d906221fdfedfed8aed282b4039edb064ee35f98f131341f6ba7443593b458914f5d6b5e79ed88781ac051cd384616").unwrap()), + 72888 => Some(HexBinary::from_hex("8bb08b62d708b0b7ac11dc40a25cd34e79eb7eb84cc8b10748a9c8cd0bf945dd31ea09c9a99004aff28b5189a80d1b44").unwrap()), + 72889 => Some(HexBinary::from_hex("8e4a72f21e5f037c6cbae81cc8186288e20bbd2deae14b29a4b8eea690b5e20da1f9bc33f62331626f5d09361567edc8").unwrap()), + 72890 => Some(HexBinary::from_hex("920766c4ba623a879bf0e9eb0edcb1fd20ebf61a4397994fb635f348cb4b0cf413bb7b16b5ea72626a918a56e20e114a").unwrap()), + 72891 => Some(HexBinary::from_hex("a79f6d66dd4523ebb98b4fbb2438d090a12d5feddcdf1196531ea8fbb0b2355298b0e0c1284291b087de1876ba5310fe").unwrap()), + 72892 => Some(HexBinary::from_hex("a7c4573015c9e9addd6657965cd141ed265d55b05d55e95457ec9403b608b77ecd745dbee3d254e597a6ae9ebe6b9063").unwrap()), + 72893 => Some(HexBinary::from_hex("b7e2554b5ec074d09bda8a50af81dc06d0749f4a62acfe3c23591338293d1a8162ed6a96e17884099c39ddca1f2d0e28").unwrap()), + 72894 => Some(HexBinary::from_hex("a71bd5d077d83623254e54ed050960cb7e698783b92b307c69516fddf05b038d3bd912cd3ec8170aebe651c11de370aa").unwrap()), + 72895 => Some(HexBinary::from_hex("b9d3c35981ef6efdf03d4060705be535b3f9f4304e95687c7d23557092b1913d2d4b03fa4a45851982b15d25d13ca0ef").unwrap()), + 72896 => Some(HexBinary::from_hex("a27659f0ecd113064158d8f94e540839bb212082162d779ad2840a2853b1c303ea4627ea73dbcb1b284f4895117558fa").unwrap()), + 72897 => Some(HexBinary::from_hex("a8dd27a5d7c7f66790381a0eb9fdffa2e71089e646010cea1694af5399f7535ff7bb88a7066f9d852eaa6d609e84c7e8").unwrap()), + 72898 => Some(HexBinary::from_hex("a95e7c617fa6d921c62614a6edefa641628b109c82f424483fc441dbedd28cc82b84fcd4d99cafb6efcfce398e90ed07").unwrap()), + 72899 => Some(HexBinary::from_hex("b631694cc999aedcf7379f588361b2c3b9d1b35ac135560ae36cf6d480540362aae67beb5d4c66cb14055b381a3f70d7").unwrap()), + 72900 => Some(HexBinary::from_hex("a9be09cce2ee871b12a770d8fa3fd7b1fc95a82ea730deb8915d4c460ecd51d21d05ec0bb7a5c54d543f5a1f00750d69").unwrap()), + _ => None, + } +} diff --git a/packages/multitest/tests/drand-gateway.rs b/packages/multitest/tests/drand-gateway.rs index 72f138b7..f7674911 100644 --- a/packages/multitest/tests/drand-gateway.rs +++ b/packages/multitest/tests/drand-gateway.rs @@ -347,6 +347,7 @@ fn integration_test() { // curl -sS https://drand.cloudflare.com/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/public/72775 const SIGNATURE: &str = "973ae0dd58e53c7ca80952ee26e0565627dd61cc5ded60b20d2d846e5354d2aec13d08a2bfbc240c794993d16a0dae90"; let msg = nois_drand::msg::ExecuteMsg::AddRound { + network: None, round: ROUND, signature: HexBinary::from_hex(SIGNATURE).unwrap(), }; @@ -366,6 +367,7 @@ fn integration_test() { ); // Add round 2nd submission let msg = nois_drand::msg::ExecuteMsg::AddRound { + network: None, round: ROUND, signature: HexBinary::from_hex(SIGNATURE).unwrap(), }; @@ -385,6 +387,7 @@ fn integration_test() { ); // Add round 3rd submission let msg = nois_drand::msg::ExecuteMsg::AddRound { + network: None, round: ROUND, signature: HexBinary::from_hex(SIGNATURE).unwrap(), }; @@ -404,6 +407,7 @@ fn integration_test() { ); // Add round 4th submission let msg = nois_drand::msg::ExecuteMsg::AddRound { + network: None, round: ROUND, signature: HexBinary::from_hex(SIGNATURE).unwrap(), }; @@ -423,6 +427,7 @@ fn integration_test() { ); // Add round 5th submission let msg = nois_drand::msg::ExecuteMsg::AddRound { + network: None, round: ROUND, signature: HexBinary::from_hex(SIGNATURE).unwrap(), }; @@ -442,6 +447,7 @@ fn integration_test() { ); // Add round 6th submission let msg = nois_drand::msg::ExecuteMsg::AddRound { + network: None, round: ROUND, signature: HexBinary::from_hex(SIGNATURE).unwrap(), }; @@ -461,6 +467,7 @@ fn integration_test() { ); // Add round 7th submission let msg = nois_drand::msg::ExecuteMsg::AddRound { + network: None, round: ROUND, signature: HexBinary::from_hex(SIGNATURE).unwrap(), }; @@ -483,6 +490,7 @@ fn integration_test() { // and when a new bot brings a submission that won't go through verification. It should fail if it // is different from the randomness already registered on contract state for that round. let msg = nois_drand::msg::ExecuteMsg::AddRound { + network: None, round: ROUND, signature: HexBinary::from_hex("886832ac1b059709a8966347fc447773e15ceff1eada944504fa541ab71c1d1c9ff4f2bbc69f90669a0cf936d018ab52").unwrap(), }; diff --git a/packages/multitest/tests/multitest.rs b/packages/multitest/tests/multitest.rs index e31e4999..9cc6752c 100644 --- a/packages/multitest/tests/multitest.rs +++ b/packages/multitest/tests/multitest.rs @@ -174,6 +174,7 @@ fn integration_test() { // Add verified round let msg = nois_gateway::msg::ExecuteMsg::AddVerifiedRound { // curl -sS https://drand.cloudflare.com/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/public/72785 + network: Some("fastnet".to_string()), round: 72785, randomness: HexBinary::from_hex( "650be14f6ffd7dcb67df9138c3b7d7d6bca455d0438fc81d3fbb24a4ee038f36", diff --git a/packages/multitest/tests/proxy-governance-owned.rs b/packages/multitest/tests/proxy-governance-owned.rs index 9b8eb02b..1814302e 100644 --- a/packages/multitest/tests/proxy-governance-owned.rs +++ b/packages/multitest/tests/proxy-governance-owned.rs @@ -223,6 +223,7 @@ fn integration_test() { // Add verified round let msg = nois_gateway::msg::ExecuteMsg::AddVerifiedRound { // curl -sS https://drand.cloudflare.com/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493/public/72785 + network: Some("fastnet".to_string()), round: 72785, randomness: HexBinary::from_hex( "650be14f6ffd7dcb67df9138c3b7d7d6bca455d0438fc81d3fbb24a4ee038f36", diff --git a/tests/src/contracts.ts b/tests/src/contracts.ts index 5916e7b4..29f94ac4 100644 --- a/tests/src/contracts.ts +++ b/tests/src/contracts.ts @@ -36,6 +36,7 @@ export interface DrandInstantiateMsg { export interface DrandExecuteMsg { readonly add_round?: { + readonly network?: null | "fastnet" | "quicknet"; readonly round: number; readonly signature: string; };