Skip to content

Commit ba1fc74

Browse files
authored
Always fetch the chain description on follow-chain. (#4532)
## Motivation `follow-chain` synchronizes the new chain only if `--sync` is specified. Otherwise it doesn't even verify that the chain exists. ## Proposal Without `--sync`, still download the chain description. If that fails, don't add the chain to the wallet. ## Test Plan An end-to-end test was extended. ## Release Plan - These changes should be backported to the latest `testnet` branch, then - be released in a new SDK. ## Links - Closes #4529. - [reviewer checklist](https://github.com/linera-io/linera-protocol/blob/main/CONTRIBUTING.md#reviewer-checklist)
1 parent 26cdd6a commit ba1fc74

File tree

3 files changed

+30
-31
lines changed

3 files changed

+30
-31
lines changed

linera-core/src/client/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2804,6 +2804,14 @@ impl<Env: Environment> ChainClient<Env> {
28042804
self.transfer(owner, amount, recipient).await
28052805
}
28062806

2807+
#[instrument(level = "trace")]
2808+
pub async fn fetch_chain_info(&self) -> Result<Box<ChainInfo>, ChainClientError> {
2809+
let validators = self.client.validator_nodes().await?;
2810+
self.client
2811+
.fetch_chain_info(self.chain_id, &validators)
2812+
.await
2813+
}
2814+
28072815
/// Attempts to synchronize chains that have sent us messages and populate our local
28082816
/// inbox.
28092817
///

linera-service/src/cli/main.rs

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,25 +1632,25 @@ impl Runnable for Job {
16321632
.await?;
16331633
}
16341634

1635-
Wallet(WalletCommand::FollowChain {
1636-
chain_id,
1637-
sync: true,
1638-
}) => {
1635+
Wallet(WalletCommand::FollowChain { chain_id, sync }) => {
16391636
let mut context = ClientContext::new(
16401637
storage,
16411638
options.context_options.clone(),
16421639
wallet,
16431640
signer.into_value(),
16441641
);
1642+
let start_time = Instant::now();
1643+
context.client.track_chain(chain_id);
16451644
let chain_client = context.make_chain_client(chain_id);
1646-
info!("Synchronizing chain information");
1647-
let time_start = Instant::now();
1648-
chain_client.synchronize_from_validators().await?;
1645+
if sync {
1646+
chain_client.synchronize_from_validators().await?;
1647+
} else {
1648+
chain_client.fetch_chain_info().await?;
1649+
}
16491650
context.update_wallet_from_client(&chain_client).await?;
1650-
let time_total = time_start.elapsed();
16511651
info!(
1652-
"Synchronized chain information in {} ms",
1653-
time_total.as_millis()
1652+
"Chain followed and added in {} ms",
1653+
start_time.elapsed().as_millis()
16541654
);
16551655
}
16561656

@@ -2372,22 +2372,6 @@ async fn run(options: &ClientOptions) -> Result<i32, Error> {
23722372
Ok(0)
23732373
}
23742374

2375-
WalletCommand::FollowChain { chain_id, sync } => {
2376-
let start_time = Instant::now();
2377-
options
2378-
.wallet()?
2379-
.mutate(|w| w.extend([UserChain::make_other(*chain_id, Timestamp::now())]))
2380-
.await?;
2381-
if *sync {
2382-
options.run_with_storage(Job(options.clone())).await??;
2383-
}
2384-
info!(
2385-
"Chain followed and added in {} ms",
2386-
start_time.elapsed().as_millis()
2387-
);
2388-
Ok(0)
2389-
}
2390-
23912375
WalletCommand::ForgetChain { chain_id } => {
23922376
let start_time = Instant::now();
23932377
options
@@ -2398,11 +2382,6 @@ async fn run(options: &ClientOptions) -> Result<i32, Error> {
23982382
Ok(0)
23992383
}
24002384

2401-
WalletCommand::RequestChain { .. } => {
2402-
options.run_with_storage(Job(options.clone())).await??;
2403-
Ok(0)
2404-
}
2405-
24062385
WalletCommand::Init {
24072386
genesis_config_path,
24082387
faucet,
@@ -2449,6 +2428,11 @@ Make sure to use a Linera client compatible with this network.
24492428
);
24502429
Ok(0)
24512430
}
2431+
2432+
WalletCommand::FollowChain { .. } | WalletCommand::RequestChain { .. } => {
2433+
options.run_with_storage(Job(options.clone())).await??;
2434+
Ok(0)
2435+
}
24522436
},
24532437

24542438
_ => {

linera-service/tests/linera_net_tests.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4080,6 +4080,13 @@ async fn test_end_to_end_assign_greatgrandchild_chain(config: impl LineraNetConf
40804080
// Verify that a third party can also follow the chain.
40814081
client3.follow_chain(chain2, true).await?;
40824082
assert!(client3.local_balance(account2).await? > Amount::ZERO);
4083+
assert!(client3.load_wallet()?.chain_ids().contains(&chain2));
4084+
4085+
// Verify that trying to follow a chain that does not exist will fail, even without --sync.
4086+
let wrong_id = ChainId(CryptoHash::test_hash("wrong chain ID"));
4087+
let result = client3.follow_chain(wrong_id, false).await;
4088+
assert!(result.is_err());
4089+
assert!(!client3.load_wallet()?.chain_ids().contains(&wrong_id));
40834090

40844091
net.ensure_is_running().await?;
40854092
net.terminate().await?;

0 commit comments

Comments
 (0)