cli: Deploy with upgradeable loader

This commit is contained in:
Armani Ferrante 2021-01-28 01:17:33 -08:00
parent 80e1fd54ca
commit 345d25a583
No known key found for this signature in database
GPG Key ID: D597A80BCF8E12B7
4 changed files with 49 additions and 39 deletions

View File

@ -50,6 +50,9 @@ pub enum Command {
#[clap(short, long)] #[clap(short, long)]
keypair: Option<String>, keypair: Option<String>,
}, },
/// Not yet implemented. Please use `solana program deploy` command to
/// upgrade your program.
Upgrade {},
} }
fn main() -> Result<()> { fn main() -> Result<()> {
@ -67,6 +70,10 @@ fn main() -> Result<()> {
idl(file, Some(&PathBuf::from(out.unwrap()))) idl(file, Some(&PathBuf::from(out.unwrap())))
} }
Command::Deploy { url, keypair } => deploy(url, keypair), Command::Deploy { url, keypair } => deploy(url, keypair),
Command::Upgrade {} => {
println!("This command is not yet implemented. Please use `solana program deploy`.");
Ok(())
}
} }
} }
@ -296,7 +303,7 @@ fn test() -> Result<()> {
// Run the tests. // Run the tests.
if let Err(e) = std::process::Command::new("mocha") if let Err(e) = std::process::Command::new("mocha")
.arg("-t") .arg("-t")
.arg("10000") .arg("1000000")
.arg("tests/") .arg("tests/")
.env("ANCHOR_PROVIDER_URL", cfg.cluster.url()) .env("ANCHOR_PROVIDER_URL", cfg.cluster.url())
.stdout(Stdio::inherit()) .stdout(Stdio::inherit())
@ -424,16 +431,24 @@ fn run_hosted_deploy(url: &str) -> Result<()> {
fn deploy_ws(url: &str, keypair: &str) -> Result<Vec<(Program, Pubkey)>> { fn deploy_ws(url: &str, keypair: &str) -> Result<Vec<(Program, Pubkey)>> {
let mut programs = vec![]; let mut programs = vec![];
println!("Deploying workspace to {}...", url); println!("Deploying workspace to {}...", url);
println!("Upgrade authority: {}", keypair);
for program in read_all_programs()? { for program in read_all_programs()? {
let binary_path = format!("target/deploy/{}.so", program.lib_name); let binary_path = format!("target/deploy/{}.so", program.lib_name);
// The Solana CLI doesn't redeploy a program if this file exists.
// So remove it to make deploys explicit.
let keypair_path = format!("target/deploy/{}-keypair.json", program.lib_name);
std::fs::remove_file(keypair_path)?;
println!("Deploying {}...", binary_path); println!("Deploying {}...", binary_path);
let exit = std::process::Command::new("solana") let exit = std::process::Command::new("solana")
.arg("program")
.arg("deploy") .arg("deploy")
.arg(&binary_path)
.arg("--url") .arg("--url")
.arg(url) .arg(url)
.arg("--keypair") .arg("--keypair")
.arg(keypair) .arg(keypair)
.arg(&binary_path)
.output() .output()
.expect("Must deploy"); .expect("Must deploy");
if !exit.status.success() { if !exit.status.success() {

View File

@ -90,15 +90,15 @@ async function genesis(provider) {
) { ) {
return { return {
srm: { srm: {
withdrawalTimelock: 60, withdrawalTimelock: 60 * 60 * 24 * 7, // 1 week.
stakeRate: 1000 * 10 ** 6, stakeRate: 500 * 10 ** 6, // 500 SRM.
rewardQLen: 100, rewardQLen: 150,
mint: "SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt", mint: "SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt",
}, },
msrm: { msrm: {
withdrawalTimelock: 45, withdrawalTimelock: 60 * 60 * 24 * 7, // 1 week.
stakeRate: 1, stakeRate: 1,
rewardQLen: 100, rewardQLen: 150,
mint: "MSRMcoVyrFxnSgo5uXwone5SKcGhT1KEJMFEkMEWf9L", mint: "MSRMcoVyrFxnSgo5uXwone5SKcGhT1KEJMFEkMEWf9L",
}, },
}; };
@ -117,15 +117,15 @@ async function genesis(provider) {
); );
return { return {
token1: { token1: {
withdrawalTimelock: 60, withdrawalTimelock: 60 * 60 * 24 * 7,
stakeRate: 2 * 10 ** 6, stakeRate: 1000 * 10 ** 6,
rewardQLen: 100, rewardQLen: 150,
mint: token1Mint.toString(), mint: token1Mint.toString(),
}, },
token2: { token2: {
withdrawalTimelock: 45, withdrawalTimelock: 60 * 60 * 24 * 7,
stakeRate: 1, stakeRate: 1,
rewardQLen: 100, rewardQLen: 150,
mint: token2Mint.toString(), mint: token2Mint.toString(),
}, },
}; };

View File

@ -23,7 +23,7 @@ pub mod lockup {
} }
impl Lockup { impl Lockup {
pub const WHITELIST_SIZE: usize = 5; pub const WHITELIST_SIZE: usize = 10;
pub fn new(ctx: Context<Auth>) -> Result<Self> { pub fn new(ctx: Context<Auth>) -> Result<Self> {
let mut whitelist = vec![]; let mut whitelist = vec![];
@ -111,7 +111,7 @@ pub mod lockup {
ctx.accounts.clock.unix_timestamp, ctx.accounts.clock.unix_timestamp,
) )
{ {
return Err(ErrorCode::InsufficienWithdrawalBalance.into()); return Err(ErrorCode::InsufficientWithdrawalBalance.into());
} }
// Transfer funds out. // Transfer funds out.
@ -348,7 +348,7 @@ pub enum ErrorCode {
#[msg("Vault amount must be zero.")] #[msg("Vault amount must be zero.")]
InvalidVaultAmount, InvalidVaultAmount,
#[msg("Insufficient withdrawal balance.")] #[msg("Insufficient withdrawal balance.")]
InsufficienWithdrawalBalance, InsufficientWithdrawalBalance,
#[msg("Whitelist is full")] #[msg("Whitelist is full")]
WhitelistFull, WhitelistFull,
#[msg("Whitelist entry already exists")] #[msg("Whitelist entry already exists")]

View File

@ -1,5 +1,5 @@
const assert = require("assert"); const assert = require("assert");
const anchor = require('@project-serum/anchor'); const anchor = require("@project-serum/anchor");
const serumCmn = require("@project-serum/common"); const serumCmn = require("@project-serum/common");
const TokenInstructions = require("@project-serum/serum").TokenInstructions; const TokenInstructions = require("@project-serum/serum").TokenInstructions;
const utils = require("./utils"); const utils = require("./utils");
@ -15,6 +15,7 @@ describe("Lockup and Registry", () => {
const registry = anchor.workspace.Registry; const registry = anchor.workspace.Registry;
let lockupAddress = null; let lockupAddress = null;
const WHITELIST_SIZE = 10;
let mint = null; let mint = null;
let god = null; let god = null;
@ -39,7 +40,7 @@ describe("Lockup and Registry", () => {
const lockupAccount = await lockup.state(); const lockupAccount = await lockup.state();
assert.ok(lockupAccount.authority.equals(provider.wallet.publicKey)); assert.ok(lockupAccount.authority.equals(provider.wallet.publicKey));
assert.ok(lockupAccount.whitelist.length === 5); assert.ok(lockupAccount.whitelist.length === WHITELIST_SIZE);
lockupAccount.whitelist.forEach((e) => { lockupAccount.whitelist.forEach((e) => {
assert.ok(e.programId.equals(new anchor.web3.PublicKey())); assert.ok(e.programId.equals(new anchor.web3.PublicKey()));
}); });
@ -76,11 +77,7 @@ describe("Lockup and Registry", () => {
assert.ok(lockupAccount.authority.equals(provider.wallet.publicKey)); assert.ok(lockupAccount.authority.equals(provider.wallet.publicKey));
}); });
let e0 = null; const entries = [];
let e1 = null;
let e2 = null;
let e3 = null;
let e4 = null;
it("Adds to the whitelist", async () => { it("Adds to the whitelist", async () => {
const generateEntry = async () => { const generateEntry = async () => {
@ -89,36 +86,34 @@ describe("Lockup and Registry", () => {
programId, programId,
}; };
}; };
e0 = await generateEntry();
e1 = await generateEntry(); for (let k = 0; k < WHITELIST_SIZE; k += 1) {
e2 = await generateEntry(); entries.push(await generateEntry());
e3 = await generateEntry(); }
e4 = await generateEntry();
const e5 = await generateEntry();
const accounts = { const accounts = {
authority: provider.wallet.publicKey, authority: provider.wallet.publicKey,
}; };
await lockup.state.rpc.whitelistAdd(e0, { accounts }); await lockup.state.rpc.whitelistAdd(entries[0], { accounts });
let lockupAccount = await lockup.state(); let lockupAccount = await lockup.state();
assert.ok(lockupAccount.whitelist.length === 1); assert.ok(lockupAccount.whitelist.length === 1);
assert.deepEqual(lockupAccount.whitelist, [e0]); assert.deepEqual(lockupAccount.whitelist, [entries[0]]);
await lockup.state.rpc.whitelistAdd(e1, { accounts }); for (let k = 1; k < WHITELIST_SIZE; k += 1) {
await lockup.state.rpc.whitelistAdd(e2, { accounts }); await lockup.state.rpc.whitelistAdd(entries[k], { accounts });
await lockup.state.rpc.whitelistAdd(e3, { accounts }); }
await lockup.state.rpc.whitelistAdd(e4, { accounts });
lockupAccount = await lockup.state(); lockupAccount = await lockup.state();
assert.deepEqual(lockupAccount.whitelist, [e0, e1, e2, e3, e4]); assert.deepEqual(lockupAccount.whitelist, entries);
await assert.rejects( await assert.rejects(
async () => { async () => {
await lockup.state.rpc.whitelistAdd(e5, { accounts }); const e = await generateEntry();
await lockup.state.rpc.whitelistAdd(e, { accounts });
}, },
(err) => { (err) => {
assert.equal(err.code, 108); assert.equal(err.code, 108);
@ -129,13 +124,13 @@ describe("Lockup and Registry", () => {
}); });
it("Removes from the whitelist", async () => { it("Removes from the whitelist", async () => {
await lockup.state.rpc.whitelistDelete(e0, { await lockup.state.rpc.whitelistDelete(entries[0], {
accounts: { accounts: {
authority: provider.wallet.publicKey, authority: provider.wallet.publicKey,
}, },
}); });
let lockupAccount = await lockup.state(); let lockupAccount = await lockup.state();
assert.deepEqual(lockupAccount.whitelist, [e1, e2, e3, e4]); assert.deepEqual(lockupAccount.whitelist, entries.slice(1));
}); });
const vesting = new anchor.web3.Account(); const vesting = new anchor.web3.Account();
@ -264,7 +259,7 @@ describe("Lockup and Registry", () => {
const rewardQ = new anchor.web3.Account(); const rewardQ = new anchor.web3.Account();
const withdrawalTimelock = new anchor.BN(4); const withdrawalTimelock = new anchor.BN(4);
const stakeRate = new anchor.BN(2); const stakeRate = new anchor.BN(2);
const rewardQLen = 100; const rewardQLen = 170;
let registrarAccount = null; let registrarAccount = null;
let registrarSigner = null; let registrarSigner = null;
let nonce = null; let nonce = null;