Skip to content

Commit

Permalink
Merge branch 'master' into hotfix/proposal-loads-sortition-view-from-…
Browse files Browse the repository at this point in the history
…block
  • Loading branch information
obycode authored Nov 27, 2024
2 parents f56bfc7 + 160b495 commit 06bc712
Show file tree
Hide file tree
Showing 137 changed files with 16,726 additions and 7,285 deletions.
2 changes: 1 addition & 1 deletion .github/actions/dockerfiles/Dockerfile.debian-source
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ RUN --mount=type=tmpfs,target=${BUILD_DIR} cp -R /src/. ${BUILD_DIR}/ \
&& cp -R ${BUILD_DIR}/target/${TARGET}/release/. /out

FROM --platform=${TARGETPLATFORM} debian:bookworm
COPY --from=build /out/stacks-node /out/stacks-signer /bin/
COPY --from=build /out/stacks-node /out/stacks-signer /out/stacks-inspect /bin/
CMD ["stacks-node", "mainnet"]
11 changes: 11 additions & 0 deletions .github/workflows/bitcoin-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ jobs:
- tests::signer::v0::forked_tenure_okay
- tests::signer::v0::forked_tenure_invalid
- tests::signer::v0::empty_sortition
- tests::signer::v0::empty_sortition_before_approval
- tests::signer::v0::empty_sortition_before_proposal
- tests::signer::v0::bitcoind_forking_test
- tests::signer::v0::multiple_miners
- tests::signer::v0::mock_sign_epoch_25
Expand All @@ -112,6 +114,7 @@ jobs:
- tests::signer::v0::locally_accepted_blocks_overriden_by_global_rejection
- tests::signer::v0::locally_rejected_blocks_overriden_by_global_acceptance
- tests::signer::v0::reorg_locally_accepted_blocks_across_tenures_succeeds
- tests::signer::v0::reorg_locally_accepted_blocks_across_tenures_fails
- tests::signer::v0::miner_recovers_when_broadcast_block_delay_across_tenures_occurs
- tests::signer::v0::multiple_miners_with_nakamoto_blocks
- tests::signer::v0::partial_tenure_fork
Expand All @@ -120,6 +123,10 @@ jobs:
- tests::signer::v0::signing_in_0th_tenure_of_reward_cycle
- tests::signer::v0::continue_after_tenure_extend
- tests::signer::v0::multiple_miners_with_custom_chain_id
- tests::signer::v0::block_commit_delay
- tests::signer::v0::continue_after_fast_block_no_sortition
- tests::signer::v0::block_validation_response_timeout
- tests::signer::v0::tenure_extend_after_bad_commit
- tests::nakamoto_integrations::burn_ops_integration_test
- tests::nakamoto_integrations::check_block_heights
- tests::nakamoto_integrations::clarity_burn_state
Expand All @@ -133,6 +140,10 @@ jobs:
- tests::nakamoto_integrations::utxo_check_on_startup_panic
- tests::nakamoto_integrations::utxo_check_on_startup_recover
- tests::nakamoto_integrations::v3_signer_api_endpoint
- tests::nakamoto_integrations::test_shadow_recovery
- tests::nakamoto_integrations::signer_chainstate
- tests::nakamoto_integrations::clarity_cost_spend_down
- tests::nakamoto_integrations::v3_blockbyheight_api_endpoint
# TODO: enable these once v1 signer is supported by a new nakamoto epoch
# - tests::signer::v1::dkg
# - tests::signer::v1::sign_request_rejected
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/p2p-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ jobs:
- net::tests::convergence::test_walk_star_15_pingback
- net::tests::convergence::test_walk_star_15_org_biased
- net::tests::convergence::test_walk_inbound_line_15
- net::api::tests::postblock_proposal::test_try_make_response
- net::server::tests::test_http_10_threads_getinfo
- net::server::tests::test_http_10_threads_getblock
- net::server::tests::test_http_too_many_clients
- net::server::tests::test_http_slow_client
steps:
## Setup test environment
- name: Setup Test Environment
Expand Down
42 changes: 42 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,48 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE

