Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE
- New `/new_pox_anchor` endpoint for broadcasting PoX anchor block processing.
- Stacker bitvec in NakamotoBlock
- New [`pox-4` contract](./stackslib/src/chainstate/stacks/boot/pox-4.clar) that reflects changes in how Stackers are signers in Nakamoto:
- `stack-stx`, `stack-extend`, and `stack-aggregation-commit` now include a `signer-key` parameter, which represents the public key used by the Signer. This key is used for determining the signer set in Nakamoto.
- `stack-stx`, `stack-extend`, `stack-increase` and `stack-aggregation-commit` now include a `signer-key` parameter, which represents the public key used by the Signer. This key is used for determining the signer set in Nakamoto.
- Functions that include a `signer-key` parameter also include a `signer-sig` parameter to demonstrate that the owner of `signer-key` is approving that particular Stacking operation. For more details, refer to the `verify-signer-key-sig` method in the `pox-4` contract.
- Signer key authorizations can be added via `set-signer-key-authorization` to omit the need for `signer-key` signatures
- A `max-amount` field is a field in signer key authorizations and defines the maximum amount of STX that can be locked in a single transaction.

### Modified

Expand Down
6 changes: 6 additions & 0 deletions stacks-signer/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,12 @@ pub struct GenerateStackingSignatureArgs {
/// Use `1` for stack-aggregation-commit
#[arg(long)]
pub period: u64,
/// The max amount of uSTX that can be used in this unique transaction
#[arg(long)]
pub max_amount: u128,
/// A unique identifier to prevent re-using this authorization
#[arg(long)]
pub auth_id: u128,
}

/// Parse the contract ID
Expand Down
24 changes: 23 additions & 1 deletion stacks-signer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,8 @@ fn handle_generate_stacking_signature(
args.method.topic(),
config.network.to_chain_id(),
args.period.into(),
args.max_amount,
args.auth_id,
)
.expect("Failed to generate signature");

