Skip to content

Commit

Permalink
Merge branch 'develop' into fix/remove-idea
Browse files Browse the repository at this point in the history
  • Loading branch information
gregorycoppola committed Jan 24, 2023
2 parents 5c9c72a + 1cc9ec6 commit 448b6df
Show file tree
Hide file tree
Showing 6 changed files with 440 additions and 14 deletions.
1 change: 1 addition & 0 deletions .github/workflows/bitcoin-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ jobs:
- tests::neon_integrations::bitcoind_integration_test
- tests::neon_integrations::liquid_ustx_integration
- tests::neon_integrations::stx_transfer_btc_integration_test
- tests::neon_integrations::stx_delegate_btc_integration_test
- tests::neon_integrations::bitcoind_forking_test
- tests::neon_integrations::should_fix_2771
- tests::neon_integrations::pox_integration_test
Expand Down
32 changes: 32 additions & 0 deletions src/chainstate/stacks/boot/pox_2_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1339,6 +1339,7 @@ fn delegate_stack_increase() {
let tip = get_tip(peer.sortdb.as_ref());

// submit delegation tx
let success_alice_delegation = alice_nonce;
let alice_delegation_1 = make_pox_2_contract_call(
&alice,
alice_nonce,
Expand Down Expand Up @@ -1554,6 +1555,37 @@ fn delegate_stack_increase() {
"(err 18)"
);

let delegate_stx_tx = &alice_txs
.get(&success_alice_delegation)
.unwrap()
.clone()
.events[0];
let delegate_stx_op_data = HashMap::from([
("pox-addr", Value::none()),
("amount-ustx", Value::UInt(10230000000000)),
("unlock-burn-height", Value::none()),
(
"delegate-to",
Value::Principal(
StacksAddress::from_string("ST1GCB6NH3XR67VT4R5PKVJ2PYXNVQ4AYQATXNP4P")
.unwrap()
.to_account_principal(),
),
),
]);
let common_data = PoxPrintFields {
op_name: "delegate-stx".to_string(),
stacker: Value::Principal(
StacksAddress::from_string("ST2Q1B4S2DY2Y96KYNZTVCCZZD1V9AGWCS5MFXM4C")
.unwrap()
.to_account_principal(),
),
balance: Value::UInt(10240000000000),
locked: Value::UInt(0),
burnchain_unlock_height: Value::UInt(0),
};
check_pox_print_event(delegate_stx_tx, common_data, delegate_stx_op_data);

// Check that the call to `delegate-stack-increase` has a well-formed print event.
let delegate_stack_increase_tx = &bob_txs.get(&4).unwrap().clone().events[0];
let pox_addr_val = generate_pox_clarity_value("60c59ab11f7063ef44c16d3dc856f76bbb915eba");
Expand Down
11 changes: 7 additions & 4 deletions src/chainstate/stacks/db/blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5867,9 +5867,9 @@ impl StacksChainState {
/// in the block, and a `PreCommitClarityBlock` struct.
///
/// The `StacksEpochReceipts` contains the list of transaction
/// receipts for both the preceeding microblock stream that the
/// block confirms, as well as the transaction receipts for the
/// anchored block's transactions. Finally, it returns the
/// receipts for the preceeding microblock stream that the
/// block confirms, the anchored block's transactions, and the
/// btc wire transactions. Finally, it returns the
/// execution costs for the microblock stream and for the anchored
/// block (separately).
///
Expand Down Expand Up @@ -12132,7 +12132,10 @@ pub mod test {
.collect();
init_balances.push((addr.to_account_principal(), initial_balance));
peer_config.initial_balances = init_balances;
peer_config.epochs = Some(StacksEpoch::unit_test_2_1(0));
let mut epochs = StacksEpoch::unit_test_2_1(0);
let num_epochs = epochs.len();
epochs[num_epochs - 1].block_limit.runtime = 10_000_000;
peer_config.epochs = Some(epochs);
peer_config.burnchain.pox_constants.v1_unlock_height = 26;

let mut peer = TestPeer::new(peer_config);
Expand Down
40 changes: 35 additions & 5 deletions src/clarity_vm/special.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,16 +253,19 @@ fn handle_pox_v1_api_contract_call(
}

/// Determine who the stacker is for a given function.
/// - for non-delegate functions, it's tx-sender
/// - for delegate functions, it's the first argument
/// - for non-delegate stacking functions, it's tx-sender
/// - for delegate stacking functions, it's the first argument
fn get_stacker(sender: &PrincipalData, function_name: &str, args: &[Value]) -> Value {
match function_name {
"stack-stx" | "stack-increase" | "stack-extend" => Value::Principal(sender.clone()),
"stack-stx" | "stack-increase" | "stack-extend" | "delegate-stx" => {
Value::Principal(sender.clone())
}
_ => args[0].clone(),
}
}

/// Craft the code snippet to evaluate an event-info for a stack-* or a delegate-stack-* function
/// Craft the code snippet to evaluate an event-info for a stack-* function,
/// a delegate-stack-* function, or for delegate-stx
fn create_event_info_stack_or_delegate_code(
sender: &PrincipalData,
function_name: &str,
Expand Down Expand Up @@ -532,6 +535,32 @@ fn create_event_info_data_code(function_name: &str, args: &[Value]) -> String {
reward_cycle = &args[1]
)
}
"delegate-stx" => {
format!(
r#"
{{
data: {{
;; amount of ustx to delegate.
;; equal to args[0]
amount-ustx: {amount_ustx},
;; address of delegatee.
;; equal to args[1]
delegate-to: '{delegate_to},
;; optional burnchain height when the delegation finishes.
;; derived from args[2]
unlock-burn-height: {until_burn_height},
;; optional PoX address tuple.
;; equal to args[3].
pox-addr: {pox_addr}
}}
}}
"#,
amount_ustx = &args[0],
delegate_to = &args[1],
until_burn_height = &args[2],
pox_addr = &args[3],
)
}
_ => format!("{{ data: {{ unimplemented: true }} }}"),
}
}
Expand All @@ -558,7 +587,8 @@ fn synthesize_pox_2_event_info(
| "stack-extend"
| "delegate-stack-extend"
| "stack-increase"
| "delegate-stack-increase" => Some(create_event_info_stack_or_delegate_code(
| "delegate-stack-increase"
| "delegate-stx" => Some(create_event_info_stack_or_delegate_code(
sender,
function_name,
args,
Expand Down
102 changes: 99 additions & 3 deletions testnet/stacks-node/src/burnchains/bitcoin_regtest_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ use stacks::burnchains::{
use stacks::burnchains::{Burnchain, BurnchainParameters};
use stacks::chainstate::burn::db::sortdb::SortitionDB;
use stacks::chainstate::burn::operations::{
BlockstackOperationType, LeaderBlockCommitOp, LeaderKeyRegisterOp, PreStxOp, TransferStxOp,
UserBurnSupportOp,
BlockstackOperationType, DelegateStxOp, LeaderBlockCommitOp, LeaderKeyRegisterOp, PreStxOp,
TransferStxOp, UserBurnSupportOp,
};
use stacks::chainstate::coordinator::comm::CoordinatorChannels;
#[cfg(test)]
Expand Down Expand Up @@ -834,6 +834,17 @@ impl BitcoinRegtestController {
unimplemented!()
}

#[cfg(not(test))]
fn build_delegate_stacks_tx(
&mut self,
_epoch_id: StacksEpochId,
_payload: DelegateStxOp,
_signer: &mut BurnchainOpSigner,
_utxo: Option<UTXO>,
) -> Option<Transaction> {
unimplemented!()
}

#[cfg(test)]
pub fn submit_manual(
&mut self,
Expand Down Expand Up @@ -950,6 +961,89 @@ impl BitcoinRegtestController {
Some(tx)
}

#[cfg(test)]
/// Build a delegate stacks tx.
/// this *only* works if the only existant UTXO is from a PreStx Op
/// this is okay for testing, but obviously not okay for actual use.
/// The reason for this constraint is that the bitcoin_regtest_controller's UTXO
/// and signing logic are fairly intertwined, and untangling the two seems excessive
/// for a functionality that won't be implemented for production via this controller.
fn build_delegate_stacks_tx(
&mut self,
epoch_id: StacksEpochId,
payload: DelegateStxOp,
signer: &mut BurnchainOpSigner,
utxo_to_use: Option<UTXO>,
) -> Option<Transaction> {
let public_key = signer.get_public_key();
let max_tx_size = 230;

let (mut tx, mut utxos) = if let Some(utxo) = utxo_to_use {
(
Transaction {
input: vec![],
output: vec![],
version: 1,
lock_time: 0,
},
UTXOSet {
bhh: BurnchainHeaderHash::zero(),
utxos: vec![utxo],
},
)
} else {
self.prepare_tx(
epoch_id,
&public_key,
DUST_UTXO_LIMIT + max_tx_size * self.config.burnchain.satoshis_per_byte,
None,
None,
0,
)?
};

// Serialize the payload
let op_bytes = {
let mut bytes = self.config.burnchain.magic_bytes.as_bytes().to_vec();
payload.consensus_serialize(&mut bytes).ok()?;
bytes
};

let consensus_output = TxOut {
value: 0,
script_pubkey: Builder::new()
.push_opcode(opcodes::All::OP_RETURN)
.push_slice(&op_bytes)
.into_script(),
};

tx.output = vec![consensus_output];
tx.output.push(
PoxAddress::Standard(payload.delegate_to.clone(), None)
.to_bitcoin_tx_out(DUST_UTXO_LIMIT),
);

self.finalize_tx(
epoch_id,
&mut tx,
DUST_UTXO_LIMIT,
0,
max_tx_size,
self.config.burnchain.satoshis_per_byte,
&mut utxos,
signer,
)?;

increment_btc_ops_sent_counter();

info!(
"Miner node: submitting stacks delegate op - {}",
public_key.to_hex()
);

Some(tx)
}

#[cfg(not(test))]
fn build_pre_stacks_tx(
&mut self,
Expand Down Expand Up @@ -1687,7 +1781,9 @@ impl BitcoinRegtestController {
self.build_transfer_stacks_tx(epoch_id, payload, op_signer, None)
}
BlockstackOperationType::StackStx(_payload) => unimplemented!(),
BlockstackOperationType::DelegateStx(_payload) => unimplemented!(),
BlockstackOperationType::DelegateStx(payload) => {
self.build_delegate_stacks_tx(epoch_id, payload, op_signer, None)
}
};

transaction.map(|tx| SerializedTx::new(tx))
Expand Down

0 comments on commit 448b6df

Please sign in to comment.