diff --git a/.cargo/config b/.cargo/config.toml
similarity index 100%
rename from .cargo/config
rename to .cargo/config.toml
diff --git a/.github/actions/dockerfiles/Dockerfile.alpine-binary b/.github/actions/dockerfiles/Dockerfile.alpine-binary
index 1915a13d113..d185121e735 100644
--- a/.github/actions/dockerfiles/Dockerfile.alpine-binary
+++ b/.github/actions/dockerfiles/Dockerfile.alpine-binary
@@ -23,5 +23,18 @@ RUN case ${TARGETPLATFORM} in \
&& unzip ${BIN_ARCH}.zip -d /out
FROM --platform=${TARGETPLATFORM} alpine
-COPY --from=builder /out/stacks-node /out/stacks-signer /bin/
-CMD ["stacks-node", "mainnet"]
+COPY --from=builder /out/* /bin/
+ARG TAG
+
+RUN case "${TAG}" in \
+ signer-*) \
+ echo "/bin/stacks-signer run --config /signer-config.toml" > /tmp/command.sh \
+ ;; \
+ *) \
+ echo "/bin/stacks-node mainnet" > /tmp/command.sh && \
+ rm /bin/blockstack-cli /bin/clarity-cli /bin/relay-server /bin/stacks-events /bin/stacks-inspect \
+ ;; \
+ esac && \
+ chmod +x /tmp/command.sh
+
+CMD ["sh", "-c", "/tmp/command.sh"]
diff --git a/.github/actions/dockerfiles/Dockerfile.debian-binary b/.github/actions/dockerfiles/Dockerfile.debian-binary
index 5432e923778..757379095c3 100644
--- a/.github/actions/dockerfiles/Dockerfile.debian-binary
+++ b/.github/actions/dockerfiles/Dockerfile.debian-binary
@@ -23,5 +23,18 @@ RUN case ${TARGETPLATFORM} in \
&& unzip ${BIN_ARCH}.zip -d /out
FROM --platform=${TARGETPLATFORM} debian:bookworm
-COPY --from=builder /out/stacks-node /out/stacks-signer /bin/
-CMD ["stacks-node", "mainnet"]
+COPY --from=builder /out/* /bin/
+ARG TAG
+
+RUN case "${TAG}" in \
+ signer-*) \
+ echo "/bin/stacks-signer run --config /signer-config.toml" > /tmp/command.sh \
+ ;; \
+ *) \
+ echo "/bin/stacks-node mainnet" > /tmp/command.sh && \
+ rm /bin/blockstack-cli /bin/clarity-cli /bin/relay-server /bin/stacks-events /bin/stacks-inspect \
+ ;; \
+ esac && \
+ chmod +x /tmp/command.sh
+
+CMD ["sh", "-c", "/tmp/command.sh"]
diff --git a/.github/workflows/bitcoin-tests.yml b/.github/workflows/bitcoin-tests.yml
index 76ca85b6463..e14934558a5 100644
--- a/.github/workflows/bitcoin-tests.yml
+++ b/.github/workflows/bitcoin-tests.yml
@@ -81,16 +81,41 @@ jobs:
- tests::nakamoto_integrations::correct_burn_outs
- tests::nakamoto_integrations::vote_for_aggregate_key_burn_op
- tests::nakamoto_integrations::follower_bootup
- - tests::signer::stackerdb_dkg
- - tests::signer::stackerdb_sign
- - tests::signer::stackerdb_block_proposal
- - tests::signer::stackerdb_filter_bad_transactions
- - tests::signer::stackerdb_mine_2_nakamoto_reward_cycles
- - tests::signer::stackerdb_sign_after_signer_reboot
+ - tests::nakamoto_integrations::forked_tenure_is_ignored
+ - tests::nakamoto_integrations::nakamoto_attempt_time
+ - tests::signer::v0::block_proposal_rejection
+ - tests::signer::v0::miner_gather_signatures
+ - tests::signer::v0::mine_2_nakamoto_reward_cycles
+ - tests::signer::v0::end_of_tenure
+ - tests::signer::v0::forked_tenure_okay
+ - tests::signer::v0::forked_tenure_invalid
+ - tests::signer::v0::empty_sortition
+ - tests::signer::v0::bitcoind_forking_test
+ - tests::signer::v0::multiple_miners
+ - tests::signer::v0::mock_sign_epoch_25
+ - tests::signer::v0::signer_set_rollover
+ - tests::signer::v0::miner_forking
+ - tests::signer::v0::reloads_signer_set_in
- tests::nakamoto_integrations::stack_stx_burn_op_integration_test
+ - tests::nakamoto_integrations::check_block_heights
+ - tests::nakamoto_integrations::clarity_burn_state
+ - tests::nakamoto_integrations::check_block_times
+ - tests::nakamoto_integrations::check_block_info
+ - tests::nakamoto_integrations::check_block_info_rewards
+ - tests::nakamoto_integrations::continue_tenure_extend
+ - tests::nakamoto_integrations::mock_mining
+ - tests::nakamoto_integrations::multiple_miners
# Do not run this one until we figure out why it fails in CI
# - tests::neon_integrations::bitcoin_reorg_flap
# - tests::neon_integrations::bitcoin_reorg_flap_with_follower
+ # TODO: enable these once v1 signer is supported by a new nakamoto epoch
+ # - tests::signer::v1::dkg
+ # - tests::signer::v1::sign_request_rejected
+ # - tests::signer::v1::filter_bad_transactions
+ # - tests::signer::v1::delayed_dkg
+ # - tests::signer::v1::mine_2_nakamoto_reward_cycles
+ # - tests::signer::v1::sign_after_signer_reboot
+ # - tests::signer::v1::block_proposal
steps:
## Setup test environment
- name: Setup Test Environment
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 39048dc01b6..d1ae6522663 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -14,10 +14,6 @@ on:
- "**.md"
- "**.yml"
workflow_dispatch:
- inputs:
- tag:
- description: "The tag to create (optional)"
- required: false
pull_request:
types:
- opened
@@ -34,7 +30,7 @@ concurrency:
## Always cancel duplicate jobs
cancel-in-progress: true
-run-name: ${{ inputs.tag }}
+run-name: ${{ github.ref_name }}
jobs:
##
@@ -48,90 +44,99 @@ jobs:
name: Rust Format
runs-on: ubuntu-latest
steps:
- - name: Checkout the latest code
- id: git_checkout
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
-
- - name: Setup Rust Toolchain
- id: setup_rust_toolchain
- uses: actions-rust-lang/setup-rust-toolchain@f3c84ee10bf5a86e7a5d607d487bf17d57670965 # v1.5.0
- with:
- components: rustfmt
- cache: false
-
- name: Rustfmt
id: rustfmt
uses: stacks-network/actions/rustfmt@main
with:
alias: "fmt-stacks"
+ ######################################################################################
+ ## Check if the branch that this workflow is being run against is a release branch
+ check-release:
+ name: Check Release
+ needs:
+ - rustfmt
+ runs-on: ubuntu-latest
+ outputs:
+ tag: ${{ steps.check_release.outputs.tag }}
+ docker_tag: ${{ steps.check_release.outputs.docker_tag }}
+ is_release: ${{ steps.check_release.outputs.is_release }}
+ steps:
+ - name: Check Release
+ id: check_release
+ uses: stacks-network/actions/stacks-core/check-release@main
+ with:
+ tag: ${{ github.ref_name }}
+
######################################################################################
## Create a tagged github release
##
- ## Runs when the following is true:
- ## - tag is provided
+ ## Runs when:
+ ## - it is a release run
create-release:
if: |
- inputs.tag != ''
+ needs.check-release.outputs.is_release == 'true'
name: Create Release
needs:
- rustfmt
+ - check-release
uses: ./.github/workflows/github-release.yml
with:
- tag: ${{ inputs.tag }}
+ tag: ${{ needs.check-release.outputs.tag }}
+ docker_tag: ${{ needs.check-release.outputs.docker_tag }}
secrets: inherit
## Build and push Debian image built from source
##
## Runs when:
- ## - tag is not provided
+ ## - it is not a release run
docker-image:
if: |
- inputs.tag == ''
+ needs.check-release.outputs.is_release != 'true'
name: Docker Image (Source)
uses: ./.github/workflows/image-build-source.yml
needs:
- rustfmt
+ - check-release
secrets: inherit
## Create a reusable cache for tests
##
## Runs when:
- ## - tag is provided
+ ## - it is a release run
## or:
- ## - no tag provided
+ ## - it is not a release run
## and any of:
## - this workflow is called manually
## - PR is opened
## - commit to either (development, master) branch
create-cache:
if: |
- inputs.tag != '' || (
- inputs.tag == '' && (
- github.event_name == 'workflow_dispatch' ||
- github.event_name == 'pull_request' ||
- github.event_name == 'merge_group' ||
- (
- contains('
- refs/heads/master
- refs/heads/develop
- refs/heads/next
- ', github.event.pull_request.head.ref) &&
- github.event_name == 'push'
- )
+ needs.check-release.outputs.is_release == 'true' || (
+ github.event_name == 'workflow_dispatch' ||
+ github.event_name == 'pull_request' ||
+ github.event_name == 'merge_group' ||
+ (
+ contains('
+ refs/heads/master
+ refs/heads/develop
+ refs/heads/next
+ ', github.event.pull_request.head.ref) &&
+ github.event_name == 'push'
)
)
name: Create Test Cache
needs:
- rustfmt
+ - check-release
uses: ./.github/workflows/create-cache.yml
## Tests to run regularly
##
## Runs when:
- ## - tag is provided
+ ## - it is a release run
## or:
- ## - no tag provided
+ ## - it is not a release run
## and any of:
## - this workflow is called manually
## - PR is opened
@@ -139,75 +144,75 @@ jobs:
## - commit to either (development, next, master) branch
stacks-core-tests:
if: |
- inputs.tag != '' || (
- inputs.tag == '' && (
- github.event_name == 'workflow_dispatch' ||
- github.event_name == 'pull_request' ||
- github.event_name == 'merge_group' ||
- (
- contains('
- refs/heads/master
- refs/heads/develop
- refs/heads/next
- ', github.event.pull_request.head.ref) &&
- github.event_name == 'push'
- )
+ needs.check-release.outputs.is_release == 'true' || (
+ github.event_name == 'workflow_dispatch' ||
+ github.event_name == 'pull_request' ||
+ github.event_name == 'merge_group' ||
+ (
+ contains('
+ refs/heads/master
+ refs/heads/develop
+ refs/heads/next
+ ', github.event.pull_request.head.ref) &&
+ github.event_name == 'push'
)
)
name: Stacks Core Tests
needs:
- rustfmt
- create-cache
+ - check-release
uses: ./.github/workflows/stacks-core-tests.yml
bitcoin-tests:
if: |
- inputs.tag != '' || (
- inputs.tag == '' && (
- github.event_name == 'workflow_dispatch' ||
- github.event_name == 'pull_request' ||
- github.event_name == 'merge_group' ||
- (
- contains('
- refs/heads/master
- refs/heads/develop
- refs/heads/next
- ', github.event.pull_request.head.ref) &&
- github.event_name == 'push'
- )
+ needs.check-release.outputs.is_release == 'true' || (
+ github.event_name == 'workflow_dispatch' ||
+ github.event_name == 'pull_request' ||
+ github.event_name == 'merge_group' ||
+ (
+ contains('
+ refs/heads/master
+ refs/heads/develop
+ refs/heads/next
+ ', github.event.pull_request.head.ref) &&
+ github.event_name == 'push'
)
)
name: Bitcoin Tests
needs:
- rustfmt
- create-cache
+ - check-release
uses: ./.github/workflows/bitcoin-tests.yml
## Test to run on a tagged release
##
## Runs when:
- ## - tag is provided
+ ## - it is a release run
atlas-tests:
- if: inputs.tag != ''
+ if: needs.check-release.outputs.is_release == 'true'
name: Atlas Tests
needs:
- rustfmt
- create-cache
+ - check-release
uses: ./.github/workflows/atlas-tests.yml
epoch-tests:
- if: inputs.tag != ''
+ if: needs.check-release.outputs.is_release == 'true'
name: Epoch Tests
needs:
- rustfmt
- create-cache
+ - check-release
uses: ./.github/workflows/epoch-tests.yml
slow-tests:
- if: inputs.tag != ''
+ if: needs.check-release.outputs.is_release == 'true'
name: Slow Tests
needs:
- rustfmt
- create-cache
+ - check-release
uses: ./.github/workflows/slow-tests.yml
-
diff --git a/.github/workflows/clarity-js-sdk-pr.yml b/.github/workflows/clarity-js-sdk-pr.yml
index 45238084100..6bcd555ca9f 100644
--- a/.github/workflows/clarity-js-sdk-pr.yml
+++ b/.github/workflows/clarity-js-sdk-pr.yml
@@ -28,7 +28,7 @@ jobs:
steps:
- name: Checkout latest clarity js sdk
id: git_checkout
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
+ uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
with:
token: ${{ secrets.GH_TOKEN }}
repository: ${{ env.CLARITY_JS_SDK_REPOSITORY }}
@@ -46,7 +46,7 @@ jobs:
- name: Create Pull Request
id: create_pr
- uses: peter-evans/create-pull-request@153407881ec5c347639a548ade7d8ad1d6740e38 # v5.0.2
+ uses: peter-evans/create-pull-request@6d6857d36972b65feb161a90e484f2984215f83e # v6.0.5
with:
token: ${{ secrets.GH_TOKEN }}
commit-message: "chore: update clarity-native-bin tag"
diff --git a/.github/workflows/docs-pr.yml b/.github/workflows/docs-pr.yml
index 7543bdd7507..8b005e0402c 100644
--- a/.github/workflows/docs-pr.yml
+++ b/.github/workflows/docs-pr.yml
@@ -36,7 +36,7 @@ jobs:
steps:
- name: Checkout the latest code
id: git_checkout
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
+ uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Build docs
id: build_docs
@@ -46,7 +46,7 @@ jobs:
- name: Checkout latest docs
id: git_checkout_docs
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
+ uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
with:
token: ${{ secrets.DOCS_GITHUB_TOKEN }}
repository: ${{ env.TARGET_REPOSITORY }}
@@ -77,7 +77,7 @@ jobs:
- name: Open PR
id: open_pr
if: ${{ steps.push.outputs.open_pr == '1' }}
- uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6.4.1
+ uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
github-token: ${{ secrets.DOCS_GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/github-release.yml b/.github/workflows/github-release.yml
index 02243c4cbf0..9d4e18c6653 100644
--- a/.github/workflows/github-release.yml
+++ b/.github/workflows/github-release.yml
@@ -9,6 +9,10 @@ on:
description: "Release Tag"
required: true
type: string
+ docker_tag:
+ description: "Docker Release Tag"
+ required: true
+ type: string
secrets:
GH_TOKEN:
required: true
@@ -48,25 +52,28 @@ jobs:
## Downloads the artifacts built in `create-source-binary.yml`
- name: Download Artifacts
id: download_artifacts
- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
+ uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
with:
- name: artifact
+ pattern: ${{ inputs.tag }}-binary-build-*
path: release
+ merge-multiple: true
## Generate a checksums file to be added to the release page
- name: Generate Checksums
id: generate_checksum
uses: stacks-network/actions/generate-checksum@main
+ with:
+ artifact_download_pattern: "${{ inputs.tag }}-binary-build-*"
## Upload the release archives with the checksums file
- name: Upload Release
id: upload_release
- uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 #v0.1.15
+ uses: softprops/action-gh-release@69320dbe05506a9a39fc8ae11030b214ec2d1f87 #v2.0.5
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
with:
- name: Release ${{ github.event.inputs.tag || github.ref }}
- tag_name: ${{ github.event.inputs.tag || github.ref }}
+ name: Release ${{ inputs.tag || github.ref }}
+ tag_name: ${{ inputs.tag || github.ref }}
draft: false
prerelease: true
fail_on_unmatched_files: true
@@ -91,4 +98,5 @@ jobs:
- create-release
with:
tag: ${{ inputs.tag }}
+ docker_tag: ${{ inputs.docker_tag }}
secrets: inherit
diff --git a/.github/workflows/image-build-binary.yml b/.github/workflows/image-build-binary.yml
index 74415e7f16a..5966d7e68a4 100644
--- a/.github/workflows/image-build-binary.yml
+++ b/.github/workflows/image-build-binary.yml
@@ -6,6 +6,10 @@ on:
workflow_call:
inputs:
tag:
+ required: true
+ type: string
+ description: "Version tag of release"
+ docker_tag:
required: true
type: string
description: "Version tag for docker images"
@@ -57,34 +61,81 @@ jobs:
run: |
echo "docker-org=${{ github.repository_owner }}" >> "$GITHUB_ENV"
+ - name: Check Signer Release
+ id: check_signer_release
+ run: |
+ case "${{ inputs.tag }}" in
+ signer-*)
+ echo "is-signer-release=true" >> $GITHUB_ENV
+ ;;
+ *)
+ echo "is-signer-release=false" >> $GITHUB_ENV
+ ;;
+ esac
+
## Set docker metatdata
## - depending on the matrix.dist, different tags will be enabled
## ex. debian will have this tag: `type=ref,event=tag,enable=${{ matrix.dist == 'debian' }}`
- name: Docker Metadata ( ${{matrix.dist}} )
- id: docker_metadata
- uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 #v5.0.0
+ if: ${{ env.is-signer-release == 'true' }}
+ id: docker_metadata_signer
+ uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 #v5.5.1
+ with:
+ images: |
+ ${{env.docker-org}}/stacks-signer
+ tags: |
+ type=raw,value=latest,enable=${{ inputs.docker_tag != '' && (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) ) && matrix.dist == 'debian' }}
+ type=raw,value=${{ inputs.docker_tag }}-${{ matrix.dist }},enable=${{ inputs.docker_tag != '' && matrix.dist == 'debian'}}
+ type=raw,value=${{ inputs.docker_tag }},enable=${{ inputs.docker_tag != '' && matrix.dist == 'debian' }}
+ type=ref,event=tag,enable=${{ matrix.dist == 'debian' }}
+ type=raw,value=latest-${{ matrix.dist }},enable=${{ inputs.docker_tag != '' && (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) ) && matrix.dist == 'alpine' }}
+ type=raw,value=${{ inputs.docker_tag }}-${{ matrix.dist }},enable=${{ inputs.docker_tag != '' && matrix.dist == 'alpine' }}
+
+ - name: Docker Metadata ( ${{matrix.dist}} )
+ if: ${{ env.is-signer-release == 'false' }}
+ id: docker_metadata_node
+ uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 #v5.5.1
with:
## tag images with current repo name `stacks-core` as well as legacy `stacks-blockchain`
images: |
${{env.docker-org}}/${{ github.event.repository.name }}
${{env.docker-org}}/stacks-blockchain
tags: |
- type=raw,value=latest,enable=${{ inputs.tag != '' && (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) ) && matrix.dist == 'debian' }}
- type=raw,value=${{ inputs.tag }}-${{ matrix.dist }},enable=${{ inputs.tag != '' && matrix.dist == 'debian'}}
- type=raw,value=${{ inputs.tag }},enable=${{ inputs.tag != '' && matrix.dist == 'debian' }}
+ type=raw,value=latest,enable=${{ inputs.docker_tag != '' && (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) ) && matrix.dist == 'debian' }}
+ type=raw,value=${{ inputs.docker_tag }}-${{ matrix.dist }},enable=${{ inputs.docker_tag != '' && matrix.dist == 'debian'}}
+ type=raw,value=${{ inputs.docker_tag }},enable=${{ inputs.docker_tag != '' && matrix.dist == 'debian' }}
type=ref,event=tag,enable=${{ matrix.dist == 'debian' }}
- type=raw,value=latest-${{ matrix.dist }},enable=${{ inputs.tag != '' && (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) ) && matrix.dist == 'alpine' }}
- type=raw,value=${{ inputs.tag }}-${{ matrix.dist }},enable=${{ inputs.tag != '' && matrix.dist == 'alpine' }}
+ type=raw,value=latest-${{ matrix.dist }},enable=${{ inputs.docker_tag != '' && (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) ) && matrix.dist == 'alpine' }}
+ type=raw,value=${{ inputs.docker_tag }}-${{ matrix.dist }},enable=${{ inputs.docker_tag != '' && matrix.dist == 'alpine' }}
+
+ ## Build docker image for signer release
+ - name: Build and Push ( ${{matrix.dist}} )
+ if: ${{ env.is-signer-release == 'true' }}
+ id: docker_build_signer
+ uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0
+ with:
+ file: ./.github/actions/dockerfiles/Dockerfile.${{ matrix.dist }}-binary
+ platforms: ${{ env.docker_platforms }}
+ tags: ${{ steps.docker_metadata_signer.outputs.tags }}
+ labels: ${{ steps.docker_metadata_signer.outputs.labels }}
+ build-args: |
+ TAG=${{ inputs.tag }}
+ REPO=${{ github.repository_owner }}/${{ github.event.repository.name }}
+ STACKS_NODE_VERSION=${{ inputs.tag || env.GITHUB_SHA_SHORT }}
+ GIT_BRANCH=${{ env.GITHUB_REF_SHORT }}
+ GIT_COMMIT=${{ env.GITHUB_SHA_SHORT }}
+ push: ${{ env.DOCKER_PUSH }}
- ## Build docker image for release
+ ## Build docker image for node release
- name: Build and Push ( ${{matrix.dist}} )
- id: docker_build
- uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
+ if: ${{ env.is-signer-release == 'false' }}
+ id: docker_build_node
+ uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0
with:
file: ./.github/actions/dockerfiles/Dockerfile.${{ matrix.dist }}-binary
platforms: ${{ env.docker_platforms }}
- tags: ${{ steps.docker_metadata.outputs.tags }}
- labels: ${{ steps.docker_metadata.outputs.labels }}
+ tags: ${{ steps.docker_metadata_node.outputs.tags }}
+ labels: ${{ steps.docker_metadata_node.outputs.labels }}
build-args: |
TAG=${{ inputs.tag }}
REPO=${{ github.repository_owner }}/${{ github.event.repository.name }}
diff --git a/.github/workflows/image-build-source.yml b/.github/workflows/image-build-source.yml
index ebb9afc6790..e45455f05b6 100644
--- a/.github/workflows/image-build-source.yml
+++ b/.github/workflows/image-build-source.yml
@@ -49,7 +49,7 @@ jobs:
## Set docker metatdata
- name: Docker Metadata ( ${{matrix.dist}} )
id: docker_metadata
- uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 #v5.0.0
+ uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 #v5.5.1
with:
images: |
${{env.docker-org}}/${{ github.event.repository.name }}
@@ -61,7 +61,7 @@ jobs:
## Build docker image
- name: Build and Push ( ${{matrix.dist}} )
id: docker_build
- uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
+ uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0
with:
file: ./.github/actions/dockerfiles/Dockerfile.${{matrix.dist}}-source
platforms: ${{ env.docker_platforms }}
diff --git a/.github/workflows/lock-threads.yml b/.github/workflows/lock-threads.yml
new file mode 100644
index 00000000000..83b5a6b63f1
--- /dev/null
+++ b/.github/workflows/lock-threads.yml
@@ -0,0 +1,36 @@
+## Workflow to lock closed PRs/issues/discussions
+## timeframe to lock defaults to:
+## issues: 30 days
+## prs: 30 days
+## discussions: 365 days
+
+name: "Lock Threads"
+
+on:
+ schedule:
+ - cron: "0 0 * * *"
+ workflow_dispatch:
+
+permissions:
+ issues: write
+ pull-requests: write
+ discussions: write
+
+concurrency:
+ group: lock-threads
+
+jobs:
+ ## Lock closed issues/prs/discussions
+ lock:
+ name: Lock Threads
+ runs-on: ubuntu-latest
+ steps:
+ - name: Lock Threads
+ id: lock_threads
+ uses: stacks-network/actions/lock-threads@main
+ with:
+ github-token: ${{ secrets.GH_TOKEN }}
+ issue-inactive-days: 7
+ pr-inactive-days: 7
+ discussion-inactive-days: 7
+
diff --git a/.github/workflows/pr-differences-mutants.yml b/.github/workflows/pr-differences-mutants.yml
index fc4a7256873..788e4ccb520 100644
--- a/.github/workflows/pr-differences-mutants.yml
+++ b/.github/workflows/pr-differences-mutants.yml
@@ -9,6 +9,11 @@ on:
- ready_for_review
paths:
- '**.rs'
+ workflow_dispatch:
+ inputs:
+ automated:
+ description: "Set to 'false' to ignore mutants limit."
+ required: true
concurrency:
group: pr-differences-${{ github.head_ref || github.ref || github.run_id }}
@@ -33,7 +38,9 @@ jobs:
steps:
- id: check_packages_and_shards
- uses: stacks-network/actions/stacks-core/mutation-testing/check-packages-and-shards@main
+ uses: stacks-network/actions/stacks-core/mutation-testing/check-packages-and-shards@feat/mutation-testing
+ with:
+ automated: ${{ inputs.automated }}
# Mutation testing - Execute on PR on small packages that have functions modified (normal run, no shards)
pr-differences-mutants-small-normal:
@@ -49,7 +56,7 @@ jobs:
steps:
- name: Run mutants on diffs
- uses: stacks-network/actions/stacks-core/mutation-testing/pr-differences@main
+ uses: stacks-network/actions/stacks-core/mutation-testing/pr-differences@feat/mutation-testing
with:
package: 'small'
@@ -72,7 +79,7 @@ jobs:
steps:
- name: Run mutants on diffs
- uses: stacks-network/actions/stacks-core/mutation-testing/pr-differences@main
+ uses: stacks-network/actions/stacks-core/mutation-testing/pr-differences@feat/mutation-testing
with:
shard: ${{ matrix.shard }}
package: 'small'
@@ -94,7 +101,7 @@ jobs:
env:
BITCOIND_TEST: 1
RUST_BACKTRACE: full
- uses: stacks-network/actions/stacks-core/mutation-testing/pr-differences@main
+ uses: stacks-network/actions/stacks-core/mutation-testing/pr-differences@feat/mutation-testing
with:
package: 'stackslib'
@@ -120,7 +127,7 @@ jobs:
env:
BITCOIND_TEST: 1
RUST_BACKTRACE: full
- uses: stacks-network/actions/stacks-core/mutation-testing/pr-differences@main
+ uses: stacks-network/actions/stacks-core/mutation-testing/pr-differences@feat/mutation-testing
with:
shard: ${{ matrix.shard }}
package: 'stackslib'
@@ -142,7 +149,7 @@ jobs:
env:
BITCOIND_TEST: 1
RUST_BACKTRACE: full
- uses: stacks-network/actions/stacks-core/mutation-testing/pr-differences@main
+ uses: stacks-network/actions/stacks-core/mutation-testing/pr-differences@feat/mutation-testing
with:
package: 'stacks-node'
@@ -168,7 +175,7 @@ jobs:
env:
BITCOIND_TEST: 1
RUST_BACKTRACE: full
- uses: stacks-network/actions/stacks-core/mutation-testing/pr-differences@main
+ uses: stacks-network/actions/stacks-core/mutation-testing/pr-differences@feat/mutation-testing
with:
shard: ${{ matrix.shard }}
package: 'stacks-node'
@@ -186,7 +193,7 @@ jobs:
steps:
- name: Run mutants on diffs
- uses: stacks-network/actions/stacks-core/mutation-testing/pr-differences@main
+ uses: stacks-network/actions/stacks-core/mutation-testing/pr-differences@feat/mutation-testing
with:
package: 'stacks-signer'
@@ -211,7 +218,7 @@ jobs:
steps:
- name: Output Mutants
- uses: stacks-network/actions/stacks-core/mutation-testing/output-pr-mutants@main
+ uses: stacks-network/actions/stacks-core/mutation-testing/output-pr-mutants@feat/mutation-testing
with:
stackslib_package: ${{ needs.check-big-packages-and-shards.outputs.run_stackslib }}
shards_for_stackslib_package: ${{ needs.check-big-packages-and-shards.outputs.stackslib_with_shards }}
diff --git a/.github/workflows/slow-tests.yml b/.github/workflows/slow-tests.yml
index bce6a15a1f0..02c5bdf552d 100644
--- a/.github/workflows/slow-tests.yml
+++ b/.github/workflows/slow-tests.yml
@@ -32,6 +32,7 @@ jobs:
test-name:
- tests::epoch_21::test_pox_reorg_flap_duel
- tests::epoch_21::test_pox_reorg_flap_reward_cycles
+ - tests::nakamoto_integrations::check_block_info_rewards
steps:
## Setup test environment
- name: Setup Test Environment
diff --git a/.github/workflows/stacks-core-tests.yml b/.github/workflows/stacks-core-tests.yml
index 3195f279fcb..98eb5cf92c0 100644
--- a/.github/workflows/stacks-core-tests.yml
+++ b/.github/workflows/stacks-core-tests.yml
@@ -127,7 +127,7 @@ jobs:
## checkout the code
- name: Checkout the latest code
id: git_checkout
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
+ uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Run network relay tests
id: nettest
@@ -145,10 +145,10 @@ jobs:
steps:
- name: Checkout the latest code
id: git_checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Execute core contract unit tests with clarinet-sdk
id: clarinet_unit_test
- uses: actions/setup-node@v3
+ uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 18.x
cache: "npm"
@@ -174,7 +174,7 @@ jobs:
steps:
- name: Checkout the latest code
id: git_checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Execute core contract unit tests in Clarinet
id: clarinet_unit_test_v1
uses: docker://hirosystems/clarinet:1.7.1
@@ -187,7 +187,6 @@ jobs:
if: always()
needs:
- full-genesis
- - unit-tests
- open-api-validation
- core-contracts-clarinet-test
steps:
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index be7e11c2a88..00035443cbf 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -2,7 +2,7 @@
"recommendations": [
"rust-lang.rust-analyzer",
"vadimcn.vscode-lldb",
- "serayuzgur.crates",
+ "fill-labs.dependi",
"editorconfig.editorconfig",
]
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c318efebc87..eb6061cb9d4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,62 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to the versioning scheme outlined in the [README.md](README.md).
+## [Unreleased]
+
+- Added support for Clarity 3
+ - Keywords / variable
+ - `tenure-height` added
+ - `stacks-block-height` added
+ - `block-height` removed
+ - Functions
+ - `get-stacks-block-info?` added
+ - `get-tenure-info?` added
+ - `get-block-info?` removed
+
+## [2.5.0.0.5]
+
+### Added
+
+- Added configuration option `connections.antientropy_retry` (#4932)
+
+### Changed
+
+- Set default antientropy_retry to run once per hour (#4935)
+
+## [2.5.0.0.4]
+
+### Added
+
+- Adds the solo stacking scenarios to the stateful property-based testing strategy for PoX-4 (#4725)
+- Add signer-key to synthetic stack-aggregation-increase event (#4728)
+- Implement the assumed total commit with carry-over (ATC-C) strategy for denying opportunistic Bitcoin miners from mining Stacks at a discount (#4733)
+- Adding support for stacks-block-height and tenure-height in Clarity 3 (#4745)
+- Preserve PeerNetwork struct when transitioning to 3.0 (#4767)
+- Implement singer monitor server error (#4773)
+- Pull current stacks signer out into v1 implementation and create placeholder v0 mod (#4778)
+- Create new block signature message type for v0 signer (#4787)
+- Isolate the rusqlite dependency in stacks-common and clarity behind a cargo feature (#4791)
+- Add next_initiative_delay config option to control how frequently the miner checks if a new burnchain block has been processed (#4795)
+- Various performance improvements and cleanup
+
+### Changed
+
+- Downgraded log messages about transactions from warning to info (#4697)
+- Fix race condition between the signer binary and the /v2/pox endpoint (#4738)
+- Make node config mock_miner item hot-swappable (#4743)
+- Mandates that a burnchain block header be resolved by a BurnchainHeaderReader, which will resolve a block height to at most one burnchain header (#4748)
+- Optional config option to resolve DNS of bootstrap nodes (#4749)
+- Limit inventory syncs with new peers (#4750)
+- Update /v2/fees/transfer to report the median transaction fee estimate for a STX-transfer of 180 bytes (#4754)
+- Reduce connection spamming in stackerdb (#4759)
+- Remove deprecated signer cli commands (#4772)
+- Extra pair of signer slots got introduced at the epoch 2.5 boundary (#4845, #4868, #4891)
+- Never consider Stacks chain tips that are not on the canonical burn chain #4886 (#4893)
+
+### Fixed
+
+- Allow Nakamoto blocks to access the burn block associated with the current tenure (#4333)
+
## [2.5.0.0.3]
This release fixes a regression in `2.5.0.0.0` from `2.4.0.1.0` caused by git merge
@@ -22,7 +78,6 @@ This is the first consensus-critical release for Nakamoto. Nodes which do not up
**This is a required release before Nakamoto rules are enabled in 3.0.**
-
### Timing of Release from 2.5 to 3.0
Activating Nakamoto will include two epochs:
diff --git a/CODEOWNERS b/CODEOWNERS
new file mode 100644
index 00000000000..b30973662f6
--- /dev/null
+++ b/CODEOWNERS
@@ -0,0 +1,20 @@
+# These owners will be the default owners for everything in
+# the repo. Unless a later match takes precedence,
+# @stacks-network/blockchain-team-codeowners will be requested for
+# review when someone opens a pull request.
+* @stacks-network/blockchain-team-codeowners
+
+# Generic file extensions that shouldn't require much scrutiny. Anyone with write access to the repo may approve a PR
+*.md @stacks-network/blockchain-team
+*.yml @stacks-network/blockchain-team
+*.yaml @stacks-network/blockchain-team
+*.txt @stacks-network/blockchain-team
+*.toml @stacks-network/blockchain-team
+
+# Signer code
+libsigner/**/*.rs @stacks-network/blockchain-team-signer
+stacks-signer/**/*.rs @stacks-network/blockchain-team-signer
+
+# CI workflows
+/.github/workflows/ @stacks-network/blockchain-team-ci
+/.github/actions/ @stacks-network/blockchain-team-ci
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 7609cba29f7..5bdfbfc8eac 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -43,6 +43,11 @@ Branch names should use a prefix that conveys the overall goal of the branch:
- `test/more-coverage` for branches that only add more tests
- `refactor/formatting-fix` for refactors
+The branch suffix must only include ASCII lowercase and uppercase letters,
+digits, underscores, periods and dashes.
+
+The full branch name must be max 128 characters long.
+
### Merging PRs from Forks
PRs from forks or opened by contributors without commit access require
diff --git a/Cargo.lock b/Cargo.lock
index 9cfd1ad9a1e..357a9def709 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -112,12 +112,6 @@ dependencies = [
"opaque-debug",
]
-[[package]]
-name = "ahash"
-version = "0.4.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0453232ace82dee0dd0b4c87a59bd90f7b53b314f3e0f61fe2ee7c8a16482289"
-
[[package]]
name = "ahash"
version = "0.8.8"
@@ -717,7 +711,7 @@ name = "clarity"
version = "0.0.1"
dependencies = [
"assert-json-diff",
- "hashbrown 0.14.3",
+ "hashbrown",
"integer-sqrt",
"lazy_static",
"mutants",
@@ -1188,9 +1182,9 @@ dependencies = [
[[package]]
name = "fallible-iterator"
-version = "0.2.0"
+version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
+checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
[[package]]
name = "fallible-streaming-iterator"
@@ -1495,33 +1489,24 @@ version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
-[[package]]
-name = "hashbrown"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
-dependencies = [
- "ahash 0.4.8",
-]
-
[[package]]
name = "hashbrown"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
dependencies = [
- "ahash 0.8.8",
+ "ahash",
"allocator-api2",
"serde",
]
[[package]]
name = "hashlink"
-version = "0.6.0"
+version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d99cf782f0dc4372d26846bec3de7804ceb5df083c2d4462c0b8d2330e894fa8"
+checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af"
dependencies = [
- "hashbrown 0.9.1",
+ "hashbrown",
]
[[package]]
@@ -1758,7 +1743,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177"
dependencies = [
"equivalent",
- "hashbrown 0.14.3",
+ "hashbrown",
]
[[package]]
@@ -1920,9 +1905,12 @@ name = "libsigner"
version = "0.0.1"
dependencies = [
"clarity",
- "hashbrown 0.14.3",
+ "hashbrown",
+ "lazy_static",
"libc",
"libstackerdb",
+ "mutants",
+ "prometheus",
"rand 0.8.5",
"rand_core 0.6.4",
"secp256k1",
@@ -1943,9 +1931,9 @@ dependencies = [
[[package]]
name = "libsqlite3-sys"
-version = "0.20.1"
+version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64d31059f22935e6c31830db5249ba2b7ecd54fd73a9909286f0a67aa55c2fbd"
+checksum = "0c10584274047cb335c23d3e61bcef8e323adae7c5c8c760540f73610177fc3f"
dependencies = [
"cc",
"pkg-config",
@@ -2446,6 +2434,7 @@ name = "pox-locking"
version = "2.4.0"
dependencies = [
"clarity",
+ "mutants",
"slog",
"stacks-common",
]
@@ -2718,7 +2707,7 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
name = "relay-server"
version = "0.0.1"
dependencies = [
- "hashbrown 0.14.3",
+ "hashbrown",
]
[[package]]
@@ -2870,17 +2859,15 @@ dependencies = [
[[package]]
name = "rusqlite"
-version = "0.24.2"
+version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5f38ee71cbab2c827ec0ac24e76f82eca723cee92c509a65f67dee393c25112"
+checksum = "b838eba278d213a8beaf485bd313fd580ca4505a00d5871caeb1457c55322cae"
dependencies = [
- "bitflags 1.3.2",
- "byteorder",
+ "bitflags 2.4.2",
"fallible-iterator",
"fallible-streaming-iterator",
"hashlink",
"libsqlite3-sys",
- "memchr",
"serde_json",
"smallvec",
]
@@ -3291,7 +3278,7 @@ dependencies = [
"serde",
"serde_json",
"slog",
- "time 0.3.34",
+ "time 0.3.36",
]
[[package]]
@@ -3304,7 +3291,7 @@ dependencies = [
"slog",
"term",
"thread_local",
- "time 0.3.34",
+ "time 0.3.36",
]
[[package]]
@@ -3376,7 +3363,7 @@ dependencies = [
"chrono",
"curve25519-dalek 2.0.0",
"ed25519-dalek",
- "hashbrown 0.14.3",
+ "hashbrown",
"lazy_static",
"libc",
"nix",
@@ -3412,7 +3399,7 @@ dependencies = [
"base64 0.12.3",
"chrono",
"clarity",
- "hashbrown 0.14.3",
+ "hashbrown",
"http-types",
"lazy_static",
"libc",
@@ -3449,11 +3436,13 @@ dependencies = [
"backoff",
"clap 4.5.0",
"clarity",
- "hashbrown 0.14.3",
+ "hashbrown",
+ "lazy_static",
"libsigner",
"libstackerdb",
"num-traits",
"polynomial",
+ "prometheus",
"rand 0.8.5",
"rand_core 0.6.4",
"reqwest",
@@ -3469,6 +3458,7 @@ dependencies = [
"stacks-common",
"stackslib",
"thiserror",
+ "tiny_http",
"toml 0.5.11",
"tracing",
"tracing-subscriber",
@@ -3486,7 +3476,7 @@ dependencies = [
"criterion",
"curve25519-dalek 2.0.0",
"ed25519-dalek",
- "hashbrown 0.14.3",
+ "hashbrown",
"integer-sqrt",
"lazy_static",
"libc",
@@ -3770,9 +3760,9 @@ dependencies = [
[[package]]
name = "time"
-version = "0.3.34"
+version = "0.3.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749"
+checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
dependencies = [
"deranged",
"itoa",
@@ -3782,7 +3772,7 @@ dependencies = [
"powerfmt",
"serde",
"time-core",
- "time-macros 0.2.17",
+ "time-macros 0.2.18",
]
[[package]]
@@ -3803,9 +3793,9 @@ dependencies = [
[[package]]
name = "time-macros"
-version = "0.2.17"
+version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774"
+checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
dependencies = [
"num-conv",
"time-core",
@@ -4604,7 +4594,7 @@ checksum = "9c80d57a61294350ed91e91eb20a6c34da084ec8f15d039bab79ce3efabbd1a4"
dependencies = [
"aes-gcm 0.10.3",
"bs58 0.5.0",
- "hashbrown 0.14.3",
+ "hashbrown",
"hex",
"num-traits",
"p256k1",
diff --git a/Cargo.toml b/Cargo.toml
index feab983833c..8ac168f1f7e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -21,6 +21,7 @@ rand = "0.8"
rand_chacha = "0.3.1"
tikv-jemallocator = "0.5.4"
wsts = { version = "9.0.0", default-features = false }
+rusqlite = { version = "0.31.0", features = ["blob", "serde_json", "i128_blob", "bundled", "trace"] }
# Use a bit more than default optimization for
# dev builds to speed up test execution
diff --git a/Dockerfile b/Dockerfile
index 055cc3df764..5cfacc8ab08 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -12,7 +12,7 @@ RUN apk add --no-cache musl-dev
RUN mkdir /out
-RUN cd testnet/stacks-node && cargo build --features monitoring_prom,slog_json --release
+RUN cargo build --features monitoring_prom,slog_json --release
RUN cp target/release/stacks-node /out
diff --git a/Dockerfile.debian b/Dockerfile.debian
index 8b6759527ed..ce219640391 100644
--- a/Dockerfile.debian
+++ b/Dockerfile.debian
@@ -10,7 +10,7 @@ COPY . .
RUN mkdir /out
-RUN cd testnet/stacks-node && cargo build --features monitoring_prom,slog_json --release
+RUN cargo build --features monitoring_prom,slog_json --release
RUN cp target/release/stacks-node /out
diff --git a/README.md b/README.md
index 3f91b1a9f21..6cdb42857f4 100644
--- a/README.md
+++ b/README.md
@@ -55,7 +55,7 @@ _Note on building_: you may set `RUSTFLAGS` to build binaries for your native cp
RUSTFLAGS="-Ctarget-cpu=native"
```
-or uncomment these lines in `./cargo/config`:
+or uncomment these lines in `./cargo/config.toml`:
```
# [build]
@@ -87,7 +87,7 @@ cd testnet/stacks-node
cargo run --bin stacks-node -- start --config ./conf/testnet-follower-conf.toml
```
-_On Windows, many tests will fail if the line endings aren't `LF`. Please ensure that you are have git's `core.autocrlf` set to `input` when you clone the repository to avoid any potential issues. This is due to the Clarity language currently being sensitive to line endings._
+_On Windows, many tests will fail if the line endings aren't `LF`. Please ensure that you have git's `core.autocrlf` set to `input` when you clone the repository to avoid any potential issues. This is due to the Clarity language currently being sensitive to line endings._
Additional testnet documentation is available [here](./docs/testnet.md) and [here](https://docs.stacks.co/docs/nodes-and-miners/miner-testnet)
diff --git a/clarity/Cargo.toml b/clarity/Cargo.toml
index 70cbcec5857..284e856e498 100644
--- a/clarity/Cargo.toml
+++ b/clarity/Cargo.toml
@@ -27,33 +27,33 @@ regex = "1"
lazy_static = "1.4.0"
integer-sqrt = "0.1.3"
slog = { version = "2.5.2", features = [ "max_level_trace" ] }
-stacks_common = { package = "stacks-common", path = "../stacks-common" }
+stacks_common = { package = "stacks-common", path = "../stacks-common", optional = true, default-features = false }
rstest = "0.17.0"
rstest_reuse = "0.5.0"
hashbrown = { workspace = true }
-mutants = "0.0.3"
+rusqlite = { workspace = true, optional = true}
[dependencies.serde_json]
version = "1.0"
features = ["arbitrary_precision", "unbounded_depth"]
-[dependencies.rusqlite]
-version = "=0.24.2"
-features = ["blob", "serde_json", "i128_blob", "bundled", "trace"]
-
[dependencies.time]
version = "0.2.23"
features = ["std"]
[dev-dependencies]
assert-json-diff = "1.0.0"
+mutants = "0.0.3"
# a nightly rustc regression (35dbef235 2021-03-02) prevents criterion from compiling
# but it isn't necessary for tests: only benchmarks. therefore, commenting out for now.
# criterion = "0.3"
[features]
-default = []
-developer-mode = []
+default = ["canonical"]
+canonical = ["rusqlite", "stacks_common/canonical"]
+developer-mode = ["stacks_common/developer-mode"]
slog_json = ["stacks_common/slog_json"]
-testing = []
+testing = ["canonical"]
devtools = []
+rollback_value_check = []
+disable-costs = []
diff --git a/clarity/src/vm/analysis/arithmetic_checker/mod.rs b/clarity/src/vm/analysis/arithmetic_checker/mod.rs
index 5595905a484..aa69f650f01 100644
--- a/clarity/src/vm/analysis/arithmetic_checker/mod.rs
+++ b/clarity/src/vm/analysis/arithmetic_checker/mod.rs
@@ -148,7 +148,7 @@ impl<'a> ArithmeticOnlyChecker<'a> {
{
match native_var {
ContractCaller | TxSender | TotalLiquidMicroSTX | BlockHeight | BurnBlockHeight
- | Regtest | TxSponsor | Mainnet | ChainId => {
+ | Regtest | TxSponsor | Mainnet | ChainId | StacksBlockHeight | TenureHeight => {
Err(Error::VariableForbidden(native_var))
}
NativeNone | NativeTrue | NativeFalse => Ok(()),
@@ -174,13 +174,12 @@ impl<'a> ArithmeticOnlyChecker<'a> {
) -> Result<(), Error> {
use crate::vm::functions::NativeFunctions::*;
match function {
- FetchVar | GetBlockInfo | GetBurnBlockInfo | GetTokenBalance | GetAssetOwner
- | FetchEntry | SetEntry | DeleteEntry | InsertEntry | SetVar | MintAsset
- | MintToken | TransferAsset | TransferToken | ContractCall | StxTransfer
- | StxTransferMemo | StxBurn | AtBlock | GetStxBalance | GetTokenSupply | BurnToken
- | FromConsensusBuff | ToConsensusBuff | BurnAsset | StxGetAccount => {
- Err(Error::FunctionNotPermitted(function))
- }
+ FetchVar | GetBlockInfo | GetBurnBlockInfo | GetStacksBlockInfo | GetTenureInfo
+ | GetTokenBalance | GetAssetOwner | FetchEntry | SetEntry | DeleteEntry
+ | InsertEntry | SetVar | MintAsset | MintToken | TransferAsset | TransferToken
+ | ContractCall | StxTransfer | StxTransferMemo | StxBurn | AtBlock | GetStxBalance
+ | GetTokenSupply | BurnToken | FromConsensusBuff | ToConsensusBuff | BurnAsset
+ | StxGetAccount => Err(Error::FunctionNotPermitted(function)),
Append | Concat | AsMaxLen | ContractOf | PrincipalOf | ListCons | Print
| AsContract | ElementAt | ElementAtAlias | IndexOf | IndexOfAlias | Map | Filter
| Fold | Slice | ReplaceAt => Err(Error::FunctionNotPermitted(function)),
diff --git a/clarity/src/vm/analysis/arithmetic_checker/tests.rs b/clarity/src/vm/analysis/arithmetic_checker/tests.rs
index 4ad02c08d5e..0e7d520cb3b 100644
--- a/clarity/src/vm/analysis/arithmetic_checker/tests.rs
+++ b/clarity/src/vm/analysis/arithmetic_checker/tests.rs
@@ -22,12 +22,13 @@ use stacks_common::types::StacksEpochId;
use crate::vm::analysis::arithmetic_checker::Error::*;
use crate::vm::analysis::arithmetic_checker::{ArithmeticOnlyChecker, Error};
-use crate::vm::analysis::{mem_type_check, ContractAnalysis};
+use crate::vm::analysis::ContractAnalysis;
use crate::vm::ast::parse;
use crate::vm::costs::LimitedCostTracker;
use crate::vm::functions::define::DefineFunctions;
use crate::vm::functions::NativeFunctions;
use crate::vm::tests::test_clarity_versions;
+use crate::vm::tooling::mem_type_check;
use crate::vm::types::QualifiedContractIdentifier;
use crate::vm::variables::NativeVariables;
use crate::vm::ClarityVersion;
diff --git a/clarity/src/vm/analysis/errors.rs b/clarity/src/vm/analysis/errors.rs
index 71fefb64571..f86308f8d9c 100644
--- a/clarity/src/vm/analysis/errors.rs
+++ b/clarity/src/vm/analysis/errors.rs
@@ -132,10 +132,15 @@ pub enum CheckErrors {
// get-block-info? errors
NoSuchBlockInfoProperty(String),
NoSuchBurnBlockInfoProperty(String),
+ NoSuchStacksBlockInfoProperty(String),
+ NoSuchTenureInfoProperty(String),
GetBlockInfoExpectPropertyName,
GetBurnBlockInfoExpectPropertyName,
+ GetStacksBlockInfoExpectPropertyName,
+ GetTenureInfoExpectPropertyName,
NameAlreadyUsed(String),
+ ReservedWord(String),
// expect a function, or applying a function to a list
NonFunctionApplication,
@@ -405,9 +410,14 @@ impl DiagnosableError for CheckErrors {
CheckErrors::ExpectedCallableType(found_type) => format!("expected a callable contract, found {}", found_type),
CheckErrors::NoSuchBlockInfoProperty(property_name) => format!("use of block unknown property '{}'", property_name),
CheckErrors::NoSuchBurnBlockInfoProperty(property_name) => format!("use of burn block unknown property '{}'", property_name),
+ CheckErrors::NoSuchStacksBlockInfoProperty(property_name) => format!("use of unknown stacks block property '{}'", property_name),
+ CheckErrors::NoSuchTenureInfoProperty(property_name) => format!("use of unknown tenure property '{}'", property_name),
CheckErrors::GetBlockInfoExpectPropertyName => "missing property name for block info introspection".into(),
CheckErrors::GetBurnBlockInfoExpectPropertyName => "missing property name for burn block info introspection".into(),
+ CheckErrors::GetStacksBlockInfoExpectPropertyName => "missing property name for stacks block info introspection".into(),
+ CheckErrors::GetTenureInfoExpectPropertyName => "missing property name for tenure info introspection".into(),
CheckErrors::NameAlreadyUsed(name) => format!("defining '{}' conflicts with previous value", name),
+ CheckErrors::ReservedWord(name) => format!("{name} is a reserved word"),
CheckErrors::NonFunctionApplication => "expecting expression of type function".into(),
CheckErrors::ExpectedListApplication => "expecting expression of type list".into(),
CheckErrors::ExpectedSequence(found_type) => format!("expecting expression of type 'list', 'buff', 'string-ascii' or 'string-utf8' - found '{}'", found_type),
diff --git a/clarity/src/vm/analysis/mod.rs b/clarity/src/vm/analysis/mod.rs
index 4da10f88bf9..6a8f64f1b26 100644
--- a/clarity/src/vm/analysis/mod.rs
+++ b/clarity/src/vm/analysis/mod.rs
@@ -37,12 +37,15 @@ use self::type_checker::v2_1::TypeChecker as TypeChecker2_1;
pub use self::types::{AnalysisPass, ContractAnalysis};
use crate::vm::ast::{build_ast_with_rules, ASTRules};
use crate::vm::costs::LimitedCostTracker;
-use crate::vm::database::{MemoryBackingStore, STORE_CONTRACT_SRC_INTERFACE};
+#[cfg(feature = "canonical")]
+use crate::vm::database::MemoryBackingStore;
+use crate::vm::database::STORE_CONTRACT_SRC_INTERFACE;
use crate::vm::representations::SymbolicExpression;
use crate::vm::types::{QualifiedContractIdentifier, TypeSignature};
use crate::vm::ClarityVersion;
/// Used by CLI tools like the docs generator. Not used in production
+#[cfg(feature = "canonical")]
pub fn mem_type_check(
snippet: &str,
version: ClarityVersion,
diff --git a/clarity/src/vm/analysis/read_only_checker/mod.rs b/clarity/src/vm/analysis/read_only_checker/mod.rs
index b02923c1a1a..006b4f0cfe6 100644
--- a/clarity/src/vm/analysis/read_only_checker/mod.rs
+++ b/clarity/src/vm/analysis/read_only_checker/mod.rs
@@ -290,10 +290,11 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> {
| BuffToUIntBe | IntToAscii | IntToUtf8 | StringToInt | StringToUInt | IsStandard
| ToConsensusBuff | PrincipalDestruct | PrincipalConstruct | Append | Concat
| AsMaxLen | ContractOf | PrincipalOf | ListCons | GetBlockInfo | GetBurnBlockInfo
- | TupleGet | TupleMerge | Len | Print | AsContract | Begin | FetchVar
- | GetStxBalance | StxGetAccount | GetTokenBalance | GetAssetOwner | GetTokenSupply
- | ElementAt | IndexOf | Slice | ReplaceAt | BitwiseAnd | BitwiseOr | BitwiseNot
- | BitwiseLShift | BitwiseRShift | BitwiseXor2 | ElementAtAlias | IndexOfAlias => {
+ | GetStacksBlockInfo | GetTenureInfo | TupleGet | TupleMerge | Len | Print
+ | AsContract | Begin | FetchVar | GetStxBalance | StxGetAccount | GetTokenBalance
+ | GetAssetOwner | GetTokenSupply | ElementAt | IndexOf | Slice | ReplaceAt
+ | BitwiseAnd | BitwiseOr | BitwiseNot | BitwiseLShift | BitwiseRShift | BitwiseXor2
+ | ElementAtAlias | IndexOfAlias => {
// Check all arguments.
self.check_each_expression_is_read_only(args)
}
diff --git a/clarity/src/vm/analysis/tests/mod.rs b/clarity/src/vm/analysis/tests/mod.rs
index adb36b94fbd..2484ee86cd3 100644
--- a/clarity/src/vm/analysis/tests/mod.rs
+++ b/clarity/src/vm/analysis/tests/mod.rs
@@ -14,10 +14,15 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+use stacks_common::types::StacksEpochId;
+
use crate::vm::analysis::errors::CheckErrors;
use crate::vm::analysis::type_checker::v2_1::tests::mem_type_check;
-use crate::vm::analysis::{type_check, AnalysisDatabase, ContractAnalysis};
+use crate::vm::analysis::{
+ mem_type_check as mem_run_analysis, type_check, AnalysisDatabase, ContractAnalysis,
+};
use crate::vm::ast::parse;
+use crate::vm::ClarityVersion;
#[test]
fn test_list_types_must_match() {
@@ -202,18 +207,87 @@ fn test_contract_call_expect_name() {
#[test]
fn test_no_such_block_info_property() {
let snippet = "(get-block-info? unicorn 1)";
- let err = mem_type_check(snippet).unwrap_err();
+ let err =
+ mem_run_analysis(snippet, ClarityVersion::Clarity2, StacksEpochId::latest()).unwrap_err();
assert!(format!("{}", err.diagnostic).contains("use of block unknown property 'unicorn'"));
}
+#[test]
+fn test_no_such_stacks_block_info_property() {
+ let snippet = "(get-stacks-block-info? unicorn 1)";
+ let err =
+ mem_run_analysis(snippet, ClarityVersion::Clarity3, StacksEpochId::latest()).unwrap_err();
+ assert!(
+ format!("{}", err.diagnostic).contains("use of unknown stacks block property 'unicorn'")
+ );
+}
+
+#[test]
+fn test_no_such_tenure_info_property() {
+ let snippet = "(get-tenure-info? unicorn 1)";
+ let err =
+ mem_run_analysis(snippet, ClarityVersion::Clarity3, StacksEpochId::latest()).unwrap_err();
+ assert!(format!("{}", err.diagnostic).contains("use of unknown tenure property 'unicorn'"));
+}
+
#[test]
fn test_get_block_info_expect_property_name() {
let snippet = "(get-block-info? 0 1)";
- let err = mem_type_check(snippet).unwrap_err();
+ let err =
+ mem_run_analysis(snippet, ClarityVersion::Clarity2, StacksEpochId::latest()).unwrap_err();
assert!(format!("{}", err.diagnostic)
.contains("missing property name for block info introspection"));
}
+#[test]
+fn test_get_stacks_block_info_expect_property_name() {
+ let snippet = "(get-stacks-block-info? 0 1)";
+ let err =
+ mem_run_analysis(snippet, ClarityVersion::Clarity3, StacksEpochId::latest()).unwrap_err();
+ assert!(format!("{}", err.diagnostic)
+ .contains("missing property name for stacks block info introspection"));
+}
+
+#[test]
+fn test_get_tenure_info_expect_property_name() {
+ let snippet = "(get-tenure-info? 0 1)";
+ let err =
+ mem_run_analysis(snippet, ClarityVersion::Clarity3, StacksEpochId::latest()).unwrap_err();
+ assert!(format!("{}", err.diagnostic)
+ .contains("missing property name for tenure info introspection"));
+}
+
+#[test]
+fn test_no_such_block_info_height() {
+ let snippet = "(get-block-info? time 1)";
+ let err =
+ mem_run_analysis(snippet, ClarityVersion::Clarity2, StacksEpochId::latest()).unwrap_err();
+ println!("{}", err.diagnostic);
+ assert!(
+ format!("{}", err.diagnostic).contains("expecting expression of type 'uint', found 'int'")
+ );
+}
+
+#[test]
+fn test_no_such_stacks_block_info_height() {
+ let snippet = "(get-stacks-block-info? time 1)";
+ let err =
+ mem_run_analysis(snippet, ClarityVersion::Clarity3, StacksEpochId::latest()).unwrap_err();
+ assert!(
+ format!("{}", err.diagnostic).contains("expecting expression of type 'uint', found 'int'")
+ );
+}
+
+#[test]
+fn test_no_such_tenure_info_height() {
+ let snippet = "(get-tenure-info? time 1)";
+ let err =
+ mem_run_analysis(snippet, ClarityVersion::Clarity3, StacksEpochId::latest()).unwrap_err();
+ assert!(
+ format!("{}", err.diagnostic).contains("expecting expression of type 'uint', found 'int'")
+ );
+}
+
#[test]
fn test_name_already_used() {
let snippet = "(define-constant var1 true) (define-constant var1 1)";
diff --git a/clarity/src/vm/analysis/trait_checker/tests.rs b/clarity/src/vm/analysis/trait_checker/tests.rs
index bc3f9962841..b1d9bdb2228 100644
--- a/clarity/src/vm/analysis/trait_checker/tests.rs
+++ b/clarity/src/vm/analysis/trait_checker/tests.rs
@@ -1463,7 +1463,7 @@ fn test_dynamic_dispatch_pass_bound_principal_as_trait_in_user_defined_functions
_ => panic!("{:?}", err),
};
}
- Ok(_) if version == ClarityVersion::Clarity2 => (),
+ Ok(_) if version >= ClarityVersion::Clarity2 => (),
_ => panic!("got {:?}", result),
}
}
diff --git a/clarity/src/vm/analysis/type_checker/mod.rs b/clarity/src/vm/analysis/type_checker/mod.rs
index c8185dde74e..800347d0f01 100644
--- a/clarity/src/vm/analysis/type_checker/mod.rs
+++ b/clarity/src/vm/analysis/type_checker/mod.rs
@@ -84,3 +84,21 @@ impl FunctionType {
}
}
}
+
+fn is_reserved_word_v3(word: &str) -> bool {
+ match word {
+ "block-height" => true,
+ _ => false,
+ }
+}
+
+/// Is this a reserved word that should trigger an analysis error for the given
+/// Clarity version? Note that most of the reserved words do not trigger an
+/// analysis error, but will trigger an error at runtime. This should likely be
+/// changed in a future Clarity version.
+pub fn is_reserved_word(word: &str, version: ClarityVersion) -> bool {
+ match version {
+ ClarityVersion::Clarity1 | ClarityVersion::Clarity2 => false,
+ ClarityVersion::Clarity3 => is_reserved_word_v3(word),
+ }
+}
diff --git a/clarity/src/vm/analysis/type_checker/v2_05/mod.rs b/clarity/src/vm/analysis/type_checker/v2_05/mod.rs
index d66cad5d4ee..2b913a3ac9c 100644
--- a/clarity/src/vm/analysis/type_checker/v2_05/mod.rs
+++ b/clarity/src/vm/analysis/type_checker/v2_05/mod.rs
@@ -323,9 +323,9 @@ fn type_reserved_variable(variable_name: &str) -> CheckResult