## [Unreleased]

### Added

### Changed


## [3.0.0.0.3]

### Added

### Changed
- Add index for StacksBlockId to nakamoto block headers table (improves node performance)
- Remove the panic for reporting DB deadlocks (just error and continue waiting)
- Add index to `metadata_table` in Clarity DB on `blockhash`
- Add `block_commit_delay_ms` to the config file to control the time to wait after seeing a new burn block, before submitting a block commit, to allow time for the first Nakamoto block of the new tenure to be mined, allowing this miner to avoid the need to RBF the block commit.
- Add `tenure_cost_limit_per_block_percentage` to the miner config file to control the percentage remaining tenure cost limit to consume per nakamoto block.
- Add `/v3/blocks/height/:block_height` rpc endpoint
- If the winning miner of a sortition is committed to the wrong parent tenure, the previous miner can immediately tenure extend and continue mining since the winning miner would never be able to propose a valid block. (#5361)

## [3.0.0.0.2]

### Added

### Changed
- Fixes a few bugs in the relayer and networking stack
- detects and deprioritizes unhealthy replicas
- fixes an issue in the p2p stack which was preventing it from caching the reward set.

## [3.0.0.0.1]

### Changed
- Add index for StacksBlockId to nakamoto block headers table (improves node performance)
- Remove the panic for reporting DB deadlocks (just error and continue waiting)
- Various test fixes for CI (5353, 5368, 5372, 5371, 5380, 5378, 5387, 5396, 5390, 5394)
- Various log fixes:
- don't say proceeding to mine blocks if not a miner
- misc. warns downgraded to debugs
- 5391: Update default block proposal timeout to 10 minutes
- 5406: After block rejection, miner pauses
- Docs fixes
- Fix signer docs link
- Specify burn block in clarity docs

## [3.0.0.0.0]

### Added
Expand Down
9 changes: 5 additions & 4 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ rand = "0.8"
rand_chacha = "0.3.1"
tikv-jemallocator = "0.5.4"
rusqlite = { version = "0.31.0", features = ["blob", "serde_json", "i128_blob", "bundled", "trace"] }
thiserror = { version = "1.0.65" }

# Use a bit more than default optimization for
# dev builds to speed up test execution
Expand Down
15 changes: 15 additions & 0 deletions clarity/src/vm/costs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,7 @@ impl LimitedCostTracker {
Self::Free => ExecutionCost::max_value(),
}
}

