Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✅ Add contract update test #691

Merged
merged 1 commit into from
Jan 28, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 69 additions & 1 deletion src/tests/tx_settlement.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use client_sdk::rest_client::{IndexerApiHttpClient, NodeApiHttpClient};
use hyle_model::{
BlobTransaction, ContractAction, ContractName, Hashable, ProgramId, ProofData,
ProofTransaction, RegisterContractAction, StateDigest,
ProofTransaction, RegisterContractAction, RegisterContractEffect, StateDigest,
};
use testcontainers_modules::{
postgres::Postgres,
Expand Down Expand Up @@ -138,3 +138,71 @@ async fn test_full_settlement_flow() -> Result<()> {

Ok(())
}

#[test_log::test(tokio::test)]
async fn test_contract_upgrade() -> Result<()> {
let builder = NodeIntegrationCtxBuilder::new().await;
let rest_url = builder.conf.rest.clone();
let mut node_modules = builder.build().await?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible to call it "node" please :D :D :D my brain can't deal with npm's "node_modules" nightmare XD

and it makes sense to write node.wait_for_n_blocks(1).await?;


node_modules.wait_for_genesis_event().await?;

let client = NodeApiHttpClient::new(format!("http://{rest_url}/")).unwrap();

info!("➡️ Registering contracts c1.hyle");

let b1 = make_register_blob_action("c1.hyle".into(), StateDigest(vec![1, 2, 3]));
client.send_tx_blob(&b1).await.unwrap();

node_modules.wait_for_settled_tx(b1.hash()).await?;

let contract = client.get_contract(&"c1.hyle".into()).await?;
assert_eq!(contract.program_id, ProgramId(vec![1, 2, 3]));

// Send contract update transaction
let b2 = BlobTransaction {
identity: "toto.c1.hyle".into(),
blobs: vec![Blob {
contract_name: "c1.hyle".into(),
data: BlobData(vec![1]),
}],
};
client.send_tx_blob(&b2).await.unwrap();

let mut hyle_output =
make_hyle_output_with_state(b2.clone(), BlobIndex(0), &[1, 2, 3], &[8, 8, 8]);

hyle_output
.registered_contracts
.push(RegisterContractEffect {
verifier: "test".into(),
program_id: ProgramId(vec![7, 7, 7]),
// The state digest is ignored during the update phase.
state_digest: StateDigest(vec![3, 3, 3]),
Comment on lines +180 to +181
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ça je pense que ça va être confusant non ? Est-ce qu'on aurait pas plutôt un "UpdateContractEffect" avec uniquement les fields nécessaire ? Pas sûr que le contract_name soit utile par exemple

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mh, en soit je suis d'accord que c'est pas obvious, mais je me dis que ça pourrait être caché par le SDK.
Je suis pas sûr que ça soit ultra-utile côté node d'avoir la distinction?

En pratique c'est un artefact du fait que je process les registrations avant de process les contract-update dans node_state, si on inverse, c'est le contraire et c'est le next_state de la proof qui est zappé.

contract_name: "c1.hyle".into(),
});

let proof_update = ProofTransaction {
contract_name: "c1.hyle".into(),
proof: ProofData(
bincode::encode_to_vec(vec![hyle_output], bincode::config::standard()).unwrap(),
),
};

client.send_tx_proof(&proof_update).await.unwrap();

info!("➡️ Waiting for TX to be settled");
node_modules.wait_for_settled_tx(b2.hash()).await?;
// Wait a block on top to make sure the state is updated.
node_modules.wait_for_n_blocks(1).await?;

info!("➡️ Getting contracts");

let contract = client.get_contract(&"c1.hyle".into()).await?;
// Check program ID has changed.
assert_eq!(contract.program_id, ProgramId(vec![7, 7, 7]));
// We use the next_state, not the state_digest of the update effect.
assert_eq!(contract.state.0, vec![8, 8, 8]);

Ok(())
}
Loading