Skip to content

Commit

Permalink
[contract update] fixes and finish implementation of bond funding and…
Browse files Browse the repository at this point in the history
… withdrawal
  • Loading branch information
ochaloup committed Feb 14, 2024
1 parent a2c20b7 commit 27221b3
Show file tree
Hide file tree
Showing 105 changed files with 6,294 additions and 1,882 deletions.
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

root = true

[*]
Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ pnpm test:cargo
### Contract deployment

```sh
anchor build --verifiable
anchor build --verifiable \
--env "GIT_REV=`git rev-parse --short HEAD`" --env 'GIT_REV_NAME=<SOME_VERSION>'

# 1. DEPLOY
## deploy (devnet, hot wallet upgrade)
Expand Down Expand Up @@ -82,9 +83,12 @@ anchor idl set-authority --provider.cluster mainnet --provider.wallet [fee-payer


# 3.check verifiable deployment (<BUFFER_PUBKEY> can be verified as well)
# a) when the target/verifiable/.so has been built already use switch --skip-build
anchor --provider.cluster mainnet \
verify -p validator_bonds \
vBoNdEvzMrSai7is21XgVYik65mqtaKXuSdMBJ1xkW4
--env "GIT_REV=`git rev-parse --short HEAD`" --env 'GIT_REV_NAME=v1.1.0' \
<PROGRAM_ID_or_BUFFER_ID>

```

## TODO
Expand Down
115 changes: 115 additions & 0 deletions insurance-engine/src/merkle_tree_collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,118 @@ fn get_proof(merkle_tree: &MerkleTree, i: usize) -> Vec<[u8; 32]> {
}
proof
}

#[cfg(test)]
mod tests {
use super::*;
use solana_sdk::bs58;
use solana_sdk::hash::hashv;
use solana_sdk::pubkey::Pubkey;
use std::str::FromStr;

/// This is a constant pubkey test to verify against the TS tree node implementation
/// the TS implementation uses the same static pubkeys and the tests should pass here and there
#[test]
pub fn ts_cross_check_hash_generate() {
let hash_pub = TreeNode {
stake_authority: Pubkey::from_str("EjeWgRiaawLSCUM7uojZgSnwipEiypS986yorgvfAzYW")
.unwrap()
.to_string(),
withdraw_authority: Pubkey::from_str("BT6Y2kX5RLhQ6DDzbjbiHNDyyWJgn9jp7g5rCFn8stqy")
.unwrap()
.to_string(),
vote_account: Pubkey::from_str("DYSosfmS9gp1hTY4jAdKJFWK3XHsemecgVPwjqgwM2Pb")
.unwrap()
.to_string(),
claim: 444,
proof: None,
}
.hash();
let tree_node = hashv(&[&[0], hash_pub.as_ref()]).to_bytes();
assert_eq!(
hash_pub.to_string(),
"3LrYLzt4P6LJCyLsbYPAes4d5U8aohjbmW1dJvbrkdse"
);
assert_eq!(
bs58::encode(tree_node).into_string(),
"37uc7x9LVzJqsPB9un28SJEPbSop8NGHXHQjZCe6GKAX"
);
}

// TS cross-check constant test
#[test]
pub fn ts_cross_check_merkle_proof() {
let mut items: Vec<TreeNode> = vec![
TreeNode {
stake_authority: "612S5jWDKhCxdzugJ6JED5whc1dCkZBPrer3mx3D2V5J".to_string(),
withdraw_authority: "3vGstFWWyQbDknu9WKr9vbTn2Kw5qgorP7UkRXVrfe9t".to_string(),
vote_account: "FHUuZcuLB3ZLWZhKoY7metTEJ2Y2Xton99TTuDmzFmgW".to_string(),
claim: 1234,
proof: None,
},
TreeNode {
stake_authority: "612S5jWDKhCxdzugJ6JED5whc1dCkZBPrer3mx3D2V5J".to_string(),
withdraw_authority: "DBnWKq1Ln9y8HtGwYxFMqMWLY1Ld9xpB28ayKfHejiTs".to_string(),
vote_account: "FHUuZcuLB3ZLWZhKoY7metTEJ2Y2Xton99TTuDmzFmgW".to_string(),
claim: 99999,
proof: None,
},
TreeNode {
stake_authority: "612S5jWDKhCxdzugJ6JED5whc1dCkZBPrer3mx3D2V5J".to_string(),
withdraw_authority: "CgoqXy3e1hsnuNw6bJ8iuzqZwr93CA4jsRa1AnsseJ53".to_string(),
vote_account: "FHUuZcuLB3ZLWZhKoY7metTEJ2Y2Xton99TTuDmzFmgW".to_string(),
claim: 212121,
proof: None,
},
TreeNode {
stake_authority: "612S5jWDKhCxdzugJ6JED5whc1dCkZBPrer3mx3D2V5J".to_string(),
withdraw_authority: "3vGstFWWyQbDknu9WKr9vbTn2Kw5qgorP7UkRXVrfe9t".to_string(),
vote_account: "9D6EuvndvhgDBLRzpxNjHdvLWicJE1WvZrdTbapjhKR6".to_string(),
claim: 69,
proof: None,
},
TreeNode {
stake_authority: "612S5jWDKhCxdzugJ6JED5whc1dCkZBPrer3mx3D2V5J".to_string(),
withdraw_authority: "DBnWKq1Ln9y8HtGwYxFMqMWLY1Ld9xpB28ayKfHejiTs".to_string(),
vote_account: "9D6EuvndvhgDBLRzpxNjHdvLWicJE1WvZrdTbapjhKR6".to_string(),
claim: 111111,
proof: None,
},
];
let item_hashes = items.clone().iter().map(|n| n.hash()).collect::<Vec<_>>();
let merkle_tree = MerkleTree::new(&item_hashes[..], true);
let merkle_tree_root = merkle_tree.get_root().unwrap();
// println!("merkle tree root: {}", merkle_tree_root);
for (i, tree_node) in items.iter_mut().enumerate() {
tree_node.proof = Some(get_proof(&merkle_tree, i));
// println!(
// "proof: {:?}, hash tree node: {}",
// tree_node.proof,
// tree_node.hash()
// )
}
assert_eq!(
merkle_tree_root.to_string(),
"CJWSpJD2yeL1JPUH9pyfAefFetdiSuvPNCqq5LfQ71je"
);
let check_proof = [
[
217, 141, 69, 36, 65, 205, 32, 76, 165, 35, 197, 94, 188, 141, 93, 158, 129, 239,
253, 174, 42, 156, 151, 29, 197, 253, 160, 116, 10, 112, 12, 10,
],
[
190, 99, 233, 8, 249, 68, 135, 70, 128, 15, 2, 169, 47, 194, 102, 12, 200, 64, 213,
103, 134, 64, 112, 215, 201, 36, 212, 236, 32, 93, 76, 106,
],
[
147, 52, 104, 182, 174, 190, 248, 228, 27, 240, 240, 245, 6, 218, 13, 196, 53, 63,
242, 117, 208, 239, 15, 106, 255, 30, 248, 47, 107, 170, 233, 94,
],
];
assert_eq!(items.get(3).unwrap().proof, Some(check_proof.to_vec()));
assert_eq!(
item_hashes.get(3).unwrap().to_string(),
"C94ftStYh3afdysMEnf4KGMvyQZVcMY6P16UkEJGkYbU"
);
}
}
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"_test": "pnpm jest --config jest.config.test-validator.js -- \"$FILE\"",
"test:validator": "anchor test",
"test:bankrun": "pnpm anchor:build && pnpm jest --config jest.config.bankrun.js --runInBand true -- \"$FILE\"",
"test:cargo": "cargo test --features no-entrypoint",
"test:cargo": "cargo test --features no-entrypoint -- --nocapture",
"test": "pnpm test:cargo && pnpm test:bankrun && pnpm test:validator",
"cli": "ts-node ./packages/validator-bonds-cli/src/",
"lint:cargo": "cargo fmt -- --check && cargo clippy",
Expand All @@ -27,12 +27,12 @@
"@types/bn.js": "^5.1.3",
"@types/jest": "^29.5.6",
"@types/node": "^18.11.9",
"gts": "^4.0.1",
"gts": "^5.2.0",
"jest": "^29.7.0",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"ts-jest": "^29.1.2",
"ts-node": "^10.9.2",
"typescript": "4.9.5",
"@marinade.finance/jest-utils": "^2.2.1"
"@marinade.finance/jest-utils": "^2.2.2"
},
"pnpm": {
"peerDependencyRules": {
Expand Down
2 changes: 0 additions & 2 deletions packages/validator-bonds-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,7 @@ validator-bonds -um show-bond ...
config: 'vbMaRfmTCg92HWGzmd53APkMNpPnGVGZTUHwUJQkXAU',
validatorVoteAccount: '...',
authority: '...',
revenueShare: { hundredthBps: 0 },
bump: 255,
reserved: { reserved: [Array] }
}
}
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ describe('Configure bond account using CLI', () => {
provider,
validatorIdentity
))
;({ bondAccount } = await executeInitBondInstruction(
;({ bondAccount } = await executeInitBondInstruction({
program,
provider,
configAccount,
bondAuthorityKeypair,
config: configAccount,
bondAuthority: bondAuthorityKeypair,
voteAccount,
validatorIdentity,
33
))
cpmpe: 33,
}))
})