pub fn get_memory(&self) -> u64 {
match self {
Self::Limited(TrackerData { memory, .. }) => *memory,
Expand Down Expand Up @@ -1170,6 +1171,7 @@ pub trait CostOverflowingMath<T> {
fn cost_overflow_mul(self, other: T) -> Result<T>;
fn cost_overflow_add(self, other: T) -> Result<T>;
fn cost_overflow_sub(self, other: T) -> Result<T>;
fn cost_overflow_div(self, other: T) -> Result<T>;
}

impl CostOverflowingMath<u64> for u64 {
Expand All @@ -1185,6 +1187,10 @@ impl CostOverflowingMath<u64> for u64 {
self.checked_sub(other)
.ok_or_else(|| CostErrors::CostOverflow)
}
fn cost_overflow_div(self, other: u64) -> Result<u64> {
self.checked_div(other)
.ok_or_else(|| CostErrors::CostOverflow)
}
}

impl ExecutionCost {
Expand Down Expand Up @@ -1293,6 +1299,15 @@ impl ExecutionCost {
Ok(())
}

pub fn divide(&mut self, divisor: u64) -> Result<()> {
self.runtime = self.runtime.cost_overflow_div(divisor)?;
self.read_count = self.read_count.cost_overflow_div(divisor)?;
self.read_length = self.read_length.cost_overflow_div(divisor)?;
self.write_length = self.write_length.cost_overflow_div(divisor)?;
self.write_count = self.write_count.cost_overflow_div(divisor)?;
Ok(())
}

/// Returns whether or not this cost exceeds any dimension of the
/// other cost.
pub fn exceeds(&self, other: &ExecutionCost) -> bool {
Expand Down
6 changes: 6 additions & 0 deletions clarity/src/vm/database/sqlite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,12 @@ impl SqliteConnection {
)
.map_err(|x| InterpreterError::SqliteError(IncomparableError { err: x }))?;

conn.execute(
"CREATE INDEX IF NOT EXISTS md_blockhashes ON metadata_table(blockhash)",
NO_PARAMS,
)
.map_err(|x| InterpreterError::SqliteError(IncomparableError { err: x }))?;

Self::check_schema(conn)?;

Ok(())
Expand Down
22 changes: 11 additions & 11 deletions clarity/src/vm/docs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1775,17 +1775,17 @@ this value is less than or equal to the value for `miner-spend-total` at the sam
const GET_BURN_BLOCK_INFO_API: SpecialAPI = SpecialAPI {
input_type: "BurnBlockInfoPropertyName, uint",
output_type: "(optional buff) | (optional (tuple (addrs (list 2 (tuple (hashbytes (buff 32)) (version (buff 1))))) (payout uint)))",
snippet: "get-burn-block-info? ${1:prop} ${2:block-height}",
signature: "(get-burn-block-info? prop-name block-height)",
snippet: "get-burn-block-info? ${1:prop} ${2:burn-block-height}",
signature: "(get-burn-block-info? prop-name burn-block-height)",
description: "The `get-burn-block-info?` function fetches data for a block of the given *burnchain* block height. The
value and type returned are determined by the specified `BlockInfoPropertyName`. Valid values for `block-height` only
value and type returned are determined by the specified `BlockInfoPropertyName`. Valid values for `burn-block-height` only
include heights between the burnchain height at the time the Stacks chain was launched, and the last-processed burnchain
block. If the `block-height` argument falls outside of this range, then `none` shall be returned.
block. If the `burn-block-height` argument falls outside of this range, then `none` shall be returned.
The following `BlockInfoPropertyName` values are defined:
* The `header-hash` property returns a 32-byte buffer representing the header hash of the burnchain block at
burnchain height `block-height`.
burnchain height `burn-block-height`.
* The `pox-addrs` property returns a tuple with two items: a list of up to two PoX addresses that received a PoX payout at that block height, and the amount of burnchain
tokens paid to each address (note that per the blockchain consensus rules, each PoX payout will be the same for each address in the block-commit transaction).
Expand All @@ -1811,11 +1811,11 @@ The `addrs` list contains the same PoX address values passed into the PoX smart

const GET_STACKS_BLOCK_INFO_API: SpecialAPI = SpecialAPI {
input_type: "StacksBlockInfoPropertyName, uint",
snippet: "get-stacks-block-info? ${1:prop} ${2:block-height}",
snippet: "get-stacks-block-info? ${1:prop} ${2:stacks-block-height}",
output_type: "(optional buff) | (optional uint)",
signature: "(get-stacks-block-info? prop-name block-height)",
signature: "(get-stacks-block-info? prop-name stacks-block-height)",
description: "The `get-stacks-block-info?` function fetches data for a block of the given *Stacks* block height. The
value and type returned are determined by the specified `StacksBlockInfoPropertyName`. If the provided `block-height` does
value and type returned are determined by the specified `StacksBlockInfoPropertyName`. If the provided `stacks-block-height` does
not correspond to an existing block prior to the current block, the function returns `none`. The currently available property names
are as follows:
Expand All @@ -1840,11 +1840,11 @@ the mining of this block started, but is not guaranteed to be accurate. This tim

const GET_TENURE_INFO_API: SpecialAPI = SpecialAPI {
input_type: "TenureInfoPropertyName, uint",
snippet: "get-tenure-info? ${1:prop} ${2:block-height}",
snippet: "get-tenure-info? ${1:prop} ${2:stacks-block-height}",
output_type: "(optional buff) | (optional uint)",
signature: "(get-tenure-info? prop-name block-height)",
signature: "(get-tenure-info? prop-name stacks-block-height)",
description: "The `get-tenure-info?` function fetches data for the tenure at the given block height. The
value and type returned are determined by the specified `TenureInfoPropertyName`. If the provided `block-height` does
value and type returned are determined by the specified `TenureInfoPropertyName`. If the provided `stacks-block-height` does
not correspond to an existing block prior to the current block, the function returns `none`. The currently available property names
are as follows:
Expand Down
20 changes: 16 additions & 4 deletions docs/mining.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,26 @@ nakamoto_attempt_time_ms = 20000
[burnchain]
# Maximum amount (in sats) of "burn commitment" to broadcast for the next block's leader election
burn_fee_cap = 20000
# Amount (in sats) per byte - Used to calculate the transaction fees
satoshis_per_byte = 25
# Amount of sats to add when RBF'ing bitcoin tx (default: 5)
# Amount in sats per byte used to calculate the Bitcoin transaction fee (default: 50)
satoshis_per_byte = 50
# Amount of sats per byte to add when RBF'ing a Bitcoin tx (default: 5)
rbf_fee_increment = 5
# Maximum percentage to RBF bitcoin tx (default: 150% of satsv/B)
# Maximum percentage of satoshis_per_byte to allow in RBF fee (default: 150)
max_rbf = 150
```

NOTE: Ensuring that your miner can successfully use RBF (Replace-by-Fee) is
critical for reliable block production. If a miner fails to replace an outdated
block commit with a higher-fee transaction, it risks committing to an incorrect
tenure. This would prevent the miner from producing valid blocks during its
tenure, as it would be building on an invalid chain tip, causing the signers to
reject its blocks.

To avoid this, configure satoshis_per_byte, rbf_fee_increment, and max_rbf to
allow for at least three fee increments within the max_rbf limit. This helps
ensure that your miner can adjust its fees sufficiently to stay on the canonical
chain.

You can verify that your node is operating as a miner by checking its log output
to verify that it was able to find its Bitcoin UTXOs:

Expand Down
11 changes: 11 additions & 0 deletions docs/rpc-endpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,17 @@ data.

This will return 404 if the block does not exist.

### GET /v3/blocks/height/[Block Height]

Fetch a Nakamoto block given its block height. This returns the raw block
data.

This will return 404 if the block does not exist.

This endpoint also accepts a querystring parameter `?tip=` which when supplied
will return the block relative to the specified tip allowing the querying of
sibling blocks (same height, different tip) too.

### GET /v3/tenures/[Block ID]

Fetch a Nakamoto block and all of its ancestors in the same tenure, given its
Expand Down
34 changes: 34 additions & 0 deletions docs/rpc/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,40 @@ paths:
content:
application/text-plain: {}

/v3/blocks/height/{block_height}:
get:
summary: Fetch a Nakamoto block by its height and optional tip
tags:
- Blocks
operationId: get_block_v3_by_height
description:
Fetch a Nakamoto block by its height and optional tip.
parameters:
- name: block_height
in: path
description: The block's height
required: true
schema:
type: integer
- name: tip
in: query
schema:
type: string
description: The Stacks chain tip to query from. If tip == latest or empty, the query will be run
from the latest known tip.
responses:
"200":
description: The raw SIP-003-encoded block will be returned.
content:
application/octet-stream:
schema:
type: string
format: binary
"404":
description: The block could not be found
content:
application/text-plain: {}

/v3/tenures/info:
get:
summary: Fetch metadata about the ongoing Nakamoto tenure
Expand Down
2 changes: 1 addition & 1 deletion libsigner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ slog-term = "2.6.0"
slog-json = { version = "2.3.0", optional = true }
stacks-common = { path = "../stacks-common" }
stackslib = { path = "../stackslib"}
thiserror = "1.0"
thiserror = { workspace = true }
tiny_http = "0.12"

[dev-dependencies]
Expand Down
Loading

0 comments on commit 06bc712

Please sign in to comment.