Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clarity] Cast aggregated public key vote #4239

Merged
merged 21 commits into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions contrib/core-contract-tests/Clarinet.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,15 @@ path = "../../stackslib/src/chainstate/stacks/boot/pox-4.clar"
depends_on = []
clarity = 2
epoch = 2.4

[contracts.signers]
path = "../../stackslib/src/chainstate/stacks/boot/signers.clar"
depends_on = []
clarity = 2
epoch = 2.4

[contracts.signers-voting]
path = "../../stackslib/src/chainstate/stacks/boot/signers-voting.clar"
depends_on = []
clarity = 2
epoch = 2.4
92 changes: 92 additions & 0 deletions contrib/core-contract-tests/tests/pox-4/signers-voting.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { Cl } from "@stacks/transactions";
import { beforeEach, describe, expect, it } from "vitest";

const accounts = simnet.getAccounts();
const alice = accounts.get("wallet_1")!;
const bob = accounts.get("wallet_2")!;
const charlie = accounts.get("wallet_3")!;

const ERR_SIGNER_INDEX_MISMATCH = 10000;
const ERR_INVALID_SIGNER_INDEX = 10001;
const ERR_OUT_OF_VOTING_WINDOW = 10002
const ERR_OLD_ROUND = 10003;
const ERR_ILL_FORMED_AGGREGATE_PUBLIC_KEY = 10004;
const ERR_DUPLICATE_AGGREGATE_PUBLIC_KEY = 10005;
const ERR_DUPLICATE_VOTE = 10006;
const ERR_INVALID_BURN_BLOCK_HEIGHT = 10007

const KEY_1 = "123456789a123456789a123456789a123456789a123456789a123456789a010203";
const KEY_2 = "123456789a123456789a123456789a123456789a123456789a123456789ab0b1b2";
const SIGNERS_VOTING = "signers-voting";

