diff --git a/.github/actionlint.yml b/.github/actionlint.yml index 62bee747e6f..9ffc000795d 100644 --- a/.github/actionlint.yml +++ b/.github/actionlint.yml @@ -1,4 +1,4 @@ self-hosted-runner: labels: - - custom-arm64-focal - custom-arm64-jammy + - custom-arm64-noble diff --git a/.github/actions/install-focal-deps/action.yml b/.github/actions/install-focal-deps/action.yml deleted file mode 100644 index 0770ca11a6d..00000000000 --- a/.github/actions/install-focal-deps/action.yml +++ /dev/null @@ -1,16 +0,0 @@ -# This action installs dependencies missing from the default -# focal image used by arm64 github workers. -# -# TODO(marun): Find an image with the required dependencies already installed. - -name: 'Install focal arm64 dependencies' -description: 'Installs the dependencies required to build avalanchego on an arm64 github worker running Ubuntu 20.04 (focal)' - -runs: - using: composite - steps: - - name: Install build-essential - run: | - sudo apt update - sudo apt -y install build-essential - shell: bash diff --git a/.github/packer/clean-public-ami.sh b/.github/packer/clean-public-ami.sh deleted file mode 100644 index 4fa50733a18..00000000000 --- a/.github/packer/clean-public-ami.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -echo "Clearing out public ssh keys" - -rm -f /root/.ssh/authorized_keys -rm -f /home/ubuntu/.ssh/authorized_keys diff --git a/.github/packer/create_public_ami.yml b/.github/packer/create_public_ami.yml deleted file mode 100644 index 409b4b30459..00000000000 --- a/.github/packer/create_public_ami.yml +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env ansible-playbook ---- -- name: Create a public AMI image for AWS Marketplace - connection: ssh - gather_facts: false - become: yes - hosts: all - roles: - - name: public-ami diff --git a/.github/packer/roles/public-ami/defaults/main.yml b/.github/packer/roles/public-ami/defaults/main.yml deleted file mode 100644 index 7e5e95f7980..00000000000 --- a/.github/packer/roles/public-ami/defaults/main.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -ava_user: avalanche -ava_group: admin -ava_uid: 1014 -network: mainnet -db_dir: /data/avalanchego -log_dir: /var/log/avalanchego -config_dir: /etc/avalanchego -repo_url: https://github.com/ava-labs/avalanchego -repo_folder: /tmp/avalanchego diff --git a/.github/packer/roles/public-ami/tasks/main.yml b/.github/packer/roles/public-ami/tasks/main.yml deleted file mode 100644 index dad871e1de7..00000000000 --- a/.github/packer/roles/public-ami/tasks/main.yml +++ /dev/null @@ -1,82 +0,0 @@ -- name: Setup gpg key - apt_key: - url: https://downloads.avax.network/avalanchego.gpg.key - state: present - -- name: Setup avalanchego repo - apt_repository: - repo: deb https://downloads.avax.network/apt jammy main - state: present - -- name: Setup golang repo - apt_repository: - repo: ppa:longsleep/golang-backports - state: present - -- name: Install go - apt: - name: golang - state: latest - -- name: Update git clone - git: - repo: "{{ repo_url }}" - dest: "{{ repo_folder }}" - version: "{{ tag }}" - update: yes - force: yes - -- name: Setup systemd - template: - src: templates/avalanchego.service.j2 - dest: /etc/systemd/system/avalanchego.service - mode: 0755 - -- name: Create avalanche user - user: - name: "{{ ava_user }}" - shell: /bin/bash - uid: "{{ ava_uid }}" - group: "{{ ava_group }}" - -- name: Create avalanche config dir - file: - path: /etc/avalanchego - owner: "{{ ava_user }}" - group: "{{ ava_group }}" - state: directory - -- name: Create avalanche log dir - file: - path: "{{ log_dir }}" - owner: "{{ ava_user }}" - group: "{{ ava_group }}" - state: directory - -- name: Create avalanche database dir - file: - path: "{{ db_dir }}" - owner: "{{ ava_user }}" - group: "{{ ava_group }}" - state: directory - -- name: Build avalanchego - command: ./scripts/build.sh - args: - chdir: "{{ repo_folder }}" - -- name: Copy avalanchego binaries to the correct location - command: cp build/avalanchego /usr/local/bin/avalanchego - args: - chdir: "{{ repo_folder }}" - -- name: Configure avalanche - template: - src: templates/conf.json.j2 - dest: /etc/avalanchego/conf.json - mode: 0644 - -- name: Enable Avalanche - systemd: - name: avalanchego - enabled: yes diff --git a/.github/packer/roles/public-ami/templates/avalanchego.service.j2 b/.github/packer/roles/public-ami/templates/avalanchego.service.j2 deleted file mode 100644 index 37e1401622b..00000000000 --- a/.github/packer/roles/public-ami/templates/avalanchego.service.j2 +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=Avalanche go client -After=syslog.target network.target - -[Service] -User=avalanche -Type=simple -Environment=HOME=/home/avalanche -ExecStart=/usr/local/bin/avalanchego --config-file /etc/avalanchego/conf.json -KillMode=process -KillSignal=SIGINT -TimeoutStopSec=90 -Restart=on-failure -RestartSec=10s -LimitNOFILE=65000 - -[Install] -WantedBy=multi-user.target diff --git a/.github/packer/roles/public-ami/templates/conf.json.j2 b/.github/packer/roles/public-ami/templates/conf.json.j2 deleted file mode 100644 index 43825438c7c..00000000000 --- a/.github/packer/roles/public-ami/templates/conf.json.j2 +++ /dev/null @@ -1,9 +0,0 @@ -{ - "api-keystore-enabled": false, - "http-host": "0.0.0.0", - "log-dir": "{{ log_dir }}", - "db-dir": "{{ db_dir }}", - "api-admin-enabled": false, - "public-ip-resolution-service": "opendns", - "network-id": "{{ network }}" -} diff --git a/.github/packer/ubuntu-jammy-x86_64-public-ami.pkr.hcl b/.github/packer/ubuntu-jammy-x86_64-public-ami.pkr.hcl deleted file mode 100644 index c319e87134c..00000000000 --- a/.github/packer/ubuntu-jammy-x86_64-public-ami.pkr.hcl +++ /dev/null @@ -1,81 +0,0 @@ -packer { - required_plugins { - amazon = { - source = "github.com/hashicorp/amazon" - version = "~> 1" - } - ansible = { - source = "github.com/hashicorp/ansible" - version = "~> 1" - } - } -} - -variable "skip_create_ami" { - type = string - default = "${env("SKIP_CREATE_AMI")}" -} - -variable "tag" { - type = string - default = "${env("TAG")}" -} - -variable "version" { - type = string - default = "jammy-22.04" -} - -data "amazon-ami" "autogenerated_1" { - filters = { - architecture = "x86_64" - name = "ubuntu/images/*ubuntu-${var.version}-*-server-*" - root-device-type = "ebs" - virtualization-type = "hvm" - } - most_recent = true - owners = ["099720109477"] - region = "us-east-1" -} - -locals { - skip_create_ami = var.skip_create_ami == "True" - timestamp = regex_replace(timestamp(), "[- TZ:]", "") - clean_name = regex_replace(timestamp(), "[^a-zA-Z0-9-]", "-") -} - -source "amazon-ebs" "autogenerated_1" { - ami_groups = ["all"] - ami_name = "public-avalanche-ubuntu-${var.version}-${var.tag}-${local.timestamp}" - instance_type = "c5.large" - region = "us-east-1" - skip_create_ami = local.skip_create_ami - source_ami = "${data.amazon-ami.autogenerated_1.id}" - ssh_username = "ubuntu" - tags = { - Base_AMI_Name = "{{ .SourceAMIName }}" - Name = "public-avalanche-ubuntu-${var.version}-${var.tag}-${local.clean_name}" - Release = "${var.version}" - } -} - -build { - sources = ["source.amazon-ebs.autogenerated_1"] - - provisioner "shell" { - inline = ["while [ ! -f /var/lib/cloud/instance/boot-finished ]; do echo 'Waiting for cloud-init...'; sleep 1; done", "wait_apt=$(ps aux | grep apt | wc -l)", "while [ \"$wait_apt\" -gt \"1\" ]; do echo \"waiting for apt to be ready....\"; wait_apt=$(ps aux | grep apt | wc -l); sleep 5; done", "sudo apt-get -y update", "sudo apt-get install -y python3-boto3 golang"] - } - - provisioner "ansible" { - extra_arguments = ["-e", "component=public-ami build=packer os_release=jammy tag=${var.tag}"] - playbook_file = ".github/packer/create_public_ami.yml" - roles_path = ".github/packer/roles/" - use_proxy = false - } - - provisioner "shell" { - execute_command = "sudo bash -x {{ .Path }}" - script = ".github/packer/clean-public-ami.sh" - } - -} diff --git a/.github/workflows/amichange.json b/.github/workflows/amichange.json deleted file mode 100644 index 9ede5621b00..00000000000 --- a/.github/workflows/amichange.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "Version": { - "VersionTitle": "", - "ReleaseNotes": "Automated latest avalanchego release" - }, - "DeliveryOptions": [ - { - "Details": { - "AmiDeliveryOptionDetails": { - "AmiSource": { - "AmiId": "", - "AccessRoleArn": "", - "UserName": "ubuntu", - "OperatingSystemName": "UBUNTU", - "OperatingSystemVersion": "Ubuntu 22.04" - }, - "UsageInstructions": "Connect via SSH and you can make local calls to port 9650", - "RecommendedInstanceType": "c5.2xlarge", - "SecurityGroups": [ - { - "IpProtocol": "tcp", - "FromPort": 9651, - "ToPort": 9651, - "IpRanges": [ - "0.0.0.0/0" - ] - }, - { - "IpProtocol": "tcp", - "FromPort": 22, - "ToPort": 22, - "IpRanges": [ - "0.0.0.0/0" - ] - } - ] - } - } - } - ] -} - diff --git a/.github/workflows/build-linux-binaries.yml b/.github/workflows/build-linux-binaries.yml index c59192883c0..f4f69104b1e 100644 --- a/.github/workflows/build-linux-binaries.yml +++ b/.github/workflows/build-linux-binaries.yml @@ -28,9 +28,7 @@ jobs: run: ./scripts/build.sh - name: Install aws cli - run: | - sudo apt update - sudo apt -y install awscli + run: sudo snap install aws-cli --classic - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 @@ -74,7 +72,7 @@ jobs: rm -rf /tmp/avalanchego build-arm64-binaries-tarball: - runs-on: custom-arm64-focal + runs-on: custom-arm64-jammy permissions: id-token: write contents: read @@ -82,8 +80,6 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: ./.github/actions/install-focal-deps - - uses: ./.github/actions/setup-go-for-project - run: go version @@ -92,9 +88,7 @@ jobs: run: ./scripts/build.sh - name: Install aws cli - run: | - sudo apt update - sudo apt -y install awscli + run: sudo snap install aws-cli --classic - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 @@ -124,7 +118,7 @@ jobs: TAG: ${{ env.TAG }} BUCKET: ${{ secrets.BUCKET }} ARCH: "arm64" - RELEASE: "focal" + RELEASE: "jammy" - name: Save as Github artifact uses: actions/upload-artifact@v4 diff --git a/.github/workflows/build-public-ami.yml b/.github/workflows/build-public-ami.yml deleted file mode 100644 index bfb1629e425..00000000000 --- a/.github/workflows/build-public-ami.yml +++ /dev/null @@ -1,80 +0,0 @@ -name: build-public-ami - -on: - workflow_dispatch: - inputs: - tag: - description: 'Tag to create AMI from' - required: true - push: - tags: - - "*" - -env: - PACKER_VERSION: "1.10.2" - PYTHON3_BOTO3_VERSION: "1.20.34+dfsg-1" - -jobs: - build-public-ami-and-upload: - runs-on: ubuntu-22.04 - timeout-minutes: 45 - permissions: - id-token: write - contents: read - - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/setup-go-for-project - - run: go version - - - name: Install aws cli - run: | - sudo apt update - sudo apt-get -y install python3-boto3="${PYTHON3_BOTO3_VERSION}" - - - name: Get the tag - id: get_tag - run: | - if [[ ${{ github.event_name }} == 'push' ]]; - then - echo "TAG=${GITHUB_REF/refs\/tags\//}" >> "$GITHUB_ENV" - else - echo "TAG=${{ inputs.tag }}" >> "$GITHUB_ENV" - fi - shell: bash - - - name: Set whether to skip ami creation in packer - run: | - if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then - echo "Setting SKIP_CREATE_AMI to False" - echo "SKIP_CREATE_AMI=False" >> "$GITHUB_ENV" - fi - - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - role-to-assume: ${{ secrets.AWS_MARKETPLACE_SA_ROLE_ARN }} - role-session-name: githubrolesession - aws-region: us-east-1 - - - name: Setup `packer` - uses: hashicorp/setup-packer@main - id: setup - with: - version: ${{ env.PACKER_VERSION }} - - - name: Run `packer init` - id: init - run: "packer init ./.github/packer/ubuntu-jammy-x86_64-public-ami.pkr.hcl" - - - name: Run `packer validate` - id: validate - run: "packer validate ./.github/packer/ubuntu-jammy-x86_64-public-ami.pkr.hcl" - - - name: Create AMI and upload to marketplace - run: | - ./.github/workflows/update-ami.py - env: - TAG: ${{ env.TAG }} - PRODUCT_ID: ${{ secrets.MARKETPLACE_PRODUCT }} - ROLE_ARN: ${{ secrets.MARKETPLACE_ROLE }} diff --git a/.github/workflows/build-ubuntu-amd64-release.yml b/.github/workflows/build-ubuntu-amd64-release.yml index 6d6514584f0..e38fee1d8aa 100644 --- a/.github/workflows/build-ubuntu-amd64-release.yml +++ b/.github/workflows/build-ubuntu-amd64-release.yml @@ -11,6 +11,64 @@ on: - "*" jobs: + build-focal-amd64-package: + runs-on: ubuntu-20.04 + permissions: + id-token: write + contents: read + + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/setup-go-for-project + - run: go version + + - name: Build the avalanchego binaries + run: ./scripts/build.sh + + - name: Install aws cli + run: sudo snap install aws-cli --classic + + - name: Try to get tag from git + if: "${{ github.event.inputs.tag == '' }}" + id: get_tag_from_git + run: | + echo "TAG=${GITHUB_REF/refs\/tags\//}" >> "$GITHUB_ENV" + shell: bash + + - name: Try to get tag from workflow dispatch + if: "${{ github.event.inputs.tag != '' }}" + id: get_tag_from_workflow + run: | + echo "TAG=${{ github.event.inputs.tag }}" >> "$GITHUB_ENV" + shell: bash + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.AWS_DEPLOY_SA_ROLE_ARN }} + role-session-name: githubrolesession + aws-region: us-east-1 + + - name: Create debian package + run: ./.github/workflows/build-deb-pkg.sh + env: + PKG_ROOT: /tmp/avalanchego + TAG: ${{ env.TAG }} + BUCKET: ${{ secrets.BUCKET }} + ARCH: "amd64" + RELEASE: "focal" + + - name: Save as Github artifact + uses: actions/upload-artifact@v4 + with: + name: focal + path: /tmp/avalanchego/avalanchego-${{ env.TAG }}-amd64.deb + + - name: Cleanup + run: | + rm -rf ./build + rm -rf /tmp/avalanchego + build-jammy-amd64-package: runs-on: ubuntu-22.04 permissions: @@ -26,9 +84,7 @@ jobs: run: ./scripts/build.sh - name: Install aws cli - run: | - sudo apt update - sudo apt -y install awscli + run: sudo snap install aws-cli --classic - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 @@ -71,8 +127,8 @@ jobs: rm -rf ./build rm -rf /tmp/avalanchego - build-focal-amd64-package: - runs-on: ubuntu-20.04 + build-noble-amd64-package: + runs-on: ubuntu-24.04 permissions: id-token: write contents: read @@ -86,9 +142,7 @@ jobs: run: ./scripts/build.sh - name: Install aws cli - run: | - sudo apt update - sudo apt -y install awscli + run: sudo snap install aws-cli --classic - name: Try to get tag from git if: "${{ github.event.inputs.tag == '' }}" @@ -118,12 +172,12 @@ jobs: TAG: ${{ env.TAG }} BUCKET: ${{ secrets.BUCKET }} ARCH: "amd64" - RELEASE: "focal" + RELEASE: "noble" - name: Save as Github artifact uses: actions/upload-artifact@v4 with: - name: focal + name: noble path: /tmp/avalanchego/avalanchego-${{ env.TAG }}-amd64.deb - name: Cleanup diff --git a/.github/workflows/build-ubuntu-arm64-release.yml b/.github/workflows/build-ubuntu-arm64-release.yml index 0443487b55e..de9382be6f1 100644 --- a/.github/workflows/build-ubuntu-arm64-release.yml +++ b/.github/workflows/build-ubuntu-arm64-release.yml @@ -26,9 +26,7 @@ jobs: run: ./scripts/build.sh - name: Install aws cli - run: | - sudo apt update - sudo apt -y install awscli + run: sudo snap install aws-cli --classic - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 @@ -71,15 +69,14 @@ jobs: rm -rf ./build rm -rf /tmp/avalanchego - build-focal-arm64-package: - runs-on: custom-arm64-focal + build-noble-arm64-package: + runs-on: custom-arm64-noble permissions: id-token: write contents: read steps: - uses: actions/checkout@v4 - - uses: ./.github/actions/install-focal-deps - uses: ./.github/actions/setup-go-for-project - run: go version @@ -87,9 +84,7 @@ jobs: run: ./scripts/build.sh - name: Install aws cli - run: | - sudo apt update - sudo apt -y install awscli + run: sudo snap install aws-cli --classic - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 @@ -119,12 +114,12 @@ jobs: TAG: ${{ env.TAG }} BUCKET: ${{ secrets.BUCKET }} ARCH: "arm64" - RELEASE: "focal" + RELEASE: "noble" - name: Save as Github artifact uses: actions/upload-artifact@v4 with: - name: focal + name: noble path: /tmp/avalanchego/avalanchego-${{ env.TAG }}-arm64.deb - name: Cleanup diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a7c6145e2a6..39550d4259f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,11 +25,9 @@ jobs: strategy: fail-fast: false matrix: - os: [macos-12, ubuntu-20.04, ubuntu-22.04, windows-2022, custom-arm64-focal, custom-arm64-jammy] + os: [macos-12, ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-2022, custom-arm64-jammy, custom-arm64-noble] steps: - uses: actions/checkout@v4 - - uses: ./.github/actions/install-focal-deps - if: matrix.os == 'custom-arm64-focal' - uses: ./.github/actions/setup-go-for-project - name: Set timeout on Windows # Windows UT run slower and need a longer timeout shell: bash @@ -41,7 +39,7 @@ jobs: env: TIMEOUT: ${{ env.TIMEOUT }} Fuzz: - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: ./.github/actions/setup-go-for-project diff --git a/.github/workflows/update-ami.py b/.github/workflows/update-ami.py deleted file mode 100755 index 95360c553d3..00000000000 --- a/.github/workflows/update-ami.py +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env python3 -import json -import os -import boto3 -import uuid -import re -import subprocess -import sys - -# Globals -amifile = '.github/workflows/amichange.json' -packerfile = ".github/packer/ubuntu-jammy-x86_64-public-ami.pkr.hcl" - -# Environment Globals -product_id = os.getenv('PRODUCT_ID') -role_arn = os.getenv('ROLE_ARN') -vtag = os.getenv('TAG') -tag = vtag.replace('v', '') -skip_create_ami = os.getenv('SKIP_CREATE_AMI', "True") - -def packer_build(packerfile): - print("Running the packer build") - output = subprocess.run('/usr/local/bin/packer build ' + packerfile, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - if output.returncode != 0: - raise RuntimeError(f"Command returned with code: {output.returncode}") - -def packer_build_update(packerfile): - print("Creating packer AMI image for Marketplace") - output = subprocess.run('/usr/local/bin/packer build ' + packerfile, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - if output.returncode != 0: - raise RuntimeError(f"Command returned with code: {output.returncode}") - - found = re.findall('ami-[a-z0-9]*', str(output.stdout)) - - if found: - amiid = found[-1] - return amiid - else: - raise RuntimeError(f"No AMI ID found in packer output: {output.stdout}") - -def parse_amichange(amifile, amiid, role_arn, tag): - # Create json blob to submit with the catalog update - print("Updating the json artifact with recent amiid and tag information") - with open(amifile, 'r') as file: - data = json.load(file) - - data['DeliveryOptions'][0]['Details']['AmiDeliveryOptionDetails']['AmiSource']['AmiId']=amiid - data['DeliveryOptions'][0]['Details']['AmiDeliveryOptionDetails']['AmiSource']['AccessRoleArn']=role_arn - data['Version']['VersionTitle']=tag - return json.dumps(data) - -def update_ami(amifile, amiid): - # Update the catalog with the last amiimage - print('Updating the marketplace image') - client = boto3.client('marketplace-catalog',region_name='us-east-1') - uid = str(uuid.uuid4()) - global tag - global product_id - global role_arn - - try: - response = client.start_change_set( - Catalog='AWSMarketplace', - ChangeSet=[ - { - 'ChangeType': 'AddDeliveryOptions', - 'Entity': { - 'Type': 'AmiProduct@1.0', - 'Identifier': product_id - }, - 'Details': parse_amichange(amifile,amiid,role_arn,tag), - 'ChangeName': 'Update' - }, - ], - ChangeSetName='AvalancheGo Update ' + tag, - ClientRequestToken=uid - ) - print(response) - except client.exceptions.ResourceInUseException: - print("The product is currently blocked by Amazon. Please check the product site for more details") - except Exception as e: - print(f"An error occurred while updating AMI delivery options: {e}") - -def main(): - try: - if skip_create_ami == "True": - packer_build(packerfile) - else: - update_ami(amifile, packer_build_update(packerfile)) - - print("Ran packer build and update ami successfully") - except Exception as e: - print(f"An error occurred while running packer") - sys.exit(5) - -if __name__ == '__main__': - main() - diff --git a/config/config.go b/config/config.go index 4d793708607..46fd0aac8af 100644 --- a/config/config.go +++ b/config/config.go @@ -47,8 +47,10 @@ import ( "github.com/ava-labs/avalanchego/version" "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/avalanchego/vms/platformvm/reward" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/proposervm" + + txfee "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + validatorfee "github.com/ava-labs/avalanchego/vms/platformvm/validators/fee" ) const ( @@ -768,7 +770,7 @@ func getTxFeeConfig(v *viper.Viper, networkID uint32) genesis.TxFeeConfig { if networkID != constants.MainnetID && networkID != constants.FujiID { return genesis.TxFeeConfig{ CreateAssetTxFee: v.GetUint64(CreateAssetTxFeeKey), - StaticFeeConfig: fee.StaticConfig{ + StaticFeeConfig: txfee.StaticConfig{ TxFee: v.GetUint64(TxFeeKey), CreateSubnetTxFee: v.GetUint64(CreateSubnetTxFeeKey), TransformSubnetTxFee: v.GetUint64(TransformSubnetTxFeeKey), @@ -791,6 +793,12 @@ func getTxFeeConfig(v *viper.Viper, networkID uint32) genesis.TxFeeConfig { MinPrice: gas.Price(v.GetUint64(DynamicFeesMinGasPriceKey)), ExcessConversionConstant: gas.Gas(v.GetUint64(DynamicFeesExcessConversionConstantKey)), }, + ValidatorFeeCapacity: gas.Gas(v.GetUint64(ValidatorFeesCapacityKey)), + ValidatorFeeConfig: validatorfee.Config{ + Target: gas.Gas(v.GetUint64(ValidatorFeesTargetKey)), + MinPrice: gas.Price(v.GetUint64(ValidatorFeesMinPriceKey)), + ExcessConversionConstant: gas.Gas(v.GetUint64(ValidatorFeesExcessConversionConstantKey)), + }, } } return genesis.GetTxFeeConfig(networkID) diff --git a/config/flags.go b/config/flags.go index 9f092c563b3..c20b243c807 100644 --- a/config/flags.go +++ b/config/flags.go @@ -105,6 +105,11 @@ func addNodeFlags(fs *pflag.FlagSet) { fs.IntSlice(ACPObjectKey, nil, "ACPs to object adoption") // AVAX fees: + // Validator fees: + fs.Uint64(ValidatorFeesCapacityKey, uint64(genesis.LocalParams.ValidatorFeeCapacity), "Maximum number of validators") + fs.Uint64(ValidatorFeesTargetKey, uint64(genesis.LocalParams.ValidatorFeeConfig.Target), "Target number of validators") + fs.Uint64(ValidatorFeesMinPriceKey, uint64(genesis.LocalParams.ValidatorFeeConfig.MinPrice), "Minimum validator price in nAVAX per second") + fs.Uint64(ValidatorFeesExcessConversionConstantKey, uint64(genesis.LocalParams.ValidatorFeeConfig.ExcessConversionConstant), "Constant to convert validator excess price") // Dynamic fees: fs.Uint64(DynamicFeesBandwidthWeightKey, genesis.LocalParams.DynamicFeeConfig.Weights[gas.Bandwidth], "Complexity multiplier used to convert Bandwidth into Gas") fs.Uint64(DynamicFeesDBReadWeightKey, genesis.LocalParams.DynamicFeeConfig.Weights[gas.DBRead], "Complexity multiplier used to convert DB Reads into Gas") diff --git a/config/keys.go b/config/keys.go index 714136a7407..dcea2621f6f 100644 --- a/config/keys.go +++ b/config/keys.go @@ -8,63 +8,67 @@ package config const HTTPWriteTimeoutKey = "http-write-timeout" // #nosec G101 const ( - DataDirKey = "data-dir" - ConfigFileKey = "config-file" - ConfigContentKey = "config-file-content" - ConfigContentTypeKey = "config-file-content-type" - VersionKey = "version" - VersionJSONKey = "version-json" - GenesisFileKey = "genesis-file" - GenesisFileContentKey = "genesis-file-content" - UpgradeFileKey = "upgrade-file" - UpgradeFileContentKey = "upgrade-file-content" - NetworkNameKey = "network-id" - ACPSupportKey = "acp-support" - ACPObjectKey = "acp-object" - DynamicFeesBandwidthWeightKey = "dynamic-fees-bandwidth-weight" - DynamicFeesDBReadWeightKey = "dynamic-fees-db-read-weight" - DynamicFeesDBWriteWeightKey = "dynamic-fees-db-write-weight" - DynamicFeesComputeWeightKey = "dynamic-fees-compute-weight" - DynamicFeesMaxGasCapacityKey = "dynamic-fees-max-gas-capacity" - DynamicFeesMaxGasPerSecondKey = "dynamic-fees-max-gas-per-second" - DynamicFeesTargetGasPerSecondKey = "dynamic-fees-target-gas-per-second" - DynamicFeesMinGasPriceKey = "dynamic-fees-min-gas-price" - DynamicFeesExcessConversionConstantKey = "dynamic-fees-excess-conversion-constant" - TxFeeKey = "tx-fee" - CreateAssetTxFeeKey = "create-asset-tx-fee" - CreateSubnetTxFeeKey = "create-subnet-tx-fee" - TransformSubnetTxFeeKey = "transform-subnet-tx-fee" - CreateBlockchainTxFeeKey = "create-blockchain-tx-fee" - AddPrimaryNetworkValidatorFeeKey = "add-primary-network-validator-fee" - AddPrimaryNetworkDelegatorFeeKey = "add-primary-network-delegator-fee" - AddSubnetValidatorFeeKey = "add-subnet-validator-fee" - AddSubnetDelegatorFeeKey = "add-subnet-delegator-fee" - UptimeRequirementKey = "uptime-requirement" - MinValidatorStakeKey = "min-validator-stake" - MaxValidatorStakeKey = "max-validator-stake" - MinDelegatorStakeKey = "min-delegator-stake" - MinDelegatorFeeKey = "min-delegation-fee" - MinStakeDurationKey = "min-stake-duration" - MaxStakeDurationKey = "max-stake-duration" - StakeMaxConsumptionRateKey = "stake-max-consumption-rate" - StakeMinConsumptionRateKey = "stake-min-consumption-rate" - StakeMintingPeriodKey = "stake-minting-period" - StakeSupplyCapKey = "stake-supply-cap" - DBTypeKey = "db-type" - DBReadOnlyKey = "db-read-only" - DBPathKey = "db-dir" - DBConfigFileKey = "db-config-file" - DBConfigContentKey = "db-config-file-content" - PublicIPKey = "public-ip" - PublicIPResolutionFreqKey = "public-ip-resolution-frequency" - PublicIPResolutionServiceKey = "public-ip-resolution-service" - HTTPHostKey = "http-host" - HTTPPortKey = "http-port" - HTTPSEnabledKey = "http-tls-enabled" - HTTPSKeyFileKey = "http-tls-key-file" - HTTPSKeyContentKey = "http-tls-key-file-content" - HTTPSCertFileKey = "http-tls-cert-file" - HTTPSCertContentKey = "http-tls-cert-file-content" + DataDirKey = "data-dir" + ConfigFileKey = "config-file" + ConfigContentKey = "config-file-content" + ConfigContentTypeKey = "config-file-content-type" + VersionKey = "version" + VersionJSONKey = "version-json" + GenesisFileKey = "genesis-file" + GenesisFileContentKey = "genesis-file-content" + UpgradeFileKey = "upgrade-file" + UpgradeFileContentKey = "upgrade-file-content" + NetworkNameKey = "network-id" + ACPSupportKey = "acp-support" + ACPObjectKey = "acp-object" + DynamicFeesBandwidthWeightKey = "dynamic-fees-bandwidth-weight" + DynamicFeesDBReadWeightKey = "dynamic-fees-db-read-weight" + DynamicFeesDBWriteWeightKey = "dynamic-fees-db-write-weight" + DynamicFeesComputeWeightKey = "dynamic-fees-compute-weight" + DynamicFeesMaxGasCapacityKey = "dynamic-fees-max-gas-capacity" + DynamicFeesMaxGasPerSecondKey = "dynamic-fees-max-gas-per-second" + DynamicFeesTargetGasPerSecondKey = "dynamic-fees-target-gas-per-second" + DynamicFeesMinGasPriceKey = "dynamic-fees-min-gas-price" + DynamicFeesExcessConversionConstantKey = "dynamic-fees-excess-conversion-constant" + ValidatorFeesCapacityKey = "validator-fees-capacity" + ValidatorFeesTargetKey = "validator-fees-target" + ValidatorFeesMinPriceKey = "validator-fees-min-price" + ValidatorFeesExcessConversionConstantKey = "validator-fees-excess-conversion-constant" + TxFeeKey = "tx-fee" + CreateAssetTxFeeKey = "create-asset-tx-fee" + CreateSubnetTxFeeKey = "create-subnet-tx-fee" + TransformSubnetTxFeeKey = "transform-subnet-tx-fee" + CreateBlockchainTxFeeKey = "create-blockchain-tx-fee" + AddPrimaryNetworkValidatorFeeKey = "add-primary-network-validator-fee" + AddPrimaryNetworkDelegatorFeeKey = "add-primary-network-delegator-fee" + AddSubnetValidatorFeeKey = "add-subnet-validator-fee" + AddSubnetDelegatorFeeKey = "add-subnet-delegator-fee" + UptimeRequirementKey = "uptime-requirement" + MinValidatorStakeKey = "min-validator-stake" + MaxValidatorStakeKey = "max-validator-stake" + MinDelegatorStakeKey = "min-delegator-stake" + MinDelegatorFeeKey = "min-delegation-fee" + MinStakeDurationKey = "min-stake-duration" + MaxStakeDurationKey = "max-stake-duration" + StakeMaxConsumptionRateKey = "stake-max-consumption-rate" + StakeMinConsumptionRateKey = "stake-min-consumption-rate" + StakeMintingPeriodKey = "stake-minting-period" + StakeSupplyCapKey = "stake-supply-cap" + DBTypeKey = "db-type" + DBReadOnlyKey = "db-read-only" + DBPathKey = "db-dir" + DBConfigFileKey = "db-config-file" + DBConfigContentKey = "db-config-file-content" + PublicIPKey = "public-ip" + PublicIPResolutionFreqKey = "public-ip-resolution-frequency" + PublicIPResolutionServiceKey = "public-ip-resolution-service" + HTTPHostKey = "http-host" + HTTPPortKey = "http-port" + HTTPSEnabledKey = "http-tls-enabled" + HTTPSKeyFileKey = "http-tls-key-file" + HTTPSKeyContentKey = "http-tls-key-file-content" + HTTPSCertFileKey = "http-tls-cert-file" + HTTPSCertContentKey = "http-tls-cert-file-content" HTTPAllowedOrigins = "http-allowed-origins" HTTPAllowedHostsKey = "http-allowed-hosts" diff --git a/database/batch.go b/database/batch.go index f3187a1fa95..8a37ee72369 100644 --- a/database/batch.go +++ b/database/batch.go @@ -75,6 +75,7 @@ func (b *BatchOps) Size() int { } func (b *BatchOps) Reset() { + clear(b.Ops) b.Ops = b.Ops[:0] b.size = 0 } diff --git a/database/encdb/db.go b/database/encdb/db.go index 2bdacb465ff..ea82b16a365 100644 --- a/database/encdb/db.go +++ b/database/encdb/db.go @@ -204,6 +204,7 @@ func (b *batch) Reset() { if cap(b.ops) > len(b.ops)*database.MaxExcessCapacityFactor { b.ops = make([]database.BatchOp, 0, cap(b.ops)/database.CapacityReductionFactor) } else { + clear(b.ops) b.ops = b.ops[:0] } b.Batch.Reset() diff --git a/database/prefixdb/db.go b/database/prefixdb/db.go index b3082d9e986..e1ec8da5007 100644 --- a/database/prefixdb/db.go +++ b/database/prefixdb/db.go @@ -313,6 +313,7 @@ func (b *batch) Reset() { if cap(b.ops) > len(b.ops)*database.MaxExcessCapacityFactor { b.ops = make([]batchOp, 0, cap(b.ops)/database.CapacityReductionFactor) } else { + clear(b.ops) b.ops = b.ops[:0] } b.Batch.Reset() diff --git a/genesis/genesis_fuji.go b/genesis/genesis_fuji.go index 3d59bb72575..82a8ffecaa3 100644 --- a/genesis/genesis_fuji.go +++ b/genesis/genesis_fuji.go @@ -11,7 +11,9 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/avalanchego/vms/platformvm/reward" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + + txfee "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + validatorfee "github.com/ava-labs/avalanchego/vms/platformvm/validators/fee" ) var ( @@ -22,7 +24,7 @@ var ( FujiParams = Params{ TxFeeConfig: TxFeeConfig{ CreateAssetTxFee: 10 * units.MilliAvax, - StaticFeeConfig: fee.StaticConfig{ + StaticFeeConfig: txfee.StaticConfig{ TxFee: units.MilliAvax, CreateSubnetTxFee: 100 * units.MilliAvax, TransformSubnetTxFee: 1 * units.Avax, @@ -46,6 +48,16 @@ var ( MinPrice: 1, ExcessConversionConstant: 5_000, }, + ValidatorFeeCapacity: 20_000, + ValidatorFeeConfig: validatorfee.Config{ + Target: 10_000, + MinPrice: gas.Price(512 * units.NanoAvax), + // ExcessConversionConstant = (Capacity - Target) * NumberOfSecondsPerDoubling / ln(2) + // + // ln(2) is a float and the result is consensus critical, so we + // hardcode the result. + ExcessConversionConstant: 51_937_021, // Double every hour + }, }, StakingConfig: StakingConfig{ UptimeRequirement: .8, // 80% diff --git a/genesis/genesis_local.go b/genesis/genesis_local.go index d3ce77aec96..aefdbf2c25b 100644 --- a/genesis/genesis_local.go +++ b/genesis/genesis_local.go @@ -14,7 +14,9 @@ import ( "github.com/ava-labs/avalanchego/utils/wrappers" "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/avalanchego/vms/platformvm/reward" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + + txfee "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + validatorfee "github.com/ava-labs/avalanchego/vms/platformvm/validators/fee" ) // PrivateKey-vmRQiZeXEXYMyJhEiqdC2z5JhuDbxL8ix9UVvjgMu2Er1NepE => P-local1g65uqn6t77p656w64023nh8nd9updzmxyymev2 @@ -40,7 +42,7 @@ var ( LocalParams = Params{ TxFeeConfig: TxFeeConfig{ CreateAssetTxFee: units.MilliAvax, - StaticFeeConfig: fee.StaticConfig{ + StaticFeeConfig: txfee.StaticConfig{ TxFee: units.MilliAvax, CreateSubnetTxFee: 100 * units.MilliAvax, TransformSubnetTxFee: 100 * units.MilliAvax, @@ -64,6 +66,16 @@ var ( MinPrice: 1, ExcessConversionConstant: 5_000, }, + ValidatorFeeCapacity: 20_000, + ValidatorFeeConfig: validatorfee.Config{ + Target: 10_000, + MinPrice: gas.Price(1 * units.NanoAvax), + // ExcessConversionConstant = (Capacity - Target) * NumberOfSecondsPerDoubling / ln(2) + // + // ln(2) is a float and the result is consensus critical, so we + // hardcode the result. + ExcessConversionConstant: 865_617, // Double every minute + }, }, StakingConfig: StakingConfig{ UptimeRequirement: .8, // 80% diff --git a/genesis/genesis_mainnet.go b/genesis/genesis_mainnet.go index 8d4a6d4f777..2395d88d34b 100644 --- a/genesis/genesis_mainnet.go +++ b/genesis/genesis_mainnet.go @@ -11,7 +11,9 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/avalanchego/vms/platformvm/reward" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + + txfee "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + validatorfee "github.com/ava-labs/avalanchego/vms/platformvm/validators/fee" ) var ( @@ -22,7 +24,7 @@ var ( MainnetParams = Params{ TxFeeConfig: TxFeeConfig{ CreateAssetTxFee: 10 * units.MilliAvax, - StaticFeeConfig: fee.StaticConfig{ + StaticFeeConfig: txfee.StaticConfig{ TxFee: units.MilliAvax, CreateSubnetTxFee: 1 * units.Avax, TransformSubnetTxFee: 10 * units.Avax, @@ -46,6 +48,16 @@ var ( MinPrice: 1, ExcessConversionConstant: 5_000, }, + ValidatorFeeCapacity: 20_000, + ValidatorFeeConfig: validatorfee.Config{ + Target: 10_000, + MinPrice: gas.Price(512 * units.NanoAvax), + // ExcessConversionConstant = (Capacity - Target) * NumberOfSecondsPerDoubling / ln(2) + // + // ln(2) is a float and the result is consensus critical, so we + // hardcode the result. + ExcessConversionConstant: 1_246_488_515, // Double every day + }, }, StakingConfig: StakingConfig{ UptimeRequirement: .8, // 80% diff --git a/genesis/params.go b/genesis/params.go index e51af8b81c1..43c2f1c1301 100644 --- a/genesis/params.go +++ b/genesis/params.go @@ -9,7 +9,9 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/avalanchego/vms/platformvm/reward" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + + txfee "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + validatorfee "github.com/ava-labs/avalanchego/vms/platformvm/validators/fee" ) type StakingConfig struct { @@ -36,9 +38,11 @@ type StakingConfig struct { } type TxFeeConfig struct { - CreateAssetTxFee uint64 `json:"createAssetTxFee"` - StaticFeeConfig fee.StaticConfig `json:"staticFeeConfig"` - DynamicFeeConfig gas.Config `json:"dynamicFeeConfig"` + CreateAssetTxFee uint64 `json:"createAssetTxFee"` + StaticFeeConfig txfee.StaticConfig `json:"staticFeeConfig"` + DynamicFeeConfig gas.Config `json:"dynamicFeeConfig"` + ValidatorFeeCapacity gas.Gas `json:"validatorFeeCapacity"` + ValidatorFeeConfig validatorfee.Config `json:"validatorFeeConfig"` } type Params struct { diff --git a/node/node.go b/node/node.go index b2aba931443..5f6ef111858 100644 --- a/node/node.go +++ b/node/node.go @@ -1228,6 +1228,8 @@ func (n *Node) initVMs() error { CreateAssetTxFee: n.Config.CreateAssetTxFee, StaticFeeConfig: n.Config.StaticFeeConfig, DynamicFeeConfig: n.Config.DynamicFeeConfig, + ValidatorFeeCapacity: n.Config.ValidatorFeeCapacity, + ValidatorFeeConfig: n.Config.ValidatorFeeConfig, UptimePercentage: n.Config.UptimeRequirement, MinValidatorStake: n.Config.MinValidatorStake, MaxValidatorStake: n.Config.MaxValidatorStake, diff --git a/utils/set/sampleable_set.go b/utils/set/sampleable_set.go index efb63c2d777..a70b332a9a6 100644 --- a/utils/set/sampleable_set.go +++ b/utils/set/sampleable_set.go @@ -108,9 +108,7 @@ func (s *SampleableSet[T]) Remove(elements ...T) { // Clear empties this set func (s *SampleableSet[T]) Clear() { clear(s.indices) - for i := range s.elements { - s.elements[i] = utils.Zero[T]() - } + clear(s.elements) s.elements = s.elements[:0] } diff --git a/utils/zero.go b/utils/zero.go index c691ed2e653..bb31de1c8d5 100644 --- a/utils/zero.go +++ b/utils/zero.go @@ -4,16 +4,6 @@ package utils // Returns a new instance of a T. -func Zero[T any]() T { - return *new(T) -} - -// ZeroSlice sets all values of the provided slice to the type's zero value. -// -// This can be useful to ensure that the garbage collector doesn't hold -// references to values that are no longer desired. -func ZeroSlice[T any](s []T) { - for i := range s { - s[i] = *new(T) - } +func Zero[T any]() (_ T) { + return } diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index 406285f0e59..f8bda923455 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -16,7 +16,9 @@ import ( "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/avalanchego/vms/platformvm/reward" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + + txfee "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + validatorfee "github.com/ava-labs/avalanchego/vms/platformvm/validators/fee" ) // Struct collecting all foundational parameters of PlatformVM @@ -32,13 +34,17 @@ type Config struct { // calling VM.Initialize. Validators validators.Manager - // Static fees are active before the E-upgrade + // Static fees are active before Etna CreateAssetTxFee uint64 // Override for CreateSubnet and CreateChain before AP3 - StaticFeeConfig fee.StaticConfig + StaticFeeConfig txfee.StaticConfig - // Dynamic fees are active after the E-upgrade + // Dynamic fees are active after Etna DynamicFeeConfig gas.Config + // ACP-77 validator fees are active after Etna + ValidatorFeeCapacity gas.Gas + ValidatorFeeConfig validatorfee.Config + // Provides access to the uptime manager as a thread safe data structure UptimeLockedCalculator uptime.LockedCalculator