feat: Add account-dir test-validator argument support (#2436)
This commit is contained in:
parent
00c2fc3601
commit
9a075087d0
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"pubkey": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
||||||
|
"account": {
|
||||||
|
"lamports": 182698617139,
|
||||||
|
"data": [
|
||||||
|
"AQAAABzjWe1aAS4E+hQrnHUaHF6Hz9CgFhuchf/TG3jN/Nj2pIW9lUPjEQAGAQEAAAAqnl7btTwEZ5CY/3sSZRcUQ0/AjFYqmjuGEQXmctQicw==",
|
||||||
|
"base64"
|
||||||
|
],
|
||||||
|
"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
|
||||||
|
"executable": false,
|
||||||
|
"rentEpoch": 361
|
||||||
|
}
|
||||||
|
}
|
|
@ -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");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue