feat: Add account-dir test-validator argument support (#2436)

This commit is contained in:
Pierre 2023-03-25 05:13:18 +11:00 committed by GitHub
parent 00c2fc3601
commit 9a075087d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 66 additions and 2 deletions

View File

@ -884,11 +884,20 @@ pub struct AccountEntry {
pub filename: String, pub filename: String,
} }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AccountDirEntry {
// Directory containing account JSON files
pub directory: String,
}
#[derive(Debug, Default, Clone, Serialize, Deserialize)] #[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct _Validator { pub struct _Validator {
// Load an account from the provided JSON file // Load an account from the provided JSON file
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub account: Option<Vec<AccountEntry>>, pub account: Option<Vec<AccountEntry>>,
// Load all the accounts from the JSON files found in the specified DIRECTORY
#[serde(skip_serializing_if = "Option::is_none")]
pub account_dir: Option<Vec<AccountDirEntry>>,
// IP address to bind the validator ports. [default: 0.0.0.0] // IP address to bind the validator ports. [default: 0.0.0.0]
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub bind_address: Option<String>, pub bind_address: Option<String>,
@ -940,6 +949,8 @@ pub struct _Validator {
pub struct Validator { pub struct Validator {
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub account: Option<Vec<AccountEntry>>, pub account: Option<Vec<AccountEntry>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub account_dir: Option<Vec<AccountDirEntry>>,
pub bind_address: String, pub bind_address: String,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub clone: Option<Vec<CloneEntry>>, pub clone: Option<Vec<CloneEntry>>,
@ -973,6 +984,7 @@ impl From<_Validator> for Validator {
fn from(_validator: _Validator) -> Self { fn from(_validator: _Validator) -> Self {
Self { Self {
account: _validator.account, account: _validator.account,
account_dir: _validator.account_dir,
bind_address: _validator bind_address: _validator
.bind_address .bind_address
.unwrap_or_else(|| DEFAULT_BIND_ADDRESS.to_string()), .unwrap_or_else(|| DEFAULT_BIND_ADDRESS.to_string()),
@ -1002,6 +1014,7 @@ impl From<Validator> for _Validator {
fn from(validator: Validator) -> Self { fn from(validator: Validator) -> Self {
Self { Self {
account: validator.account, account: validator.account,
account_dir: validator.account_dir,
bind_address: Some(validator.bind_address), bind_address: Some(validator.bind_address),
clone: validator.clone, clone: validator.clone,
dynamic_port_range: validator.dynamic_port_range, dynamic_port_range: validator.dynamic_port_range,
@ -1048,6 +1061,24 @@ impl Merge for _Validator {
} }
}, },
}, },
account_dir: match self.account_dir.take() {
None => other.account_dir,
Some(mut entries) => match other.account_dir {
None => Some(entries),
Some(other_entries) => {
for other_entry in other_entries {
match entries
.iter()
.position(|my_entry| *my_entry.directory == other_entry.directory)
{
None => entries.push(other_entry),
Some(i) => entries[i] = other_entry,
};
}
Some(entries)
}
},
},
bind_address: other.bind_address.or_else(|| self.bind_address.take()), bind_address: other.bind_address.or_else(|| self.bind_address.take()),
clone: match self.clone.take() { clone: match self.clone.take() {
None => other.clone, None => other.clone,

View File

@ -2536,14 +2536,19 @@ fn validator_flags(
flags.push(entry["address"].as_str().unwrap().to_string()); flags.push(entry["address"].as_str().unwrap().to_string());
flags.push(entry["filename"].as_str().unwrap().to_string()); flags.push(entry["filename"].as_str().unwrap().to_string());
} }
} else if key == "account_dir" {
for entry in value.as_array().unwrap() {
flags.push("--account-dir".to_string());
flags.push(entry["directory"].as_str().unwrap().to_string());
}
} else if key == "clone" { } else if key == "clone" {
// Client for fetching accounts data // Client for fetching accounts data
let client = if let Some(url) = entries["url"].as_str() { let client = if let Some(url) = entries["url"].as_str() {
RpcClient::new(url.to_string()) RpcClient::new(url.to_string())
} else { } else {
return Err(anyhow!( return Err(anyhow!(
"Validator url for Solana's JSON RPC should be provided in order to clone accounts from it" "Validator url for Solana's JSON RPC should be provided in order to clone accounts from it"
)); ));
}; };
let mut pubkeys = value let mut pubkeys = value

View File

@ -36,3 +36,9 @@ address = "mv3ekLzLbnVPNxjSKvqBpU3ZeZXPQdEC3bp5MDEBG68"
[[test.validator.clone]] [[test.validator.clone]]
address = "8DKwAVrCEVStDYNPCsmxHtUj8LH9oXNtkVRrBfpNKvhp" address = "8DKwAVrCEVStDYNPCsmxHtUj8LH9oXNtkVRrBfpNKvhp"
[[test.validator.clone]]
address = "8DKwAVrCEVStDYNPCsmxHtUj8LH9oXNtkVRrBfpNKvhp"
[[test.validator.account_dir]]
directory = "accounts-snapshot"

View File

@ -0,0 +1,13 @@
{
"pubkey": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"account": {
"lamports": 182698617139,
"data": [
"AQAAABzjWe1aAS4E+hQrnHUaHF6Hz9CgFhuchf/TG3jN/Nj2pIW9lUPjEQAGAQEAAAAqnl7btTwEZ5CY/3sSZRcUQ0/AjFYqmjuGEQXmctQicw==",
"base64"
],
"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
"executable": false,
"rentEpoch": 361
}
}

View File

@ -67,4 +67,13 @@ describe("validator-clone", () => {
assert.isNotNull(acc, "Account " + accounts[i] + " not found"); assert.isNotNull(acc, "Account " + accounts[i] + " not found");
}); });
}); });
it("Load accounts from account-dir directory", async () => {
// USDC mint
const account = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
const accountInfo = await connection.getAccountInfo(
new anchor.web3.PublicKey(account)
);
assert.isNotNull(accountInfo, "Account " + account + " not found");
});
}); });