Skip to content

Commit dd9f859

Browse files
authored
Merge branch 'develop' into feat/pox-4-stateful-solo-scenarios
2 parents 482c195 + 08e04d9 commit dd9f859

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+2283
-619
lines changed

.github/actions/dockerfiles/Dockerfile.alpine-binary

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@ RUN case ${TARGETPLATFORM} in \
2323
&& unzip ${BIN_ARCH}.zip -d /out
2424

2525
FROM --platform=${TARGETPLATFORM} alpine
26-
COPY --from=builder /out/stacks-node /bin/
26+
COPY --from=builder /out/stacks-node /out/stacks-signer /bin/
2727
CMD ["stacks-node", "mainnet"]

.github/actions/dockerfiles/Dockerfile.debian-binary

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@ RUN case ${TARGETPLATFORM} in \
2323
&& unzip ${BIN_ARCH}.zip -d /out
2424

2525
FROM --platform=${TARGETPLATFORM} debian:bookworm
26-
COPY --from=builder /out/stacks-node /bin/
26+
COPY --from=builder /out/stacks-node /out/stacks-signer /bin/
2727
CMD ["stacks-node", "mainnet"]

.github/workflows/bitcoin-tests.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,18 @@ jobs:
8181
- tests::nakamoto_integrations::correct_burn_outs
8282
- tests::nakamoto_integrations::vote_for_aggregate_key_burn_op
8383
- tests::nakamoto_integrations::follower_bootup
84+
- tests::nakamoto_integrations::forked_tenure_is_ignored
8485
- tests::signer::stackerdb_dkg
85-
- tests::signer::stackerdb_sign
86+
- tests::signer::stackerdb_sign_request_rejected
8687
- tests::signer::stackerdb_block_proposal
8788
- tests::signer::stackerdb_filter_bad_transactions
8889
- tests::signer::stackerdb_mine_2_nakamoto_reward_cycles
8990
- tests::signer::stackerdb_sign_after_signer_reboot
9091
- tests::nakamoto_integrations::stack_stx_burn_op_integration_test
92+
- tests::signer::stackerdb_delayed_dkg
9193
# Do not run this one until we figure out why it fails in CI
9294
# - tests::neon_integrations::bitcoin_reorg_flap
95+
# - tests::neon_integrations::bitcoin_reorg_flap_with_follower
9396
steps:
9497
## Setup test environment
9598
- name: Setup Test Environment

.github/workflows/github-release.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ jobs:
7070
draft: false
7171
prerelease: true
7272
fail_on_unmatched_files: true
73+
target_commitish: ${{ github.sha }}
74+
generate_release_notes: true
7375
files: |
7476
release/*.zip
7577
CHECKSUMS.txt

CHANGELOG.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,30 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to the versioning scheme outlined in the [README.md](README.md).
77

8-
## [Next-Branch]
8+
## [2.5.0.0.3]
9+
10+
This release fixes a regression in `2.5.0.0.0` from `2.4.0.1.0` caused by git merge
11+
12+
## [2.5.0.0.2]
13+
14+
This release fixes two bugs in `2.5.0.0.0`, correctly setting the activation height for 2.5, and the network peer version.
15+
16+
## [2.5.0.0.0]
17+
18+
This release implements the 2.5 Stacks consensus rules which activates at Bitcoin block `840,360`: primarily the instantiation
19+
of the pox-4 contract. For more details see SIP-021.
20+
21+
This is the first consensus-critical release for Nakamoto. Nodes which do not update before the 2.5 activation height will be forked away from the rest of the network. This release is compatible with 2.4.x chain state directories and does not require resyncing from genesis. The first time a node boots with this version it will perform some database migrations which could lengthen the normal node startup time.
22+
23+
**This is a required release before Nakamoto rules are enabled in 3.0.**
24+
25+
26+
### Timing of Release from 2.5 to 3.0
27+
28+
Activating Nakamoto will include two epochs:
29+
30+
- **Epoch 2.5:** Pox-4 contract is booted up but no Nakamoto consensus rules take effect.
31+
- **Epoch 3:** Nakamoto consensus rules take effect.
932

1033
### Added
1134

clarity/src/vm/contexts.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1340,7 +1340,7 @@ impl<'a, 'b, 'hooks> Environment<'a, 'b, 'hooks> {
13401340
self.global_context.begin();
13411341
let result = stx_transfer_consolidated(self, from, to, amount, memo);
13421342
match result {
1343-
Ok(value) => match value.clone().expect_result() {
1343+
Ok(value) => match value.clone().expect_result()? {
13441344
Ok(_) => {
13451345
self.global_context.commit()?;
13461346
Ok(value)
@@ -1966,8 +1966,14 @@ impl CallStack {
19661966

19671967
#[cfg(test)]
19681968
mod test {
1969+
use stacks_common::types::chainstate::StacksAddress;
1970+
use stacks_common::util::hash::Hash160;
1971+
19691972
use super::*;
19701973
use crate::vm::callables::DefineType;
1974+
use crate::vm::tests::{
1975+
test_epochs, tl_env_factory, MemoryEnvironmentGenerator, TopLevelMemoryEnvironmentGenerator,
1976+
};
19711977
use crate::vm::types::signatures::CallableSubtype;
19721978
use crate::vm::types::{FixedFunction, FunctionArg, FunctionType, StandardPrincipalData};
19731979

@@ -2123,6 +2129,35 @@ mod test {
21232129
assert_eq!(table[&p2][&t7], AssetMapEntry::Burn(35 + 36));
21242130
}
21252131

2132+
/// Test the stx-transfer consolidation tx invalidation
2133+
/// bug from 2.4.0.1.0-rc1
2134+
#[apply(test_epochs)]
2135+
fn stx_transfer_consolidate_regr_24010(
2136+
epoch: StacksEpochId,
2137+
mut tl_env_factory: TopLevelMemoryEnvironmentGenerator,
2138+
) {
2139+
let mut env = tl_env_factory.get_env(epoch);
2140+
let u1 = StacksAddress {
2141+
version: 0,
2142+
bytes: Hash160([1; 20]),
2143+
};
2144+
let u2 = StacksAddress {
2145+
version: 0,
2146+
bytes: Hash160([2; 20]),
2147+
};
2148+
// insufficient balance must be a non-includable transaction. it must error here,
2149+
// not simply rollback the tx and squelch the error as includable.
2150+
let e = env
2151+
.stx_transfer(
2152+
&PrincipalData::from(u1.clone()),
2153+
&PrincipalData::from(u2.clone()),
2154+
1000,
2155+
&BuffData::empty(),
2156+
)
2157+
.unwrap_err();
2158+
assert_eq!(e.to_string(), "Interpreter(InsufficientBalance)");
2159+
}
2160+
21262161
#[test]
21272162
fn test_canonicalize_contract_context() {
21282163
let trait_id = TraitIdentifier::new(

clarity/src/vm/tests/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ impl MemoryEnvironmentGenerator {
149149

150150
pub struct TopLevelMemoryEnvironmentGenerator(MemoryBackingStore);
151151
impl TopLevelMemoryEnvironmentGenerator {
152-
fn get_env(&mut self, epoch: StacksEpochId) -> OwnedEnvironment {
152+
pub fn get_env(&mut self, epoch: StacksEpochId) -> OwnedEnvironment {
153153
let owned_env = OwnedEnvironment::new(self.0.as_clarity_db(), epoch);
154154
owned_env
155155
}

libsigner/src/events.rs

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,9 @@ pub struct BlockProposalSigners {
6868
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
6969
pub enum SignerEvent {
7070
/// A miner sent a message over .miners
71-
/// The `Vec<BlockProposalSigners>` will contain any block proposals made by the miner during this StackerDB event.
7271
/// The `Vec<SignerMessage>` will contain any signer WSTS messages made by the miner while acting as a coordinator.
73-
/// The `Option<StacksPublicKey>` will contain the message sender's public key if either of the vecs is non-empty.
74-
MinerMessages(
75-
Vec<BlockProposalSigners>,
76-
Vec<SignerMessage>,
77-
Option<StacksPublicKey>,
78-
),
72+
/// The `Option<StacksPublicKey>` will contain the message sender's public key if the vec is non-empty.
73+
MinerMessages(Vec<SignerMessage>, Option<StacksPublicKey>),
7974
/// The signer messages for other signers and miners to observe
8075
/// The u32 is the signer set to which the message belongs (either 0 or 1)
8176
SignerMessages(u32, Vec<SignerMessage>),
@@ -417,7 +412,6 @@ impl TryFrom<StackerDBChunksEvent> for SignerEvent {
417412
let signer_event = if event.contract_id.name.as_str() == MINERS_NAME
418413
&& event.contract_id.is_boot()
419414
{
420-
let mut blocks = vec![];
421415
let mut messages = vec![];
422416
let mut miner_pk = None;
423417
for chunk in event.modified_slots {
@@ -426,28 +420,13 @@ impl TryFrom<StackerDBChunksEvent> for SignerEvent {
426420
"Failed to recover PK from StackerDB chunk: {e}"
427421
))
428422
})?);
429-
if chunk.slot_id % MINER_SLOT_COUNT == 0 {
430-
// block
431-
let Ok(block) =
432-
BlockProposalSigners::consensus_deserialize(&mut chunk.data.as_slice())
433-
else {
434-
continue;
435-
};
436-
blocks.push(block);
437-
} else if chunk.slot_id % MINER_SLOT_COUNT == 1 {
438-
// message
439-
let Ok(msg) = SignerMessage::consensus_deserialize(&mut chunk.data.as_slice())
440-
else {
441-
continue;
442-
};
443-
messages.push(msg);
444-
} else {
445-
return Err(EventError::UnrecognizedEvent(
446-
"Unrecognized slot_id for miners contract".into(),
447-
));
423+
let Ok(msg) = SignerMessage::consensus_deserialize(&mut chunk.data.as_slice())
424+
else {
425+
continue;
448426
};
427+
messages.push(msg);
449428
}
450-
SignerEvent::MinerMessages(blocks, messages, miner_pk)
429+
SignerEvent::MinerMessages(messages, miner_pk)
451430
} else if event.contract_id.name.starts_with(SIGNERS_NAME) && event.contract_id.is_boot() {
452431
let Some((signer_set, _)) =
453432
get_signers_db_signer_set_message_id(event.contract_id.name.as_str())

libsigner/src/session.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ use std::str;
2020
use clarity::vm::types::QualifiedContractIdentifier;
2121
use libstackerdb::{
2222
stackerdb_get_chunk_path, stackerdb_get_metadata_path, stackerdb_post_chunk_path, SlotMetadata,
23-
StackerDBChunkAckData, StackerDBChunkData,
23+
StackerDBChunkAckData, StackerDBChunkData, SIGNERS_STACKERDB_CHUNK_SIZE,
24+
STACKERDB_MAX_CHUNK_SIZE,
2425
};
2526
use stacks_common::codec::StacksMessageCodec;
2627

@@ -214,10 +215,23 @@ impl SignerSession for StackerDBSession {
214215
/// query the replica for zero or more latest chunks
215216
fn get_latest_chunks(&mut self, slot_ids: &[u32]) -> Result<Vec<Option<Vec<u8>>>, RPCError> {
216217
let mut payloads = vec![];
218+
let limit = if self.stackerdb_contract_id.name.starts_with("signer") {
219+
SIGNERS_STACKERDB_CHUNK_SIZE
220+
} else {
221+
usize::try_from(STACKERDB_MAX_CHUNK_SIZE)
222+
.expect("infallible: StackerDB chunk size exceeds usize::MAX")
223+
};
217224
for slot_id in slot_ids.iter() {
218225
let path = stackerdb_get_chunk_path(self.stackerdb_contract_id.clone(), *slot_id, None);
219226
let chunk = match self.rpc_request("GET", &path, None, &[]) {
220-
Ok(body_bytes) => Some(body_bytes),
227+
Ok(body_bytes) => {
228+
// Verify that the chunk is not too large
229+
if body_bytes.len() > limit {
230+
None
231+
} else {
232+
Some(body_bytes)
233+
}
234+
}
221235
Err(RPCError::HttpError(code)) => {
222236
if code != 404 {
223237
return Err(RPCError::HttpError(code));

libstackerdb/src/libstackerdb.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ use stacks_common::util::secp256k1::MessageSignature;
3535

3636
/// maximum chunk size (16 MB; same as MAX_PAYLOAD_SIZE)
3737
pub const STACKERDB_MAX_CHUNK_SIZE: u32 = 16 * 1024 * 1024;
38+
/// CHUNK_SIZE constant for signers StackerDBs (2MB)
39+
pub const SIGNERS_STACKERDB_CHUNK_SIZE: usize = 2 * 1024 * 1024; // 2MB
3840

3941
#[cfg(test)]
4042
mod tests;

0 commit comments

Comments
 (0)