describe("test signers-voting contract voting rounds", () => {
describe("test pox-info", () => {
it("should return correct burn-height", () => {
const { result:result1 } = simnet.callReadOnlyFn(SIGNERS_VOTING,
"reward-cycle-to-burn-height",
[Cl.uint(1)],
alice)
expect(result1).toEqual(Cl.uint(1050))

const { result:result2 } = simnet.callReadOnlyFn(SIGNERS_VOTING,
"reward-cycle-to-burn-height",
[Cl.uint(2)],
alice)
expect(result2).toEqual(Cl.uint(2100))
})

it("should return correct reward-cycle", () => {
const { result: result1 } = simnet.callReadOnlyFn(SIGNERS_VOTING,
"burn-height-to-reward-cycle",
[Cl.uint(1)],
alice)
expect(result1).toEqual(Cl.uint(0))

const { result: result2000 } = simnet.callReadOnlyFn(SIGNERS_VOTING,
"burn-height-to-reward-cycle",
[Cl.uint(2000)],
alice)
expect(result2000).toEqual(Cl.uint(1))
})

it("should return true if in prepare phase", () => {
const { result:result999 } = simnet.callReadOnlyFn(SIGNERS_VOTING,
"is-in-prepare-phase",
[Cl.uint(999)],
alice)
expect(result999).toEqual(Cl.bool(false))

const { result } = simnet.callReadOnlyFn(SIGNERS_VOTING,
"is-in-prepare-phase",
[Cl.uint(1000)],
alice)
expect(result).toEqual(Cl.bool(true))

const { result: result1001 } = simnet.callReadOnlyFn(SIGNERS_VOTING,
"is-in-prepare-phase",
[Cl.uint(1001)],
alice)
expect(result1001).toEqual(Cl.bool(true))


const { result: result0 } = simnet.callReadOnlyFn(SIGNERS_VOTING,
"is-in-prepare-phase",
[Cl.uint(1049)],
alice)
expect(result0).toEqual(Cl.bool(true))

const { result: result1 } = simnet.callReadOnlyFn(SIGNERS_VOTING,
"is-in-prepare-phase",
[Cl.uint(1050)],
alice)
expect(result1).toEqual(Cl.bool(false))

const { result: result2 } = simnet.callReadOnlyFn(SIGNERS_VOTING,
"is-in-prepare-phase",
[Cl.uint(1051)],
alice)
expect(result2).toEqual(Cl.bool(false))
})
})

});
14 changes: 10 additions & 4 deletions stackslib/src/chainstate/nakamoto/coordinator/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ pub fn boot_nakamoto<'a>(
mut initial_balances: Vec<(PrincipalData, u64)>,
test_signers: &TestSigners,
test_stackers: Option<Vec<&TestStacker>>,
observer: Option<&'a TestEventObserver>,
) -> TestPeer<'a> {
let aggregate_public_key = test_signers.aggregate_public_key.clone();
let mut peer_config = TestPeerConfig::new(test_name, 0, 0);
Expand Down Expand Up @@ -135,7 +136,7 @@ pub fn boot_nakamoto<'a>(
(0..test_signers.num_keys)
.map(|index| {
let stacker_private_key = StacksPrivateKey::from_seed(&index.to_be_bytes());
let signer_private_key = StacksPrivateKey::from_seed(&(index + 1000).to_be_bytes());
let signer_private_key = StacksPrivateKey::from_seed(&index.to_be_bytes());
TestStacker {
stacker_private_key,
signer_private_key,
Expand All @@ -151,7 +152,7 @@ pub fn boot_nakamoto<'a>(
.map(|test_stacker| {
(
PrincipalData::from(key_to_stacks_addr(&test_stacker.stacker_private_key)),
u64::try_from(test_stacker.amount).expect("Stacking amount too large"),
u64::try_from(test_stacker.amount + 10000).expect("Stacking amount too large"),
friedger marked this conversation as resolved.
Show resolved Hide resolved
)
})
.collect();
Expand All @@ -163,7 +164,7 @@ pub fn boot_nakamoto<'a>(
peer_config.burnchain.pox_constants.v3_unlock_height = 27;
peer_config.burnchain.pox_constants.pox_4_activation_height = 31;
peer_config.test_stackers = Some(test_stackers.clone());
let mut peer = TestPeer::new(peer_config);
let mut peer = TestPeer::new_with_observer(peer_config, observer);

advance_to_nakamoto(&mut peer, &test_signers, test_stackers);

Expand Down Expand Up @@ -296,7 +297,7 @@ fn replay_reward_cycle(
#[test]
fn test_simple_nakamoto_coordinator_bootup() {
let mut test_signers = TestSigners::default();
let mut peer = boot_nakamoto(function_name!(), vec![], &test_signers, None);
let mut peer = boot_nakamoto(function_name!(), vec![], &test_signers, None, None);

let (burn_ops, mut tenure_change, miner_key) =
peer.begin_nakamoto_tenure(TenureChangeCause::BlockFound);
Expand Down Expand Up @@ -357,6 +358,7 @@ fn test_simple_nakamoto_coordinator_1_tenure_10_blocks() {
vec![(addr.into(), 100_000_000)],
&test_signers,
None,
None,
);

let (burn_ops, mut tenure_change, miner_key) =
Expand Down Expand Up @@ -479,6 +481,7 @@ fn test_nakamoto_chainstate_getters() {
vec![(addr.into(), 100_000_000)],
&test_signers,
None,
None,
);

let sort_tip = {
Expand Down Expand Up @@ -969,6 +972,7 @@ fn test_simple_nakamoto_coordinator_10_tenures_10_blocks() {
vec![(addr.into(), 100_000_000)],
&test_signers,
None,
None,
);

let mut all_blocks = vec![];
Expand Down Expand Up @@ -1290,6 +1294,7 @@ fn test_simple_nakamoto_coordinator_2_tenures_3_sortitions() {
vec![(addr.into(), 100_000_000)],
&test_signers,
None,
None,
);

let mut rc_burn_ops = vec![];
Expand Down Expand Up @@ -1619,6 +1624,7 @@ fn test_simple_nakamoto_coordinator_10_tenures_and_extensions_10_blocks() {
vec![(addr.into(), 100_000_000)],
&test_signers,
None,
None,
);

let mut all_blocks = vec![];
Expand Down
4 changes: 2 additions & 2 deletions stackslib/src/chainstate/nakamoto/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1502,7 +1502,7 @@ fn make_fork_run_with_arrivals(
#[test]
pub fn test_get_highest_nakamoto_tenure() {
let test_signers = TestSigners::default();
let mut peer = boot_nakamoto(function_name!(), vec![], &test_signers, None);
let mut peer = boot_nakamoto(function_name!(), vec![], &test_signers, None, None);

// extract chainstate and sortdb -- we don't need the peer anymore
let chainstate = &mut peer.stacks_node.as_mut().unwrap().chainstate;
Expand Down Expand Up @@ -1644,7 +1644,7 @@ pub fn test_get_highest_nakamoto_tenure() {
#[test]
fn test_make_miners_stackerdb_config() {
let test_signers = TestSigners::default();
let mut peer = boot_nakamoto(function_name!(), vec![], &test_signers, None);
let mut peer = boot_nakamoto(function_name!(), vec![], &test_signers, None, None);

let naka_miner_hash160 = peer.miner.nakamoto_miner_hash160();
let miner_keys: Vec<_> = (0..10).map(|_| StacksPrivateKey::new()).collect();
Expand Down
31 changes: 31 additions & 0 deletions stackslib/src/chainstate/stacks/boot/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ pub const POX_2_NAME: &'static str = "pox-2";
pub const POX_3_NAME: &'static str = "pox-3";
pub const POX_4_NAME: &'static str = "pox-4";
pub const SIGNERS_NAME: &'static str = "signers";
pub const SIGNERS_VOTING_NAME: &'static str = "signers-voting";
/// This is the name of a variable in the `.signers` contract which tracks the most recently updated
/// reward cycle number.
pub const SIGNERS_UPDATE_STATE: &'static str = "last-set-cycle";
Expand All @@ -89,6 +90,7 @@ const POX_2_BODY: &'static str = std::include_str!("pox-2.clar");
const POX_3_BODY: &'static str = std::include_str!("pox-3.clar");
const POX_4_BODY: &'static str = std::include_str!("pox-4.clar");
pub const SIGNERS_BODY: &'static str = std::include_str!("signers.clar");
const SIGNERS_VOTING_BODY: &'static str = std::include_str!("signers-voting.clar");

pub const COSTS_1_NAME: &'static str = "costs";
pub const COSTS_2_NAME: &'static str = "costs-2";
Expand Down Expand Up @@ -117,6 +119,7 @@ lazy_static! {
pub static ref POX_3_TESTNET_CODE: String =
format!("{}\n{}", BOOT_CODE_POX_TESTNET_CONSTS, POX_3_BODY);
pub static ref POX_4_CODE: String = format!("{}", POX_4_BODY);
pub static ref SIGNER_VOTING_CODE: String = format!("{}", SIGNERS_VOTING_BODY);
pub static ref BOOT_CODE_COST_VOTING_TESTNET: String = make_testnet_cost_voting();
pub static ref STACKS_BOOT_CODE_MAINNET: [(&'static str, &'static str); 6] = [
("pox", &BOOT_CODE_POX_MAINNET),
Expand Down Expand Up @@ -1307,14 +1310,18 @@ pub mod pox_3_tests;
pub mod pox_4_tests;
#[cfg(test)]
mod signers_tests;
#[cfg(test)]
pub mod signers_voting_tests;

#[cfg(test)]
pub mod test {
use std::collections::{HashMap, HashSet};
use std::convert::From;
use std::fs;

use clarity::boot_util::boot_code_addr;
use clarity::vm::contracts::Contract;
use clarity::vm::tests::symbols_from_values;
use clarity::vm::types::*;
use stacks_common::util::hash::to_hex;
use stacks_common::util::*;
Expand Down Expand Up @@ -1874,6 +1881,30 @@ pub mod test {
make_tx(key, nonce, 0, payload)
}

pub fn make_signers_vote_for_aggregate_public_key(
key: &StacksPrivateKey,
nonce: u64,
signer_index: u128,
aggregate_public_key: &Point,
round: u128,
) -> StacksTransaction {
let aggregate_public_key = Value::buff_from(aggregate_public_key.compress().data.to_vec())
.expect("Failed to serialize aggregate public key");
let payload = TransactionPayload::new_contract_call(
boot_code_test_addr(),
SIGNERS_VOTING_NAME,
"vote-for-aggregate-public-key",
vec![
Value::UInt(signer_index),
aggregate_public_key,
Value::UInt(round),
],
)
.unwrap();
// TODO set tx_fee back to 0 once these txs are free
make_tx(key, nonce, 1, payload)
}

pub fn make_pox_2_increase(
key: &StacksPrivateKey,
nonce: u64,
Expand Down
2 changes: 1 addition & 1 deletion stackslib/src/chainstate/stacks/boot/pox_4_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ const ERR_REUSED_SIGNER_KEY: i128 = 33;

/// Return the BlockSnapshot for the latest sortition in the provided
/// SortitionDB option-reference. Panics on any errors.
fn get_tip(sortdb: Option<&SortitionDB>) -> BlockSnapshot {
pub fn get_tip(sortdb: Option<&SortitionDB>) -> BlockSnapshot {
SortitionDB::get_canonical_burn_chain_tip(&sortdb.unwrap().conn()).unwrap()
}

Expand Down
Loading