Skip to content

Commit 3697124

Browse files
committed
Add integration tests for smart-contracts
1 parent fd2d551 commit 3697124

File tree

5 files changed

+207
-1
lines changed

5 files changed

+207
-1
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ pallas-addresses = { git = "https://github.com/txpipe/pallas.git", tag = "v0.31.
8383
pallas-primitives = { git = "https://github.com/txpipe/pallas.git", tag = "v0.31.0" }
8484
proptest = { version = "1.5.0" }
8585
scale-info = { version = "2.11.1", default-features = false, features = ["derive"] }
86+
testcontainers = { version = "0.15.0" }
8687
quickcheck_macros = { version = "1" }
8788
quote = "1.0"
8889
rand_chacha = { version = "0.3.1", default-features = false }

toolkit/offchain/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,4 @@ fraction = { workspace = true, features = ["with-decimal", "with-serde-support"]
4040
proptest = { workspace = true }
4141
time = { workspace = true, features = ["std", "serde", "parsing"] }
4242
pretty_assertions = { workspace = true }
43+
testcontainers = { workspace = true }

toolkit/offchain/tests/docker/entrypoint.sh

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#! /bin/bash
22

3+
chmod 400 /config/keys/kes.skey
4+
chmod 400 /config/keys/vrf.skey
5+
36
byron_startTime=$(( $(date +%s) + 1 ))
47
shelley_systemStart=$(date --utc +"%Y-%m-%dT%H:%M:%SZ" --date="@$byron_startTime")
58

toolkit/offchain/tests/integration_tests.rs

+201-1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,204 @@
66
//! In case of change to the supported cardano-node or ogmios,
77
//! it should be updated accordingly and pushed to the registry.
88
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

Comments
 (0)