Expand Down Expand Up @@ -403,11 +405,14 @@ pub mod tests {
lock_period: u128,
public_key: &Secp256k1PublicKey,
signature: Vec<u8>,
amount: u128,
max_amount: u128,
auth_id: u128,
) -> bool {
let program = format!(
r#"
{}
(verify-signer-key-sig {} u{} "{}" u{} (some 0x{}) 0x{})
(verify-signer-key-sig {} u{} "{}" u{} (some 0x{}) 0x{} u{} u{} u{})
"#,
&*POX_4_CODE, //s
Value::Tuple(pox_addr.clone().as_clarity_tuple().unwrap()), //p
Expand All @@ -416,6 +421,9 @@ pub mod tests {
lock_period,
to_hex(signature.as_slice()),
to_hex(public_key.to_bytes_compressed().as_slice()),
amount,
max_amount,
auth_id,
);
execute_v2(&program)
.expect("FATAL: could not execute program")
Expand All @@ -436,6 +444,8 @@ pub mod tests {
reward_cycle: 6,
method: Pox4SignatureTopic::StackStx.into(),
period: 12,
max_amount: u128::MAX,
auth_id: 1,
};

let signature = handle_generate_stacking_signature(args.clone(), false);
Expand All @@ -448,13 +458,18 @@ pub mod tests {
args.period.into(),
&public_key,
signature.to_rsv(),
100,
args.max_amount,
args.auth_id,
);
assert!(valid);

// change up some args
args.period = 6;
args.method = Pox4SignatureTopic::AggregationCommit.into();
args.reward_cycle = 7;
args.auth_id = 2;
args.max_amount = 100;

let signature = handle_generate_stacking_signature(args.clone(), false);
let public_key = Secp256k1PublicKey::from_private(&config.stacks_private_key);
Expand All @@ -466,6 +481,9 @@ pub mod tests {
args.period.into(),
&public_key,
signature.to_rsv(),
100,
args.max_amount,
args.auth_id,
);
assert!(valid);
}
Expand All @@ -480,6 +498,8 @@ pub mod tests {
reward_cycle: 6,
method: Pox4SignatureTopic::StackStx.into(),
period: 12,
max_amount: u128::MAX,
auth_id: 1,
};

let signature = handle_generate_stacking_signature(args.clone(), false);
Expand All @@ -492,6 +512,8 @@ pub mod tests {
&Pox4SignatureTopic::StackStx,
CHAIN_ID_TESTNET,
args.period.into(),
args.max_amount,
args.auth_id,
);

let verify_result = public_key.verify(&message_hash.0, &signature);
Expand Down
4 changes: 4 additions & 0 deletions stackslib/src/chainstate/nakamoto/coordinator/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ fn advance_to_nakamoto(
6,
&Pox4SignatureTopic::StackStx,
12_u128,
u128::MAX,
1,
);
let signing_key =
StacksPublicKey::from_private(&test_stacker.signer_private_key);
Expand All @@ -109,6 +111,8 @@ fn advance_to_nakamoto(
&signing_key,
34,
Some(signature),
u128::MAX,
1,
)
})
.collect()
Expand Down
35 changes: 34 additions & 1 deletion stackslib/src/chainstate/stacks/boot/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1845,6 +1845,8 @@ pub mod test {
signer_key: &StacksPublicKey,
burn_ht: u64,
signature_opt: Option<Vec<u8>>,
max_amount: u128,
auth_id: u128,
) -> StacksTransaction {
let addr_tuple = Value::Tuple(addr.as_clarity_tuple().unwrap());
let signature = match signature_opt {
Expand All @@ -1862,6 +1864,8 @@ pub mod test {
Value::UInt(lock_period),
signature,
Value::buff_from(signer_key.to_bytes_compressed()).unwrap(),
Value::UInt(max_amount),
Value::UInt(auth_id),
],
)
.unwrap();
Expand Down Expand Up @@ -2005,6 +2009,8 @@ pub mod test {
lock_period: u128,
signer_key: StacksPublicKey,
signature_opt: Option<Vec<u8>>,
max_amount: u128,
auth_id: u128,
) -> StacksTransaction {
let addr_tuple = Value::Tuple(addr.as_clarity_tuple().unwrap());
let signature = match signature_opt {
Expand All @@ -2020,6 +2026,8 @@ pub mod test {
addr_tuple,
signature,
Value::buff_from(signer_key.to_bytes_compressed()).unwrap(),
Value::UInt(max_amount),
Value::UInt(auth_id),
],
)
.unwrap();
Expand Down Expand Up @@ -2114,6 +2122,8 @@ pub mod test {
reward_cycle: u128,
signature_opt: Option<Vec<u8>>,
signer_key: &Secp256k1PublicKey,
max_amount: u128,
auth_id: u128,
) -> StacksTransaction {
let addr_tuple = Value::Tuple(pox_addr.as_clarity_tuple().unwrap());
let signature = match signature_opt {
Expand All @@ -2129,6 +2139,8 @@ pub mod test {
Value::UInt(reward_cycle),
signature,
Value::buff_from(signer_key.to_bytes_compressed()).unwrap(),
Value::UInt(max_amount),
Value::UInt(auth_id),
],
)
.unwrap();
Expand All @@ -2140,12 +2152,25 @@ pub mod test {
key: &StacksPrivateKey,
nonce: u64,
amount: u128,
signer_key: &Secp256k1PublicKey,
signature_opt: Option<Vec<u8>>,
max_amount: u128,
auth_id: u128,
) -> StacksTransaction {
let signature = signature_opt
.map(|sig| Value::some(Value::buff_from(sig).unwrap()).unwrap())
.unwrap_or_else(|| Value::none());
let payload = TransactionPayload::new_contract_call(
boot_code_test_addr(),
POX_4_NAME,
"stack-increase",
vec![Value::UInt(amount)],
vec![
Value::UInt(amount),
signature,
Value::buff_from(signer_key.to_bytes_compressed()).unwrap(),
Value::UInt(max_amount),
Value::UInt(auth_id),
],
)
.unwrap();

Expand Down Expand Up @@ -2192,6 +2217,8 @@ pub mod test {
reward_cycle: u128,
topic: &Pox4SignatureTopic,
period: u128,
max_amount: u128,
auth_id: u128,
) -> Vec<u8> {
let signature = make_pox_4_signer_key_signature(
pox_addr,
Expand All @@ -2200,6 +2227,8 @@ pub mod test {
topic,
CHAIN_ID_TESTNET,
period,
max_amount,
auth_id,
)
.unwrap();

Expand All @@ -2215,6 +2244,8 @@ pub mod test {
enabled: bool,
nonce: u64,
sender_key: Option<&StacksPrivateKey>,
max_amount: u128,
auth_id: u128,
) -> StacksTransaction {
let signer_pubkey = StacksPublicKey::from_private(signer_key);
let payload = TransactionPayload::new_contract_call(
Expand All @@ -2228,6 +2259,8 @@ pub mod test {
Value::string_ascii_from_bytes(topic.get_name_str().into()).unwrap(),
Value::buff_from(signer_pubkey.to_bytes_compressed()).unwrap(),
Value::Bool(enabled),
Value::UInt(max_amount),
Value::UInt(auth_id),
],
)
.unwrap();
Expand Down
Loading