afterEach(async () => {
Expand All @@ -85,8 +85,6 @@ describe('Configure bond account using CLI', () => {
bondAccount.toBase58(),
'--authority',
bondAuthorityPath,
'--revenue-share',
'42',
'--confirmation-finality',
'confirmed',
],
Expand All @@ -101,9 +99,9 @@ describe('Configure bond account using CLI', () => {
const [, bump] = bondAddress(configAccount, voteAccount, program.programId)
const bondsData1 = await getBond(program, bondAccount)
expect(bondsData1.config).toEqual(configAccount)
expect(bondsData1.validatorVoteAccount).toEqual(voteAccount)
expect(bondsData1.voteAccount).toEqual(voteAccount)
expect(bondsData1.authority).toEqual(bondAuthorityKeypair.publicKey)
expect(bondsData1.revenueShare.hundredthBps).toEqual(42 * 10 ** 4)
expect(bondsData1.cpmpe).toEqual(33)
expect(bondsData1.bump).toEqual(bump)

const newBondAuthority = PublicKey.unique()
Expand All @@ -125,8 +123,6 @@ describe('Configure bond account using CLI', () => {
validatorIdentityPath,
'--bond-authority',
newBondAuthority.toBase58(),
'--revenue-share',
43,
'--confirmation-finality',
'confirmed',
],
Expand All @@ -140,7 +136,7 @@ describe('Configure bond account using CLI', () => {

const bondsData2 = await getBond(program, bondAccount)
expect(bondsData2.authority).toEqual(newBondAuthority)
expect(bondsData2.revenueShare.hundredthBps).toEqual(43 * 10 ** 4)
expect(bondsData2.cpmpe).toEqual(33)
})

it('configure bond in print-only mode', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,16 @@ describe('Fund bond account using CLI', () => {
provider.connection.getAccountInfo(configAccount)
).resolves.not.toBeNull()
const { voteAccount: voteAccountAddress, validatorIdentity } =
await createVoteAccount(provider)
await createVoteAccount({ provider })
voteAccount = voteAccountAddress
;({ bondAccount } = await executeInitBondInstruction(
;({ bondAccount } = await executeInitBondInstruction({
program,
provider,
configAccount,
undefined,
config: configAccount,
voteAccount,
validatorIdentity,
123
))
cpmpe: 123,
}))
})

afterEach(async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,6 @@ describe('Init bond account using CLI', () => {
validatorIdentityPath,
'--bond-authority',
bondAuthority.publicKey.toBase58(),
'--revenue-share',
'10',
'--rent-payer',
rentPayerPath,
'--confirmation-finality',
Expand All @@ -120,9 +118,9 @@ describe('Init bond account using CLI', () => {
)
const bondsData = await getBond(program, bondAccount)
expect(bondsData.config).toEqual(configAccount)
expect(bondsData.validatorVoteAccount).toEqual(voteAccount)
expect(bondsData.voteAccount).toEqual(voteAccount)
expect(bondsData.authority).toEqual(bondAuthority.publicKey)
expect(bondsData.revenueShare.hundredthBps).toEqual(10 * 10 ** 4)
expect(bondsData.cpmpe).toEqual(0)
expect(bondsData.bump).toEqual(bump)
await expect(
provider.connection.getBalance(rentPayerKeypair.publicKey)
Expand All @@ -144,8 +142,6 @@ describe('Init bond account using CLI', () => {
configAccount.toBase58(),
'--vote-account',
voteAccount.toBase58(),
'--revenue-share',
'1000',
'--confirmation-finality',
'confirmed',
],
Expand All @@ -164,9 +160,9 @@ describe('Init bond account using CLI', () => {
)
const bondsData = await getBond(program, bondAccount)
expect(bondsData.config).toEqual(configAccount)
expect(bondsData.validatorVoteAccount).toEqual(voteAccount)
expect(bondsData.voteAccount).toEqual(voteAccount)
expect(bondsData.authority).toEqual(validatorIdentity.publicKey)
expect(bondsData.revenueShare.hundredthBps).toEqual(0)
expect(bondsData.cpmpe).toEqual(0)
expect(bondsData.bump).toEqual(bump)
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,10 @@ describe('Merge stake accounts using CLI', () => {
stdout: /successfully merged/,
})

const stakeAccount1Info = await provider.connection.getAccountInfo(
stakeAccount1
)
const stakeAccount2Info = await provider.connection.getAccountInfo(
stakeAccount2
)
const stakeAccount1Info =
await provider.connection.getAccountInfo(stakeAccount1)
const stakeAccount2Info =
await provider.connection.getAccountInfo(stakeAccount2)
expect(stakeAccount1Info).toBeNull()
expect(stakeAccount2Info).not.toBeNull()
expect(stakeAccount2Info?.lamports).toEqual(LAMPORTS_PER_SOL * 5)
Expand Down Expand Up @@ -177,12 +175,10 @@ async function createMergeStakeAccounts({
staker: bondWithdrawer,
withdrawer: bondWithdrawer,
})
const stakeAccount1Info = await provider.connection.getAccountInfo(
stakeAccount1
)
const stakeAccount2Info = await provider.connection.getAccountInfo(
stakeAccount2
)
const stakeAccount1Info =
await provider.connection.getAccountInfo(stakeAccount1)
const stakeAccount2Info =
await provider.connection.getAccountInfo(stakeAccount2)
expect(stakeAccount1Info).not.toBeNull()
expect(stakeAccount2Info).not.toBeNull()
expect(stakeAccount1Info?.lamports).toEqual(lamports1)
Expand Down
Loading

0 comments on commit 27221b3

Please sign in to comment.