feat: fully integrate Sequencer, Indexer and Explorer with Bedrock

This commit is contained in:
Daniil Polyakov
2026-02-12 16:31:13 +03:00
parent 818fc5e601
commit 975cfb9ec6
131 changed files with 3160 additions and 2824 deletions
+5 -3
View File
@@ -7,20 +7,20 @@ license = { workspace = true }
[dependencies]
nssa_core = { workspace = true, features = ["host"] }
nssa.workspace = true
sequencer_core = { workspace = true, features = ["testnet"] }
sequencer_core = { workspace = true, features = ["default", "testnet"] }
sequencer_runner.workspace = true
wallet.workspace = true
common.workspace = true
key_protocol.workspace = true
indexer_core.workspace = true
wallet-ffi.workspace = true
serde_json.workspace = true
token_core.workspace = true
indexer_service.workspace = true
url.workspace = true
anyhow.workspace = true
env_logger.workspace = true
log.workspace = true
serde_json.workspace = true
actix-web.workspace = true
base64.workspace = true
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
@@ -28,3 +28,5 @@ hex.workspace = true
tempfile.workspace = true
borsh.workspace = true
futures.workspace = true
rand.workspace = true
testcontainers = { version = "0.26.3", features = ["docker-compose"] }
+32
View File
@@ -0,0 +1,32 @@
# Bedrock Configuration Files for Integration Tests
## How to update
- `docker-compose.yml` file.
Compare with `https://github.com/logos-blockchain/logos-blockchain/blob/master/compose.static.yml` and update the file accordingly, don't bring unneeded things like grafana and etc.
Replace `sha` hash with the latest `testnet` tag hash.
- `scripts` folder.
```bash
curl https://raw.githubusercontent.com/logos-blockchain/logos-blockchain/master/testnet/scripts/run_cfgsync.sh >> scripts/run_cfgsync.sh
curl https://raw.githubusercontent.com/logos-blockchain/logos-blockchain/master/testnet/scripts/run_logos_blockchain_node.sh >> scripts/run_logos_blockchain_node.sh
chmod +x scripts/*
```
Then in `scripts/run_logos_blockchain_node.sh` update `cfgsync-client` to `logos-blockchain-cfgsync-client` and in `scripts/run_cfgsync.sh` update `cfgsync-server` to `logos-blockchain-cfgsync-server` if it hasn't been fixed already, see <https://github.com/logos-blockchain/logos-blockchain/pull/2092>.
- `cfgsync.yaml` file.
```bash
curl -O https://raw.githubusercontent.com/logos-blockchain/logos-blockchain/master/testnet/cfgsync.yaml
```
Set `logger`, `tracing` and `metrics` to `None`
- `kzgrs_test_params` file.
```bash
curl -O https://raw.githubusercontent.com/logos-blockchain/logos-blockchain/master/tests/kzgrs/kzgrs_test_params
```
+14
View File
@@ -0,0 +1,14 @@
port: 4400
n_hosts: 4
timeout: 10
# Tracing
tracing_settings:
logger: None
tracing: None
filter: !EnvFilter
filters:
logos-blockchain: debug
metrics: None
console: None
level: INFO
@@ -0,0 +1,47 @@
services:
cfgsync:
image: ghcr.io/logos-blockchain/logos-blockchain@sha256:000982e751dfd346ca5346b8025c685fc3abc585079c59cde3bde7fd63100657
volumes:
- ./scripts:/etc/logos-blockchain/scripts
- ./cfgsync.yaml:/etc/logos-blockchain/cfgsync.yaml:z
entrypoint: /etc/logos-blockchain/scripts/run_cfgsync.sh
logos-blockchain-node-0:
image: ghcr.io/logos-blockchain/logos-blockchain@sha256:000982e751dfd346ca5346b8025c685fc3abc585079c59cde3bde7fd63100657
ports:
# Map 0 port so that multiple instances can run on the same host
- "0:18080/tcp"
volumes:
- ./scripts:/etc/logos-blockchain/scripts
- ./kzgrs_test_params:/kzgrs_test_params:z
depends_on:
- cfgsync
entrypoint: /etc/logos-blockchain/scripts/run_logos_blockchain_node.sh
logos-blockchain-node-1:
image: ghcr.io/logos-blockchain/logos-blockchain@sha256:000982e751dfd346ca5346b8025c685fc3abc585079c59cde3bde7fd63100657
volumes:
- ./scripts:/etc/logos-blockchain/scripts
- ./kzgrs_test_params:/kzgrs_test_params:z
depends_on:
- cfgsync
entrypoint: /etc/logos-blockchain/scripts/run_logos_blockchain_node.sh
logos-blockchain-node-2:
image: ghcr.io/logos-blockchain/logos-blockchain@sha256:000982e751dfd346ca5346b8025c685fc3abc585079c59cde3bde7fd63100657
volumes:
- ./scripts:/etc/logos-blockchain/scripts
- ./kzgrs_test_params:/kzgrs_test_params:z
depends_on:
- cfgsync
entrypoint: /etc/logos-blockchain/scripts/run_logos_blockchain_node.sh
logos-blockchain-node-3:
image: ghcr.io/logos-blockchain/logos-blockchain@sha256:000982e751dfd346ca5346b8025c685fc3abc585079c59cde3bde7fd63100657
volumes:
- ./scripts:/etc/logos-blockchain/scripts
- ./kzgrs_test_params:/kzgrs_test_params:z
depends_on:
- cfgsync
entrypoint: /etc/logos-blockchain/scripts/run_logos_blockchain_node.sh
Binary file not shown.
+5
View File
@@ -0,0 +1,5 @@
#!/bin/sh
set -e
exec /usr/bin/logos-blockchain-cfgsync-server /etc/logos-blockchain/cfgsync.yaml
@@ -0,0 +1,13 @@
#!/bin/sh
set -e
export CFG_FILE_PATH="/config.yaml" \
CFG_SERVER_ADDR="http://cfgsync:4400" \
CFG_HOST_IP=$(hostname -i) \
CFG_HOST_IDENTIFIER="validator-$(hostname -i)" \
LOG_LEVEL="INFO" \
POL_PROOF_DEV_MODE=true
/usr/bin/logos-blockchain-cfgsync-client && \
exec /usr/bin/logos-blockchain-node /config.yaml
@@ -1,17 +0,0 @@
{
"bedrock_client_config": {
"addr": "http://127.0.0.1:8080",
"auth": {
"username": "user"
}
},
"channel_id": "0101010101010101010101010101010101010101010101010101010101010101",
"backoff": {
"max_retries": 10,
"start_delay_millis": 100
},
"resubscribe_interval_millis": 1000,
"sequencer_client_config": {
"addr": "will_be_replaced_in_runtime"
}
}
@@ -1,165 +0,0 @@
{
"home": "",
"override_rust_log": null,
"genesis_id": 1,
"is_genesis_random": true,
"max_num_tx_in_block": 20,
"mempool_max_size": 10000,
"block_create_timeout_millis": 10000,
"port": 0,
"initial_accounts": [
{
"account_id": "BLgCRDXYdQPMMWVHYRFGQZbgeHx9frkipa8GtpG2Syqy",
"balance": 10000
},
{
"account_id": "Gj1mJy5W7J5pfmLRujmQaLfLMWidNxQ6uwnhb666ZwHw",
"balance": 20000
}
],
"initial_commitments": [
{
"npk": [
63,
202,
178,
231,
183,
82,
237,
212,
216,
221,
215,
255,
153,
101,
177,
161,
254,
210,
128,
122,
54,
190,
230,
151,
183,
64,
225,
229,
113,
1,
228,
97
],
"account": {
"program_owner": [
0,
0,
0,
0,
0,
0,
0,
0
],
"balance": 10000,
"data": [],
"nonce": 0
}
},
{
"npk": [
192,
251,
166,
243,
167,
236,
84,
249,
35,
136,
130,
172,
219,
225,
161,
139,
229,
89,
243,
125,
194,
213,
209,
30,
23,
174,
100,
244,
124,
74,
140,
47
],
"account": {
"program_owner": [
0,
0,
0,
0,
0,
0,
0,
0
],
"balance": 20000,
"data": [],
"nonce": 0
}
}
],
"signing_key": [
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37
],
"bedrock_config": {
"channel_id": "0101010101010101010101010101010101010101010101010101010101010101",
"node_url": "http://127.0.0.1:8080",
"auth": {
"username": "user"
}
}
}
@@ -1,159 +0,0 @@
{
"home": "",
"override_rust_log": null,
"genesis_id": 1,
"is_genesis_random": true,
"max_num_tx_in_block": 20,
"mempool_max_size": 10000,
"block_create_timeout_millis": 10000,
"retry_pending_blocks_timeout_millis": 240000,
"port": 0,
"initial_accounts": [
{
"account_id": "6iArKUXxhUJqS7kCaPNhwMWt3ro71PDyBj7jwAyE2VQV",
"balance": 10000
},
{
"account_id": "7wHg9sbJwc6h3NP1S9bekfAzB8CHifEcxKswCKUt3YQo",
"balance": 20000
}
],
"initial_commitments": [
{
"npk": [
63,
202,
178,
231,
183,
82,
237,
212,
216,
221,
215,
255,
153,
101,
177,
161,
254,
210,
128,
122,
54,
190,
230,
151,
183,
64,
225,
229,
113,
1,
228,
97
],
"account": {
"program_owner": [
0,
0,
0,
0,
0,
0,
0,
0
],
"balance": 10000,
"data": [],
"nonce": 0
}
},
{
"npk": [
192,
251,
166,
243,
167,
236,
84,
249,
35,
136,
130,
172,
219,
225,
161,
139,
229,
89,
243,
125,
194,
213,
209,
30,
23,
174,
100,
244,
124,
74,
140,
47
],
"account": {
"program_owner": [
0,
0,
0,
0,
0,
0,
0,
0
],
"balance": 20000,
"data": [],
"nonce": 0
}
}
],
"signing_key": [
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37,
37
]
}
@@ -1,547 +0,0 @@
{
"override_rust_log": null,
"sequencer_addr": "",
"seq_poll_timeout_millis": 12000,
"seq_tx_poll_max_blocks": 5,
"seq_poll_max_retries": 5,
"seq_block_poll_max_amount": 100,
"basic_auth": null,
"initial_accounts": [
{
"Public": {
"account_id": "6iArKUXxhUJqS7kCaPNhwMWt3ro71PDyBj7jwAyE2VQV",
"pub_sign_key": [
16,
162,
106,
154,
236,
125,
52,
184,
35,
100,
238,
174,
69,
197,
41,
77,
187,
10,
118,
75,
0,
11,
148,
238,
185,
181,
133,
17,
220,
72,
124,
77
]
}
},
{
"Public": {
"account_id": "7wHg9sbJwc6h3NP1S9bekfAzB8CHifEcxKswCKUt3YQo",
"pub_sign_key": [
113,
121,
64,
177,
204,
85,
229,
214,
178,
6,
109,
191,
29,
154,
63,
38,
242,
18,
244,
219,
8,
208,
35,
136,
23,
127,
207,
237,
216,
169,
190,
27
]
}
},
{
"Private": {
"account_id": "3oCG8gqdKLMegw4rRfyaMQvuPHpcASt7xwttsmnZLSkw",
"account": {
"program_owner": [
0,
0,
0,
0,
0,
0,
0,
0
],
"balance": 10000,
"data": [],
"nonce": 0
},
"key_chain": {
"secret_spending_key": [
251,
82,
235,
1,
146,
96,
30,
81,
162,
234,
33,
15,
123,
129,
116,
0,
84,
136,
176,
70,
190,
224,
161,
54,
134,
142,
154,
1,
18,
251,
242,
189
],
"private_key_holder": {
"nullifier_secret_key": [
29,
250,
10,
187,
35,
123,
180,
250,
246,
97,
216,
153,
44,
156,
16,
93,
241,
26,
174,
219,
72,
84,
34,
247,
112,
101,
217,
243,
189,
173,
75,
20
],
"incoming_viewing_secret_key": [
251,
201,
22,
154,
100,
165,
218,
108,
163,
190,
135,
91,
145,
84,
69,
241,
46,
117,
217,
110,
197,
248,
91,
193,
14,
104,
88,
103,
67,
153,
182,
158
],
"outgoing_viewing_secret_key": [
25,
67,
121,
76,
175,
100,
30,
198,
105,
123,
49,
169,
75,
178,
75,
210,
100,
143,
210,
243,
228,
243,
21,
18,
36,
84,
164,
186,
139,
113,
214,
12
]
},
"nullifer_public_key": [
63,
202,
178,
231,
183,
82,
237,
212,
216,
221,
215,
255,
153,
101,
177,
161,
254,
210,
128,
122,
54,
190,
230,
151,
183,
64,
225,
229,
113,
1,
228,
97
],
"incoming_viewing_public_key": [
3,
235,
139,
131,
237,
177,
122,
189,
6,
177,
167,
178,
202,
117,
246,
58,
28,
65,
132,
79,
220,
139,
119,
243,
187,
160,
212,
121,
61,
247,
116,
72,
205
]
}
}
},
{
"Private": {
"account_id": "AKTcXgJ1xoynta1Ec7y6Jso1z1JQtHqd7aPQ1h9er6xX",
"account": {
"program_owner": [
0,
0,
0,
0,
0,
0,
0,
0
],
"balance": 20000,
"data": [],
"nonce": 0
},
"key_chain": {
"secret_spending_key": [
238,
171,
241,
69,
111,
217,
85,
64,
19,
82,
18,
189,
32,
91,
78,
175,
107,
7,
109,
60,
52,
44,
243,
230,
72,
244,
192,
92,
137,
33,
118,
254
],
"private_key_holder": {
"nullifier_secret_key": [
25,
211,
215,
119,
57,
223,
247,
37,
245,
144,
122,
29,
118,
245,
83,
228,
23,
9,
101,
120,
88,
33,
238,
207,
128,
61,
110,
2,
89,
62,
164,
13
],
"incoming_viewing_secret_key": [
193,
181,
14,
196,
142,
84,
15,
65,
128,
101,
70,
196,
241,
47,
130,
221,
23,
146,
161,
237,
221,
40,
19,
126,
59,
15,
169,
236,
25,
105,
104,
231
],
"outgoing_viewing_secret_key": [
20,
170,
220,
108,
41,
23,
155,
217,
247,
190,
175,
168,
247,
34,
105,
134,
114,
74,
104,
91,
211,
62,
126,
13,
130,
100,
241,
214,
250,
236,
38,
150
]
},
"nullifer_public_key": [
192,
251,
166,
243,
167,
236,
84,
249,
35,
136,
130,
172,
219,
225,
161,
139,
229,
89,
243,
125,
194,
213,
209,
30,
23,
174,
100,
244,
124,
74,
140,
47
],
"incoming_viewing_public_key": [
2,
181,
98,
93,
216,
241,
241,
110,
58,
198,
119,
174,
250,
184,
1,
204,
200,
173,
44,
238,
37,
247,
170,
156,
100,
254,
116,
242,
28,
183,
187,
77,
255
]
}
}
}
]
}
+255
View File
@@ -0,0 +1,255 @@
use std::{net::SocketAddr, path::PathBuf};
use anyhow::{Context, Result};
use indexer_service::{BackoffConfig, BedrockClientConfig, ChannelId, IndexerConfig};
use key_protocol::key_management::KeyChain;
use nssa::{Account, AccountId, PrivateKey, PublicKey};
use nssa_core::{account::Data, program::DEFAULT_PROGRAM_ID};
use sequencer_core::config::{
AccountInitialData, BedrockConfig, CommitmentsInitialData, SequencerConfig,
};
use url::Url;
use wallet::config::{
InitialAccountData, InitialAccountDataPrivate, InitialAccountDataPublic, WalletConfig,
};
pub fn indexer_config(bedrock_addr: SocketAddr) -> Result<IndexerConfig> {
Ok(IndexerConfig {
resubscribe_interval_millis: 1000,
bedrock_client_config: BedrockClientConfig {
addr: addr_to_url(UrlProtocol::Http, bedrock_addr)
.context("Failed to convert bedrock addr to URL")?,
auth: None,
backoff: BackoffConfig {
start_delay_millis: 100,
max_retries: 10,
},
},
channel_id: bedrock_channel_id(),
})
}
/// Sequencer config options available for custom changes in integration tests.
pub struct SequencerPartialConfig {
pub max_num_tx_in_block: usize,
pub mempool_max_size: usize,
pub block_create_timeout_millis: u64,
}
impl Default for SequencerPartialConfig {
fn default() -> Self {
Self {
max_num_tx_in_block: 20,
mempool_max_size: 10_000,
block_create_timeout_millis: 10_000,
}
}
}
pub fn sequencer_config(
partial: SequencerPartialConfig,
home: PathBuf,
bedrock_addr: SocketAddr,
indexer_addr: SocketAddr,
initial_data: &InitialData,
) -> Result<SequencerConfig> {
let SequencerPartialConfig {
max_num_tx_in_block,
mempool_max_size,
block_create_timeout_millis,
} = partial;
Ok(SequencerConfig {
home,
override_rust_log: None,
genesis_id: 1,
is_genesis_random: true,
max_num_tx_in_block,
mempool_max_size,
block_create_timeout_millis,
retry_pending_blocks_timeout_millis: 240_000,
port: 0,
initial_accounts: initial_data.sequencer_initial_accounts(),
initial_commitments: initial_data.sequencer_initial_commitments(),
signing_key: [37; 32],
bedrock_config: BedrockConfig {
backoff: BackoffConfig {
start_delay_millis: 100,
max_retries: 5,
},
channel_id: bedrock_channel_id(),
node_url: addr_to_url(UrlProtocol::Http, bedrock_addr)
.context("Failed to convert bedrock addr to URL")?,
auth: None,
},
indexer_rpc_url: addr_to_url(UrlProtocol::Ws, indexer_addr)
.context("Failed to convert indexer addr to URL")?,
})
}
pub fn wallet_config(
sequencer_addr: SocketAddr,
initial_data: &InitialData,
) -> Result<WalletConfig> {
Ok(WalletConfig {
override_rust_log: None,
sequencer_addr: addr_to_url(UrlProtocol::Http, sequencer_addr)
.context("Failed to convert sequencer addr to URL")?,
seq_poll_timeout_millis: 12_000,
seq_tx_poll_max_blocks: 10,
seq_poll_max_retries: 5,
seq_block_poll_max_amount: 100,
initial_accounts: initial_data.wallet_initial_accounts(),
basic_auth: None,
})
}
pub struct InitialData {
pub public_accounts: Vec<(PrivateKey, u128)>,
pub private_accounts: Vec<(KeyChain, Account)>,
}
impl InitialData {
pub fn with_two_public_and_two_private_initialized_accounts() -> Self {
let mut public_alice_private_key = PrivateKey::new_os_random();
let mut public_alice_public_key =
PublicKey::new_from_private_key(&public_alice_private_key);
let mut public_alice_account_id = AccountId::from(&public_alice_public_key);
let mut public_bob_private_key = PrivateKey::new_os_random();
let mut public_bob_public_key = PublicKey::new_from_private_key(&public_bob_private_key);
let mut public_bob_account_id = AccountId::from(&public_bob_public_key);
// Ensure consistent ordering
if public_alice_account_id > public_bob_account_id {
std::mem::swap(&mut public_alice_private_key, &mut public_bob_private_key);
std::mem::swap(&mut public_alice_public_key, &mut public_bob_public_key);
std::mem::swap(&mut public_alice_account_id, &mut public_bob_account_id);
}
let mut private_charlie_key_chain = KeyChain::new_os_random();
let mut private_charlie_account_id =
AccountId::from(&private_charlie_key_chain.nullifer_public_key);
let mut private_david_key_chain = KeyChain::new_os_random();
let mut private_david_account_id =
AccountId::from(&private_david_key_chain.nullifer_public_key);
// Ensure consistent ordering
if private_charlie_account_id > private_david_account_id {
std::mem::swap(&mut private_charlie_key_chain, &mut private_david_key_chain);
std::mem::swap(
&mut private_charlie_account_id,
&mut private_david_account_id,
);
}
Self {
public_accounts: vec![
(public_alice_private_key, 10_000),
(public_bob_private_key, 20_000),
],
private_accounts: vec![
(
private_charlie_key_chain,
Account {
balance: 10_000,
data: Data::default(),
program_owner: DEFAULT_PROGRAM_ID,
nonce: 0,
},
),
(
private_david_key_chain,
Account {
balance: 20_000,
data: Data::default(),
program_owner: DEFAULT_PROGRAM_ID,
nonce: 0,
},
),
],
}
}
fn sequencer_initial_accounts(&self) -> Vec<AccountInitialData> {
self.public_accounts
.iter()
.map(|(priv_key, balance)| {
let pub_key = PublicKey::new_from_private_key(priv_key);
let account_id = AccountId::from(&pub_key);
AccountInitialData {
account_id,
balance: *balance,
}
})
.collect()
}
fn sequencer_initial_commitments(&self) -> Vec<CommitmentsInitialData> {
self.private_accounts
.iter()
.map(|(key_chain, account)| CommitmentsInitialData {
npk: key_chain.nullifer_public_key.clone(),
account: account.clone(),
})
.collect()
}
fn wallet_initial_accounts(&self) -> Vec<InitialAccountData> {
self.public_accounts
.iter()
.map(|(priv_key, _)| {
let pub_key = PublicKey::new_from_private_key(priv_key);
let account_id = AccountId::from(&pub_key);
InitialAccountData::Public(InitialAccountDataPublic {
account_id,
pub_sign_key: priv_key.clone(),
})
})
.chain(self.private_accounts.iter().map(|(key_chain, account)| {
let account_id = AccountId::from(&key_chain.nullifer_public_key);
InitialAccountData::Private(InitialAccountDataPrivate {
account_id,
account: account.clone(),
key_chain: key_chain.clone(),
})
}))
.collect()
}
}
pub enum UrlProtocol {
Http,
Ws,
}
impl std::fmt::Display for UrlProtocol {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
UrlProtocol::Http => write!(f, "http"),
UrlProtocol::Ws => write!(f, "ws"),
}
}
}
pub fn addr_to_url(protocol: UrlProtocol, addr: SocketAddr) -> Result<Url> {
// Convert 0.0.0.0 to 127.0.0.1 for client connections
// When binding to port 0, the server binds to 0.0.0.0:<random_port>
// but clients need to connect to 127.0.0.1:<port> to work reliably
let url_string = if addr.ip().is_unspecified() {
format!("{protocol}://127.0.0.1:{}", addr.port())
} else {
format!("{protocol}://{addr}")
};
url_string.parse().map_err(Into::into)
}
fn bedrock_channel_id() -> ChannelId {
let channel_id: [u8; 32] = [0u8, 1]
.repeat(16)
.try_into()
.unwrap_or_else(|_| unreachable!());
ChannelId::from(channel_id)
}
+249 -191
View File
@@ -2,173 +2,179 @@
use std::{net::SocketAddr, path::PathBuf, sync::LazyLock};
use actix_web::dev::ServerHandle;
use anyhow::{Context, Result};
use anyhow::{Context, Result, bail};
use base64::{Engine, engine::general_purpose::STANDARD as BASE64};
use common::{
sequencer_client::SequencerClient,
transaction::{EncodedTransaction, NSSATransaction},
};
use common::{HashType, sequencer_client::SequencerClient, transaction::NSSATransaction};
use futures::FutureExt as _;
use indexer_core::{IndexerCore, config::IndexerConfig};
use log::debug;
use nssa::PrivacyPreservingTransaction;
use indexer_service::IndexerHandle;
use log::{debug, error, warn};
use nssa::{AccountId, PrivacyPreservingTransaction};
use nssa_core::Commitment;
use sequencer_core::config::SequencerConfig;
use sequencer_runner::SequencerHandle;
use tempfile::TempDir;
use tokio::task::JoinHandle;
use url::Url;
use testcontainers::compose::DockerCompose;
use wallet::{WalletCore, config::WalletConfigOverrides};
pub mod config;
// TODO: Remove this and control time from tests
pub const TIME_TO_WAIT_FOR_BLOCK_SECONDS: u64 = 12;
pub const ACC_SENDER: &str = "6iArKUXxhUJqS7kCaPNhwMWt3ro71PDyBj7jwAyE2VQV";
pub const ACC_RECEIVER: &str = "7wHg9sbJwc6h3NP1S9bekfAzB8CHifEcxKswCKUt3YQo";
pub const ACC_SENDER_PRIVATE: &str = "3oCG8gqdKLMegw4rRfyaMQvuPHpcASt7xwttsmnZLSkw";
pub const ACC_RECEIVER_PRIVATE: &str = "AKTcXgJ1xoynta1Ec7y6Jso1z1JQtHqd7aPQ1h9er6xX";
pub const NSSA_PROGRAM_FOR_TEST_DATA_CHANGER: &str = "data_changer.bin";
const BEDROCK_SERVICE_WITH_OPEN_PORT: &str = "logos-blockchain-node-0";
const BEDROCK_SERVICE_PORT: u16 = 18080;
static LOGGER: LazyLock<()> = LazyLock::new(env_logger::init);
/// Test context which sets up a sequencer and a wallet for integration tests.
///
/// It's memory and logically safe to create multiple instances of this struct in parallel tests,
/// as each instance uses its own temporary directories for sequencer and wallet data.
// NOTE: Order of fields is important for proper drop order.
pub struct TestContext {
sequencer_server_handle: ServerHandle,
sequencer_loop_handle: JoinHandle<Result<()>>,
sequencer_retry_pending_blocks_handle: JoinHandle<Result<()>>,
indexer_loop_handle: Option<JoinHandle<Result<()>>>,
sequencer_client: SequencerClient,
wallet: WalletCore,
wallet_password: String,
sequencer_handle: SequencerHandle,
indexer_handle: IndexerHandle,
bedrock_compose: DockerCompose,
_temp_sequencer_dir: TempDir,
_temp_wallet_dir: TempDir,
}
impl TestContext {
/// Create new test context in detached mode. Default.
/// Create new test context.
pub async fn new() -> Result<Self> {
let manifest_dir = env!("CARGO_MANIFEST_DIR");
let sequencer_config_path =
PathBuf::from(manifest_dir).join("configs/sequencer/detached/sequencer_config.json");
let sequencer_config = SequencerConfig::from_path(&sequencer_config_path)
.context("Failed to create sequencer config from file")?;
Self::new_with_sequencer_and_maybe_indexer_configs(sequencer_config, None).await
Self::builder().build().await
}
/// Create new test context in local bedrock node attached mode.
pub async fn new_bedrock_local_attached() -> Result<Self> {
let manifest_dir = env!("CARGO_MANIFEST_DIR");
let sequencer_config_path = PathBuf::from(manifest_dir)
.join("configs/sequencer/bedrock_local_attached/sequencer_config.json");
let sequencer_config = SequencerConfig::from_path(&sequencer_config_path)
.context("Failed to create sequencer config from file")?;
let indexer_config_path =
PathBuf::from(manifest_dir).join("configs/indexer/indexer_config.json");
let indexer_config = IndexerConfig::from_path(&indexer_config_path)
.context("Failed to create indexer config from file")?;
Self::new_with_sequencer_and_maybe_indexer_configs(sequencer_config, Some(indexer_config))
.await
pub fn builder() -> TestContextBuilder {
TestContextBuilder::new()
}
/// Create new test context with custom sequencer config and maybe indexer config.
///
/// `home` and `port` fields of the provided config will be overridden to meet tests parallelism
/// requirements.
pub async fn new_with_sequencer_and_maybe_indexer_configs(
sequencer_config: SequencerConfig,
indexer_config: Option<IndexerConfig>,
async fn new_configured(
sequencer_partial_config: config::SequencerPartialConfig,
initial_data: config::InitialData,
) -> Result<Self> {
// Ensure logger is initialized only once
*LOGGER;
debug!("Test context setup");
let (
sequencer_server_handle,
sequencer_addr,
sequencer_loop_handle,
sequencer_retry_pending_blocks_handle,
temp_sequencer_dir,
) = Self::setup_sequencer(sequencer_config)
.await
.context("Failed to setup sequencer")?;
let (bedrock_compose, bedrock_addr) = Self::setup_bedrock_node().await?;
// Convert 0.0.0.0 to 127.0.0.1 for client connections
// When binding to port 0, the server binds to 0.0.0.0:<random_port>
// but clients need to connect to 127.0.0.1:<port> to work reliably
let sequencer_addr = if sequencer_addr.ip().is_unspecified() {
format!("http://127.0.0.1:{}", sequencer_addr.port())
} else {
format!("http://{sequencer_addr}")
let indexer_handle = Self::setup_indexer(bedrock_addr)
.await
.context("Failed to setup Indexer")?;
let (sequencer_handle, temp_sequencer_dir) = Self::setup_sequencer(
sequencer_partial_config,
bedrock_addr,
indexer_handle.addr(),
&initial_data,
)
.await
.context("Failed to setup Sequencer")?;
let (wallet, temp_wallet_dir, wallet_password) =
Self::setup_wallet(sequencer_handle.addr(), &initial_data)
.await
.context("Failed to setup wallet")?;
let sequencer_url = config::addr_to_url(config::UrlProtocol::Http, sequencer_handle.addr())
.context("Failed to convert sequencer addr to URL")?;
let sequencer_client =
SequencerClient::new(sequencer_url).context("Failed to create sequencer client")?;
Ok(Self {
sequencer_client,
wallet,
wallet_password,
bedrock_compose,
sequencer_handle,
indexer_handle,
_temp_sequencer_dir: temp_sequencer_dir,
_temp_wallet_dir: temp_wallet_dir,
})
}
async fn setup_bedrock_node() -> Result<(DockerCompose, SocketAddr)> {
let manifest_dir = env!("CARGO_MANIFEST_DIR");
let bedrock_compose_path = PathBuf::from(manifest_dir).join("bedrock/docker-compose.yml");
let mut compose = DockerCompose::with_auto_client(&[bedrock_compose_path])
.await
.context("Failed to setup docker compose for Bedrock")?;
async fn up_and_retrieve_port(compose: &mut DockerCompose) -> Result<u16> {
compose
.up()
.await
.context("Failed to bring up Bedrock services")?;
let container = compose
.service(BEDROCK_SERVICE_WITH_OPEN_PORT)
.with_context(|| {
format!(
"Failed to get Bedrock service container `{BEDROCK_SERVICE_WITH_OPEN_PORT}`"
)
})?;
let ports = container.ports().await.with_context(|| {
format!(
"Failed to get ports for Bedrock service container `{}`",
container.id()
)
})?;
ports
.map_to_host_port_ipv4(BEDROCK_SERVICE_PORT)
.with_context(|| {
format!(
"Failed to retrieve host port of {BEDROCK_SERVICE_PORT} container \
port for container `{}`, existing ports: {ports:?}",
container.id()
)
})
}
let mut port = None;
let mut attempt = 0;
let max_attempts = 5;
while port.is_none() && attempt < max_attempts {
attempt += 1;
match up_and_retrieve_port(&mut compose).await {
Ok(p) => {
port = Some(p);
}
Err(err) => {
warn!(
"Failed to bring up Bedrock services: {err:?}, attempt {attempt}/{max_attempts}"
);
}
}
}
let Some(port) = port else {
bail!("Failed to bring up Bedrock services after {max_attempts} attempts");
};
let (wallet, temp_wallet_dir, wallet_password) = Self::setup_wallet(sequencer_addr.clone())
let addr = SocketAddr::from(([127, 0, 0, 1], port));
Ok((compose, addr))
}
async fn setup_indexer(bedrock_addr: SocketAddr) -> Result<IndexerHandle> {
let indexer_config =
config::indexer_config(bedrock_addr).context("Failed to create Indexer config")?;
indexer_service::run_server(indexer_config, 0)
.await
.context("Failed to setup wallet")?;
let sequencer_client = SequencerClient::new(
Url::parse(&sequencer_addr).context("Failed to parse sequencer addr")?,
)
.context("Failed to create sequencer client")?;
if let Some(mut indexer_config) = indexer_config {
indexer_config.sequencer_client_config.addr =
Url::parse(&sequencer_addr).context("Failed to parse sequencer addr")?;
let indexer_core = IndexerCore::new(indexer_config)?;
let indexer_loop_handle = Some(tokio::spawn(async move {
indexer_core.subscribe_parse_block_stream().await
}));
Ok(Self {
sequencer_server_handle,
sequencer_loop_handle,
sequencer_retry_pending_blocks_handle,
indexer_loop_handle,
sequencer_client,
wallet,
_temp_sequencer_dir: temp_sequencer_dir,
_temp_wallet_dir: temp_wallet_dir,
wallet_password,
})
} else {
Ok(Self {
sequencer_server_handle,
sequencer_loop_handle,
sequencer_retry_pending_blocks_handle,
indexer_loop_handle: None,
sequencer_client,
wallet,
_temp_sequencer_dir: temp_sequencer_dir,
_temp_wallet_dir: temp_wallet_dir,
wallet_password,
})
}
.context("Failed to run Indexer Service")
}
async fn setup_sequencer(
mut config: SequencerConfig,
) -> Result<(
ServerHandle,
SocketAddr,
JoinHandle<Result<()>>,
JoinHandle<Result<()>>,
TempDir,
)> {
partial: config::SequencerPartialConfig,
bedrock_addr: SocketAddr,
indexer_addr: SocketAddr,
initial_data: &config::InitialData,
) -> Result<(SequencerHandle, TempDir)> {
let temp_sequencer_dir =
tempfile::tempdir().context("Failed to create temp dir for sequencer home")?;
@@ -176,43 +182,39 @@ impl TestContext {
"Using temp sequencer home at {:?}",
temp_sequencer_dir.path()
);
config.home = temp_sequencer_dir.path().to_owned();
// Setting port to 0 lets the OS choose a free port for us
config.port = 0;
let (
sequencer_server_handle,
sequencer_addr,
sequencer_loop_handle,
sequencer_retry_pending_blocks_handle,
) = sequencer_runner::startup_sequencer(config).await?;
let config = config::sequencer_config(
partial,
temp_sequencer_dir.path().to_owned(),
bedrock_addr,
indexer_addr,
initial_data,
)
.context("Failed to create Sequencer config")?;
Ok((
sequencer_server_handle,
sequencer_addr,
sequencer_loop_handle,
sequencer_retry_pending_blocks_handle,
temp_sequencer_dir,
))
let sequencer_handle = sequencer_runner::startup_sequencer(config).await?;
Ok((sequencer_handle, temp_sequencer_dir))
}
async fn setup_wallet(sequencer_addr: String) -> Result<(WalletCore, TempDir, String)> {
let manifest_dir = env!("CARGO_MANIFEST_DIR");
let wallet_config_source_path =
PathBuf::from(manifest_dir).join("configs/wallet/wallet_config.json");
async fn setup_wallet(
sequencer_addr: SocketAddr,
initial_data: &config::InitialData,
) -> Result<(WalletCore, TempDir, String)> {
let config = config::wallet_config(sequencer_addr, initial_data)
.context("Failed to create Wallet config")?;
let config_serialized =
serde_json::to_string_pretty(&config).context("Failed to serialize Wallet config")?;
let temp_wallet_dir =
tempfile::tempdir().context("Failed to create temp dir for wallet home")?;
let config_path = temp_wallet_dir.path().join("wallet_config.json");
std::fs::copy(&wallet_config_source_path, &config_path)
.context("Failed to copy wallet config to temp dir")?;
std::fs::write(&config_path, config_serialized)
.context("Failed to write wallet config in temp dir")?;
let storage_path = temp_wallet_dir.path().join("storage.json");
let config_overrides = WalletConfigOverrides {
sequencer_addr: Some(sequencer_addr),
..Default::default()
};
let config_overrides = WalletConfigOverrides::default();
let wallet_password = "test_pass".to_owned();
let wallet = WalletCore::new_init_storage(
@@ -248,32 +250,71 @@ impl TestContext {
pub fn sequencer_client(&self) -> &SequencerClient {
&self.sequencer_client
}
/// Get existing public account IDs in the wallet.
pub fn existing_public_accounts(&self) -> Vec<AccountId> {
self.wallet
.storage()
.user_data
.public_account_ids()
.collect()
}
/// Get existing private account IDs in the wallet.
pub fn existing_private_accounts(&self) -> Vec<AccountId> {
self.wallet
.storage()
.user_data
.private_account_ids()
.collect()
}
}
impl Drop for TestContext {
fn drop(&mut self) {
debug!("Test context cleanup");
let Self {
sequencer_server_handle,
sequencer_loop_handle,
sequencer_retry_pending_blocks_handle,
indexer_loop_handle,
sequencer_handle,
indexer_handle,
bedrock_compose,
_temp_sequencer_dir: _,
_temp_wallet_dir: _,
sequencer_client: _,
wallet: _,
_temp_sequencer_dir,
_temp_wallet_dir,
wallet_password: _,
} = self;
sequencer_loop_handle.abort();
sequencer_retry_pending_blocks_handle.abort();
if let Some(indexer_loop_handle) = indexer_loop_handle {
indexer_loop_handle.abort();
if sequencer_handle.is_finished() {
let Err(err) = self
.sequencer_handle
.run_forever()
.now_or_never()
.expect("Future is finished and should be ready");
error!(
"Sequencer handle has unexpectedly finished before TestContext drop with error: {err:#}"
);
}
// Can't wait here as Drop can't be async, but anyway stop signal should be sent
sequencer_server_handle.stop(true).now_or_never();
if indexer_handle.is_stopped() {
error!("Indexer handle has unexpectedly stopped before TestContext drop");
}
let container = bedrock_compose
.service(BEDROCK_SERVICE_WITH_OPEN_PORT)
.unwrap_or_else(|| {
panic!("Failed to get Bedrock service container `{BEDROCK_SERVICE_WITH_OPEN_PORT}`")
});
let output = std::process::Command::new("docker")
.args(["inspect", "-f", "{{.State.Running}}", container.id()])
.output()
.expect("Failed to execute docker inspect command to check if Bedrock container is still running");
let stdout = String::from_utf8(output.stdout)
.expect("Failed to parse docker inspect output as String");
if stdout.trim() != "true" {
error!(
"Bedrock container `{}` is not running during TestContext drop, docker inspect output: {stdout}",
container.id()
);
}
}
}
@@ -291,31 +332,65 @@ impl BlockingTestContext {
}
}
pub fn format_public_account_id(account_id: &str) -> String {
pub struct TestContextBuilder {
initial_data: Option<config::InitialData>,
sequencer_partial_config: Option<config::SequencerPartialConfig>,
}
impl TestContextBuilder {
fn new() -> Self {
Self {
initial_data: None,
sequencer_partial_config: None,
}
}
pub fn with_initial_data(mut self, initial_data: config::InitialData) -> Self {
self.initial_data = Some(initial_data);
self
}
pub fn with_sequencer_partial_config(
mut self,
sequencer_partial_config: config::SequencerPartialConfig,
) -> Self {
self.sequencer_partial_config = Some(sequencer_partial_config);
self
}
pub async fn build(self) -> Result<TestContext> {
TestContext::new_configured(
self.sequencer_partial_config.unwrap_or_default(),
self.initial_data.unwrap_or_else(|| {
config::InitialData::with_two_public_and_two_private_initialized_accounts()
}),
)
.await
}
}
pub fn format_public_account_id(account_id: AccountId) -> String {
format!("Public/{account_id}")
}
pub fn format_private_account_id(account_id: &str) -> String {
pub fn format_private_account_id(account_id: AccountId) -> String {
format!("Private/{account_id}")
}
pub async fn fetch_privacy_preserving_tx(
seq_client: &SequencerClient,
tx_hash: String,
tx_hash: HashType,
) -> PrivacyPreservingTransaction {
let transaction_encoded = seq_client
.get_transaction_by_hash(tx_hash.clone())
.get_transaction_by_hash(tx_hash)
.await
.unwrap()
.transaction
.unwrap();
let tx_base64_decode = BASE64.decode(transaction_encoded).unwrap();
match NSSATransaction::try_from(
&borsh::from_slice::<EncodedTransaction>(&tx_base64_decode).unwrap(),
)
.unwrap()
{
let tx_bytes = BASE64.decode(transaction_encoded).unwrap();
let tx = borsh::from_slice(&tx_bytes).unwrap();
match tx {
NSSATransaction::PrivacyPreserving(privacy_preserving_transaction) => {
privacy_preserving_transaction
}
@@ -332,20 +407,3 @@ pub async fn verify_commitment_is_in_state(
Ok(Some(_))
)
}
#[cfg(test)]
mod tests {
use super::{format_private_account_id, format_public_account_id};
#[test]
fn correct_account_id_from_prefix() {
let account_id1 = "cafecafe";
let account_id2 = "deadbeaf";
let account_id1_pub = format_public_account_id(account_id1);
let account_id2_priv = format_private_account_id(account_id2);
assert_eq!(account_id1_pub, "Public/cafecafe".to_string());
assert_eq!(account_id2_priv, "Private/deadbeaf".to_string());
}
}
+2 -2
View File
@@ -1,5 +1,5 @@
use anyhow::Result;
use integration_tests::{ACC_SENDER, TestContext};
use integration_tests::TestContext;
use log::info;
use nssa::program::Program;
use tokio::test;
@@ -10,7 +10,7 @@ async fn get_existing_account() -> Result<()> {
let account = ctx
.sequencer_client()
.get_account(ACC_SENDER.to_string())
.get_account(ctx.existing_public_accounts()[0])
.await?
.account;
+36 -40
View File
@@ -88,8 +88,8 @@ async fn amm_public() -> Result<()> {
// Create new token
let subcommand = TokenProgramAgnosticSubcommand::New {
definition_account_id: format_public_account_id(&definition_account_id_1.to_string()),
supply_account_id: format_public_account_id(&supply_account_id_1.to_string()),
definition_account_id: format_public_account_id(definition_account_id_1),
supply_account_id: format_public_account_id(supply_account_id_1),
name: "A NAM1".to_string(),
total_supply: 37,
};
@@ -99,10 +99,8 @@ async fn amm_public() -> Result<()> {
// Transfer 7 tokens from `supply_acc` to the account at account_id `recipient_account_id_1`
let subcommand = TokenProgramAgnosticSubcommand::Send {
from: format_public_account_id(&supply_account_id_1.to_string()),
to: Some(format_public_account_id(
&recipient_account_id_1.to_string(),
)),
from: format_public_account_id(supply_account_id_1),
to: Some(format_public_account_id(recipient_account_id_1)),
to_npk: None,
to_ipk: None,
amount: 7,
@@ -114,8 +112,8 @@ async fn amm_public() -> Result<()> {
// Create new token
let subcommand = TokenProgramAgnosticSubcommand::New {
definition_account_id: format_public_account_id(&definition_account_id_2.to_string()),
supply_account_id: format_public_account_id(&supply_account_id_2.to_string()),
definition_account_id: format_public_account_id(definition_account_id_2),
supply_account_id: format_public_account_id(supply_account_id_2),
name: "A NAM2".to_string(),
total_supply: 37,
};
@@ -125,10 +123,8 @@ async fn amm_public() -> Result<()> {
// Transfer 7 tokens from `supply_acc` to the account at account_id `recipient_account_id_2`
let subcommand = TokenProgramAgnosticSubcommand::Send {
from: format_public_account_id(&supply_account_id_2.to_string()),
to: Some(format_public_account_id(
&recipient_account_id_2.to_string(),
)),
from: format_public_account_id(supply_account_id_2),
to: Some(format_public_account_id(recipient_account_id_2)),
to_npk: None,
to_ipk: None,
amount: 7,
@@ -157,9 +153,9 @@ async fn amm_public() -> Result<()> {
// Send creation tx
let subcommand = AmmProgramAgnosticSubcommand::New {
user_holding_a: format_public_account_id(&recipient_account_id_1.to_string()),
user_holding_b: format_public_account_id(&recipient_account_id_2.to_string()),
user_holding_lp: format_public_account_id(&user_holding_lp.to_string()),
user_holding_a: format_public_account_id(recipient_account_id_1),
user_holding_b: format_public_account_id(recipient_account_id_2),
user_holding_lp: format_public_account_id(user_holding_lp),
balance_a: 3,
balance_b: 3,
};
@@ -170,19 +166,19 @@ async fn amm_public() -> Result<()> {
let user_holding_a_acc = ctx
.sequencer_client()
.get_account(recipient_account_id_1.to_string())
.get_account(recipient_account_id_1)
.await?
.account;
let user_holding_b_acc = ctx
.sequencer_client()
.get_account(recipient_account_id_2.to_string())
.get_account(recipient_account_id_2)
.await?
.account;
let user_holding_lp_acc = ctx
.sequencer_client()
.get_account(user_holding_lp.to_string())
.get_account(user_holding_lp)
.await?
.account;
@@ -206,8 +202,8 @@ async fn amm_public() -> Result<()> {
// Make swap
let subcommand = AmmProgramAgnosticSubcommand::Swap {
user_holding_a: format_public_account_id(&recipient_account_id_1.to_string()),
user_holding_b: format_public_account_id(&recipient_account_id_2.to_string()),
user_holding_a: format_public_account_id(recipient_account_id_1),
user_holding_b: format_public_account_id(recipient_account_id_2),
amount_in: 2,
min_amount_out: 1,
token_definition: definition_account_id_1.to_string(),
@@ -219,19 +215,19 @@ async fn amm_public() -> Result<()> {
let user_holding_a_acc = ctx
.sequencer_client()
.get_account(recipient_account_id_1.to_string())
.get_account(recipient_account_id_1)
.await?
.account;
let user_holding_b_acc = ctx
.sequencer_client()
.get_account(recipient_account_id_2.to_string())
.get_account(recipient_account_id_2)
.await?
.account;
let user_holding_lp_acc = ctx
.sequencer_client()
.get_account(user_holding_lp.to_string())
.get_account(user_holding_lp)
.await?
.account;
@@ -255,8 +251,8 @@ async fn amm_public() -> Result<()> {
// Make swap
let subcommand = AmmProgramAgnosticSubcommand::Swap {
user_holding_a: format_public_account_id(&recipient_account_id_1.to_string()),
user_holding_b: format_public_account_id(&recipient_account_id_2.to_string()),
user_holding_a: format_public_account_id(recipient_account_id_1),
user_holding_b: format_public_account_id(recipient_account_id_2),
amount_in: 2,
min_amount_out: 1,
token_definition: definition_account_id_2.to_string(),
@@ -268,19 +264,19 @@ async fn amm_public() -> Result<()> {
let user_holding_a_acc = ctx
.sequencer_client()
.get_account(recipient_account_id_1.to_string())
.get_account(recipient_account_id_1)
.await?
.account;
let user_holding_b_acc = ctx
.sequencer_client()
.get_account(recipient_account_id_2.to_string())
.get_account(recipient_account_id_2)
.await?
.account;
let user_holding_lp_acc = ctx
.sequencer_client()
.get_account(user_holding_lp.to_string())
.get_account(user_holding_lp)
.await?
.account;
@@ -304,9 +300,9 @@ async fn amm_public() -> Result<()> {
// Add liquidity
let subcommand = AmmProgramAgnosticSubcommand::AddLiquidity {
user_holding_a: format_public_account_id(&recipient_account_id_1.to_string()),
user_holding_b: format_public_account_id(&recipient_account_id_2.to_string()),
user_holding_lp: format_public_account_id(&user_holding_lp.to_string()),
user_holding_a: format_public_account_id(recipient_account_id_1),
user_holding_b: format_public_account_id(recipient_account_id_2),
user_holding_lp: format_public_account_id(user_holding_lp),
min_amount_lp: 1,
max_amount_a: 2,
max_amount_b: 2,
@@ -318,19 +314,19 @@ async fn amm_public() -> Result<()> {
let user_holding_a_acc = ctx
.sequencer_client()
.get_account(recipient_account_id_1.to_string())
.get_account(recipient_account_id_1)
.await?
.account;
let user_holding_b_acc = ctx
.sequencer_client()
.get_account(recipient_account_id_2.to_string())
.get_account(recipient_account_id_2)
.await?
.account;
let user_holding_lp_acc = ctx
.sequencer_client()
.get_account(user_holding_lp.to_string())
.get_account(user_holding_lp)
.await?
.account;
@@ -354,9 +350,9 @@ async fn amm_public() -> Result<()> {
// Remove liquidity
let subcommand = AmmProgramAgnosticSubcommand::RemoveLiquidity {
user_holding_a: format_public_account_id(&recipient_account_id_1.to_string()),
user_holding_b: format_public_account_id(&recipient_account_id_2.to_string()),
user_holding_lp: format_public_account_id(&user_holding_lp.to_string()),
user_holding_a: format_public_account_id(recipient_account_id_1),
user_holding_b: format_public_account_id(recipient_account_id_2),
user_holding_lp: format_public_account_id(user_holding_lp),
balance_lp: 2,
min_amount_a: 1,
min_amount_b: 1,
@@ -368,19 +364,19 @@ async fn amm_public() -> Result<()> {
let user_holding_a_acc = ctx
.sequencer_client()
.get_account(recipient_account_id_1.to_string())
.get_account(recipient_account_id_1)
.await?
.account;
let user_holding_b_acc = ctx
.sequencer_client()
.get_account(recipient_account_id_2.to_string())
.get_account(recipient_account_id_2)
.await?
.account;
let user_holding_lp_acc = ctx
.sequencer_client()
.get_account(user_holding_lp.to_string())
.get_account(user_holding_lp)
.await?
.account;
@@ -2,7 +2,6 @@ use std::time::Duration;
use anyhow::{Context as _, Result};
use integration_tests::{
ACC_RECEIVER, ACC_RECEIVER_PRIVATE, ACC_SENDER, ACC_SENDER_PRIVATE,
TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext, fetch_privacy_preserving_tx,
format_private_account_id, format_public_account_id, verify_commitment_is_in_state,
};
@@ -20,12 +19,12 @@ use wallet::cli::{
async fn private_transfer_to_owned_account() -> Result<()> {
let mut ctx = TestContext::new().await?;
let from: AccountId = ACC_SENDER_PRIVATE.parse()?;
let to: AccountId = ACC_RECEIVER_PRIVATE.parse()?;
let from: AccountId = ctx.existing_private_accounts()[0];
let to: AccountId = ctx.existing_private_accounts()[1];
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: format_private_account_id(&from.to_string()),
to: Some(format_private_account_id(&to.to_string())),
from: format_private_account_id(from),
to: Some(format_private_account_id(to)),
to_npk: None,
to_ipk: None,
amount: 100,
@@ -38,13 +37,13 @@ async fn private_transfer_to_owned_account() -> Result<()> {
let new_commitment1 = ctx
.wallet()
.get_private_account_commitment(&from)
.get_private_account_commitment(from)
.context("Failed to get private account commitment for sender")?;
assert!(verify_commitment_is_in_state(new_commitment1, ctx.sequencer_client()).await);
let new_commitment2 = ctx
.wallet()
.get_private_account_commitment(&to)
.get_private_account_commitment(to)
.context("Failed to get private account commitment for receiver")?;
assert!(verify_commitment_is_in_state(new_commitment2, ctx.sequencer_client()).await);
@@ -57,13 +56,13 @@ async fn private_transfer_to_owned_account() -> Result<()> {
async fn private_transfer_to_foreign_account() -> Result<()> {
let mut ctx = TestContext::new().await?;
let from: AccountId = ACC_SENDER_PRIVATE.parse()?;
let from: AccountId = ctx.existing_private_accounts()[0];
let to_npk = NullifierPublicKey([42; 32]);
let to_npk_string = hex::encode(to_npk.0);
let to_ipk = Secp256k1Point::from_scalar(to_npk.0);
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: format_private_account_id(&from.to_string()),
from: format_private_account_id(from),
to: None,
to_npk: Some(to_npk_string),
to_ipk: Some(hex::encode(to_ipk.0)),
@@ -80,10 +79,10 @@ async fn private_transfer_to_foreign_account() -> Result<()> {
let new_commitment1 = ctx
.wallet()
.get_private_account_commitment(&from)
.get_private_account_commitment(from)
.context("Failed to get private account commitment for sender")?;
let tx = fetch_privacy_preserving_tx(ctx.sequencer_client(), tx_hash.clone()).await;
let tx = fetch_privacy_preserving_tx(ctx.sequencer_client(), tx_hash).await;
assert_eq!(tx.message.new_commitments[0], new_commitment1);
assert_eq!(tx.message.new_commitments.len(), 2);
@@ -100,19 +99,19 @@ async fn private_transfer_to_foreign_account() -> Result<()> {
async fn deshielded_transfer_to_public_account() -> Result<()> {
let mut ctx = TestContext::new().await?;
let from: AccountId = ACC_SENDER_PRIVATE.parse()?;
let to: AccountId = ACC_RECEIVER.parse()?;
let from: AccountId = ctx.existing_private_accounts()[0];
let to: AccountId = ctx.existing_public_accounts()[1];
// Check initial balance of the private sender
let from_acc = ctx
.wallet()
.get_account_private(&from)
.get_account_private(from)
.context("Failed to get sender's private account")?;
assert_eq!(from_acc.balance, 10000);
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: format_private_account_id(&from.to_string()),
to: Some(format_public_account_id(&to.to_string())),
from: format_private_account_id(from),
to: Some(format_public_account_id(to)),
to_npk: None,
to_ipk: None,
amount: 100,
@@ -125,18 +124,15 @@ async fn deshielded_transfer_to_public_account() -> Result<()> {
let from_acc = ctx
.wallet()
.get_account_private(&from)
.get_account_private(from)
.context("Failed to get sender's private account")?;
let new_commitment = ctx
.wallet()
.get_private_account_commitment(&from)
.get_private_account_commitment(from)
.context("Failed to get private account commitment")?;
assert!(verify_commitment_is_in_state(new_commitment, ctx.sequencer_client()).await);
let acc_2_balance = ctx
.sequencer_client()
.get_account_balance(to.to_string())
.await?;
let acc_2_balance = ctx.sequencer_client().get_account_balance(to).await?;
assert_eq!(from_acc.balance, 9900);
assert_eq!(acc_2_balance.balance, 20100);
@@ -150,7 +146,7 @@ async fn deshielded_transfer_to_public_account() -> Result<()> {
async fn private_transfer_to_owned_account_using_claiming_path() -> Result<()> {
let mut ctx = TestContext::new().await?;
let from: AccountId = ACC_SENDER_PRIVATE.parse()?;
let from: AccountId = ctx.existing_private_accounts()[0];
// Create a new private account
let command = Command::Account(AccountSubcommand::New(NewSubcommand::Private { cci: None }));
@@ -168,13 +164,13 @@ async fn private_transfer_to_owned_account_using_claiming_path() -> Result<()> {
.wallet()
.storage()
.user_data
.get_private_account(&to_account_id)
.get_private_account(to_account_id)
.cloned()
.context("Failed to get private account")?;
// Send to this account using claiming path (using npk and ipk instead of account ID)
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: format_private_account_id(&from.to_string()),
from: format_private_account_id(from),
to: None,
to_npk: Some(hex::encode(to_keys.nullifer_public_key.0)),
to_ipk: Some(hex::encode(to_keys.incoming_viewing_public_key.0)),
@@ -186,7 +182,7 @@ async fn private_transfer_to_owned_account_using_claiming_path() -> Result<()> {
anyhow::bail!("Expected PrivacyPreservingTransfer return value");
};
let tx = fetch_privacy_preserving_tx(ctx.sequencer_client(), tx_hash.clone()).await;
let tx = fetch_privacy_preserving_tx(ctx.sequencer_client(), tx_hash).await;
// Sync the wallet to claim the new account
let command = Command::Account(AccountSubcommand::SyncPrivate {});
@@ -194,7 +190,7 @@ async fn private_transfer_to_owned_account_using_claiming_path() -> Result<()> {
let new_commitment1 = ctx
.wallet()
.get_private_account_commitment(&from)
.get_private_account_commitment(from)
.context("Failed to get private account commitment for sender")?;
assert_eq!(tx.message.new_commitments[0], new_commitment1);
@@ -205,7 +201,7 @@ async fn private_transfer_to_owned_account_using_claiming_path() -> Result<()> {
let to_res_acc = ctx
.wallet()
.get_account_private(&to_account_id)
.get_account_private(to_account_id)
.context("Failed to get recipient's private account")?;
assert_eq!(to_res_acc.balance, 100);
@@ -218,12 +214,12 @@ async fn private_transfer_to_owned_account_using_claiming_path() -> Result<()> {
async fn shielded_transfer_to_owned_private_account() -> Result<()> {
let mut ctx = TestContext::new().await?;
let from: AccountId = ACC_SENDER.parse()?;
let to: AccountId = ACC_RECEIVER_PRIVATE.parse()?;
let from: AccountId = ctx.existing_public_accounts()[0];
let to: AccountId = ctx.existing_private_accounts()[1];
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: format_public_account_id(&from.to_string()),
to: Some(format_private_account_id(&to.to_string())),
from: format_public_account_id(from),
to: Some(format_private_account_id(to)),
to_npk: None,
to_ipk: None,
amount: 100,
@@ -236,18 +232,15 @@ async fn shielded_transfer_to_owned_private_account() -> Result<()> {
let acc_to = ctx
.wallet()
.get_account_private(&to)
.get_account_private(to)
.context("Failed to get receiver's private account")?;
let new_commitment = ctx
.wallet()
.get_private_account_commitment(&to)
.get_private_account_commitment(to)
.context("Failed to get receiver's commitment")?;
assert!(verify_commitment_is_in_state(new_commitment, ctx.sequencer_client()).await);
let acc_from_balance = ctx
.sequencer_client()
.get_account_balance(from.to_string())
.await?;
let acc_from_balance = ctx.sequencer_client().get_account_balance(from).await?;
assert_eq!(acc_from_balance.balance, 9900);
assert_eq!(acc_to.balance, 20100);
@@ -264,10 +257,10 @@ async fn shielded_transfer_to_foreign_account() -> Result<()> {
let to_npk = NullifierPublicKey([42; 32]);
let to_npk_string = hex::encode(to_npk.0);
let to_ipk = Secp256k1Point::from_scalar(to_npk.0);
let from: AccountId = ACC_SENDER.parse()?;
let from: AccountId = ctx.existing_public_accounts()[0];
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: format_public_account_id(&from.to_string()),
from: format_public_account_id(from),
to: None,
to_npk: Some(to_npk_string),
to_ipk: Some(hex::encode(to_ipk.0)),
@@ -284,10 +277,7 @@ async fn shielded_transfer_to_foreign_account() -> Result<()> {
let tx = fetch_privacy_preserving_tx(ctx.sequencer_client(), tx_hash).await;
let acc_1_balance = ctx
.sequencer_client()
.get_account_balance(from.to_string())
.await?;
let acc_1_balance = ctx.sequencer_client().get_account_balance(from).await?;
assert!(
verify_commitment_is_in_state(
@@ -313,7 +303,7 @@ async fn private_transfer_to_owned_account_continuous_run_path() -> Result<()> {
// The original implementation spawned wallet::cli::execute_continuous_run() in background
// but this conflicts with TestContext's wallet management
let from: AccountId = ACC_SENDER_PRIVATE.parse()?;
let from: AccountId = ctx.existing_private_accounts()[0];
// Create a new private account
let command = Command::Account(AccountSubcommand::New(NewSubcommand::Private { cci: None }));
@@ -331,13 +321,13 @@ async fn private_transfer_to_owned_account_continuous_run_path() -> Result<()> {
.wallet()
.storage()
.user_data
.get_private_account(&to_account_id)
.get_private_account(to_account_id)
.cloned()
.context("Failed to get private account")?;
// Send transfer using nullifier and incoming viewing public keys
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: format_private_account_id(&from.to_string()),
from: format_private_account_id(from),
to: None,
to_npk: Some(hex::encode(to_keys.nullifer_public_key.0)),
to_ipk: Some(hex::encode(to_keys.incoming_viewing_public_key.0)),
@@ -349,7 +339,7 @@ async fn private_transfer_to_owned_account_continuous_run_path() -> Result<()> {
anyhow::bail!("Failed to send transaction");
};
let tx = fetch_privacy_preserving_tx(ctx.sequencer_client(), tx_hash.clone()).await;
let tx = fetch_privacy_preserving_tx(ctx.sequencer_client(), tx_hash).await;
info!("Waiting for next blocks to check if continuous run fetches account");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
@@ -364,7 +354,7 @@ async fn private_transfer_to_owned_account_continuous_run_path() -> Result<()> {
// Verify receiver account balance
let to_res_acc = ctx
.wallet()
.get_account_private(&to_account_id)
.get_account_private(to_account_id)
.context("Failed to get receiver account")?;
assert_eq!(to_res_acc.balance, 100);
@@ -383,7 +373,7 @@ async fn initialize_private_account() -> Result<()> {
};
let command = Command::AuthTransfer(AuthTransferSubcommand::Init {
account_id: format_private_account_id(&account_id.to_string()),
account_id: format_private_account_id(account_id),
});
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
@@ -395,13 +385,13 @@ async fn initialize_private_account() -> Result<()> {
let new_commitment = ctx
.wallet()
.get_private_account_commitment(&account_id)
.get_private_account_commitment(account_id)
.context("Failed to get private account commitment")?;
assert!(verify_commitment_is_in_state(new_commitment, ctx.sequencer_client()).await);
let account = ctx
.wallet()
.get_account_private(&account_id)
.get_account_private(account_id)
.context("Failed to get private account")?;
assert_eq!(
+26 -30
View File
@@ -1,9 +1,7 @@
use std::time::Duration;
use anyhow::Result;
use integration_tests::{
ACC_RECEIVER, ACC_SENDER, TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext, format_public_account_id,
};
use integration_tests::{TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext, format_public_account_id};
use log::info;
use nssa::program::Program;
use tokio::test;
@@ -18,8 +16,8 @@ async fn successful_transfer_to_existing_account() -> Result<()> {
let mut ctx = TestContext::new().await?;
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: format_public_account_id(ACC_SENDER),
to: Some(format_public_account_id(ACC_RECEIVER)),
from: format_public_account_id(ctx.existing_public_accounts()[0]),
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
to_npk: None,
to_ipk: None,
amount: 100,
@@ -33,11 +31,11 @@ async fn successful_transfer_to_existing_account() -> Result<()> {
info!("Checking correct balance move");
let acc_1_balance = ctx
.sequencer_client()
.get_account_balance(ACC_SENDER.to_string())
.get_account_balance(ctx.existing_public_accounts()[0])
.await?;
let acc_2_balance = ctx
.sequencer_client()
.get_account_balance(ACC_RECEIVER.to_string())
.get_account_balance(ctx.existing_public_accounts()[1])
.await?;
info!("Balance of sender: {acc_1_balance:#?}");
@@ -64,17 +62,15 @@ pub async fn successful_transfer_to_new_account() -> Result<()> {
.storage()
.user_data
.account_ids()
.map(ToString::to_string)
.find(|acc_id| acc_id != ACC_SENDER && acc_id != ACC_RECEIVER)
.find(|acc_id| {
*acc_id != ctx.existing_public_accounts()[0]
&& *acc_id != ctx.existing_public_accounts()[1]
})
.expect("Failed to find newly created account in the wallet storage");
if new_persistent_account_id == String::new() {
panic!("Failed to produce new account, not present in persistent accounts");
}
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: format_public_account_id(ACC_SENDER),
to: Some(format_public_account_id(&new_persistent_account_id)),
from: format_public_account_id(ctx.existing_public_accounts()[0]),
to: Some(format_public_account_id(new_persistent_account_id)),
to_npk: None,
to_ipk: None,
amount: 100,
@@ -88,7 +84,7 @@ pub async fn successful_transfer_to_new_account() -> Result<()> {
info!("Checking correct balance move");
let acc_1_balance = ctx
.sequencer_client()
.get_account_balance(ACC_SENDER.to_string())
.get_account_balance(ctx.existing_public_accounts()[0])
.await?;
let acc_2_balance = ctx
.sequencer_client()
@@ -109,8 +105,8 @@ async fn failed_transfer_with_insufficient_balance() -> Result<()> {
let mut ctx = TestContext::new().await?;
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: format_public_account_id(ACC_SENDER),
to: Some(format_public_account_id(ACC_RECEIVER)),
from: format_public_account_id(ctx.existing_public_accounts()[0]),
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
to_npk: None,
to_ipk: None,
amount: 1000000,
@@ -125,11 +121,11 @@ async fn failed_transfer_with_insufficient_balance() -> Result<()> {
info!("Checking balances unchanged");
let acc_1_balance = ctx
.sequencer_client()
.get_account_balance(ACC_SENDER.to_string())
.get_account_balance(ctx.existing_public_accounts()[0])
.await?;
let acc_2_balance = ctx
.sequencer_client()
.get_account_balance(ACC_RECEIVER.to_string())
.get_account_balance(ctx.existing_public_accounts()[1])
.await?;
info!("Balance of sender: {acc_1_balance:#?}");
@@ -147,8 +143,8 @@ async fn two_consecutive_successful_transfers() -> Result<()> {
// First transfer
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: format_public_account_id(ACC_SENDER),
to: Some(format_public_account_id(ACC_RECEIVER)),
from: format_public_account_id(ctx.existing_public_accounts()[0]),
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
to_npk: None,
to_ipk: None,
amount: 100,
@@ -162,11 +158,11 @@ async fn two_consecutive_successful_transfers() -> Result<()> {
info!("Checking correct balance move after first transfer");
let acc_1_balance = ctx
.sequencer_client()
.get_account_balance(ACC_SENDER.to_string())
.get_account_balance(ctx.existing_public_accounts()[0])
.await?;
let acc_2_balance = ctx
.sequencer_client()
.get_account_balance(ACC_RECEIVER.to_string())
.get_account_balance(ctx.existing_public_accounts()[1])
.await?;
info!("Balance of sender: {acc_1_balance:#?}");
@@ -179,8 +175,8 @@ async fn two_consecutive_successful_transfers() -> Result<()> {
// Second transfer
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: format_public_account_id(ACC_SENDER),
to: Some(format_public_account_id(ACC_RECEIVER)),
from: format_public_account_id(ctx.existing_public_accounts()[0]),
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
to_npk: None,
to_ipk: None,
amount: 100,
@@ -194,11 +190,11 @@ async fn two_consecutive_successful_transfers() -> Result<()> {
info!("Checking correct balance move after second transfer");
let acc_1_balance = ctx
.sequencer_client()
.get_account_balance(ACC_SENDER.to_string())
.get_account_balance(ctx.existing_public_accounts()[0])
.await?;
let acc_2_balance = ctx
.sequencer_client()
.get_account_balance(ACC_RECEIVER.to_string())
.get_account_balance(ctx.existing_public_accounts()[1])
.await?;
info!("Balance of sender: {acc_1_balance:#?}");
@@ -223,14 +219,14 @@ async fn initialize_public_account() -> Result<()> {
};
let command = Command::AuthTransfer(AuthTransferSubcommand::Init {
account_id: format_public_account_id(&account_id.to_string()),
account_id: format_public_account_id(account_id),
});
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
info!("Checking correct execution");
let account = ctx
.sequencer_client()
.get_account(account_id.to_string())
.get_account(account_id)
.await?
.account;
-23
View File
@@ -1,23 +0,0 @@
use anyhow::Result;
use integration_tests::TestContext;
use log::info;
use tokio::test;
#[ignore = "needs complicated setup"]
#[test]
// To run this test properly, you need nomos node running in the background.
// For instructions in building nomos node, refer to [this](https://github.com/logos-blockchain/logos-blockchain?tab=readme-ov-file#running-a-logos-blockchain-node).
//
// Recommended to run node locally from build binary.
async fn indexer_run_local_node() -> Result<()> {
let _ctx = TestContext::new_bedrock_local_attached().await?;
info!("Let's observe behaviour");
tokio::time::sleep(std::time::Duration::from_secs(180)).await;
// No way to check state of indexer now
// When it will be a service, then it will become possible.
Ok(())
}
+20 -20
View File
@@ -2,8 +2,8 @@ use std::{str::FromStr, time::Duration};
use anyhow::Result;
use integration_tests::{
ACC_SENDER, ACC_SENDER_PRIVATE, TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext,
format_private_account_id, format_public_account_id, verify_commitment_is_in_state,
TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext, format_private_account_id,
format_public_account_id, verify_commitment_is_in_state,
};
use key_protocol::key_management::key_tree::chain_index::ChainIndex;
use log::info;
@@ -19,7 +19,7 @@ use wallet::cli::{
async fn restore_keys_from_seed() -> Result<()> {
let mut ctx = TestContext::new().await?;
let from: AccountId = ACC_SENDER_PRIVATE.parse()?;
let from: AccountId = ctx.existing_private_accounts()[0];
// Create first private account at root
let command = Command::Account(AccountSubcommand::New(NewSubcommand::Private {
@@ -47,8 +47,8 @@ async fn restore_keys_from_seed() -> Result<()> {
// Send to first private account
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: format_private_account_id(&from.to_string()),
to: Some(format_private_account_id(&to_account_id1.to_string())),
from: format_private_account_id(from),
to: Some(format_private_account_id(to_account_id1)),
to_npk: None,
to_ipk: None,
amount: 100,
@@ -57,15 +57,15 @@ async fn restore_keys_from_seed() -> Result<()> {
// Send to second private account
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: format_private_account_id(&from.to_string()),
to: Some(format_private_account_id(&to_account_id2.to_string())),
from: format_private_account_id(from),
to: Some(format_private_account_id(to_account_id2)),
to_npk: None,
to_ipk: None,
amount: 101,
});
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
let from: AccountId = ACC_SENDER.parse()?;
let from: AccountId = ctx.existing_public_accounts()[0];
// Create first public account at root
let command = Command::Account(AccountSubcommand::New(NewSubcommand::Public {
@@ -93,8 +93,8 @@ async fn restore_keys_from_seed() -> Result<()> {
// Send to first public account
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: format_public_account_id(&from.to_string()),
to: Some(format_public_account_id(&to_account_id3.to_string())),
from: format_public_account_id(from),
to: Some(format_public_account_id(to_account_id3)),
to_npk: None,
to_ipk: None,
amount: 102,
@@ -103,8 +103,8 @@ async fn restore_keys_from_seed() -> Result<()> {
// Send to second public account
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: format_public_account_id(&from.to_string()),
to: Some(format_public_account_id(&to_account_id4.to_string())),
from: format_public_account_id(from),
to: Some(format_public_account_id(to_account_id4)),
to_npk: None,
to_ipk: None,
amount: 103,
@@ -166,8 +166,8 @@ async fn restore_keys_from_seed() -> Result<()> {
// Test that restored accounts can send transactions
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: format_private_account_id(&to_account_id1.to_string()),
to: Some(format_private_account_id(&to_account_id2.to_string())),
from: format_private_account_id(to_account_id1),
to: Some(format_private_account_id(to_account_id2)),
to_npk: None,
to_ipk: None,
amount: 10,
@@ -175,8 +175,8 @@ async fn restore_keys_from_seed() -> Result<()> {
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: format_public_account_id(&to_account_id3.to_string()),
to: Some(format_public_account_id(&to_account_id4.to_string())),
from: format_public_account_id(to_account_id3),
to: Some(format_public_account_id(to_account_id4)),
to_npk: None,
to_ipk: None,
amount: 11,
@@ -188,11 +188,11 @@ async fn restore_keys_from_seed() -> Result<()> {
// Verify commitments exist for private accounts
let comm1 = ctx
.wallet()
.get_private_account_commitment(&to_account_id1)
.get_private_account_commitment(to_account_id1)
.expect("Acc 1 commitment should exist");
let comm2 = ctx
.wallet()
.get_private_account_commitment(&to_account_id2)
.get_private_account_commitment(to_account_id2)
.expect("Acc 2 commitment should exist");
assert!(verify_commitment_is_in_state(comm1, ctx.sequencer_client()).await);
@@ -201,11 +201,11 @@ async fn restore_keys_from_seed() -> Result<()> {
// Verify public account balances
let acc3 = ctx
.sequencer_client()
.get_account_balance(to_account_id3.to_string())
.get_account_balance(to_account_id3)
.await?;
let acc4 = ctx
.sequencer_client()
.get_account_balance(to_account_id4.to_string())
.get_account_balance(to_account_id4)
.await?;
assert_eq!(acc3.balance, 91); // 102 - 11
+15 -15
View File
@@ -3,8 +3,8 @@ use std::time::Duration;
use anyhow::{Context as _, Result};
use common::PINATA_BASE58;
use integration_tests::{
ACC_SENDER, ACC_SENDER_PRIVATE, TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext,
format_private_account_id, format_public_account_id, verify_commitment_is_in_state,
TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext, format_private_account_id,
format_public_account_id, verify_commitment_is_in_state,
};
use log::info;
use tokio::test;
@@ -22,12 +22,12 @@ async fn claim_pinata_to_existing_public_account() -> Result<()> {
let pinata_prize = 150;
let command = Command::Pinata(PinataProgramAgnosticSubcommand::Claim {
to: format_public_account_id(ACC_SENDER),
to: format_public_account_id(ctx.existing_public_accounts()[0]),
});
let pinata_balance_pre = ctx
.sequencer_client()
.get_account_balance(PINATA_BASE58.to_string())
.get_account_balance(PINATA_BASE58.parse().unwrap())
.await?
.balance;
@@ -39,13 +39,13 @@ async fn claim_pinata_to_existing_public_account() -> Result<()> {
info!("Checking correct balance move");
let pinata_balance_post = ctx
.sequencer_client()
.get_account_balance(PINATA_BASE58.to_string())
.get_account_balance(PINATA_BASE58.parse().unwrap())
.await?
.balance;
let winner_balance_post = ctx
.sequencer_client()
.get_account_balance(ACC_SENDER.to_string())
.get_account_balance(ctx.existing_public_accounts()[0])
.await?
.balance;
@@ -63,12 +63,12 @@ async fn claim_pinata_to_existing_private_account() -> Result<()> {
let pinata_prize = 150;
let command = Command::Pinata(PinataProgramAgnosticSubcommand::Claim {
to: format_private_account_id(ACC_SENDER_PRIVATE),
to: format_private_account_id(ctx.existing_private_accounts()[0]),
});
let pinata_balance_pre = ctx
.sequencer_client()
.get_account_balance(PINATA_BASE58.to_string())
.get_account_balance(PINATA_BASE58.parse().unwrap())
.await?
.balance;
@@ -86,13 +86,13 @@ async fn claim_pinata_to_existing_private_account() -> Result<()> {
let new_commitment = ctx
.wallet()
.get_private_account_commitment(&ACC_SENDER_PRIVATE.parse()?)
.get_private_account_commitment(ctx.existing_private_accounts()[0])
.context("Failed to get private account commitment")?;
assert!(verify_commitment_is_in_state(new_commitment, ctx.sequencer_client()).await);
let pinata_balance_post = ctx
.sequencer_client()
.get_account_balance(PINATA_BASE58.to_string())
.get_account_balance(PINATA_BASE58.parse().unwrap())
.await?
.balance;
@@ -122,7 +122,7 @@ async fn claim_pinata_to_new_private_account() -> Result<()> {
anyhow::bail!("Expected RegisterAccount return value");
};
let winner_account_id_formatted = format_private_account_id(&winner_account_id.to_string());
let winner_account_id_formatted = format_private_account_id(winner_account_id);
// Initialize account under auth transfer program
let command = Command::AuthTransfer(AuthTransferSubcommand::Init {
@@ -135,7 +135,7 @@ async fn claim_pinata_to_new_private_account() -> Result<()> {
let new_commitment = ctx
.wallet()
.get_private_account_commitment(&winner_account_id)
.get_private_account_commitment(winner_account_id)
.context("Failed to get private account commitment")?;
assert!(verify_commitment_is_in_state(new_commitment, ctx.sequencer_client()).await);
@@ -146,7 +146,7 @@ async fn claim_pinata_to_new_private_account() -> Result<()> {
let pinata_balance_pre = ctx
.sequencer_client()
.get_account_balance(PINATA_BASE58.to_string())
.get_account_balance(PINATA_BASE58.parse().unwrap())
.await?
.balance;
@@ -157,13 +157,13 @@ async fn claim_pinata_to_new_private_account() -> Result<()> {
let new_commitment = ctx
.wallet()
.get_private_account_commitment(&winner_account_id)
.get_private_account_commitment(winner_account_id)
.context("Failed to get private account commitment")?;
assert!(verify_commitment_is_in_state(new_commitment, ctx.sequencer_client()).await);
let pinata_balance_post = ctx
.sequencer_client()
.get_account_balance(PINATA_BASE58.to_string())
.get_account_balance(PINATA_BASE58.parse().unwrap())
.await?
.balance;
@@ -45,11 +45,13 @@ async fn deploy_and_execute_program() -> Result<()> {
let _response = ctx.sequencer_client().send_tx_public(transaction).await?;
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
// Waiting for long time as it may take some time for such a big transaction to be included in a
// block
tokio::time::sleep(Duration::from_secs(2 * TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
let post_state_account = ctx
.sequencer_client()
.get_account(account_id.to_string())
.get_account(account_id)
.await?
.account;
+72 -76
View File
@@ -63,8 +63,8 @@ async fn create_and_transfer_public_token() -> Result<()> {
let name = "A NAME".to_string();
let total_supply = 37;
let subcommand = TokenProgramAgnosticSubcommand::New {
definition_account_id: format_public_account_id(&definition_account_id.to_string()),
supply_account_id: format_public_account_id(&supply_account_id.to_string()),
definition_account_id: format_public_account_id(definition_account_id),
supply_account_id: format_public_account_id(supply_account_id),
name: name.clone(),
total_supply,
};
@@ -76,7 +76,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
// Check the status of the token definition account
let definition_acc = ctx
.sequencer_client()
.get_account(definition_account_id.to_string())
.get_account(definition_account_id)
.await?
.account;
let token_definition = TokenDefinition::try_from(&definition_acc.data)?;
@@ -94,7 +94,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
// Check the status of the token holding account with the total supply
let supply_acc = ctx
.sequencer_client()
.get_account(supply_account_id.to_string())
.get_account(supply_account_id)
.await?
.account;
@@ -112,8 +112,8 @@ async fn create_and_transfer_public_token() -> Result<()> {
// Transfer 7 tokens from supply_acc to recipient_account_id
let transfer_amount = 7;
let subcommand = TokenProgramAgnosticSubcommand::Send {
from: format_public_account_id(&supply_account_id.to_string()),
to: Some(format_public_account_id(&recipient_account_id.to_string())),
from: format_public_account_id(supply_account_id),
to: Some(format_public_account_id(recipient_account_id)),
to_npk: None,
to_ipk: None,
amount: transfer_amount,
@@ -127,7 +127,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
// Check the status of the supply account after transfer
let supply_acc = ctx
.sequencer_client()
.get_account(supply_account_id.to_string())
.get_account(supply_account_id)
.await?
.account;
assert_eq!(supply_acc.program_owner, Program::token().id());
@@ -143,7 +143,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
// Check the status of the recipient account after transfer
let recipient_acc = ctx
.sequencer_client()
.get_account(recipient_account_id.to_string())
.get_account(recipient_account_id)
.await?
.account;
assert_eq!(recipient_acc.program_owner, Program::token().id());
@@ -159,8 +159,8 @@ async fn create_and_transfer_public_token() -> Result<()> {
// Burn 3 tokens from recipient_acc
let burn_amount = 3;
let subcommand = TokenProgramAgnosticSubcommand::Burn {
definition: format_public_account_id(&definition_account_id.to_string()),
holder: format_public_account_id(&recipient_account_id.to_string()),
definition: format_public_account_id(definition_account_id),
holder: format_public_account_id(recipient_account_id),
amount: burn_amount,
};
@@ -172,7 +172,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
// Check the status of the token definition account after burn
let definition_acc = ctx
.sequencer_client()
.get_account(definition_account_id.to_string())
.get_account(definition_account_id)
.await?
.account;
let token_definition = TokenDefinition::try_from(&definition_acc.data)?;
@@ -189,7 +189,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
// Check the status of the recipient account after burn
let recipient_acc = ctx
.sequencer_client()
.get_account(recipient_account_id.to_string())
.get_account(recipient_account_id)
.await?
.account;
let token_holding = TokenHolding::try_from(&recipient_acc.data)?;
@@ -205,8 +205,8 @@ async fn create_and_transfer_public_token() -> Result<()> {
// Mint 10 tokens at recipient_acc
let mint_amount = 10;
let subcommand = TokenProgramAgnosticSubcommand::Mint {
definition: format_public_account_id(&definition_account_id.to_string()),
holder: Some(format_public_account_id(&recipient_account_id.to_string())),
definition: format_public_account_id(definition_account_id),
holder: Some(format_public_account_id(recipient_account_id)),
holder_npk: None,
holder_ipk: None,
amount: mint_amount,
@@ -220,7 +220,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
// Check the status of the token definition account after mint
let definition_acc = ctx
.sequencer_client()
.get_account(definition_account_id.to_string())
.get_account(definition_account_id)
.await?
.account;
let token_definition = TokenDefinition::try_from(&definition_acc.data)?;
@@ -237,7 +237,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
// Check the status of the recipient account after mint
let recipient_acc = ctx
.sequencer_client()
.get_account(recipient_account_id.to_string())
.get_account(recipient_account_id)
.await?
.account;
let token_holding = TokenHolding::try_from(&recipient_acc.data)?;
@@ -302,8 +302,8 @@ async fn create_and_transfer_token_with_private_supply() -> Result<()> {
let name = "A NAME".to_string();
let total_supply = 37;
let subcommand = TokenProgramAgnosticSubcommand::New {
definition_account_id: format_public_account_id(&definition_account_id.to_string()),
supply_account_id: format_private_account_id(&supply_account_id.to_string()),
definition_account_id: format_public_account_id(definition_account_id),
supply_account_id: format_private_account_id(supply_account_id),
name: name.clone(),
total_supply,
};
@@ -316,7 +316,7 @@ async fn create_and_transfer_token_with_private_supply() -> Result<()> {
// Check the status of the token definition account
let definition_acc = ctx
.sequencer_client()
.get_account(definition_account_id.to_string())
.get_account(definition_account_id)
.await?
.account;
let token_definition = TokenDefinition::try_from(&definition_acc.data)?;
@@ -333,15 +333,15 @@ async fn create_and_transfer_token_with_private_supply() -> Result<()> {
let new_commitment1 = ctx
.wallet()
.get_private_account_commitment(&supply_account_id)
.get_private_account_commitment(supply_account_id)
.context("Failed to get supply account commitment")?;
assert!(verify_commitment_is_in_state(new_commitment1, ctx.sequencer_client()).await);
// Transfer 7 tokens from supply_acc to recipient_account_id
let transfer_amount = 7;
let subcommand = TokenProgramAgnosticSubcommand::Send {
from: format_private_account_id(&supply_account_id.to_string()),
to: Some(format_private_account_id(&recipient_account_id.to_string())),
from: format_private_account_id(supply_account_id),
to: Some(format_private_account_id(recipient_account_id)),
to_npk: None,
to_ipk: None,
amount: transfer_amount,
@@ -354,21 +354,21 @@ async fn create_and_transfer_token_with_private_supply() -> Result<()> {
let new_commitment1 = ctx
.wallet()
.get_private_account_commitment(&supply_account_id)
.get_private_account_commitment(supply_account_id)
.context("Failed to get supply account commitment")?;
assert!(verify_commitment_is_in_state(new_commitment1, ctx.sequencer_client()).await);
let new_commitment2 = ctx
.wallet()
.get_private_account_commitment(&recipient_account_id)
.get_private_account_commitment(recipient_account_id)
.context("Failed to get recipient account commitment")?;
assert!(verify_commitment_is_in_state(new_commitment2, ctx.sequencer_client()).await);
// Burn 3 tokens from recipient_acc
let burn_amount = 3;
let subcommand = TokenProgramAgnosticSubcommand::Burn {
definition: format_public_account_id(&definition_account_id.to_string()),
holder: format_private_account_id(&recipient_account_id.to_string()),
definition: format_public_account_id(definition_account_id),
holder: format_private_account_id(recipient_account_id),
amount: burn_amount,
};
@@ -380,7 +380,7 @@ async fn create_and_transfer_token_with_private_supply() -> Result<()> {
// Check the token definition account after burn
let definition_acc = ctx
.sequencer_client()
.get_account(definition_account_id.to_string())
.get_account(definition_account_id)
.await?
.account;
let token_definition = TokenDefinition::try_from(&definition_acc.data)?;
@@ -396,14 +396,14 @@ async fn create_and_transfer_token_with_private_supply() -> Result<()> {
let new_commitment2 = ctx
.wallet()
.get_private_account_commitment(&recipient_account_id)
.get_private_account_commitment(recipient_account_id)
.context("Failed to get recipient account commitment")?;
assert!(verify_commitment_is_in_state(new_commitment2, ctx.sequencer_client()).await);
// Check the recipient account balance after burn
let recipient_acc = ctx
.wallet()
.get_account_private(&recipient_account_id)
.get_account_private(recipient_account_id)
.context("Failed to get recipient account")?;
let token_holding = TokenHolding::try_from(&recipient_acc.data)?;
@@ -458,8 +458,8 @@ async fn create_token_with_private_definition() -> Result<()> {
let name = "A NAME".to_string();
let total_supply = 37;
let subcommand = TokenProgramAgnosticSubcommand::New {
definition_account_id: format_private_account_id(&definition_account_id.to_string()),
supply_account_id: format_public_account_id(&supply_account_id.to_string()),
definition_account_id: format_private_account_id(definition_account_id),
supply_account_id: format_public_account_id(supply_account_id),
name: name.clone(),
total_supply,
};
@@ -472,14 +472,14 @@ async fn create_token_with_private_definition() -> Result<()> {
// Verify private definition commitment
let new_commitment = ctx
.wallet()
.get_private_account_commitment(&definition_account_id)
.get_private_account_commitment(definition_account_id)
.context("Failed to get definition commitment")?;
assert!(verify_commitment_is_in_state(new_commitment, ctx.sequencer_client()).await);
// Verify supply account
let supply_acc = ctx
.sequencer_client()
.get_account(supply_account_id.to_string())
.get_account(supply_account_id)
.await?
.account;
@@ -522,10 +522,8 @@ async fn create_token_with_private_definition() -> Result<()> {
// Mint to public account
let mint_amount_public = 10;
let subcommand = TokenProgramAgnosticSubcommand::Mint {
definition: format_private_account_id(&definition_account_id.to_string()),
holder: Some(format_public_account_id(
&recipient_account_id_public.to_string(),
)),
definition: format_private_account_id(definition_account_id),
holder: Some(format_public_account_id(recipient_account_id_public)),
holder_npk: None,
holder_ipk: None,
amount: mint_amount_public,
@@ -539,7 +537,7 @@ async fn create_token_with_private_definition() -> Result<()> {
// Verify definition account has updated supply
let definition_acc = ctx
.wallet()
.get_account_private(&definition_account_id)
.get_account_private(definition_account_id)
.context("Failed to get definition account")?;
let token_definition = TokenDefinition::try_from(&definition_acc.data)?;
@@ -555,7 +553,7 @@ async fn create_token_with_private_definition() -> Result<()> {
// Verify public recipient received tokens
let recipient_acc = ctx
.sequencer_client()
.get_account(recipient_account_id_public.to_string())
.get_account(recipient_account_id_public)
.await?
.account;
let token_holding = TokenHolding::try_from(&recipient_acc.data)?;
@@ -571,10 +569,8 @@ async fn create_token_with_private_definition() -> Result<()> {
// Mint to private account
let mint_amount_private = 5;
let subcommand = TokenProgramAgnosticSubcommand::Mint {
definition: format_private_account_id(&definition_account_id.to_string()),
holder: Some(format_private_account_id(
&recipient_account_id_private.to_string(),
)),
definition: format_private_account_id(definition_account_id),
holder: Some(format_private_account_id(recipient_account_id_private)),
holder_npk: None,
holder_ipk: None,
amount: mint_amount_private,
@@ -588,14 +584,14 @@ async fn create_token_with_private_definition() -> Result<()> {
// Verify private recipient commitment
let new_commitment = ctx
.wallet()
.get_private_account_commitment(&recipient_account_id_private)
.get_private_account_commitment(recipient_account_id_private)
.context("Failed to get recipient commitment")?;
assert!(verify_commitment_is_in_state(new_commitment, ctx.sequencer_client()).await);
// Verify private recipient balance
let recipient_acc_private = ctx
.wallet()
.get_account_private(&recipient_account_id_private)
.get_account_private(recipient_account_id_private)
.context("Failed to get private recipient account")?;
let token_holding = TokenHolding::try_from(&recipient_acc_private.data)?;
@@ -646,8 +642,8 @@ async fn create_token_with_private_definition_and_supply() -> Result<()> {
let name = "A NAME".to_string();
let total_supply = 37;
let subcommand = TokenProgramAgnosticSubcommand::New {
definition_account_id: format_private_account_id(&definition_account_id.to_string()),
supply_account_id: format_private_account_id(&supply_account_id.to_string()),
definition_account_id: format_private_account_id(definition_account_id),
supply_account_id: format_private_account_id(supply_account_id),
name,
total_supply,
};
@@ -660,21 +656,21 @@ async fn create_token_with_private_definition_and_supply() -> Result<()> {
// Verify definition commitment
let definition_commitment = ctx
.wallet()
.get_private_account_commitment(&definition_account_id)
.get_private_account_commitment(definition_account_id)
.context("Failed to get definition commitment")?;
assert!(verify_commitment_is_in_state(definition_commitment, ctx.sequencer_client()).await);
// Verify supply commitment
let supply_commitment = ctx
.wallet()
.get_private_account_commitment(&supply_account_id)
.get_private_account_commitment(supply_account_id)
.context("Failed to get supply commitment")?;
assert!(verify_commitment_is_in_state(supply_commitment, ctx.sequencer_client()).await);
// Verify supply balance
let supply_acc = ctx
.wallet()
.get_account_private(&supply_account_id)
.get_account_private(supply_account_id)
.context("Failed to get supply account")?;
let token_holding = TokenHolding::try_from(&supply_acc.data)?;
@@ -702,8 +698,8 @@ async fn create_token_with_private_definition_and_supply() -> Result<()> {
// Transfer tokens
let transfer_amount = 7;
let subcommand = TokenProgramAgnosticSubcommand::Send {
from: format_private_account_id(&supply_account_id.to_string()),
to: Some(format_private_account_id(&recipient_account_id.to_string())),
from: format_private_account_id(supply_account_id),
to: Some(format_private_account_id(recipient_account_id)),
to_npk: None,
to_ipk: None,
amount: transfer_amount,
@@ -717,20 +713,20 @@ async fn create_token_with_private_definition_and_supply() -> Result<()> {
// Verify both commitments updated
let supply_commitment = ctx
.wallet()
.get_private_account_commitment(&supply_account_id)
.get_private_account_commitment(supply_account_id)
.context("Failed to get supply commitment")?;
assert!(verify_commitment_is_in_state(supply_commitment, ctx.sequencer_client()).await);
let recipient_commitment = ctx
.wallet()
.get_private_account_commitment(&recipient_account_id)
.get_private_account_commitment(recipient_account_id)
.context("Failed to get recipient commitment")?;
assert!(verify_commitment_is_in_state(recipient_commitment, ctx.sequencer_client()).await);
// Verify balances
let supply_acc = ctx
.wallet()
.get_account_private(&supply_account_id)
.get_account_private(supply_account_id)
.context("Failed to get supply account")?;
let token_holding = TokenHolding::try_from(&supply_acc.data)?;
assert_eq!(
@@ -743,7 +739,7 @@ async fn create_token_with_private_definition_and_supply() -> Result<()> {
let recipient_acc = ctx
.wallet()
.get_account_private(&recipient_account_id)
.get_account_private(recipient_account_id)
.context("Failed to get recipient account")?;
let token_holding = TokenHolding::try_from(&recipient_acc.data)?;
assert_eq!(
@@ -806,8 +802,8 @@ async fn shielded_token_transfer() -> Result<()> {
let name = "A NAME".to_string();
let total_supply = 37;
let subcommand = TokenProgramAgnosticSubcommand::New {
definition_account_id: format_public_account_id(&definition_account_id.to_string()),
supply_account_id: format_public_account_id(&supply_account_id.to_string()),
definition_account_id: format_public_account_id(definition_account_id),
supply_account_id: format_public_account_id(supply_account_id),
name,
total_supply,
};
@@ -820,8 +816,8 @@ async fn shielded_token_transfer() -> Result<()> {
// Perform shielded transfer: public supply -> private recipient
let transfer_amount = 7;
let subcommand = TokenProgramAgnosticSubcommand::Send {
from: format_public_account_id(&supply_account_id.to_string()),
to: Some(format_private_account_id(&recipient_account_id.to_string())),
from: format_public_account_id(supply_account_id),
to: Some(format_private_account_id(recipient_account_id)),
to_npk: None,
to_ipk: None,
amount: transfer_amount,
@@ -835,7 +831,7 @@ async fn shielded_token_transfer() -> Result<()> {
// Verify supply account balance
let supply_acc = ctx
.sequencer_client()
.get_account(supply_account_id.to_string())
.get_account(supply_account_id)
.await?
.account;
let token_holding = TokenHolding::try_from(&supply_acc.data)?;
@@ -850,14 +846,14 @@ async fn shielded_token_transfer() -> Result<()> {
// Verify recipient commitment exists
let new_commitment = ctx
.wallet()
.get_private_account_commitment(&recipient_account_id)
.get_private_account_commitment(recipient_account_id)
.context("Failed to get recipient commitment")?;
assert!(verify_commitment_is_in_state(new_commitment, ctx.sequencer_client()).await);
// Verify recipient balance
let recipient_acc = ctx
.wallet()
.get_account_private(&recipient_account_id)
.get_account_private(recipient_account_id)
.context("Failed to get recipient account")?;
let token_holding = TokenHolding::try_from(&recipient_acc.data)?;
assert_eq!(
@@ -920,8 +916,8 @@ async fn deshielded_token_transfer() -> Result<()> {
let name = "A NAME".to_string();
let total_supply = 37;
let subcommand = TokenProgramAgnosticSubcommand::New {
definition_account_id: format_public_account_id(&definition_account_id.to_string()),
supply_account_id: format_private_account_id(&supply_account_id.to_string()),
definition_account_id: format_public_account_id(definition_account_id),
supply_account_id: format_private_account_id(supply_account_id),
name,
total_supply,
};
@@ -934,8 +930,8 @@ async fn deshielded_token_transfer() -> Result<()> {
// Perform deshielded transfer: private supply -> public recipient
let transfer_amount = 7;
let subcommand = TokenProgramAgnosticSubcommand::Send {
from: format_private_account_id(&supply_account_id.to_string()),
to: Some(format_public_account_id(&recipient_account_id.to_string())),
from: format_private_account_id(supply_account_id),
to: Some(format_public_account_id(recipient_account_id)),
to_npk: None,
to_ipk: None,
amount: transfer_amount,
@@ -949,14 +945,14 @@ async fn deshielded_token_transfer() -> Result<()> {
// Verify supply account commitment exists
let new_commitment = ctx
.wallet()
.get_private_account_commitment(&supply_account_id)
.get_private_account_commitment(supply_account_id)
.context("Failed to get supply commitment")?;
assert!(verify_commitment_is_in_state(new_commitment, ctx.sequencer_client()).await);
// Verify supply balance
let supply_acc = ctx
.wallet()
.get_account_private(&supply_account_id)
.get_account_private(supply_account_id)
.context("Failed to get supply account")?;
let token_holding = TokenHolding::try_from(&supply_acc.data)?;
assert_eq!(
@@ -970,7 +966,7 @@ async fn deshielded_token_transfer() -> Result<()> {
// Verify recipient balance
let recipient_acc = ctx
.sequencer_client()
.get_account(recipient_account_id.to_string())
.get_account(recipient_account_id)
.await?
.account;
let token_holding = TokenHolding::try_from(&recipient_acc.data)?;
@@ -1021,8 +1017,8 @@ async fn token_claiming_path_with_private_accounts() -> Result<()> {
let name = "A NAME".to_string();
let total_supply = 37;
let subcommand = TokenProgramAgnosticSubcommand::New {
definition_account_id: format_private_account_id(&definition_account_id.to_string()),
supply_account_id: format_private_account_id(&supply_account_id.to_string()),
definition_account_id: format_private_account_id(definition_account_id),
supply_account_id: format_private_account_id(supply_account_id),
name,
total_supply,
};
@@ -1050,14 +1046,14 @@ async fn token_claiming_path_with_private_accounts() -> Result<()> {
.wallet()
.storage()
.user_data
.get_private_account(&recipient_account_id)
.get_private_account(recipient_account_id)
.cloned()
.context("Failed to get private account keys")?;
// Mint using claiming path (foreign account)
let mint_amount = 9;
let subcommand = TokenProgramAgnosticSubcommand::Mint {
definition: format_private_account_id(&definition_account_id.to_string()),
definition: format_private_account_id(definition_account_id),
holder: None,
holder_npk: Some(hex::encode(holder_keys.nullifer_public_key.0)),
holder_ipk: Some(hex::encode(holder_keys.incoming_viewing_public_key.0)),
@@ -1076,14 +1072,14 @@ async fn token_claiming_path_with_private_accounts() -> Result<()> {
// Verify commitment exists
let recipient_commitment = ctx
.wallet()
.get_private_account_commitment(&recipient_account_id)
.get_private_account_commitment(recipient_account_id)
.context("Failed to get recipient commitment")?;
assert!(verify_commitment_is_in_state(recipient_commitment, ctx.sequencer_client()).await);
// Verify balance
let recipient_acc = ctx
.wallet()
.get_account_private(&recipient_account_id)
.get_account_private(recipient_account_id)
.context("Failed to get recipient account")?;
let token_holding = TokenHolding::try_from(&recipient_acc.data)?;
assert_eq!(
+27 -38
View File
@@ -1,8 +1,11 @@
use std::time::{Duration, Instant};
use anyhow::Result;
use integration_tests::TestContext;
use key_protocol::key_management::ephemeral_key_holder::EphemeralKeyHolder;
use integration_tests::{
TestContext,
config::{InitialData, SequencerPartialConfig},
};
use key_protocol::key_management::{KeyChain, ephemeral_key_holder::EphemeralKeyHolder};
use log::info;
use nssa::{
Account, AccountId, PrivacyPreservingTransaction, PrivateKey, PublicKey, PublicTransaction,
@@ -15,21 +18,20 @@ use nssa_core::{
account::{AccountWithMetadata, data::Data},
encryption::IncomingViewingPublicKey,
};
use sequencer_core::config::{AccountInitialData, CommitmentsInitialData, SequencerConfig};
use tokio::test;
// TODO: Make a proper benchmark instead of an ad-hoc test
#[test]
pub async fn tps_test() -> Result<()> {
let num_transactions = 300 * 5;
let target_tps = 12;
let target_tps = 8;
let tps_test = TpsTestManager::new(target_tps, num_transactions);
let ctx = TestContext::new_with_sequencer_and_maybe_indexer_configs(
tps_test.generate_sequencer_config(),
None,
)
.await?;
let ctx = TestContext::builder()
.with_sequencer_partial_config(TpsTestManager::generate_sequencer_partial_config())
.with_initial_data(tps_test.generate_initial_data())
.build()
.await?;
let target_time = tps_test.target_time();
info!(
@@ -59,12 +61,10 @@ pub async fn tps_test() -> Result<()> {
let tx_obj = ctx
.sequencer_client()
.get_transaction_by_hash(tx_hash.clone())
.get_transaction_by_hash(*tx_hash)
.await
.inspect_err(|err| {
log::warn!(
"Failed to get transaction by hash {tx_hash:#?} with error: {err:#?}"
)
log::warn!("Failed to get transaction by hash {tx_hash} with error: {err:#?}")
});
if let Ok(tx_obj) = tx_obj
@@ -151,46 +151,35 @@ impl TpsTestManager {
/// Generates a sequencer configuration with initial balance in a number of public accounts.
/// The transactions generated with the function `build_public_txs` will be valid in a node
/// started with the config from this method.
pub(crate) fn generate_sequencer_config(&self) -> SequencerConfig {
fn generate_initial_data(&self) -> InitialData {
// Create public public keypairs
let initial_public_accounts = self
let public_accounts = self
.public_keypairs
.iter()
.map(|(_, account_id)| AccountInitialData {
account_id: account_id.to_string(),
balance: 10,
})
.map(|(key, _)| (key.clone(), 10))
.collect();
// Generate an initial commitment to be used with the privacy preserving transaction
// created with the `build_privacy_transaction` function.
let sender_nsk = [1; 32];
let sender_npk = NullifierPublicKey::from(&sender_nsk);
let key_chain = KeyChain::new_os_random();
let account = Account {
balance: 100,
nonce: 0xdeadbeef,
program_owner: Program::authenticated_transfer_program().id(),
data: Data::default(),
};
let initial_commitment = CommitmentsInitialData {
npk: sender_npk,
account,
};
SequencerConfig {
home: ".".into(),
override_rust_log: None,
genesis_id: 1,
is_genesis_random: true,
InitialData {
public_accounts,
private_accounts: vec![(key_chain, account)],
}
}
fn generate_sequencer_partial_config() -> SequencerPartialConfig {
SequencerPartialConfig {
max_num_tx_in_block: 300,
mempool_max_size: 10000,
block_create_timeout_millis: 12000,
port: 3040,
initial_accounts: initial_public_accounts,
initial_commitments: vec![initial_commitment],
signing_key: [37; 32],
bedrock_config: None,
retry_pending_blocks_timeout_millis: 1000 * 60 * 4,
mempool_max_size: 10_000,
block_create_timeout_millis: 12_000,
}
}
}
+19 -18
View File
@@ -6,12 +6,9 @@ use std::{
};
use anyhow::Result;
use integration_tests::{
ACC_RECEIVER, ACC_SENDER, ACC_SENDER_PRIVATE, BlockingTestContext,
TIME_TO_WAIT_FOR_BLOCK_SECONDS,
};
use integration_tests::{BlockingTestContext, TIME_TO_WAIT_FOR_BLOCK_SECONDS};
use log::info;
use nssa::{Account, AccountId, PublicKey, program::Program};
use nssa::{Account, AccountId, PrivateKey, PublicKey, program::Program};
use nssa_core::program::DEFAULT_PROGRAM_ID;
use tempfile::tempdir;
use wallet::WalletCore;
@@ -328,7 +325,7 @@ fn test_wallet_ffi_list_accounts() {
#[test]
fn test_wallet_ffi_get_balance_public() -> Result<()> {
let ctx = BlockingTestContext::new()?;
let account_id: AccountId = ACC_SENDER.parse().unwrap();
let account_id: AccountId = ctx.ctx.existing_public_accounts()[0];
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx);
let balance = unsafe {
@@ -356,7 +353,7 @@ fn test_wallet_ffi_get_balance_public() -> Result<()> {
#[test]
fn test_wallet_ffi_get_account_public() -> Result<()> {
let ctx = BlockingTestContext::new()?;
let account_id: AccountId = ACC_SENDER.parse().unwrap();
let account_id: AccountId = ctx.ctx.existing_public_accounts()[0];
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx);
let mut out_account = FfiAccount::default();
@@ -391,7 +388,7 @@ fn test_wallet_ffi_get_account_public() -> Result<()> {
#[test]
fn test_wallet_ffi_get_public_account_keys() -> Result<()> {
let ctx = BlockingTestContext::new()?;
let account_id: AccountId = ACC_SENDER.parse().unwrap();
let account_id: AccountId = ctx.ctx.existing_public_accounts()[0];
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx);
let mut out_key = FfiPublicAccountKey::default();
@@ -409,7 +406,7 @@ fn test_wallet_ffi_get_public_account_keys() -> Result<()> {
let private_key = ctx
.ctx
.wallet()
.get_account_public_signing_key(&account_id)
.get_account_public_signing_key(account_id)
.unwrap();
PublicKey::new_from_private_key(private_key)
};
@@ -428,7 +425,7 @@ fn test_wallet_ffi_get_public_account_keys() -> Result<()> {
#[test]
fn test_wallet_ffi_get_private_account_keys() -> Result<()> {
let ctx = BlockingTestContext::new()?;
let account_id: AccountId = ACC_SENDER_PRIVATE.parse().unwrap();
let account_id: AccountId = ctx.ctx.existing_public_accounts()[0];
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx);
let mut keys = FfiPrivateAccountKeys::default();
@@ -446,7 +443,7 @@ fn test_wallet_ffi_get_private_account_keys() -> Result<()> {
.wallet()
.storage()
.user_data
.get_private_account(&account_id)
.get_private_account(account_id)
.unwrap()
.0;
@@ -468,14 +465,15 @@ fn test_wallet_ffi_get_private_account_keys() -> Result<()> {
#[test]
fn test_wallet_ffi_account_id_to_base58() {
let account_id_str = ACC_SENDER;
let account_id: AccountId = account_id_str.parse().unwrap();
let private_key = PrivateKey::new_os_random();
let public_key = PublicKey::new_from_private_key(&private_key);
let account_id = AccountId::from(&public_key);
let ffi_bytes: FfiBytes32 = (&account_id).into();
let ptr = unsafe { wallet_ffi_account_id_to_base58((&ffi_bytes) as *const FfiBytes32) };
let ffi_result = unsafe { CStr::from_ptr(ptr).to_str().unwrap() };
assert_eq!(account_id_str, ffi_result);
assert_eq!(account_id.to_string(), ffi_result);
unsafe {
wallet_ffi_free_string(ptr);
@@ -484,8 +482,11 @@ fn test_wallet_ffi_account_id_to_base58() {
#[test]
fn test_wallet_ffi_base58_to_account_id() {
let account_id_str = ACC_SENDER;
let account_id_c_str = CString::new(account_id_str).unwrap();
let private_key = PrivateKey::new_os_random();
let public_key = PublicKey::new_from_private_key(&private_key);
let account_id = AccountId::from(&public_key);
let account_id_str = account_id.to_string();
let account_id_c_str = CString::new(account_id_str.clone()).unwrap();
let account_id: AccountId = unsafe {
let mut out_account_id_bytes = FfiBytes32::default();
wallet_ffi_account_id_from_base58(
@@ -566,8 +567,8 @@ fn test_wallet_ffi_init_public_account_auth_transfer() -> Result<()> {
fn test_wallet_ffi_transfer_public() -> Result<()> {
let ctx = BlockingTestContext::new().unwrap();
let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx);
let from: FfiBytes32 = (&ACC_SENDER.parse::<AccountId>().unwrap()).into();
let to: FfiBytes32 = (&ACC_RECEIVER.parse::<AccountId>().unwrap()).into();
let from: FfiBytes32 = (&ctx.ctx.existing_public_accounts()[0]).into();
let to: FfiBytes32 = (&ctx.ctx.existing_public_accounts()[1]).into();
let amount: [u8; 16] = 100u128.to_le_bytes();
let mut transfer_result = FfiTransferResult::default();