|
6 | 6 | //! In case of change to the supported cardano-node or ogmios,
|
7 | 7 | //! it should be updated accordingly and pushed to the registry.
|
8 | 8 |
|
9 |
| -pub const WHY_EMPTY: &str = "test will be implemented in the next pull request"; |
| 9 | +use hex_literal::hex; |
| 10 | +use jsonrpsee::http_client::HttpClient; |
| 11 | +use ogmios_client::{ |
| 12 | + query_ledger_state::{QueryLedgerState, QueryUtxoByUtxoId}, |
| 13 | + query_network::QueryNetwork, |
| 14 | + transactions::Transactions, |
| 15 | + types::OgmiosTx, |
| 16 | + OgmiosClientError, |
| 17 | +}; |
| 18 | +use partner_chains_cardano_offchain::{ |
| 19 | + await_tx::{AwaitTx, FixedDelayRetries}, |
| 20 | + d_param, init_governance, |
| 21 | + register::Register, |
| 22 | +}; |
| 23 | +use sidechain_domain::{ |
| 24 | + AdaBasedStaking, AuraPublicKey, CandidateRegistration, DParameter, GrandpaPublicKey, |
| 25 | + MainchainAddressHash, MainchainPrivateKey, MainchainPublicKey, MainchainSignature, McTxHash, |
| 26 | + SidechainPublicKey, SidechainSignature, UtxoId, |
| 27 | +}; |
| 28 | +use std::time::Duration; |
| 29 | +use testcontainers::{clients::Cli, Container, GenericImage}; |
| 30 | +use tokio_retry::{strategy::FixedInterval, Retry}; |
| 31 | + |
| 32 | +const TEST_IMAGE: &str = "ghcr.io/input-output-hk/smart-contracts-tests-cardano-node-ogmios"; |
| 33 | + |
| 34 | +const TEST_IMAGE_TAG: &str = "v10.2.1-v6.9.0"; |
| 35 | + |
| 36 | +const GOVERNANCE_AUTHORITY: MainchainAddressHash = |
| 37 | + MainchainAddressHash(hex!("e8c300330fe315531ca89d4a2e7d0c80211bc70b473b1ed4979dff2b")); |
| 38 | + |
| 39 | +const GOVERNANCE_AUTHORITY_PAYMENT_KEY: MainchainPrivateKey = |
| 40 | + MainchainPrivateKey(hex!("d0a6c5c921266d15dc8d1ce1e51a01e929a686ed3ec1a9be1145727c224bf386")); |
| 41 | + |
| 42 | +const GOVERNANCE_AUTHORITY_ADDRESS: &str = |
| 43 | + "addr_test1vr5vxqpnpl3325cu4zw55tnapjqzzx78pdrnk8k5j7wl72c6y08nd"; |
| 44 | + |
| 45 | +const EVE_PAYMENT_KEY: MainchainPrivateKey = |
| 46 | + MainchainPrivateKey(hex!("34a6ce19688e950b58ea73803a00db61d0505ba10d65756d85f27c37d24c06af")); |
| 47 | + |
| 48 | +const EVE_PUBLIC_KEY: MainchainPublicKey = |
| 49 | + MainchainPublicKey(hex!("a5ab6e82531cac3480cf7ff360f38a0beeea93cabfdd1ed0495e0423f7875c57")); |
| 50 | + |
| 51 | +const EVE_PUBLIC_KEY_HASH: MainchainAddressHash = |
| 52 | + MainchainAddressHash(hex!("84ba05c28879b299a8377e62128adc7a0e0df3ac438ff95efc7c8443")); |
| 53 | + |
| 54 | +const EVE_ADDRESS: &str = "addr_test1vzzt5pwz3pum9xdgxalxyy52m3aqur0n43pcl727l37ggscl8h7v8"; |
| 55 | + |
| 56 | +#[tokio::test] |
| 57 | +async fn init_goveranance() { |
| 58 | + let image = GenericImage::new(TEST_IMAGE, TEST_IMAGE_TAG); |
| 59 | + let client = Cli::default(); |
| 60 | + let container = client.run(image); |
| 61 | + let client = initialize(&container).await; |
| 62 | + let _ = run_init_goveranance(&client).await; |
| 63 | + () |
| 64 | +} |
| 65 | + |
| 66 | +#[ignore = "awaiting fix for matching evaluation costs of redeemers"] |
| 67 | +#[tokio::test] |
| 68 | +async fn upsert_d_param() { |
| 69 | + let image = GenericImage::new(TEST_IMAGE, TEST_IMAGE_TAG); |
| 70 | + let client = Cli::default(); |
| 71 | + let container = client.run(image); |
| 72 | + let client = initialize(&container).await; |
| 73 | + let genesis_utxo = run_init_goveranance(&client).await; |
| 74 | + assert!(run_upsert_d_param(genesis_utxo, 0, 1, &client).await.is_some()); |
| 75 | + assert!(run_upsert_d_param(genesis_utxo, 0, 1, &client).await.is_none()); |
| 76 | + assert!(run_upsert_d_param(genesis_utxo, 1, 1, &client).await.is_some()) |
| 77 | +} |
| 78 | + |
| 79 | +#[ignore = "Internal error: cannot use evaluateTransaction response"] |
| 80 | +#[tokio::test] |
| 81 | +async fn register() { |
| 82 | + let _ = env_logger::builder().is_test(true).try_init(); |
| 83 | + let image = GenericImage::new(TEST_IMAGE, TEST_IMAGE_TAG); |
| 84 | + let client = Cli::default(); |
| 85 | + let container = client.run(image); |
| 86 | + let client = initialize(&container).await; |
| 87 | + let genesis_utxo = run_init_goveranance(&client).await; |
| 88 | + let signature = SidechainSignature([21u8; 33].to_vec()); |
| 89 | + let other_signature = SidechainSignature([121u8; 33].to_vec()); |
| 90 | + assert!(run_register(genesis_utxo, signature.clone(), &client).await.is_some()); |
| 91 | + assert!(run_register(genesis_utxo, signature, &client).await.is_none()); |
| 92 | + assert!(run_register(genesis_utxo, other_signature, &client).await.is_some()); |
| 93 | +} |
| 94 | + |
| 95 | +async fn initialize<'a>(container: &Container<'a, GenericImage>) -> HttpClient { |
| 96 | + let ogmios_port = container.get_host_port_ipv4(1337); |
| 97 | + println!("Ogmios port: {}", ogmios_port); |
| 98 | + let client = HttpClient::builder() |
| 99 | + .build(format!("http://localhost:{}", ogmios_port)) |
| 100 | + .unwrap(); |
| 101 | + |
| 102 | + await_ogmios(&client).await.unwrap(); |
| 103 | + println!("Ogmios is up"); |
| 104 | + let _ = initial_transaction(&client).await.unwrap(); |
| 105 | + println!("Initial transaction confirmed"); |
| 106 | + client |
| 107 | +} |
| 108 | + |
| 109 | +async fn await_ogmios<T: QueryNetwork>(client: &T) -> Result<(), OgmiosClientError> { |
| 110 | + Retry::spawn(FixedInterval::new(Duration::from_millis(100)).take(1000), || async { |
| 111 | + client.shelley_genesis_configuration().await.map(|_| ()) |
| 112 | + }) |
| 113 | + .await |
| 114 | +} |
| 115 | + |
| 116 | +/// initial transaction was obtained with cardano-cli and it sends funds to: |
| 117 | +/// * goveranance authority: addr_test1vr5vxqpnpl3325cu4zw55tnapjqzzx78pdrnk8k5j7wl72c6y08nd (2 x UTXO) |
| 118 | +/// * "dave" address: addr_test1vphpcf32drhhznv6rqmrmgpuwq06kug0lkg22ux777rtlqst2er0r |
| 119 | +/// * "eve" address: addr_test1vzzt5pwz3pum9xdgxalxyy52m3aqur0n43pcl727l37ggscl8h7v8 |
| 120 | +/// Its hash is 0xc389187c6cabf1cd2ca64cf8c76bf57288eb9c02ced6781935b810a1d0e7fbb4 |
| 121 | +async fn initial_transaction<T: Transactions + QueryUtxoByUtxoId>( |
| 122 | + client: &T, |
| 123 | +) -> Result<McTxHash, ()> { |
| 124 | + let signed_tx_bytes = hex!("84a300d9010281825820781cb948a37c7c38b43872af9b1e22135a94826eafd3740260a6db0a303885d800018582581d60e8c300330fe315531ca89d4a2e7d0c80211bc70b473b1ed4979dff2b1a3b9aca0082581d60e8c300330fe315531ca89d4a2e7d0c80211bc70b473b1ed4979dff2b1a3b9aca0082581d606e1c262a68ef714d9a18363da03c701fab710ffd90a570def786bf821a3b9aca0082581d6084ba05c28879b299a8377e62128adc7a0e0df3ac438ff95efc7c84431a3b9aca0082581d60e8c300330fe315531ca89d4a2e7d0c80211bc70b473b1ed4979dff2b1b006a8e81e074b5c0021a000f4240a100d9010281825820e6ceac21f27c463f9065fafdc62883d7e52f6a376b498b8838ba513e44c74eca58406d60019f2589001024a15c300e034de74998a5b7bc995a8d0f21c2fdfc0cd7c9106d77e6507d5b708434d0616a7b1a53ec0341dffc553e2ab8c9be15197d0503f5f6"); |
| 125 | + let tx_hash = client |
| 126 | + .submit_transaction(&signed_tx_bytes) |
| 127 | + .await |
| 128 | + .map_err(|_| ()) |
| 129 | + .map(|response| McTxHash(response.transaction.id))?; |
| 130 | + FixedDelayRetries::new(Duration::from_millis(500), 100) |
| 131 | + .await_tx_output(client, UtxoId::new(tx_hash.0, 0)) |
| 132 | + .await |
| 133 | + .map_err(|_| ())?; |
| 134 | + Ok(tx_hash) |
| 135 | +} |
| 136 | + |
| 137 | +async fn run_init_goveranance< |
| 138 | + T: QueryLedgerState + Transactions + QueryNetwork + QueryUtxoByUtxoId, |
| 139 | +>( |
| 140 | + client: &T, |
| 141 | +) -> UtxoId { |
| 142 | + let governance_utxos = |
| 143 | + client.query_utxos(&[GOVERNANCE_AUTHORITY_ADDRESS.to_string()]).await.unwrap(); |
| 144 | + let genesis_utxo = governance_utxos.first().cloned().unwrap().utxo_id(); |
| 145 | + let _ = init_governance::run_init_governance( |
| 146 | + GOVERNANCE_AUTHORITY, |
| 147 | + GOVERNANCE_AUTHORITY_PAYMENT_KEY, |
| 148 | + Some(genesis_utxo), |
| 149 | + client, |
| 150 | + FixedDelayRetries::new(Duration::from_millis(500), 100), |
| 151 | + ) |
| 152 | + .await |
| 153 | + .unwrap(); |
| 154 | + genesis_utxo |
| 155 | +} |
| 156 | + |
| 157 | +async fn run_upsert_d_param< |
| 158 | + T: QueryLedgerState + Transactions + QueryNetwork + QueryUtxoByUtxoId, |
| 159 | +>( |
| 160 | + genesis_utxo: UtxoId, |
| 161 | + num_permissioned_candidates: u16, |
| 162 | + num_registered_candidates: u16, |
| 163 | + client: &T, |
| 164 | +) -> Option<McTxHash> { |
| 165 | + let tx_hash = d_param::upsert_d_param( |
| 166 | + genesis_utxo, |
| 167 | + &DParameter { num_permissioned_candidates, num_registered_candidates }, |
| 168 | + GOVERNANCE_AUTHORITY_PAYMENT_KEY.0, |
| 169 | + client, |
| 170 | + ) |
| 171 | + .await |
| 172 | + .unwrap(); |
| 173 | + match tx_hash { |
| 174 | + Some(tx_hash) => FixedDelayRetries::new(Duration::from_millis(500), 100) |
| 175 | + .await_tx_output(client, UtxoId::new(tx_hash.0, 0)) |
| 176 | + .await |
| 177 | + .unwrap(), |
| 178 | + None => (), |
| 179 | + }; |
| 180 | + tx_hash |
| 181 | +} |
| 182 | + |
| 183 | +async fn run_register<T: QueryLedgerState + Transactions + QueryNetwork + QueryUtxoByUtxoId>( |
| 184 | + genesis_utxo: UtxoId, |
| 185 | + partnerchain_signature: SidechainSignature, |
| 186 | + client: &T, |
| 187 | +) -> Option<OgmiosTx> { |
| 188 | + let eve_utxos = client.query_utxos(&[EVE_ADDRESS.to_string()]).await.unwrap(); |
| 189 | + let registration_utxo = eve_utxos.first().unwrap().utxo_id(); |
| 190 | + client |
| 191 | + .register( |
| 192 | + genesis_utxo, |
| 193 | + &CandidateRegistration { |
| 194 | + stake_ownership: AdaBasedStaking { |
| 195 | + pub_key: EVE_PUBLIC_KEY, |
| 196 | + signature: MainchainSignature(vec![19u8; 32]), |
| 197 | + }, |
| 198 | + partnerchain_pub_key: SidechainPublicKey([20u8; 32].to_vec()), |
| 199 | + partnerchain_signature, |
| 200 | + own_pkh: EVE_PUBLIC_KEY_HASH, |
| 201 | + registration_utxo, |
| 202 | + aura_pub_key: AuraPublicKey([22u8; 32].to_vec()), |
| 203 | + grandpa_pub_key: GrandpaPublicKey([23u8; 32].to_vec()), |
| 204 | + }, |
| 205 | + EVE_PAYMENT_KEY, |
| 206 | + ) |
| 207 | + .await |
| 208 | + .unwrap() |
| 209 | +} |
0 commit comments