diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml
index bd7c93f7e5..0c6dbc2167 100644
--- a/.github/workflows/benchmarks.yml
+++ b/.github/workflows/benchmarks.yml
@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- - uses: actions/setup-go@v4.0.1
+ - uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
- run: go version
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 0c08e8abbb..1a96c67950 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -24,7 +24,7 @@ jobs:
id: go_version
run: echo "GO_VERSION=$(./scripts/get_golang_version.sh)" >> $GITHUB_ENV
- name: Install golang
- uses: actions/setup-go@v4.0.1
+ uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
- name: Restore libsodium from cache
diff --git a/.github/workflows/reviewdog.yml b/.github/workflows/reviewdog.yml
index 7c0f2d26ae..f967bbd916 100644
--- a/.github/workflows/reviewdog.yml
+++ b/.github/workflows/reviewdog.yml
@@ -1,4 +1,6 @@
name: "ReviewDog workflow"
+env:
+ GOLANGCI_LINT_VERSION: "v1.62.0"
on:
push:
branches:
@@ -17,10 +19,10 @@ jobs:
- name: Make libsodium.a
run: sudo mv /usr/bin/go /usr/bin/go.bak && make crypto/libs/linux/amd64/lib/libsodium.a && sudo mv /usr/bin/go.bak /usr/bin/go
- name: reviewdog-golangci-lint
- uses: reviewdog/action-golangci-lint@v2.6.1
+ uses: reviewdog/action-golangci-lint@v2.6.2
with:
go_version_file: go.mod
- golangci_lint_version: "v1.58.0"
+ golangci_lint_version: ${{ env.GOLANGCI_LINT_VERSION }}
golangci_lint_flags: "-c .golangci.yml --allow-parallel-runners"
reporter: "github-pr-check"
tool_name: "Lint Errors"
@@ -46,7 +48,7 @@ jobs:
id: go_version
run: echo "GO_VERSION=$(./scripts/get_golang_version.sh)" >> $GITHUB_ENV
- name: Install specific golang
- uses: actions/setup-go@v4.0.1
+ uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
- name: Create folders for golangci-lint
@@ -56,20 +58,20 @@ jobs:
uses: actions/cache@v3.3.1
with:
path: cicdtmp/golangci-lint/golangci-lint-cgo
- key: cicd-golangci-lint-cgo-v0.0.2-${{ env.GO_VERSION }}
+ key: cicd-golangci-lint-cgo-v0.0.3-${{ env.GO_VERSION }}-${{ env.GOLANGCI_LINT_VERSION }}
- name: Build custom golangci-lint with CGO_ENABLED
if: steps.cache-golangci-lint.outputs.cache-hit != 'true'
run: |
cd cicdtmp/golangci-lint
git clone https://github.com/golangci/golangci-lint.git .
- git checkout tags/v1.58.0
+ git checkout tags/${GOLANGCI_LINT_VERSION}
CGO_ENABLED=true go build -trimpath -o golangci-lint-cgo ./cmd/golangci-lint
./golangci-lint-cgo --version
cd ../../
- name: Install reviewdog
run: |
- curl -sfL https://raw.githubusercontent.com/reviewdog/reviewdog/v0.18.1/install.sh | sh -s -- v0.18.1
+ curl -sfL https://raw.githubusercontent.com/reviewdog/reviewdog/v0.20.2/install.sh | sh -s -- v0.20.2
reviewdog --version
- name: Build custom linters
run: |
@@ -92,7 +94,7 @@ jobs:
cat temp_golangci-lint-cgo.txt | reviewdog \
-f=golangci-lint \
-name="Lint Warnings" \
- -reporter=github-check \
+ -reporter=github-pr-check \
-filter-mode=added \
-fail-on-error=true \
-level=warning
diff --git a/.github/workflows/tools.yml b/.github/workflows/tools.yml
index 95acb22474..16fcbaa372 100644
--- a/.github/workflows/tools.yml
+++ b/.github/workflows/tools.yml
@@ -28,7 +28,7 @@ jobs:
id: go_version
run: echo "GO_VERSION=$(./scripts/get_golang_version.sh)" >> $GITHUB_ENV
- name: Install go version
- uses: actions/setup-go@v4.0.1
+ uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
- name: Test tools/block-generator
diff --git a/.golangci-warnings.yml b/.golangci-warnings.yml
index d813e97e59..8ab68f9faf 100644
--- a/.golangci-warnings.yml
+++ b/.golangci-warnings.yml
@@ -9,8 +9,8 @@ linters:
- partitiontest
linters-settings:
- gosec: # we are mostly only interested in G601
- excludes: [G101, G103, G104, G107, G202, G301, G302, G303, G304, G306, G307, G404]
+ gosec: # Go 1.22 makes G601 irrelevant
+ excludes: [G101, G103, G104, G107, G115, G202, G301, G302, G303, G304, G306, G307, G404, G601]
custom:
partitiontest:
path: cmd/partitiontest_linter/plugin.so
diff --git a/.golangci.yml b/.golangci.yml
index bb44c1ee36..bb78ecc6ed 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -7,7 +7,7 @@ linters:
disable-all: true
enable:
- errcheck
- - exportloopref
+ - copyloopvar
- gofmt
- gosimple
- govet
@@ -127,7 +127,6 @@ issues:
- path: _test\.go
linters:
- errcheck
- # - exportloopref
# - gofmt
- gosimple
# - govet
diff --git a/Dockerfile b/Dockerfile
index 99a30949fa..0a7c6fca3d 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,6 @@
FROM ubuntu:20.04 as builder
-ARG GO_VERSION="1.21.10"
+ARG GO_VERSION="1.23.3"
ARG CHANNEL
ARG URL
diff --git a/README.md b/README.md
index 6925f02225..947984d5a1 100644
--- a/README.md
+++ b/README.md
@@ -1,38 +1,32 @@
-| rel/stable
[![CircleCI](https://circleci.com/gh/algorand/go-algorand/tree/rel%2Fstable.svg?style=svg)](https://circleci.com/gh/algorand/go-algorand/tree/rel%2Fstable) | rel/beta
[![CircleCI](https://circleci.com/gh/algorand/go-algorand/tree/rel%2Fbeta.svg?style=svg)](https://circleci.com/gh/algorand/go-algorand/tree/rel%2Fbeta) | rel/nightly
[![CircleCI](https://circleci.com/gh/algorand/go-algorand/tree/rel%2Fnightly.svg?style=svg)](https://circleci.com/gh/algorand/go-algorand/tree/rel%2Fnightly) |
-| --- | --- | --- |
# go-algorand
+| **Branch** | **Build Status** |
+| --------------- | ---------------- |
+| **rel/stable** | [![CircleCI](https://circleci.com/gh/algorand/go-algorand/tree/rel%2Fstable.svg?style=svg)](https://circleci.com/gh/algorand/go-algorand/tree/rel%2Fstable) |
+| **rel/beta** | [![CircleCI](https://circleci.com/gh/algorand/go-algorand/tree/rel%2Fbeta.svg?style=svg)](https://circleci.com/gh/algorand/go-algorand/tree/rel%2Fbeta) |
+| **rel/nightly** | [![CircleCI](https://circleci.com/gh/algorand/go-algorand/tree/rel%2Fnightly.svg?style=svg)](https://circleci.com/gh/algorand/go-algorand/tree/rel%2Fnightly) |
-Algorand's official implementation in Go.
-Algorand is a permissionless, pure proof-of-stake blockchain that delivers
-decentralization, scalability, security, and transaction finality.
+**Algorand's** official implementation in Go.
+
+Algorand is a permissionless, pure proof-of-stake blockchain that delivers decentralization, scalability, security, and transaction finality.
## Getting Started
-Our [developer website][developer site url] has the most up to date information
-about using and installing the Algorand platform.
+Visit our [developer website](https://developer.algorand.org/) for the most up-to-date information about using and installing the Algorand platform.
-## Building from source
+## Building from Source
-Development is done using the [Go Programming Language](https://golang.org/).
-The version of go is specified in the project's [go.mod](go.mod) file. This document assumes that you have a functioning
-environment setup. If you need assistance setting up an environment please visit
-the [official Go documentation website](https://golang.org/doc/).
+Development is done using the Go Programming Language. The Go version is specified in the project's [go.mod](go.mod) file. This document assumes you have a functioning environment set up. If you need assistance setting up an environment, please visit the [official Go documentation website](https://golang.org/doc/).
### Linux / OSX
-We currently strive to support Debian-based distributions with Ubuntu 20.04
-being our official release target.
-Building on Arch Linux works as well.
-Our core engineering team uses Linux and OSX, so both environments are well
-supported for development.
+We currently strive to support Debian-based distributions, with Ubuntu 20.04 as our official release target. Building on Arch Linux also works well. Our core engineering team uses Linux and OSX, so both environments are well-supported for development.
+
+**OSX Only**: [Homebrew (brew)](https://brew.sh) must be installed before continuing. [Here](https://docs.brew.sh/Installation) are the installation requirements.
-OSX only: [Homebrew (brew)](https://brew.sh) must be installed before
-continuing. [Here](https://docs.brew.sh/Installation) are the installation
-requirements.
+### Initial Environment Setup
-Initial environment setup:
```bash
git clone https://github.com/algorand/go-algorand
cd go-algorand
@@ -40,165 +34,140 @@ cd go-algorand
./scripts/buildtools/install_buildtools.sh
```
-At this point, you are ready to build go-algorand. We use `make` and have a
-number of targets to automate common tasks.
+At this point, you are ready to build go-algorand. We use `make` and have several targets to automate common tasks.
+
+### Build
-#### build
```bash
make install
```
-#### test
+### Test
+
```bash
-# unit tests
+# Unit tests
make test
-# integration tests
+# Integration tests
make integration
```
-#### style and checks
+### Style and Checks
+
```bash
make fmt
make lint
make fix
make vet
```
-or alternatively
+
+Alternatively, run:
+
```bash
make sanity
```
-### Running a node
+## Running a Node
+
+Once the software is built, you'll find binaries in `${GOPATH}/bin`, and a data directory will be initialized at `~/.algorand`. Start your node with:
+
+```bash
+${GOPATH}/bin/goal node start -d ~/.algorand
+```
-Once the software is built you'll find binaries in `${GOPATH}/bin`, and a data
-directory will be initialized at `~/.algorand`. Start your node with
-`${GOPATH}/bin/goal node start -d ~/.algorand`, use `${GOPATH}/bin/carpenter -d
-~/.algorand` to see activity. Refer to the [developer website][developer site
-url] for how to use the different tools.
+Use:
+
+```bash
+${GOPATH}/bin/carpenter -d ~/.algorand
+```
+
+to see activity. Refer to the [developer website](https://developer.algorand.org/) for instructions on using different tools.
+
+### Providing Your Own Data Directory
+
+You can run a node out of other directories than `~/.algorand` and join networks other than mainnet. Just make a new directory and copy the `genesis.json` file for the network into it. For example:
-#### Providing your own data directory
-You can run a node out of other directories than `~/.algorand` and join networks
-other than mainnet. Just make a new directory and copy into it the
-`genesis.json` file for the network. For example:
```bash
mkdir ~/testnet_data
cp installer/genesis/testnet/genesis.json ~/testnet_data/genesis.json
${GOPATH}/bin/goal node start -d ~/testnet_data
```
-Genesis files for mainnet, testnet, and betanet can be found in
-`installer/genesis/`.
+
+Genesis files for mainnet, testnet, and betanet can be found in `installer/genesis/`.
## Contributing
Please refer to our [CONTRIBUTING](CONTRIBUTING.md) document.
-
## Project Layout
-`go-algorand` is split into various subsystems containing various packages.
+`go-algorand` is organized into various subsystems and packages:
### Core
Provides core functionality to the `algod` and `kmd` daemons, as well as other tools and commands:
- - `crypto` contains the cryptographic constructions we're using for hashing,
- signatures, and VRFs. There are also some Algorand-specific details here
- about spending keys, protocols keys, one-time-use signing keys, and how they
- relate to each other.
- - `config` holds configuration parameters. These include parameters used
- locally by the node as well as parameters that must be agreed upon by the
- protocol.
- - `data` defines various types used throughout the codebase.
- - `basics` hold basic types such as MicroAlgos, account data, and
- addresses.
- - `account` defines accounts, including "root" accounts (which can
- spend money) and "participation" accounts (which can participate in
- the agreement protocol).
- - `transactions` define transactions that accounts can issue against
- the Algorand state. These include standard payments and also
- participation key registration transactions.
- - `bookkeeping` defines blocks, which are batches of transactions
- atomically committed to Algorand.
- - `pools` implement the transaction pool. The transaction pool holds
- transactions seen by a node in memory before they are proposed in a
- block.
- - `committee` implements the credentials that authenticate a
- participating account's membership in the agreement protocol.
- - `ledger` ([README](ledger/README.md)) contains the Algorand Ledger state
- machine, which holds the sequence of blocks. The Ledger executes the state
- transitions that result from applying these blocks. It answers queries on
- blocks (e.g., what transactions were in the last committed block?) and on
- accounts (e.g., what is my balance?).
- - `protocol` declares constants used to identify protocol versions, tags for
- routing network messages, and prefixes for domain separation of
- cryptographic inputs. It also implements the canonical encoder.
- - `network` contains the code for participating in a mesh network based on
- WebSockets. Maintains connection to some number of peers, (optionally)
- accepts connections from peers, sends point to point and broadcast messages,
- and receives messages routing them to various handler code
- (e.g. agreement/gossip/network.go registers three handlers).
- - `rpcs` contains the HTTP RPCs used by `algod` processes to query one
- another.
- - `agreement` ([README](agreement/README.md)) contains the agreement service,
- which implements Algorand's Byzantine Agreement protocol. This protocol
- allows participating accounts to quickly confirm blocks in a fork-safe
- manner, provided that sufficient account stake is correctly executing the
- protocol.
- - `node` integrates the components above and handles initialization and
- shutdown. It provides queries into these components.
+- **crypto**: Contains the cryptographic constructions used for hashing, signatures, and VRFs. It also includes Algorand-specific details about spending keys, protocol keys, one-time-use signing keys, and how they relate to each other.
+- **config**: Holds configuration parameters, including those used locally by the node and those that must be agreed upon by the protocol.
+- **data**: Defines various types used throughout the codebase.
+ - **basics**: Holds basic types such as MicroAlgos, account data, and addresses.
+ - **account**: Defines accounts, including "root" accounts (which can spend money) and "participation" accounts (which can participate in the agreement protocol).
+ - **transactions**: Defines transactions that accounts can issue against the Algorand state, including standard payments and participation key registration transactions.
+ - **bookkeeping**: Defines blocks, which are batches of transactions atomically committed to Algorand.
+ - **pools**: Implements the transaction pool, holding transactions seen by a node in memory before they are proposed in a block.
+ - **committee**: Implements the credentials that authenticate a participating account's membership in the agreement protocol.
+- **ledger** ([README](ledger/README.md)): Contains the Algorand Ledger state machine, which holds the sequence of blocks. The Ledger executes the state transitions resulting from applying these blocks. It answers queries on blocks (e.g., what transactions were in the last committed block?) and on accounts (e.g., what is my balance?).
+- **protocol**: Declares constants used to identify protocol versions, tags for routing network messages, and prefixes for domain separation of cryptographic inputs. It also implements the canonical encoder.
+- **network**: Contains the code for participating in a mesh network based on WebSockets. It maintains connections to some number of peers, (optionally) accepts connections from peers, sends point-to-point and broadcast messages, and receives messages, routing them to various handler code (e.g., agreement/gossip/network.go registers three handlers).
+ - **rpcs**: Contains the HTTP RPCs used by `algod` processes to query one another.
+- **agreement** ([README](agreement/README.md)): Contains the agreement service, which implements Algorand's Byzantine Agreement protocol. This protocol allows participating accounts to quickly confirm blocks in a fork-safe manner, provided that sufficient account stake is correctly executing the protocol.
+- **node**: Integrates the components above and handles initialization and shutdown. It provides queries into these components.
### Daemon
-Contains the two daemons which provide Algorand clients with services:
+Contains the two daemons that provide Algorand clients with services:
- - `daemon/algod` holds the `algod` daemon, which implements a participating
- node. `algod` allows a node to participate in the agreement protocol,
- submit and confirm transactions, and view the state of the Algorand Ledger.
- - `daemon/algod/api` ([README](daemon/algod/api/README.md)) is the REST
- interface used for interactions with algod.
- - `daemon/kmd` ([README](daemon/kmd/README.md)) holds the `kmd` daemon. This
- daemon allows a node to sign transactions. Because `kmd` is separate from
- `algod`, `kmd` allows a user to sign transactions on an air-gapped computer.
+- **daemon/algod**: Holds the `algod` daemon, which implements a participating node. `algod` allows a node to participate in the agreement protocol, submit and confirm transactions, and view the state of the Algorand Ledger.
+ - **daemon/algod/api** ([README](daemon/algod/api/README.md)): The REST interface used for interactions with `algod`.
+- **daemon/kmd** ([README](daemon/kmd/README.md)): Holds the `kmd` daemon, which allows a node to sign transactions. Since `kmd` is separate from `algod`, it enables a user to sign transactions on an air-gapped computer.
### Interfacing
-Allows developers to interface with the Algorand system:
+Enables developers to interface with the Algorand system:
- - `cmd` holds the primary commands defining entry points into the system.
- - `cmd/catchupsrv` ([README](cmd/catchupsrv/README.md)) is a tool to
- assist with processing historic blocks on a new node.
- - `libgoal` exports a Go interface useful for developers of Algorand clients.
- - `tools` ([README](tools/README.md)) various tools and utilities without a better place to go.
- - `tools/debug` holds secondary commands which assist developers during debugging.
- - `tools/misc` ([README](tools/misc/README.md)) small tools that are sometimes handy in a pinch.
+- **cmd**: Contains the primary commands defining entry points into the system.
+ - **cmd/catchupsrv** ([README](cmd/catchupsrv/README.md)): A tool to assist with processing historic blocks on a new node.
+- **libgoal**: Exports a Go interface useful for developers of Algorand clients.
+- **tools** ([README](tools/README.md)): Various tools and utilities that don’t have a better place to go.
+- **tools/debug**: Holds secondary commands that assist developers during debugging.
+- **tools/misc** ([README](tools/misc/README.md)): Small tools that are handy in a pinch.
### Deployment
-Help Algorand developers deploy networks of their own:
- - `nodecontrol`
- - `docker`
- - `commandandcontrol` ([README](test/commandandcontrol/README.md)) is a tool to
- automate a network of algod instances.
- - `components`
- - `netdeploy`
+Helps Algorand developers deploy networks of their own:
+
+- **nodecontrol**
+- **docker**
+- **commandandcontrol** ([README](test/commandandcontrol/README.md)): A tool to automate a network of `algod` instances.
+- **components**
+- **netdeploy**
### Utilities
+
Provides utilities for the various components:
- - `logging` is a wrapper around `logrus`.
- - `util` contains a variety of utilities, including a codec, a SQLite wrapper,
- a goroutine pool, a timer interface, node metrics, and more.
+- **logging**: A wrapper around `logrus`.
+- **util**: Contains a variety of utilities, including a codec, a SQLite wrapper, a goroutine pool, a timer interface, node metrics, and more.
### Test
-`test` ([README](test/README.md)) contains end-to-end tests and utilities for the above components.
+- **test** ([README](test/README.md)): Contains end-to-end tests and utilities for the above components.
## License
+
[![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](COPYING)
-Please see the [COPYING_FAQ](COPYING_FAQ) for details about how to apply our license.
+Please see the [COPYING_FAQ](COPYING_FAQ) for details on how to apply our license.
Copyright (C) 2019-2024, Algorand Inc.
-[developer site url]: https://developer.algorand.org/
diff --git a/agreement/agreementtest/simulate_test.go b/agreement/agreementtest/simulate_test.go
index 6c071ed8a8..02ba048cb7 100644
--- a/agreement/agreementtest/simulate_test.go
+++ b/agreement/agreementtest/simulate_test.go
@@ -19,6 +19,7 @@ package agreementtest
import (
"context"
"fmt"
+ "maps"
"math/rand"
"os"
"strconv"
@@ -27,7 +28,6 @@ import (
"github.com/algorand/go-deadlock"
"github.com/stretchr/testify/require"
- "golang.org/x/exp/maps"
"github.com/algorand/go-algorand/agreement"
"github.com/algorand/go-algorand/config"
diff --git a/agreement/autopsy.go b/agreement/autopsy.go
index 82df84473a..dd9fe81420 100644
--- a/agreement/autopsy.go
+++ b/agreement/autopsy.go
@@ -20,11 +20,11 @@ import (
"fmt"
"io"
"os"
+ "slices"
"github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/logging"
"github.com/algorand/go-algorand/protocol"
- "golang.org/x/exp/slices"
)
// An Autopsy is a trace of the ordered input events and output
diff --git a/agreement/common_test.go b/agreement/common_test.go
index ca8983705e..f468bae4a1 100644
--- a/agreement/common_test.go
+++ b/agreement/common_test.go
@@ -19,12 +19,12 @@ package agreement
import (
"context"
"fmt"
+ "maps"
"math/rand"
"testing"
"github.com/algorand/go-deadlock"
"github.com/stretchr/testify/require"
- "golang.org/x/exp/maps"
"github.com/algorand/go-algorand/config"
"github.com/algorand/go-algorand/crypto"
diff --git a/agreement/gossip/networkFull_test.go b/agreement/gossip/networkFull_test.go
index e64811d6a9..fa0133d1a7 100644
--- a/agreement/gossip/networkFull_test.go
+++ b/agreement/gossip/networkFull_test.go
@@ -362,6 +362,7 @@ func testNetworkImplFull(t *testing.T, nodesCount int) {
// which is a different test of logic that agremeent needs to
// deal with.
cfg := config.GetDefaultLocal()
+ cfg.MaxConnectionsPerIP = nodesCount
cfg.AgreementIncomingVotesQueueLength = 100
cfg.AgreementIncomingProposalsQueueLength = 100
cfg.AgreementIncomingBundlesQueueLength = 100
diff --git a/catchup/ledgerFetcher_test.go b/catchup/ledgerFetcher_test.go
index a080aca31e..71562984bb 100644
--- a/catchup/ledgerFetcher_test.go
+++ b/catchup/ledgerFetcher_test.go
@@ -100,7 +100,6 @@ func TestLedgerFetcherErrorResponseHandling(t *testing.T) {
},
}
for _, tc := range testcases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
// create a dummy server.
diff --git a/cmd/algocfg/getCommand_test.go b/cmd/algocfg/getCommand_test.go
index 52587f7f90..b2b63c3763 100644
--- a/cmd/algocfg/getCommand_test.go
+++ b/cmd/algocfg/getCommand_test.go
@@ -56,7 +56,6 @@ func TestPrint(t *testing.T) {
},
}
for i, tc := range testcases {
- tc := tc
t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
t.Parallel()
ret, err := serializeObjectProperty(tc, "Input")
diff --git a/cmd/algod/main.go b/cmd/algod/main.go
index 47008256ac..306435ad94 100644
--- a/cmd/algod/main.go
+++ b/cmd/algod/main.go
@@ -194,6 +194,10 @@ func run() int {
log.Fatalf("Error validating DNSBootstrap input: %v", err)
}
+ // Apply network-specific consensus overrides, noting the configurable consensus protocols file
+ // takes precedence over network-specific overrides.
+ config.ApplyShorterUpgradeRoundsForDevNetworks(genesis.Network)
+
err = config.LoadConfigurableConsensusProtocols(absolutePath)
if err != nil {
// log is not setup yet, this will log to stderr
diff --git a/cmd/algokey/keyreg.go b/cmd/algokey/keyreg.go
index 43b072f4d0..4b034cef50 100644
--- a/cmd/algokey/keyreg.go
+++ b/cmd/algokey/keyreg.go
@@ -20,11 +20,12 @@ import (
"encoding/base64"
"errors"
"fmt"
+ "maps"
"os"
+ "slices"
"strings"
"github.com/spf13/cobra"
- "golang.org/x/exp/maps"
"github.com/algorand/go-algorand/crypto"
"github.com/algorand/go-algorand/data/account"
@@ -95,7 +96,7 @@ func init() {
"betanet": mustConvertB64ToDigest("mFgazF+2uRS1tMiL9dsj01hJGySEmPN28B/TjjvpVW0="),
"devnet": mustConvertB64ToDigest("sC3P7e2SdbqKJK0tbiCdK9tdSpbe6XeCGKdoNzmlj0E="),
}
- validNetworkList = maps.Keys(validNetworks)
+ validNetworkList = slices.Collect(maps.Keys(validNetworks))
}
func mustConvertB64ToDigest(b64 string) (digest crypto.Digest) {
diff --git a/cmd/goal/account.go b/cmd/goal/account.go
index 67d382bf45..b92d58f962 100644
--- a/cmd/goal/account.go
+++ b/cmd/goal/account.go
@@ -24,12 +24,12 @@ import (
"net/http"
"os"
"path/filepath"
+ "slices"
"sort"
"strings"
"time"
"github.com/spf13/cobra"
- "golang.org/x/exp/slices"
"github.com/algorand/go-algorand/cmd/util/datadir"
"github.com/algorand/go-algorand/config"
diff --git a/cmd/goal/application.go b/cmd/goal/application.go
index 0a42f65b5d..a949e78211 100644
--- a/cmd/goal/application.go
+++ b/cmd/goal/application.go
@@ -199,7 +199,7 @@ func panicIfErr(err error) {
func newAppCallBytes(arg string) apps.AppCallBytes {
appBytes, err := apps.NewAppCallBytes(arg)
if err != nil {
- reportErrorf(err.Error())
+ reportErrorln(err.Error())
}
return appBytes
}
@@ -508,7 +508,7 @@ var createAppCmd = &cobra.Command{
err = writeTxnToFile(client, sign, dataDir, walletName, tx, outFilename)
}
if err != nil {
- reportErrorf(err.Error())
+ reportErrorln(err.Error())
}
}
},
@@ -569,7 +569,7 @@ var updateAppCmd = &cobra.Command{
if !noWaitAfterSend {
_, err2 = waitForCommit(client, txid, lv)
if err2 != nil {
- reportErrorf(err2.Error())
+ reportErrorln(err2.Error())
}
}
} else {
@@ -579,7 +579,7 @@ var updateAppCmd = &cobra.Command{
err = writeTxnToFile(client, sign, dataDir, walletName, tx, outFilename)
}
if err != nil {
- reportErrorf(err.Error())
+ reportErrorln(err.Error())
}
}
},
@@ -639,7 +639,7 @@ var optInAppCmd = &cobra.Command{
if !noWaitAfterSend {
_, err2 = waitForCommit(client, txid, lv)
if err2 != nil {
- reportErrorf(err2.Error())
+ reportErrorln(err2.Error())
}
}
} else {
@@ -649,7 +649,7 @@ var optInAppCmd = &cobra.Command{
err = writeTxnToFile(client, sign, dataDir, walletName, tx, outFilename)
}
if err != nil {
- reportErrorf(err.Error())
+ reportErrorln(err.Error())
}
}
},
@@ -709,7 +709,7 @@ var closeOutAppCmd = &cobra.Command{
if !noWaitAfterSend {
_, err2 = waitForCommit(client, txid, lv)
if err2 != nil {
- reportErrorf(err2.Error())
+ reportErrorln(err2.Error())
}
}
} else {
@@ -719,7 +719,7 @@ var closeOutAppCmd = &cobra.Command{
err = writeTxnToFile(client, sign, dataDir, walletName, tx, outFilename)
}
if err != nil {
- reportErrorf(err.Error())
+ reportErrorln(err.Error())
}
}
},
@@ -779,7 +779,7 @@ var clearAppCmd = &cobra.Command{
if !noWaitAfterSend {
_, err2 = waitForCommit(client, txid, lv)
if err2 != nil {
- reportErrorf(err2.Error())
+ reportErrorln(err2.Error())
}
}
} else {
@@ -789,7 +789,7 @@ var clearAppCmd = &cobra.Command{
err = writeTxnToFile(client, sign, dataDir, walletName, tx, outFilename)
}
if err != nil {
- reportErrorf(err.Error())
+ reportErrorln(err.Error())
}
}
},
@@ -849,7 +849,7 @@ var callAppCmd = &cobra.Command{
if !noWaitAfterSend {
_, err2 = waitForCommit(client, txid, lv)
if err2 != nil {
- reportErrorf(err2.Error())
+ reportErrorln(err2.Error())
}
}
} else {
@@ -859,7 +859,7 @@ var callAppCmd = &cobra.Command{
err = writeTxnToFile(client, sign, dataDir, walletName, tx, outFilename)
}
if err != nil {
- reportErrorf(err.Error())
+ reportErrorln(err.Error())
}
}
},
@@ -919,7 +919,7 @@ var deleteAppCmd = &cobra.Command{
if !noWaitAfterSend {
_, err2 = waitForCommit(client, txid, lv)
if err2 != nil {
- reportErrorf(err2.Error())
+ reportErrorln(err2.Error())
}
}
} else {
@@ -929,7 +929,7 @@ var deleteAppCmd = &cobra.Command{
err = writeTxnToFile(client, sign, dataDir, walletName, tx, outFilename)
}
if err != nil {
- reportErrorf(err.Error())
+ reportErrorln(err.Error())
}
}
},
@@ -1442,7 +1442,7 @@ var methodAppCmd = &cobra.Command{
err = writeSignedTxnsToFile(signedTxnGroup, outFilename)
}
if err != nil {
- reportErrorf(err.Error())
+ reportErrorln(err.Error())
}
return
}
@@ -1472,12 +1472,12 @@ var methodAppCmd = &cobra.Command{
if !noWaitAfterSend {
_, err := waitForCommit(client, txid, lv)
if err != nil {
- reportErrorf(err.Error())
+ reportErrorln(err.Error())
}
resp, err := client.PendingTransactionInformation(txid)
if err != nil {
- reportErrorf(err.Error())
+ reportErrorln(err.Error())
}
if methodCreatesApp && resp.ApplicationIndex != nil && *resp.ApplicationIndex != 0 {
diff --git a/cmd/goal/application_test.go b/cmd/goal/application_test.go
index 1950337fdd..2f49a276a2 100644
--- a/cmd/goal/application_test.go
+++ b/cmd/goal/application_test.go
@@ -134,7 +134,6 @@ func TestParseMethodArgJSONtoByteSlice(t *testing.T) {
}
for i, test := range tests {
- test := test
t.Run(fmt.Sprintf("index=%d", i), func(t *testing.T) {
t.Parallel()
applicationArgs := [][]byte{}
diff --git a/cmd/goal/asset.go b/cmd/goal/asset.go
index d67e4f4acb..0263188048 100644
--- a/cmd/goal/asset.go
+++ b/cmd/goal/asset.go
@@ -402,7 +402,7 @@ var destroyAssetCmd = &cobra.Command{
if !noWaitAfterSend {
_, err2 = waitForCommit(client, txid, lastValid)
if err2 != nil {
- reportErrorf(err2.Error())
+ reportErrorln(err2.Error())
}
}
} else {
@@ -495,7 +495,7 @@ var configAssetCmd = &cobra.Command{
if !noWaitAfterSend {
_, err2 = waitForCommit(client, txid, lastValid)
if err2 != nil {
- reportErrorf(err2.Error())
+ reportErrorln(err2.Error())
}
}
} else {
@@ -582,7 +582,7 @@ var sendAssetCmd = &cobra.Command{
if !noWaitAfterSend {
_, err2 = waitForCommit(client, txid, lastValid)
if err2 != nil {
- reportErrorf(err2.Error())
+ reportErrorln(err2.Error())
}
}
} else {
@@ -651,7 +651,7 @@ var freezeAssetCmd = &cobra.Command{
if !noWaitAfterSend {
_, err2 = waitForCommit(client, txid, lastValid)
if err2 != nil {
- reportErrorf(err2.Error())
+ reportErrorln(err2.Error())
}
}
} else {
@@ -740,13 +740,13 @@ var optinAssetCmd = &cobra.Command{
if !noWaitAfterSend {
_, err2 = waitForCommit(client, txid, lastValid)
if err2 != nil {
- reportErrorf(err2.Error())
+ reportErrorln(err2.Error())
}
}
} else {
err = writeTxnToFile(client, sign, dataDir, walletName, tx, outFilename)
if err != nil {
- reportErrorf(err.Error())
+ reportErrorln(err.Error())
}
}
},
diff --git a/cmd/goal/clerk.go b/cmd/goal/clerk.go
index 1a2495007d..9387918881 100644
--- a/cmd/goal/clerk.go
+++ b/cmd/goal/clerk.go
@@ -555,7 +555,7 @@ var sendCmd = &cobra.Command{
err = writeFile(outFilename, protocol.Encode(&stx), 0600)
}
if err != nil {
- reportErrorf(err.Error())
+ reportErrorln(err.Error())
}
}
},
@@ -979,16 +979,6 @@ func assembleFileImpl(fname string, printWarnings bool) *logic.OpStream {
ops.ReportMultipleErrors(fname, os.Stderr)
reportErrorf("%s: %s", fname, err)
}
- _, params := getProto(protoVersion)
- if ops.HasStatefulOps {
- if len(ops.Program) > config.MaxAvailableAppProgramLen {
- reportErrorf(tealAppSize, fname, len(ops.Program), config.MaxAvailableAppProgramLen)
- }
- } else {
- if uint64(len(ops.Program)) > params.LogicSigMaxSize {
- reportErrorf(tealLogicSigSize, fname, len(ops.Program), params.LogicSigMaxSize)
- }
- }
if printWarnings && len(ops.Warnings) != 0 {
for _, warning := range ops.Warnings {
@@ -1165,7 +1155,7 @@ var dryrunCmd = &cobra.Command{
client := ensureFullClient(dataDir)
accts, err := unmarshalSlice(dumpForDryrunAccts)
if err != nil {
- reportErrorf(err.Error())
+ reportErrorln(err.Error())
}
data, err := libgoal.MakeDryrunStateBytes(client, nil, stxns, accts, string(proto), dumpForDryrunFormat.String())
if err != nil {
@@ -1178,14 +1168,19 @@ var dryrunCmd = &cobra.Command{
if timeStamp <= 0 {
timeStamp = time.Now().Unix()
}
+
+ lSigPooledSize := 0
for i, txn := range stxns {
if txn.Lsig.Blank() {
continue
}
- if uint64(txn.Lsig.Len()) > params.LogicSigMaxSize {
+ lsigLen := txn.Lsig.Len()
+ lSigPooledSize += lsigLen
+ if !params.EnableLogicSigSizePooling && uint64(lsigLen) > params.LogicSigMaxSize {
reportErrorf("program size too large: %d > %d", len(txn.Lsig.Logic), params.LogicSigMaxSize)
}
ep := logic.NewSigEvalParams(stxns, ¶ms, logic.NoHeaderLedger{})
+
err := logic.CheckSignature(i, ep)
if err != nil {
reportErrorf("program failed Check: %s", err)
@@ -1203,6 +1198,10 @@ var dryrunCmd = &cobra.Command{
fmt.Fprintf(os.Stdout, "ERROR: %s\n", err.Error())
}
}
+ lSigMaxPooledSize := len(stxns) * int(params.LogicSigMaxSize)
+ if params.EnableLogicSigSizePooling && lSigPooledSize > lSigMaxPooledSize {
+ reportErrorf("total lsigs size too large: %d > %d", lSigPooledSize, lSigMaxPooledSize)
+ }
},
}
diff --git a/cmd/goal/clerk_test.go b/cmd/goal/clerk_test.go
index 2efc67f3a7..92bcd0315a 100644
--- a/cmd/goal/clerk_test.go
+++ b/cmd/goal/clerk_test.go
@@ -75,7 +75,6 @@ func TestDeterminePathToSourceFromSourceMap(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
diff --git a/cmd/goal/commands.go b/cmd/goal/commands.go
index 3ba9891d7d..4758abbc3a 100644
--- a/cmd/goal/commands.go
+++ b/cmd/goal/commands.go
@@ -529,11 +529,11 @@ func writeDryrunReqToFile(client libgoal.Client, txnOrStxn interface{}, outFilen
proto, _ := getProto(protoVersion)
accts, err := unmarshalSlice(dumpForDryrunAccts)
if err != nil {
- reportErrorf(err.Error())
+ reportErrorln(err.Error())
}
data, err := libgoal.MakeDryrunStateBytes(client, txnOrStxn, []transactions.SignedTxn{}, accts, string(proto), dumpForDryrunFormat.String())
if err != nil {
- reportErrorf(err.Error())
+ reportErrorln(err.Error())
}
err = writeFile(outFilename, data, 0600)
return
diff --git a/cmd/goal/formatting_test.go b/cmd/goal/formatting_test.go
index 1247cddf14..158271cf44 100644
--- a/cmd/goal/formatting_test.go
+++ b/cmd/goal/formatting_test.go
@@ -115,7 +115,6 @@ func TestBytesToAppCallBytes(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.expected, func(t *testing.T) {
t.Parallel()
acb := encodeBytesAsAppCallBytes(tc.input)
diff --git a/cmd/goal/node_test.go b/cmd/goal/node_test.go
index bdbcf31b54..e789c786a2 100644
--- a/cmd/goal/node_test.go
+++ b/cmd/goal/node_test.go
@@ -85,7 +85,6 @@ func TestGetMissingCatchpointLabel(t *testing.T) {
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
diff --git a/cmd/loadgenerator/main.go b/cmd/loadgenerator/main.go
index df142de4ce..00b3a96727 100644
--- a/cmd/loadgenerator/main.go
+++ b/cmd/loadgenerator/main.go
@@ -69,14 +69,14 @@ func findRootKeys(algodDir string) []*crypto.SignatureSecrets {
var handle db.Accessor
handle, err := db.MakeErasableAccessor(path)
if err != nil {
- return nil //nolint:nilerr // don't care, move on
+ return nil
}
defer handle.Close()
// Fetch an account.Participation from the database
root, err := algodAcct.RestoreRoot(handle)
if err != nil {
- return nil //nolint:nilerr // don't care, move on
+ return nil
}
keylist = append(keylist, root.Secrets())
return nil
diff --git a/cmd/partitiontest_linter/go.mod b/cmd/partitiontest_linter/go.mod
index 871ea35935..bb2ceb5d74 100644
--- a/cmd/partitiontest_linter/go.mod
+++ b/cmd/partitiontest_linter/go.mod
@@ -1,12 +1,12 @@
module github.com/algorand/go-algorand/cmd/partitiontest_linter
-go 1.21
+go 1.23
-toolchain go1.21.10
+toolchain go1.23.3
require (
- golang.org/x/mod v0.17.0 // indirect
- golang.org/x/sync v0.7.0 // indirect
+ golang.org/x/mod v0.22.0 // indirect
+ golang.org/x/sync v0.9.0 // indirect
)
-require golang.org/x/tools v0.20.0
+require golang.org/x/tools v0.27.0
diff --git a/cmd/partitiontest_linter/go.sum b/cmd/partitiontest_linter/go.sum
index 9e7e462a7c..394d668cc6 100644
--- a/cmd/partitiontest_linter/go.sum
+++ b/cmd/partitiontest_linter/go.sum
@@ -1,6 +1,8 @@
-golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
-golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
-golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
-golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
-golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY=
-golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
+golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
+golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
+golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o=
+golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q=
diff --git a/cmd/tealdbg/local.go b/cmd/tealdbg/local.go
index 6f61fb2da3..332b581cfb 100644
--- a/cmd/tealdbg/local.go
+++ b/cmd/tealdbg/local.go
@@ -20,6 +20,7 @@ import (
"fmt"
"io"
"log"
+ "slices"
"time"
"github.com/algorand/go-algorand/config"
@@ -28,7 +29,6 @@ import (
"github.com/algorand/go-algorand/data/transactions/logic"
"github.com/algorand/go-algorand/ledger/apply"
"github.com/algorand/go-algorand/protocol"
- "golang.org/x/exp/slices"
)
func protoFromString(protoString string) (name string, proto config.ConsensusParams, err error) {
diff --git a/cmd/tealdbg/local_test.go b/cmd/tealdbg/local_test.go
index c290b67142..78558d8cf2 100644
--- a/cmd/tealdbg/local_test.go
+++ b/cmd/tealdbg/local_test.go
@@ -1265,7 +1265,6 @@ int 1`
}
for _, test := range tests {
- test := test
t.Run(fmt.Sprintf("fee=%d", test.fee), func(t *testing.T) {
t.Parallel()
stxn := transactions.SignedTxn{
@@ -1395,7 +1394,6 @@ byte 0x5ce9454909639d2d17a3f753ce7d93fa0b9ab12e // addr
}},
}
for _, test := range tests {
- test := test
t.Run(fmt.Sprintf("txn-count=%d", test.additionalApps+1), func(t *testing.T) {
t.Parallel()
txnBlob := protocol.EncodeMsgp(&stxn)
diff --git a/config/config_test.go b/config/config_test.go
index 936622b06c..fd16bb0813 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -725,7 +725,6 @@ func TestLocal_RecalculateConnectionLimits(t *testing.T) {
}
for i, test := range tests {
- test := test
t.Run(fmt.Sprintf("test=%d", i), func(t *testing.T) {
t.Parallel()
@@ -772,8 +771,8 @@ func TestLocal_ValidateP2PHybridConfig(t *testing.T) {
}
for i, test := range tests {
- test := test
- t.Run(fmt.Sprintf("test=%d", i), func(t *testing.T) {
+ name := fmt.Sprintf("test=%d", i)
+ t.Run(name, func(t *testing.T) {
t.Parallel()
c := Local{
@@ -782,7 +781,7 @@ func TestLocal_ValidateP2PHybridConfig(t *testing.T) {
NetAddress: test.netAddress,
}
err := c.ValidateP2PHybridConfig()
- require.Equal(t, test.err, err != nil, "test=%d", i)
+ require.Equal(t, test.err, err != nil, name)
})
}
}
diff --git a/config/consensus.go b/config/consensus.go
index 58678571ab..debecca244 100644
--- a/config/consensus.go
+++ b/config/consensus.go
@@ -113,9 +113,13 @@ type ConsensusParams struct {
EnableAppCostPooling bool
// EnableLogicSigCostPooling specifies LogicSig budgets are pooled across a
- // group. The total available is len(group) * LogicSigMaxCost)
+ // group. The total available is len(group) * LogicSigMaxCost
EnableLogicSigCostPooling bool
+ // EnableLogicSigSizePooling specifies LogicSig sizes are pooled across a
+ // group. The total available is len(group) * LogicSigMaxSize
+ EnableLogicSigSizePooling bool
+
// RewardUnit specifies the number of MicroAlgos corresponding to one reward
// unit.
//
@@ -228,7 +232,7 @@ type ConsensusParams struct {
// 0 for no support, otherwise highest version supported
LogicSigVersion uint64
- // len(LogicSig.Logic) + len(LogicSig.Args[*]) must be less than this
+ // len(LogicSig.Logic) + len(LogicSig.Args[*]) must be less than this (unless pooling is enabled)
LogicSigMaxSize uint64
// sum of estimated op cost must be less than this
@@ -768,7 +772,7 @@ func checkSetAllocBounds(p ConsensusParams) {
checkSetMax(p.MaxAppProgramLen, &MaxStateDeltaKeys)
checkSetMax(p.MaxAppProgramLen, &MaxEvalDeltaAccounts)
checkSetMax(p.MaxAppProgramLen, &MaxAppProgramLen)
- checkSetMax(int(p.LogicSigMaxSize), &MaxLogicSigMaxSize)
+ checkSetMax((int(p.LogicSigMaxSize) * p.MaxTxGroupSize), &MaxLogicSigMaxSize)
checkSetMax(p.MaxTxnNoteBytes, &MaxTxnNoteBytes)
checkSetMax(p.MaxTxGroupSize, &MaxTxGroupSize)
// MaxBytesKeyValueLen is max of MaxAppKeyLen and MaxAppBytesValueLen
@@ -1515,6 +1519,8 @@ func initConsensusProtocols() {
vFuture.LogicSigVersion = 11 // When moving this to a release, put a new higher LogicSigVersion here
+ vFuture.EnableLogicSigSizePooling = true
+
vFuture.Payouts.Enabled = true
vFuture.Payouts.Percent = 50
vFuture.Payouts.GoOnlineFee = 2_000_000 // 2 algos
@@ -1565,6 +1571,23 @@ func initConsensusProtocols() {
vAlpha4.ApprovedUpgrades[protocol.ConsensusVAlpha5] = 10000
}
+// ApplyShorterUpgradeRoundsForDevNetworks applies a shorter upgrade round time for the Devnet and Betanet networks.
+// This function should not take precedence over settings loaded via `PreloadConfigurableConsensusProtocols`.
+func ApplyShorterUpgradeRoundsForDevNetworks(id protocol.NetworkID) {
+ if id == Betanet || id == Devnet {
+ // Go through all approved upgrades and set to the MinUpgradeWaitRounds valid where MinUpgradeWaitRounds is set
+ for _, p := range Consensus {
+ if p.ApprovedUpgrades != nil {
+ for v := range p.ApprovedUpgrades {
+ if p.MinUpgradeWaitRounds > 0 {
+ p.ApprovedUpgrades[v] = p.MinUpgradeWaitRounds
+ }
+ }
+ }
+ }
+ }
+}
+
// Global defines global Algorand protocol parameters which should not be overridden.
type Global struct {
SmallLambda time.Duration // min amount of time to wait for leader's credential (i.e., time to propagate one credential)
diff --git a/config/consensus_test.go b/config/consensus_test.go
index 635ad5699c..6bc8d45c45 100644
--- a/config/consensus_test.go
+++ b/config/consensus_test.go
@@ -64,6 +64,83 @@ func TestConsensusUpgradeWindow(t *testing.T) {
}
}
+func TestConsensusUpgradeWindow_NetworkOverrides(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ ApplyShorterUpgradeRoundsForDevNetworks(Devnet)
+ for _, params := range Consensus {
+ for toVersion, delay := range params.ApprovedUpgrades {
+ if params.MinUpgradeWaitRounds != 0 || params.MaxUpgradeWaitRounds != 0 {
+ require.NotZerof(t, delay, "From :%v\nTo :%v", params, toVersion)
+ require.Equalf(t, delay, params.MinUpgradeWaitRounds, "From :%v\nTo :%v", params, toVersion)
+ // This check is not really needed, but leaving for sanity
+ require.LessOrEqualf(t, delay, params.MaxUpgradeWaitRounds, "From :%v\nTo :%v", params, toVersion)
+ } else {
+ // If no MinUpgradeWaitRounds is set, leaving everything as zero value is expected
+ require.Zerof(t, delay, "From :%v\nTo :%v", params, toVersion)
+ }
+ }
+ }
+
+ // Should be no-ops for Mainnet
+ Consensus = make(ConsensusProtocols)
+ initConsensusProtocols()
+
+ origConsensus := Consensus.DeepCopy()
+ ApplyShorterUpgradeRoundsForDevNetworks(Mainnet)
+ require.EqualValues(t, origConsensus, Consensus)
+ for _, params := range Consensus {
+ for toVersion, delay := range params.ApprovedUpgrades {
+ if params.MinUpgradeWaitRounds != 0 || params.MaxUpgradeWaitRounds != 0 {
+ require.NotZerof(t, delay, "From :%v\nTo :%v", params, toVersion)
+ require.GreaterOrEqualf(t, delay, params.MinUpgradeWaitRounds, "From :%v\nTo :%v", params, toVersion)
+ require.LessOrEqualf(t, delay, params.MaxUpgradeWaitRounds, "From :%v\nTo :%v", params, toVersion)
+ } else {
+ require.Zerof(t, delay, "From :%v\nTo :%v", params, toVersion)
+
+ }
+ }
+ }
+
+ // reset consensus settings
+ Consensus = make(ConsensusProtocols)
+ initConsensusProtocols()
+
+ ApplyShorterUpgradeRoundsForDevNetworks(Betanet)
+ for _, params := range Consensus {
+ for toVersion, delay := range params.ApprovedUpgrades {
+ if params.MinUpgradeWaitRounds != 0 || params.MaxUpgradeWaitRounds != 0 {
+ require.NotZerof(t, delay, "From :%v\nTo :%v", params, toVersion)
+ require.Equalf(t, delay, params.MinUpgradeWaitRounds, "From :%v\nTo :%v", params, toVersion)
+ // This check is not really needed, but leaving for sanity
+ require.LessOrEqualf(t, delay, params.MaxUpgradeWaitRounds, "From :%v\nTo :%v", params, toVersion)
+ } else {
+ // If no MinUpgradeWaitRounds is set, leaving everything as zero value is expected
+ require.Zerof(t, delay, "From :%v\nTo :%v", params, toVersion)
+ }
+ }
+ }
+
+ // should be no-ops for Testnet
+ Consensus = make(ConsensusProtocols)
+ initConsensusProtocols()
+
+ ApplyShorterUpgradeRoundsForDevNetworks(Testnet)
+ require.EqualValues(t, origConsensus, Consensus)
+ for _, params := range Consensus {
+ for toVersion, delay := range params.ApprovedUpgrades {
+ if params.MinUpgradeWaitRounds != 0 || params.MaxUpgradeWaitRounds != 0 {
+ require.NotZerof(t, delay, "From :%v\nTo :%v", params, toVersion)
+ require.GreaterOrEqualf(t, delay, params.MinUpgradeWaitRounds, "From :%v\nTo :%v", params, toVersion)
+ require.LessOrEqualf(t, delay, params.MaxUpgradeWaitRounds, "From :%v\nTo :%v", params, toVersion)
+ } else {
+ require.Zerof(t, delay, "From :%v\nTo :%v", params, toVersion)
+
+ }
+ }
+ }
+}
+
func TestConsensusStateProofParams(t *testing.T) {
partitiontest.PartitionTest(t)
diff --git a/config/dnsbootstrap.go b/config/dnsbootstrap.go
index 3b027df9c3..17722e8952 100644
--- a/config/dnsbootstrap.go
+++ b/config/dnsbootstrap.go
@@ -17,6 +17,7 @@
package config
import (
+ "errors"
"fmt"
"net/url"
"regexp"
@@ -109,7 +110,7 @@ func parseDNSBootstrap(dnsBootstrapID string, network protocol.NetworkID, defaul
dnsBootstrapID = strings.Replace(strings.TrimSpace(strings.ToLower(dnsBootstrapID)), "", string(network), -1)
if dnsBootstrapID == "" {
- return nil, fmt.Errorf(bootstrapErrorEmpty)
+ return nil, errors.New(bootstrapErrorEmpty)
}
parsedTemplate, err := url.Parse(dnsBootstrapID)
diff --git a/config/localTemplate.go b/config/localTemplate.go
index bc9df5fbbc..0bb0c2a618 100644
--- a/config/localTemplate.go
+++ b/config/localTemplate.go
@@ -44,7 +44,7 @@ type Local struct {
// Version tracks the current version of the defaults so we can migrate old -> new
// This is specifically important whenever we decide to change the default value
// for an existing parameter. This field tag must be updated any time we add a new version.
- Version uint32 `version[0]:"0" version[1]:"1" version[2]:"2" version[3]:"3" version[4]:"4" version[5]:"5" version[6]:"6" version[7]:"7" version[8]:"8" version[9]:"9" version[10]:"10" version[11]:"11" version[12]:"12" version[13]:"13" version[14]:"14" version[15]:"15" version[16]:"16" version[17]:"17" version[18]:"18" version[19]:"19" version[20]:"20" version[21]:"21" version[22]:"22" version[23]:"23" version[24]:"24" version[25]:"25" version[26]:"26" version[27]:"27" version[28]:"28" version[29]:"29" version[30]:"30" version[31]:"31" version[32]:"32" version[33]:"33" version[34]:"34"`
+ Version uint32 `version[0]:"0" version[1]:"1" version[2]:"2" version[3]:"3" version[4]:"4" version[5]:"5" version[6]:"6" version[7]:"7" version[8]:"8" version[9]:"9" version[10]:"10" version[11]:"11" version[12]:"12" version[13]:"13" version[14]:"14" version[15]:"15" version[16]:"16" version[17]:"17" version[18]:"18" version[19]:"19" version[20]:"20" version[21]:"21" version[22]:"22" version[23]:"23" version[24]:"24" version[25]:"25" version[26]:"26" version[27]:"27" version[28]:"28" version[29]:"29" version[30]:"30" version[31]:"31" version[32]:"32" version[33]:"33" version[34]:"34" version[35]:"35"`
// Archival nodes retain a full copy of the block history. Non-Archival nodes will delete old blocks and only retain what's need to properly validate blockchain messages (the precise number of recent blocks depends on the consensus parameters. Currently the last 1321 blocks are required). This means that non-Archival nodes require significantly less storage than Archival nodes. If setting this to true for the first time, the existing ledger may need to be deleted to get the historical values stored as the setting only affects current blocks forward. To do this, shutdown the node and delete all .sqlite files within the data/testnet-version directory, except the crash.sqlite file. Restart the node and wait for the node to sync.
Archival bool `version[0]:"false"`
@@ -66,7 +66,7 @@ type Local struct {
PublicAddress string `version[0]:""`
// MaxConnectionsPerIP is the maximum number of connections allowed per IP address.
- MaxConnectionsPerIP int `version[3]:"30" version[27]:"15"`
+ MaxConnectionsPerIP int `version[3]:"30" version[27]:"15" version[35]:"8"`
// PeerPingPeriodSeconds is deprecated and unused.
PeerPingPeriodSeconds int `version[0]:"0"`
@@ -171,7 +171,7 @@ type Local struct {
EndpointAddress string `version[0]:"127.0.0.1:0"`
// Respond to Private Network Access preflight requests sent to the node. Useful when a public website is trying to access a node that's hosted on a local network.
- EnablePrivateNetworkAccessHeader bool `version[34]:"false"`
+ EnablePrivateNetworkAccessHeader bool `version[35]:"false"`
// RestReadTimeoutSeconds is passed to the API servers rest http.Server implementation.
RestReadTimeoutSeconds int `version[4]:"15"`
@@ -255,6 +255,12 @@ type Local struct {
// EnableTxBacklogAppRateLimiting controls if an app rate limiter should be attached to the tx backlog enqueue process
EnableTxBacklogAppRateLimiting bool `version[32]:"true"`
+ // TxBacklogAppRateLimitingCountERLDrops feeds messages dropped by the ERL congestion manager & rate limiter (enabled by
+ // EnableTxBacklogRateLimiting) to the app rate limiter (enabled by EnableTxBacklogAppRateLimiting), so that all TX messages
+ // are counted. This provides more accurate rate limiting for the app rate limiter, at the potential expense of additional
+ // deserialization overhead.
+ TxBacklogAppRateLimitingCountERLDrops bool `version[35]:"false"`
+
// EnableTxBacklogRateLimiting controls if a rate limiter and congestion manager should be attached to the tx backlog enqueue process
// if enabled, the over-all TXBacklog Size will be larger by MAX_PEERS*TxBacklogReservedCapacityPerPeer
EnableTxBacklogRateLimiting bool `version[27]:"false" version[30]:"true"`
@@ -683,10 +689,9 @@ func (cfg Local) SaveToDisk(root string) error {
// SaveAllToDisk writes the all Local settings into a root/ConfigFilename file
func (cfg Local) SaveAllToDisk(root string) error {
- configpath := filepath.Join(root, ConfigFilename)
- filename := os.ExpandEnv(configpath)
- prettyPrint := true
- return codecs.SaveObjectToFile(filename, cfg, prettyPrint)
+ configPath := filepath.Join(root, ConfigFilename)
+ filename := os.ExpandEnv(configPath)
+ return codecs.SaveObjectToFile(filename, cfg, true)
}
// SaveToFile saves the config to a specific filename, allowing overriding the default name
diff --git a/config/local_defaults.go b/config/local_defaults.go
index 4d2abb0053..2891184a21 100644
--- a/config/local_defaults.go
+++ b/config/local_defaults.go
@@ -20,7 +20,7 @@
package config
var defaultLocal = Local{
- Version: 34,
+ Version: 35,
AccountUpdatesStatsInterval: 5000000000,
AccountsRebuildSynchronousMode: 1,
AgreementIncomingBundlesQueueLength: 15,
@@ -111,7 +111,7 @@ var defaultLocal = Local{
MaxAcctLookback: 4,
MaxBlockHistoryLookback: 0,
MaxCatchpointDownloadDuration: 43200000000000,
- MaxConnectionsPerIP: 15,
+ MaxConnectionsPerIP: 8,
MinCatchpointFileDownloadBytesPerSecond: 20480,
NetAddress: "",
NetworkMessageTraceServer: "",
@@ -148,6 +148,7 @@ var defaultLocal = Local{
TrackerDBDir: "",
TransactionSyncDataExchangeRate: 0,
TransactionSyncSignificantMessageThreshold: 0,
+ TxBacklogAppRateLimitingCountERLDrops: false,
TxBacklogAppTxPerSecondRate: 100,
TxBacklogAppTxRateLimiterMaxSize: 1048576,
TxBacklogRateLimitingCongestionPct: 50,
diff --git a/config/version.go b/config/version.go
index 5a1b31ce0e..94a82a6ca8 100644
--- a/config/version.go
+++ b/config/version.go
@@ -33,7 +33,7 @@ const VersionMajor = 3
// VersionMinor is the Minor semantic version number (x.#.z) - changed when backwards-compatible features are introduced.
// Not enforced until after initial public release (x > 0).
-const VersionMinor = 26
+const VersionMinor = 28
// Version is the type holding our full version information.
type Version struct {
diff --git a/crypto/merklearray/merkle.go b/crypto/merklearray/merkle.go
index e540586b53..af74ad416f 100644
--- a/crypto/merklearray/merkle.go
+++ b/crypto/merklearray/merkle.go
@@ -21,10 +21,10 @@ import (
"errors"
"fmt"
"hash"
+ "slices"
"sort"
"github.com/algorand/go-algorand/crypto"
- "golang.org/x/exp/slices"
)
const (
diff --git a/crypto/merkletrie/cache.go b/crypto/merkletrie/cache.go
index d4d60b2c39..1491517e07 100644
--- a/crypto/merkletrie/cache.go
+++ b/crypto/merkletrie/cache.go
@@ -21,9 +21,8 @@ import (
"encoding/binary"
"errors"
"fmt"
-
- "golang.org/x/exp/maps"
- "golang.org/x/exp/slices"
+ "maps"
+ "slices"
)
// storedNodeIdentifier is the "equivalent" of a node-ptr, but oriented around persisting the
@@ -448,8 +447,7 @@ func (mtc *merkleTrieCache) reallocatePendingPages(stats *CommitStats) (pagesToC
}
// create a sorted list of created pages
- sortedCreatedPages := maps.Keys(createdPages)
- slices.Sort(sortedCreatedPages)
+ sortedCreatedPages := slices.Sorted(maps.Keys(createdPages))
mtc.reallocatedPages = make(map[uint64]map[storedNodeIdentifier]*node)
diff --git a/crypto/merkletrie/committer.go b/crypto/merkletrie/committer.go
index 66dd2c65c8..bbfb54966e 100644
--- a/crypto/merkletrie/committer.go
+++ b/crypto/merkletrie/committer.go
@@ -16,7 +16,7 @@
package merkletrie
-import "golang.org/x/exp/slices"
+import "slices"
// Committer is the interface supporting serializing tries into persistent storage.
type Committer interface {
diff --git a/crypto/merkletrie/committer_test.go b/crypto/merkletrie/committer_test.go
index 3dc6c39d2a..6260379aad 100644
--- a/crypto/merkletrie/committer_test.go
+++ b/crypto/merkletrie/committer_test.go
@@ -18,10 +18,10 @@ package merkletrie
import (
"encoding/binary"
+ "slices"
"testing"
"github.com/stretchr/testify/require"
- "golang.org/x/exp/slices"
"github.com/algorand/go-algorand/crypto"
"github.com/algorand/go-algorand/test/partitiontest"
diff --git a/crypto/merkletrie/node.go b/crypto/merkletrie/node.go
index f63d2b12ab..327a6eba65 100644
--- a/crypto/merkletrie/node.go
+++ b/crypto/merkletrie/node.go
@@ -19,11 +19,11 @@ package merkletrie
import (
"bytes"
"encoding/binary"
+ "slices"
"sort"
"unsafe"
"github.com/algorand/go-algorand/crypto"
- "golang.org/x/exp/slices"
)
type childEntry struct {
diff --git a/daemon/algod/api/algod.oas2.json b/daemon/algod/api/algod.oas2.json
index 1e5db8d9bc..51cd801803 100644
--- a/daemon/algod/api/algod.oas2.json
+++ b/daemon/algod/api/algod.oas2.json
@@ -826,6 +826,68 @@
}
}
},
+ "/v2/blocks/{round}/header": {
+ "get": {
+ "tags": [
+ "public",
+ "nonparticipating"
+ ],
+ "produces": [
+ "application/json",
+ "application/msgpack"
+ ],
+ "schemes": [
+ "http"
+ ],
+ "summary": "Get the block header for the block on the given round.",
+ "operationId": "GetBlockHeader",
+ "parameters": [
+ {
+ "minimum": 0,
+ "type": "integer",
+ "description": "The round from which to fetch block header information.",
+ "name": "round",
+ "in": "path",
+ "required": true
+ },
+ {
+ "$ref": "#/parameters/format"
+ }
+ ],
+ "responses": {
+ "200": {
+ "$ref": "#/responses/BlockHeaderResponse"
+ },
+ "400": {
+ "description": "Bad Request - Non integer number",
+ "schema": {
+ "$ref": "#/definitions/ErrorResponse"
+ }
+ },
+ "401": {
+ "description": "Invalid API Token",
+ "schema": {
+ "$ref": "#/definitions/ErrorResponse"
+ }
+ },
+ "404": {
+ "description": "None existing block ",
+ "schema": {
+ "$ref": "#/definitions/ErrorResponse"
+ }
+ },
+ "500": {
+ "description": "Internal Error",
+ "schema": {
+ "$ref": "#/definitions/ErrorResponse"
+ }
+ },
+ "default": {
+ "description": "Unknown Error"
+ }
+ }
+ }
+ },
"/v2/blocks/{round}/transactions/{txid}/proof": {
"get": {
"tags": [
@@ -5106,6 +5168,22 @@
}
}
},
+ "BlockHeaderResponse": {
+ "description": "Block header.",
+ "schema": {
+ "type": "object",
+ "required": [
+ "blockHeader"
+ ],
+ "properties": {
+ "blockHeader": {
+ "description": "Block header data.",
+ "type": "object",
+ "x-algorand-format": "BlockHeader"
+ }
+ }
+ }
+ },
"TransactionProofResponse": {
"description": "Proof of transaction in a block.",
"schema": {
diff --git a/daemon/algod/api/algod.oas3.yml b/daemon/algod/api/algod.oas3.yml
index 57bc22ce87..34832fcda3 100644
--- a/daemon/algod/api/algod.oas3.yml
+++ b/daemon/algod/api/algod.oas3.yml
@@ -352,6 +352,27 @@
},
"description": "Hash of a block header."
},
+ "BlockHeaderResponse": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "properties": {
+ "blockHeader": {
+ "description": "Block header data.",
+ "properties": {},
+ "type": "object",
+ "x-algorand-format": "BlockHeader"
+ }
+ },
+ "required": [
+ "blockHeader"
+ ],
+ "type": "object"
+ }
+ }
+ },
+ "description": "Block header."
+ },
"BlockLogsResponse": {
"content": {
"application/json": {
@@ -4203,6 +4224,143 @@
]
}
},
+ "/v2/blocks/{round}/header": {
+ "get": {
+ "operationId": "GetBlockHeader",
+ "parameters": [
+ {
+ "description": "The round from which to fetch block header information.",
+ "in": "path",
+ "name": "round",
+ "required": true,
+ "schema": {
+ "minimum": 0,
+ "type": "integer"
+ }
+ },
+ {
+ "description": "Configures whether the response object is JSON or MessagePack encoded. If not provided, defaults to JSON.",
+ "in": "query",
+ "name": "format",
+ "schema": {
+ "enum": [
+ "json",
+ "msgpack"
+ ],
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "properties": {
+ "blockHeader": {
+ "description": "Block header data.",
+ "properties": {},
+ "type": "object",
+ "x-algorand-format": "BlockHeader"
+ }
+ },
+ "required": [
+ "blockHeader"
+ ],
+ "type": "object"
+ }
+ },
+ "application/msgpack": {
+ "schema": {
+ "properties": {
+ "blockHeader": {
+ "description": "Block header data.",
+ "properties": {},
+ "type": "object",
+ "x-algorand-format": "BlockHeader"
+ }
+ },
+ "required": [
+ "blockHeader"
+ ],
+ "type": "object"
+ }
+ }
+ },
+ "description": "Block header."
+ },
+ "400": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
+ },
+ "application/msgpack": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
+ }
+ },
+ "description": "Bad Request - Non integer number"
+ },
+ "401": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
+ },
+ "application/msgpack": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
+ }
+ },
+ "description": "Invalid API Token"
+ },
+ "404": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
+ },
+ "application/msgpack": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
+ }
+ },
+ "description": "None existing block "
+ },
+ "500": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
+ },
+ "application/msgpack": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
+ }
+ },
+ "description": "Internal Error"
+ },
+ "default": {
+ "content": {},
+ "description": "Unknown Error"
+ }
+ },
+ "summary": "Get the block header for the block on the given round.",
+ "tags": [
+ "public",
+ "nonparticipating"
+ ]
+ }
+ },
"/v2/blocks/{round}/lightheader/proof": {
"get": {
"operationId": "GetLightBlockHeaderProof",
diff --git a/daemon/algod/api/server/v2/account.go b/daemon/algod/api/server/v2/account.go
index 10ec183919..dc6e3cd14d 100644
--- a/daemon/algod/api/server/v2/account.go
+++ b/daemon/algod/api/server/v2/account.go
@@ -20,6 +20,7 @@ import (
"encoding/base64"
"errors"
"math"
+ "slices"
"sort"
"github.com/algorand/go-algorand/config"
@@ -27,7 +28,6 @@ import (
"github.com/algorand/go-algorand/crypto/merklesignature"
"github.com/algorand/go-algorand/daemon/algod/api/server/v2/generated/model"
"github.com/algorand/go-algorand/data/basics"
- "golang.org/x/exp/slices"
)
// AssetHolding converts between basics.AssetHolding and model.AssetHolding
diff --git a/daemon/algod/api/server/v2/generated/data/routes.go b/daemon/algod/api/server/v2/generated/data/routes.go
index 4c32b80945..4715b09320 100644
--- a/daemon/algod/api/server/v2/generated/data/routes.go
+++ b/daemon/algod/api/server/v2/generated/data/routes.go
@@ -143,198 +143,198 @@ var swaggerSpec = []string{
"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",
- "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",
- "NwAA//+q4vIh1ggBAA==",
+ "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",
}
// GetSwagger returns the content of the embedded swagger specification file
diff --git a/daemon/algod/api/server/v2/generated/experimental/routes.go b/daemon/algod/api/server/v2/generated/experimental/routes.go
index 3d5c749701..c8b205d611 100644
--- a/daemon/algod/api/server/v2/generated/experimental/routes.go
+++ b/daemon/algod/api/server/v2/generated/experimental/routes.go
@@ -159,203 +159,203 @@ var swaggerSpec = []string{
"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",
- "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",
- "AAD//6UnopQICgEA",
+ "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",
}
// GetSwagger returns the content of the embedded swagger specification file
diff --git a/daemon/algod/api/server/v2/generated/model/types.go b/daemon/algod/api/server/v2/generated/model/types.go
index d03f3d99f0..581b790e2b 100644
--- a/daemon/algod/api/server/v2/generated/model/types.go
+++ b/daemon/algod/api/server/v2/generated/model/types.go
@@ -94,6 +94,12 @@ const (
GetBlockParamsFormatMsgpack GetBlockParamsFormat = "msgpack"
)
+// Defines values for GetBlockHeaderParamsFormat.
+const (
+ GetBlockHeaderParamsFormatJson GetBlockHeaderParamsFormat = "json"
+ GetBlockHeaderParamsFormatMsgpack GetBlockHeaderParamsFormat = "msgpack"
+)
+
// Defines values for GetTransactionProofParamsHashtype.
const (
GetTransactionProofParamsHashtypeSha256 GetTransactionProofParamsHashtype = "sha256"
@@ -1155,6 +1161,12 @@ type BlockHashResponse struct {
BlockHash string `json:"blockHash"`
}
+// BlockHeaderResponse defines model for BlockHeaderResponse.
+type BlockHeaderResponse struct {
+ // BlockHeader Block header data.
+ BlockHeader map[string]interface{} `json:"blockHeader"`
+}
+
// BlockLogsResponse defines model for BlockLogsResponse.
type BlockLogsResponse struct {
Logs []AppCallLogs `json:"logs"`
@@ -1525,6 +1537,15 @@ type GetBlockParams struct {
// GetBlockParamsFormat defines parameters for GetBlock.
type GetBlockParamsFormat string
+// GetBlockHeaderParams defines parameters for GetBlockHeader.
+type GetBlockHeaderParams struct {
+ // Format Configures whether the response object is JSON or MessagePack encoded. If not provided, defaults to JSON.
+ Format *GetBlockHeaderParamsFormat `form:"format,omitempty" json:"format,omitempty"`
+}
+
+// GetBlockHeaderParamsFormat defines parameters for GetBlockHeader.
+type GetBlockHeaderParamsFormat string
+
// GetTransactionProofParams defines parameters for GetTransactionProof.
type GetTransactionProofParams struct {
// Hashtype The type of hash function used to create the proof, must be one of:
diff --git a/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go b/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go
index aee8f09bc9..e1760f03d5 100644
--- a/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go
+++ b/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go
@@ -213,203 +213,204 @@ var swaggerSpec = []string{
"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",
- "6dF2O9oU+nYNkWbZIprqpFniS7Uyd7DEUh3DuqrqOS9LN/WQZfVWiwNPOshlyVxjBhuBCnP/cCQNO72/",
- "2Nc8XzuxgOW8LOetqkhVWQlXULpHu5AS9JzZNbft4ceRw7sGz5EBx+wssGg1Xs2EKjbd6CI0sA3HG2jj",
- "XjNV2e3TcFDDN9CTgvBGVDVqEaKHxvmLsDq4Aok8qRkawW/WiNqaePATN7f/hDNLRYsjDaAN5rsGfw2/",
- "6ADtWrf3qWynULognbV1vwnNcqVpCLrh/eTuP8B125mo836lIfNDaH4F2vDSra63qAcN+d7V6TxwMgtu",
- "eXQyPRWmH2DEObAfinegE1qaH/E/vGTus5NiHCW11CNQGFGRObWgi9mhimZyDVDfqtiGVJms4vnlUVA+",
- "bydPs5lJJ+9r0p76LfSLaHbozVYU5q62CQcb26vuCSHdVWBHA1lkL9OJ5pqCgDeqYsQ+eiAQp8DRCCFq",
- "e+fX2ldqm4LpK7UdXGlqC3eyE26cycz+K7V94SFT+jDmcewpSHcLlHwDBm83GTNON0trlztbKH0zaaJ3",
- "wUjWWhsZd6NGwtS8hyRsWleZP5sJiwU16A3UOnjsFwL6w6cw1sHCheW/ARaMG/UusNAd6K6xoDaVKOEO",
- "SH+dFOIW3MBnT9jF384+f/zk708+/8KRZKXVSvMNW+wsGHbfq+WYsbsSHiRfRyhdpEf/4mmwUXXHTY1j",
- "VK1z2PBqOBTZvuj1S82YazfEWhfNuOoGwEkcEdzVRmhnZNZ1oL2ARb26AGvdS/eVVss754aDGVLQYaNX",
- "lXaChenaCb20dFq4JqewtZqfVtgSZEF+Bm4dwrg34GZxJ0Q1tvFFO0vBPEYLOHgojt2mdppdvFV6p+u7",
- "UG+A1konr+BKK6tyVWZOzhMqoaB45Vsw3yJsV9X/naBl19wwNzdaL2tZjOgh7FZOv79o6Ddb2eJm7w1G",
- "602szs87ZV+6yG9fIRXozG4lQ+rsqEeWWm0YZwV2RFnjW7Akf4kNXFi+qX5cLu9G26lwoIQeR2zAuJkY",
- "tXDSj4FcSXLmO6Cy8aNOQU8fMcHKZMcB8Bi52MkcTWV3cWzHtVkbIdFub3Yyj1RbDsYSilWHLG+vwhpD",
- "B011zyTAceh4iZ9RV/8CSsu/UfpNK75+q1Vd3Tl77s85dTncL8ZbAwrXN6iBhVyVXQfSlYP9JLXG32VB",
- "zxslAq0BoUeKfClWaxu9F19p9RvciclZUoDiB1IWla7PUGX0gyocM7G1uQNRsh2s5XCObmO+xheqtowz",
- "qQrAza9NWsgccTlEXyd00bKx3Ir6CWHYAhx15bx2q60rhg5Ig/ui7ZjxnE5ohqgxI+4Xjd8MtaLpyJ2t",
- "1MCLHVsASKYW3sfBe1/gIjl6T9kgpnkRN8EvOnBVWuVgDBSZV0UfBC20o6vD7sETAo4AN7Mwo9iS61sD",
- "e3l1EM5L2GXo62fY/e9+Ng9+B3itsrw8gFhsk0JvX582hHra9PsIrj95THakqSOqdeKtYxAlWBhD4VE4",
- "Gd2/PkSDXbw9Wq5Ao0vJb0rxYZLbEVAD6m9M77eFtq5GPNj9M91JeG7DJJcqCFapwUpubHaILbtGHV2C",
- "W0HECVOcGAceEbxecmPJDUrIAnWadJ3gPCSEuSnGAR59hriRfw4vkOHYubsHpalN8xwxdVUpbaFIrQEt",
- "sqNz/QDbZi61jMZu3jxWsdrAoZHHsBSN75HlX8D4B7eN/dVbdIeLQ5u6u+d3SVR2gGgRsQ+Qi9Aqwm7s",
- "xTsCiDAtoolwhOlRTuM6PJ8Zq6rKcQub1bLpN4amC2p9Zn9q2w6Ji4wcdG8XCgwaUHx7D/k1YZb8t9fc",
- "MA9HMLGjOof8tYYwu8OYGSFzyPZRPj7xXKv4CBw8pHW10ryArICS7xLOAfSZ0ed9A+COt89dZSEjR9z0",
- "preUHPwe9wytcDyTEh4ZfmG5O4LuKdASiO99YOQCcOwUc/J0dK8ZCudKblEYD5dNW50YEW/DK2Xdjnt6",
- "QJA9R58C8AgemqFvjgrsnLVvz/4U/wXGT9DIEcdPsgMztoR2/KMWMKIL9jFO0XnpsfceB06yzVE2doCP",
- "jB3ZEcX0K66tyEWFb53vYHfnT7/+BEnDOSvAclFCwaIP9Ays4v6MXEj7Y97sKThJ9zYEf6B8SywnuOl0",
- "gb+EHb65X1FsQqTquIu3bGJUdz9xyRDQ4PHsRPC4CWx5bsudE9TsGnbsGjQwUy/IhWFoT7GqyuIBkvaZ",
- "PTN662zSNrrXXHyBQ0XLS/ma0ZtgP3xveg+DDjr8W6BSqpygIRsgIwnBJN8RVim368KHP4UAmEBJHSA9",
- "00bTfHP93zMdNOMK2H+pmuVc4pOrttDINEqjoIACpJvBiWDNnN45scUQlLABeknil4cP+wt/+NDvuTBs",
- "CdchZtA17KPj4UPU47xSxnYO1x3oQ91xO09cH2i4cheff4X0ecphjyc/8pSdfNUbvLF2uTNljCdct/xb",
- "M4DeydxOWXtMI9O8vXDcSbacrn/QYN247xdiU5fc3oXVCq54makr0FoUcJCT+4mFkl9f8fLHphvGQ0Lu",
- "aDSHLMcovoljwRvXhwL/3DhCCneAyel/KkBwTr0uqNOBJ2brqSo2GygEt1DuWKUhB4p3c5KjaZZ6wsgT",
- "Pl9zucIHg1b1yju30jjI8GtDqhldy8EQSaHKbmWGSu7UBeDd1ELIoxOngLsnXV9DTg+Ya97M56Ncp9zM",
- "0R70LQZJI9l8NvridUi9al+8hJxu3OaEy6Aj70X4aSeeaEpB1DnZZ4iveFvcYXKb+9uo7NuhU1AOJ448",
- "ftuPY06/7rld7u5A6KGBmIZKg8ErKlZTGfqqlnGMdnAV3BkLm6Emn7r+feT4vR59LypZCgnZRknYJdOS",
- "CAnf48fkccJrcqQzCixjfftvkA78PbC680yhxtviF3e7f0L7FivzjdJ3ZRKlASeL9xMskAfN7X7Km9pJ",
- "eVkmTIs+grPPAMy8cdYVmnFjVC5QZjsvzNx7BZM10od7dtH/qolLuYOz1x+3Z0OLkwOgjhjKinGWlwI1",
- "yEoaq+vcvpMcdVTRUhNOXOExPq61fB6apNWkCS2mH+qd5OjA12iukg4bS0ioab4BCMpLU69WYGzvrbME",
- "eCd9KyFZLYXFuTbuuGR0XirQ6El1Qi03fMeWjiasYr+CVmxR2670jwHKxoqy9AY9Nw1Ty3eSW1YCN5Z9",
- "L+SbLQ4XjP7hyEqw10pfNlhI3+4rkGCEydLOZt/SV/Tr98tfex9/dHenz8HptM2YMHPL7CRJ+f/u/8ez",
- "t2fZf/Ps10fZl/92+v7D048PHg5+fPLxr3/9/7s/ffbxrw/+419TOxVgT4XPesjPX/iX8fkLfP5Ervp9",
- "2D+Z/n8jZJYkstibo0db7D6mivAE9KCrHLNreCftVjpCuuKlKBxvuQk59G+YwVmk09Gjms5G9JRhYa1H",
- "PipuwWVYgsn0WOONpaihf2Y6UB2Nkj72HM/Lspa0lUH6pjjM4F+mlvMmGQHlKXvGMFJ9zYOTp//zyedf",
- "zOZthHnzfTaf+a/vE5Qsim0qj0AB29RbMQ6SuGdYxXcGbJp7IOxJVzry7YiH3cBmAdqsRfXpOYWxYpHm",
- "cCFkyeuctvJckoO/Oz9o4tx5y4lafnq4rQYooLLrVP6ijqCGrdrdBOi5nVRaXYGcM3ECJ32dT+Hei96p",
- "rwS+DI6pWqkpr6HmHBChBaqIsB4vZJJiJUU/vfAGf/mbO38O+YFTcPXnTHn03vv26zfs1DNMc49SWtDQ",
- "URKCxFPaB092HJIcN4tjyt7Jd/IFLFH7oOSzd7Lglp8uuBG5Oa0N6K94yWUOJyvFnoV4zBfc8ndyIGmN",
- "JlaMgqZZVS9KkbPL+EHSkiclyxqO8O7dW16u1Lt37we+GcPng58qyV9ogswJwqq2mU/1k2m45jpl+zJN",
- "qhccmXJ57ZuVhGxVk4I0pBLy46d5Hq8q00/5MFx+VZVu+REZGp/QwG0ZM1Y18WhOQPEhvW5/f1D+YtD8",
- "OuhVagOG/bLh1Vsh7XuWvasfPfoMI/vaHAi/+Cvf0eSugsnaldGUFH2lCi6cnpXoq55VfJUysb1799YC",
- "r3D3UV7eoI6jLBl260QdhgADHKpdQBPiPLoBBMfRwcG4uAvqFdI6ppeAn3ALuwHYt9qvKH7+xtt1IAaf",
- "13adubOdXJVxJB52psn2tnJCVvDGMGKFr1WfGG8BLF9DfukzlsGmsrt5p3tw+PGCZmAdwlAuO4owxGxK",
- "aKBYAKurgntRnMtdP62NoYgKHPQ1XMLujWqTMR2Tx6abVsWMHVSk1Ei6dMQaH1s/Rn/zvVdZCDT12Ukw",
- "eDOQxbOGLkKf8YNMIu8dHOIUUXTSfowhgusEIoj4R1Bwg4W68W5F+qnlCZmDtOIKMijFSixSaXj/c2gP",
- "C7A6qvSZB70XcjOgYWLJ3FN+QRerf95rLlfgrmd3pSrDS8qqmnTawPfQGri2C+B2r55fxgkpAnT4pLzG",
- "yGvU8M3dEmDr9ltY1NhJuHavClQUURvvvXwy7n9GgENxQ3hC9/alcDL61vWoS2QcDLdyg93mWetd82I6",
- "Q7jo+wYwZam6dvvioFA+2yYldYnul9rwFYy8XWLr3cR8GB2LHw5ySCJJyiBq2Rc1BpJAEmRqnLk1J88w",
- "uC/uEOMzs+eQGWYiA7G3GWESbY+wRYkCbOO5SnvPdceKSlmBx0BLsxbQshUFAxhdjMTHcc1NOI6YLzVw",
- "2UnS2W+Y9mVfarrzyJcwSoraJJ4Lt2Gfgw7e/T5BXchKF1LRxY/+CWnl3NsLwxdS26EkiqYFlLCihVPj",
- "QChtwqR2gxwcPy6XyFuylFtipKCOBAA/B7iXy0PGyDbCJo+QIuMIbHR8wIHZDyo+m3J1DJDSJ3ziYWy8",
- "IqK/IR3YR476ThhVlbtcxYi9MQ8cwKeiaCWLnkc1DsOEnDPH5q546dicf4u3gwwypOGDopcPzbvePBh7",
- "aOwxTdGVf9SaSEi4yWpiaTYAnRa190C8UNuMIpSTb5HFduHoPRm7gPHSqYNJuejuGbZQW3TnwquFfOUP",
- "wDIORwAj0r1shUF6xX5jchYBs2/a/XJuigoNkoxXtDbkMiboTZl6RLYcI5f7UXq5GwHQU0O1tRq8WuKg",
- "+qArngwv8/ZWm7dpU0NYWOr4jx2h5C6N4G+oH+smhPtbm/hvPLlYOFGfJBPeULN0mwyF1LmirIPHJCjs",
- "k0MHiD1YfdWXA5No7fp6dfEaYS3FShzzHRolh2gzUAI+grOOaJpdpjwF3Fse8B6/CN0iZR3uHpe7B5ED",
- "oYaVMBZao1HwC/o91PEc0ycrtRxfna300q3vtVLN5U9mc+zYWeYnXwF64C+FNjZDi1tyCa7RNwaVSN+4",
- "pmkJtOuiSMUGRJHmuDjtJeyyQpR1ml79vN+9cNP+0Fw0pl7gLSYkOWgtsDhG0nF5z9Tk2753wS9pwS/5",
- "na132mlwTd3E2pFLd44/ybnoMbB97CBBgCniGO7aKEr3MMgo4HzIHSNpNPJpOdlnbRgcpiKMfdBLLYS9",
- "j938NFJyLVEawHSEoFqtoAjpzYI9TEZJ5EolV1EVp6ralzPvhFHqOsw8tydpnXfDhzEn/Ejcz4QsYJuG",
- "Pn4VIORtZB0m3MNJViApXUlaLZRETezijy0iXd0ntoX2AwCSTtBvesbs1juZdqnZTtyAEnjh3yQGwvr2",
- "H8vhhnjUzcfcpzuZT/cfIRwQaUrYqLDJMA3BCAPmVSWKbc/wRKOOKsH4UdrlEWkLWYsf7AAGuk7QSYLr",
- "pNL2rtZewX6Kb95T9yoj32vvWOzom+c+AL+oNVowOp7Nw7ztzVtt4tq/+/nCKs1X4K1QGYF0qyFwOceg",
- "IcqKbpgV5E5SiOUSYuuLuYnloAPcQMdeTCDdBJGlTTS1kPaLpykyOkA9LYyHUZammAQtjNnk3wytXEGm",
- "j1RJzZUQbc0NTFXJcP3vYJf9zMvaPTKENq17rjc7dS/fI3b9avMd7HDkg16vDrADu4Kap9eANJjS9Def",
- "TJTA+p7ppPjH52VnC4/YqbP0Lt3R1viiDOPE394ynaIF3aXc5mC0ThIOlim7cZH2TXCnB7qI75PyoU0Q",
- "xWEZJJL346mECSUsh1dRk4viEO2+AV4G4sXlzD7OZ7fzBEjdZn7EA7h+1VygSTyjpylZhjuOPUeinFeV",
- "Vle8zLy/xNjlr9WVv/yxeXCv+MQvmTRlv/n67OUrD/7H+Swvgeus0QSMrgrbVX+aVVEZh/1XCWX79opO",
- "0hRFm99kZI59LK4xs3dP2TQoitL6z0RH0ftcLNMO7wd5n3f1oSXucfmBqvH4aW2e5PDTdfLhV1yUwdgY",
- "oB1xTsfFTausk+QK8QC3dhaKfL6yO2U3g9OdPh0tdR3gSTjXj5iaMv3ikD5xJbIi7/zD71x6+kbpDvP3",
- "kYlJ56HfTqxyQjbhccRXO9Sv7AtTJ4wEr19Wv7jT+PBhfNQePpyzX0r/IQIQf1/43/F98fBh0nqYVGM5",
- "JoFaKsk38KCJshjdiE/7AJdwPe2CPrvaNJKlGifDhkLJCyig+9pj71oLj8/C/1JACe6nkymP9HjTCd0x",
- "MFNO0MVYJGLjZLqhkpmGKdn3qcYgWEdayOx9SQYyxg6PkKw3aMDMTCnytGuHXBjHXiU5U7rGDBuPaGvd",
- "iLUY8c2VtYjGcs2m5EztARnNkUSmSaZtbXG3UP5411L8swYmCveqWQrQeK/1rrrwOMBRBwJpWi/mByY7",
- "VTv8bfQge+xNQRe0Twmy1373orEphYWmiv4c6QEezzhg3Hu8tz19eGqmaLZ11wVz2jtmSun0wOi8sW5k",
- "jmQpdGGypVa/QtoQgvajRCKMYPgUqOb9FWTKc6/PUhqjclvRvZ390HZPfxuPbfyt38Jh0U3VsZtcpulT",
- "fdxG3uTRa9Lpmj2Sxx5hsYdBNzRghLXg8YqcYbEMSvA+4pLOE2WB6ESYpU9lHMt5SuO3p9LDPIh/Lfn1",
- "gqdqxLi3kIMp2t6On5RVLHQOG2CaHAc0O4s8uJu2gjLJVaBbG8QwK+0N3zU07eQXTfuAQYqKny5zclMo",
- "jUoMU8trLqmKuOtH/Mr3NkAmeNfrWmnMA2nSLl0F5GKTVMe+e/e2yIfuO4VYCSqQXRuIKjD7gRglm0Qq",
- "8lWsm8wdHjXnS/ZoHpWB97tRiCthxKIEbPGYWiy4weuyMYc3XdzyQNq1weZPJjRf17LQUNi1IcQaxZq3",
- "Jwp5jWPiAuw1gGSPsN3jL9l9dMk04goeOCx6IWj27PGX6FBDfzxK3bK+wPk+ll0gzw7O2mk6Rp9UGsMx",
- "ST9q2vt6qQF+hfHbYc9poq5TzhK29BfK4bO04ZKvIB2fsTkAE/XF3URzfg8vkqwBYKxWOyZsen6w3PGn",
- "kZhvx/4IDJarzUbYjXfcM2rj6Kktr0yThuGo1r+vFxXgCh/R/7UK7n89XdcnfsbwzUjMFnop/4A22hit",
- "c8Yp+WcpWs/0UK+TnYfcwlhAq6mbRbhxc7mloyyJjupLVmkhLeo/arvM/uKexZrnjv2djIGbLb54mihE",
- "1a3VIo8D/JPjXYMBfZVGvR4h+yCz+L7svlQy2ziOUjxocyxEp3LUUTftkjnmF7p/6KmSrxslGyW3ukNu",
- "POLUtyI8uWfAW5Jis56j6PHolX1yyqx1mjx47Xbop9cvvZSxUTpVMKA97l7i0GC1gCuMmEtvkhvzlnuh",
- "y0m7cBvof1//pyByRmJZOMvJh0Bk0dwXLO+k+J+/bzOfo2GVIhF7OkClE9pOr7f7xN6Gx2nd+vZbchjD",
- "byOYm4w2HGWIlRHve3Kvb/r8Hv5CfZBozzsKx8e/MO3e4CjHP3yIQD98OPdi8C9Pup+JvT98mE5AnFS5",
- "uV9bLNzmRYx9U3v4lUoowELVwsahyOdHSCggxy4p98ExwYUfas66FeI+vRRxN/FdaW/T9Cl49+4tfgl4",
- "wD/6iPidmSVuYBulMH7YuxUykyRTNN8jP3fOvlLbqYTTu4MC8fwBUDSCkonqOVzJoAJo0lx/0F8kolE3",
- "6gJK5R6ZcVGgWJ//58GzW/x8D7ZrURY/t7ndeheJ5jJfJ72EF67j30lG71zBxCqTdUbWXEook8PR2/bv",
- "4Q2ceKX/Q02dZyPkxLb9CrS03N7iWsC7YAagwoQOvcKWboIYq920WU1ahnKlCobztEUtWuY4LOWcKqGZ",
- "iG/GYTe19X6rGAvuEw4tRYlumGm7MbbMNLcjCbSw3nmoL+TGwfLjhtQMNDpoxsUGL2bDN1UJeDKvQPMV",
- "dlUSet0xhRqOHFWsYKZyn7AlJqxQzNZaMrVcRssAaYWGcjdnFTeGBnnklgVbnHv27PGjR0m1F2JnwkoJ",
- "i2GZP7ZLeXyKTeiLL7JEpQCOAvYwrB9bijpmY4eE42tK/rMGY1M8FT9Q5CpaSd2tTfUkm9qnJ+xbzHzk",
- "iLiT6h7VlSGJcDehZl2VihdzTG785uuzl4xmpT5UQp7qWa5QW9cl/6R5ZXqC0ZDZaSRzzvRx9qfycKs2",
- "NmvKT6ZyE7oWbYFM0fO5QT1ejJ0T9oJUqE0Bf5qEYYpsvYEiqnZJj3gkDvcfa3m+Rt1kRwIa55XTC7EG",
- "dtZabqLow6b6ETJsB7evxUqlWOdM2TXoa2EAI/LhCrrpEJvcoF43HtIjdpenaymJUk6OEEabWkfHoj0A",
- "R5JscCpIQtZD/JGaKarHfGxd2gvslY7F6BW57Vn9Q3K9kGKbfe+NCzmXSoocSyGkJGlM3TbNTDmhakTa",
- "vmhm/oQmDleytG4TC+yxOFpsNzBCj7ihyT/66jaVqIP+tLD1JddWYI3nbFDMQ6VrbxAT0oCvZuWIKOaT",
- "SiecmpKBEI0DxZFkhFmZRjSc37hvP3j9NybFuBQSNV0ebf59Riar0gi0TEsmLFspMH493Wge89b1OcEs",
- "jQVs35+8VCuRX4gVjkFudG7Z5DM6HOoseJB6j03X9rlr63PnNz933MFo0rOq8pOO10FPCpJ2K0cRnPJb",
- "Co4kEXKb8ePR9pDbXtdvvE8docEVeq1BhffwgDCaWtrdUb52b0uiKGzBKKIymUBXyAQYL4UMJtT0BZEn",
- "rwTcGDyvI/1Mrrmlt8MknvYGeDkSAIERymSDv+1Q/coBDiW4xjDH+Da2ZcBHGEfToJX4udyxcCgcdUfC",
- "xHNeNq7TiaLeKFV5IarA4KJeme8U43CMOwshkx10HQzfa7pjNY5jb6KxHIWLuliBzXhRpFJbfYVfGX4N",
- "QWKwhbxuilA10YHdHOVDavMT5UqaerNnrtDgltNFdfMT1BDX7g87jJl2Fjv8N1WBaXxnvNP00VG5wUO6",
- "OC4x/zDKOCX1OprOjFhl0zGBd8rt0dFOfTNCb/vfKaWHcN0/RDRuj8vFe5Tib1+7iyNO3DvwT6erpcmr",
- "i77gCr+HhEdNRsguV8KrbFBnDL0ecPMSW9YDPjRMAn7Fy5FI+NhWQvcr2Q/G4uHz0fQN3Pr0XJazvSxo",
- "NOUR+Qr3rC9DE+KYfzC5B9+d1cKvdS9Cx21333UsdeQj1jKLUQvdzYxo7QYfa0X77mosRUKo04Hf43og",
- "3otn7tPAw5VQdfC+Cj7Q4UlIv/oUPJ26HyPrT0YW/N5Wi1Ebyxtfv5aW6d/k3/1MVlgG0urdH8DiMtj0",
- "flGZhLRL6qm2CWtKH04qhdi5FafUsEmVS/GyYdCVEWvp0NKg/MyArF5MEQcG+Pg4n50XR12YqZI7Mxol",
- "dexeitXaYsb+vwEvQL86UJGgrUKAR6xSRrQVSEs3mE8Bu8bhTqYGGzgCFnFFheFYwQn1CnKLZWdb5zoN",
- "cEx9BTdZMPr8b2WC8ed0E5PhCxLsq0IwrDV74I4fJE6Kkn9Rnc6T6Tn3zxoXaooAu+amTdfSi5meHLm5",
- "XEKOWZH3Jqr6zzXIKAnSPOhlEJZllLdKNHFMmNf7eK1jC9C+PFJ74Ynq69wanLE49kvY3TOsQw3JwqFN",
- "EN9NEgcjBsgEFnJIjymSvdeYMA1lIBaCS7BPxdwWxxjN+RylXbvhXIEk3cXRpmLbM2W66PmkuVzXo9I+",
- "YkjOWC6rYc3k8ffHCyxRbbyDHG8SD8evdHY+LJxz7RMXY1qxxnYSUhiDCb+FHII0Sykuff0AxApZqq65",
- "LkKLO0kKRXeTSAO9bGYWbQDH0MkhUYoBY6HyUjkxIhsLKOvGTDQOh/cMeYa2CXwQriVoDUVjEimVgcyq",
- "EPCxD459qCD31xshwYyWPyLgRlNfv25ze2MZOI6prrn3eo0XyDRsuINORxm4x+fch+zn9D0E4YcyYAc1",
- "TA29Hq5HG0J3hBkgMab6JfO35eHg/psom4SUoLNgeeqn45bdjGyYd7Ooc7qg44PRKOQm587Zw0qSepp8",
- "uMreGyEKkr+E3Sk9gkIh37CDMdAkORHoUcLR3ibfqfrNpOBe3Ql4v28euUqpMhsxdpwPc4j3Kf5S5JeA",
- "OQAbF/eRGu3sPurYG2v29XoXcmZXFUgoHpwwdiYpqCgYtrvlBXuTy3t23/xbnLWoKa2/V6qdvJPp6AxM",
- "uK9vyc3CMPt5mAHH6m45FQ1yIEP1Vo653Fxjcv5uFc+Tqa/yoam5X0W+JSqCIiWTXJDF6jke9JTiCFMg",
- "RLk60JDJmbd0MVOqlC/vTdI0uKHSmIonQ4AsyCnZAhoo/OBJBCTroidOIaW+80nv1JJpaI3IN83+Nyzh",
- "nnrR92duZunyu6XS0CnG7npTps8m8AXTaOJ/FsJqrnc3ydE3KCE/0J6MYvmgO1bjidUupPXGGuKwLNV1",
- "hswqa+pcpJ62rp3pXsah6Frbz53qBUR+Xdx4QW3H1rxgudIa8rhHOt6ToNooDVmp0M0rZYFeWid3bzDI",
- "S7JSrZiqclUA1YtJU9DYXLWUHMUmiLxqkigg2sFoYeoT0fHEKd2dSnakDEWt1RG183OgyPU2qxMtOiNb",
- "5ojHMhifxcljiBoP4d1T+z/Nm5dii3QDOnXkl8zqGubMt+jXyPYHn2tgG2EMgdLQ0rUoSwwcF9vI8to4",
- "LqRROyL2nqNb5ZVA35tuEgGShit35zWZFWIecBGnPWJ2rVW9WkcJphs4w5NX1/5BHI/yk6nRPQojyNwU",
- "T9lGGetfmjRSu+TW5ex+rqTVqiy7SikS0Vde0/49357luX2p1OWC55cP8F0rlW1WWsxDfHXfObCdSfdS",
- "i3Uv4IzKmR9O1Uvt0FXOE+1kBtljcUcXdo/AfH+Ygx7WuZ8NF9ZfV5eZpp8xZ5JxqzYiT5+pP5e33aiP",
- "XIpFJXOWUW1FyjKBzfCwx5dV41yBLHKIZpA8WRzujHlG4I3MyG7cf1EC74/LluAZzchFOWQuXorK8lFZ",
- "rwcAQkqhz7bWVJAxlsQarqJWlCoBTeR9QCfeKuiJdDvY3Ah3DpSFWwE18H5sALxPyoc55ZYjT8qF2obv",
- "D9rkczcC/uN+Ku8wjzEXr4uWtDQ5eYVENSMcIZ3ieq8/1BsMe19M9YpqiudOvOEjAMb9pDowTPKWOhaM",
- "JRclFFmq9uJ5o6OaRy9tH5rVL4kujOfkOa9D6UM3dq3BJ04hEV937V8Vd6SkmuZDTbIsYAsU1/EraEU1",
- "DeeR/QVKKnnYUwaoKivhCjruYz6bS42ipriC0Nc0nVkBUKE1sq8jS/lFxXd5T3Hi155FnjVTsJvUpBBi",
- "aafYATVJUqmzlRkdEzP1KDmIrkRR8w7+zLEiR1cN6I5yAlWDN0IW3pFTp/mJRngdBjgL/VOiTMDE+2l8",
- "6GgWlEbdPgZ00E+yNmOnXqbdJONURY2BBWcrGkMskXjLN0zFr+W4QnJI8u1za+I+CSUjxH69hRylGv/e",
- "gcK/eEaMFD7rCVK7BCjoVeC6JLTta5BMqqjE5DU3zVOlzaEYfqCJsZGQ/jV9A6Ny6814+51lOBgzvWRq",
- "ow8J3dDpzdXzv8tJ3HsQR8dL0YgBH/63R/8VqNs/O7ABlvKWbj+d7I9FGv0t5rn4nC3qMFBZqmuqGRm/",
- "Q19AsIMS9QUTkBfLRXMtB6/NuU/v2Vd1iMhffcN3TGn8x706/1nzUix3yGcI/NCNmTV3JOQNr+QR4L1A",
- "3cT7xat5ACxoW1SYitYtpo4ZDbdzo0RAu4s8FPdRbMMvId4GdHYg/plbxzhNvUDNhbuye9s5xIJffEjR",
- "suFF/NLHRJHdMuohdbDr/X+1sXDxVCG/W1XyPFQI9SWKunwGqwAH4rJr2OwPlhzytUACTWXhlmh1iK4v",
- "bqAyPZJ1pSIQxsqvdMAeVFwdVJ651TIman57NTb2hJlOWspd78JUr5sB0HGdxkPgx2UrPw3+kzlcx5Yx",
- "Bfw/Ct5HCtXG8FJN2k+A5U4GjgSspK1eqG2mYWkOOZiQuto953WbuyOoWIXMNXBDHjfnP/qHZ5uiVEj3",
- "ECaf0Mam2YxSwFLIllkKWdU28Y7BTKVyFyEsVvojWkdMaGNSghMmr3j54xVoLYqxjXOng0o6xiUigqHD",
- "902oMJo7dTiAMO0bDuMzWzV63Mxd4FSEitw1jeWy4LqImwvJctDu3mfXfGdublFqjAOHbEo8kma6WQMi",
- "6xKSNgFS7rxR+Jb2ngZAfoeGnwkGG/QLThhrSLVj1Yh9ZgjDn8Jgs+HbrFQrjCIcORA+Ny1a+OgJqCSq",
- "wUk+m7buMI8Rv8L+aTAtv2dEVuGsU6bYf+5/xK3EZ+RPUti9J590lP2wTvK7pYMZkCpXrfM/EcvwPKYi",
- "cX3ylTgaNwibIVQl0B5Emwgj9qGuXnxkF9ENwodxx0rw6eXOup4WqXhf0gxkqDEwe9z7wbSu7Dz37llD",
- "VdpA1UBImfto6SM1baSfD/fSCHhUm96f9e60jcuMG+eYGnH746OzSlVZPsXnkyp3FN5M4CHtwjhCH5ER",
- "YGTdjXuMaWrZdPIedYraHFsmb7SoziFrV5Xve/SPqYlGOHrXBKGWyMuocjtqtzCSp1GmzPsxZl01WMMk",
- "GGca8lqjmvia7w6XHRvJGH3xt7PPHz/5+5PPv2CuASvECkybdbxXtqv1CxSyr/f5tJ6Ag+XZ9CaE7AOE",
- "uGB/DEFVzab4s0bc1rQpRQdFy47RLycugMRxTJSLutFe4Tita/8fa7tSi7zzHUuh4LffM63KMl31oZGr",
- "EgaU1G5FJhT3AqlAG2GsY4RdC6iwrUe0WaN6EHP/XlE2GSVzCPpjTwXCjrhcpRYy5lCL/Axju73ViMG2",
- "Kj2vIkvPvnX5dxpp6FBoRK+YBbBKVV60F0uWgggjiHQUWesVn6gRj3xkG2ZL3rIpQvSe52nSiwtm7+f2",
- "3WKuNs3p3SYmxItwKG9AmmP2ifG8BTfhJK1q/w/DPxKJGO6MazTL/S14RfJ9cLOi/JNAGwblJ8gDARiJ",
- "tu3ESUaBYlEiYk1WArQnBANyX/z4vjUsHwwLQUhChwPgxeGzbbsmksGD8ztn9P2+QUq0lPdjlNBZ/qGI",
- "3MB6m4sk2iKvNLEWDLElNRQLo3Br87yJYh55lQyCnbVSlrmXaVkmgqRJj4NnKiYc9yTQV7z89FzjG6GN",
- "PUN8QPF6PDQqjpSNkUyoNDfL0/eST5o7ioq9u6nlKwzM/k9we5S85/xQ3gg/uM1QuYMV61fhVqBYb3aN",
- "Y5KT1eMv2MIX26g05ML0jfvXQThpAkNBi6V3aIWtPRCJemidPyt7CzJeBk8c9kNk3mps9h7C9oj+zkxl",
- "5OQmqTxFfQOySOAvxaPi4rwHrotbFma4WdqXKIHbkWlfhmWHpy6PUpu4S6c2MFzn5Nu6g9vERd2ubWrO",
- "osn1Hd69e2sXU1INpWsxuO6Y6+hOijIcVZLhN8hyRDjyY/h5UxTz81jeW8rtOpKbu7cftSgPOqx0Mq1/",
- "nM9WIMEIg7nE/+5rx3zauzRAQJkXhkeVYL1NuhhCTGKtncmjqaIc6hPSp/tuiZzXGNWY11rYHdYNDgo0",
- "8fdkPqZvm9wePjdMY0vzd59Vl9DUbm8zgdQm3K7fKl7ifUQmPuluIVWesK8pw7c/KH+9t/h3+OwvT4tH",
- "nz3+98VfHn3+KIenn3/56BH/8il//OVnj+HJXz5/+ggeL7/4cvGkePL0yeLpk6dffP5l/tnTx4unX3z5",
- "7/ccH3IgE6Ahtf+z2f+bnZUrlZ29Os/eOGBbnPBKfAdub/CtvFRY19IhNceTCBsuytmz8NP/HU7YSa42",
- "7fDh15mvzzRbW1uZZ6en19fXJ3GX0xWG/mdW1fn6NMyD1QY78sqr88ZHn/xwcEdb7TFuqieFM/z2+uuL",
- "N+zs1flJSzCzZ7NHJ49OHvvS1pJXYvZs9hn+hKdnjft+ivk1T41PnX/axmol7Xav0WU9COd6BQW730Td",
- "/FtjuTUPQvDOUpR4ZfzDEDE2qzgvkLh8jdIZVl1DZywE68mjR2EvvKQTXTinGP3x7MOsrW3fFyYGSH3T",
- "ApyErK35OFz0T/JSqmvJMBkgHaB6s+F6RyvoYCMaHLeJrwwq2bW44hZm713vPs6ryhcsGEM5VrnqnvLQ",
- "GQmkyXjvThglwvdlB0wK5cNiCbfE/t7kkIPJEruDjV45mEP6nCahojcIeZyhzZgQ1pwRUjsMED2fVXUC",
- "nV9jYI3Zh7N5lISfoFFl0WB8gNFX9f8QjDrS9XfT7NkH99caeImJtdwfG0eoefikgRc7/39zzVcr0Cd+",
- "ne6nqyen4RVy+sFnTPm479tp7BF2+qGTWKY40DN4PB1qcvohlMzeP2CnXLL3NY06TAR0X7PTBZbJmtoU",
- "4tWNLwVp3px+wAf46O+nXoua/oiKELphT0OCppGWlIoj/bGDwg926xayfzjXJhov5zZf19XpB/wPku1H",
- "Ou0lpDI5UYkOztrmcyYs4wulsQKzzdeOG4TSr8JELQdH/sz1ek4QhEr66F40e/Z2GP+FA7EwEooo7v5t",
- "JYjOTK2QiOaUiCk0InCnfSsIv32Uffn+w+P540cf/8UJuv7Pzz/7ONF7/nkzLrtopNiJDd/fkuMNdDbt",
- "ImmTGgY2fGR4WhiP7/Fb1RuINcg4UN+xN/zwrYQM+Okd8vhu3uEEf/+KFyykScC5H3+6uc8l+Yg7QZUE",
- "6o/z2eefcvXn0pE8L4NIdkPh7YwOf8wUmN/slPA2n0klo2SKckVihkqlqhjhN8byG/CbC9frf/lNp+HA",
- "yodxeKRt9cXdI78eukyaWnYQMsyG2AJeXHGZh2CsNjoC94skb08YjQNubWBZlyENSVWKJdXMV6oME5m6",
- "qhzHWXLTUJYPyXAPZsqi0AzNapkrSa5TGP0SDMCYDQGNyOZSVJ0uYumoyldzp0isk7Dp/6xB79pd3wj3",
- "8h28mVrnvt+ShRMe74CFdwe6Yxb+5Eg2+udf8f/sS+vpo798OghC8qI3YgOqtn/WS/OCbrBbXZpehqf6",
- "G6d2K0/Rvfv0Q+e54j8Pnivd39vucYurjSogPCHUcmlQtbLv8+kH+jeaCLYVaLEBSWX5/a90c5xiUfjd",
- "8OedzJM/DtfRycs88vNp0KimXsndlh86f3ZffmZd20JdUx3TpLyC1ycv2YZLvqIg/kYJ6e5BP0CbMpr9",
- "WDUXlY/dZRzL76natlpiCmXxAf2NHR9vtMabayUkToAGWZyFL11XHl3gvgLmUId44SH7QRUwlI1SF6GH",
- "sXMZNkchVWvy/d1oJyPG+/G4g4KGY/J6GJKR+1ib/t+n11xYJ0H53M2I0WFnC7w89YXaer+2tVEGX7Dg",
- "S/RjnJUg+esp756LrgbFbdlYx4F6JfXVaxBGGoVgmvC5Nd7ExhAkl8YM8va923UD+ipQUqvbf3Z6itGV",
- "a2XsKUqiXb1//PF9s9GhBHWz4e7bNlNarITkZeaVZG21ydmTk0ezj/8nAAD//1Xaw+sdDwEA",
+ "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",
+ "2cf/EwAA//96SivwPRABAA==",
}
// GetSwagger returns the content of the embedded swagger specification file
diff --git a/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go b/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go
index ed6e87f99f..6f44c1afad 100644
--- a/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go
+++ b/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go
@@ -48,6 +48,9 @@ type ServerInterface interface {
// Get the block hash for the block on the given round.
// (GET /v2/blocks/{round}/hash)
GetBlockHash(ctx echo.Context, round uint64) error
+ // Get the block header for the block on the given round.
+ // (GET /v2/blocks/{round}/header)
+ GetBlockHeader(ctx echo.Context, round uint64, params GetBlockHeaderParams) error
// Gets a proof for a given light block header inside a state proof commitment
// (GET /v2/blocks/{round}/lightheader/proof)
GetLightBlockHeaderProof(ctx echo.Context, round uint64) error
@@ -348,6 +351,33 @@ func (w *ServerInterfaceWrapper) GetBlockHash(ctx echo.Context) error {
return err
}
+// GetBlockHeader converts echo context to params.
+func (w *ServerInterfaceWrapper) GetBlockHeader(ctx echo.Context) error {
+ var err error
+ // ------------- Path parameter "round" -------------
+ var round uint64
+
+ err = runtime.BindStyledParameterWithLocation("simple", false, "round", runtime.ParamLocationPath, ctx.Param("round"), &round)
+ if err != nil {
+ return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter round: %s", err))
+ }
+
+ ctx.Set(Api_keyScopes, []string{""})
+
+ // Parameter object where we will unmarshal all parameters from the context
+ var params GetBlockHeaderParams
+ // ------------- Optional query parameter "format" -------------
+
+ err = runtime.BindQueryParameter("form", true, false, "format", ctx.QueryParams(), ¶ms.Format)
+ if err != nil {
+ return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter format: %s", err))
+ }
+
+ // Invoke the callback with all the unmarshalled arguments
+ err = w.Handler.GetBlockHeader(ctx, round, params)
+ return err
+}
+
// GetLightBlockHeaderProof converts echo context to params.
func (w *ServerInterfaceWrapper) GetLightBlockHeaderProof(ctx echo.Context) error {
var err error
@@ -722,6 +752,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
router.GET(baseURL+"/v2/assets/:asset-id", wrapper.GetAssetByID, m...)
router.GET(baseURL+"/v2/blocks/:round", wrapper.GetBlock, m...)
router.GET(baseURL+"/v2/blocks/:round/hash", wrapper.GetBlockHash, m...)
+ router.GET(baseURL+"/v2/blocks/:round/header", wrapper.GetBlockHeader, m...)
router.GET(baseURL+"/v2/blocks/:round/lightheader/proof", wrapper.GetLightBlockHeaderProof, m...)
router.GET(baseURL+"/v2/blocks/:round/logs", wrapper.GetBlockLogs, m...)
router.GET(baseURL+"/v2/blocks/:round/transactions/:txid/proof", wrapper.GetTransactionProof, m...)
@@ -746,308 +777,309 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
// Base64 encoded, gzipped, json marshaled Swagger object
var swaggerSpec = []string{
- "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",
- "AAD///qwGHIKvwEA",
+ "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",
}
// GetSwagger returns the content of the embedded swagger specification file
diff --git a/daemon/algod/api/server/v2/generated/participating/private/routes.go b/daemon/algod/api/server/v2/generated/participating/private/routes.go
index 3a53efec1e..2ccd7c636c 100644
--- a/daemon/algod/api/server/v2/generated/participating/private/routes.go
+++ b/daemon/algod/api/server/v2/generated/participating/private/routes.go
@@ -249,235 +249,235 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
var swaggerSpec = []string{
"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",
- "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",
- "AAD//1nr4yEUHQEA",
+ "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",
}
// GetSwagger returns the content of the embedded swagger specification file
diff --git a/daemon/algod/api/server/v2/generated/participating/public/routes.go b/daemon/algod/api/server/v2/generated/participating/public/routes.go
index 37794f0d92..e67f76c963 100644
--- a/daemon/algod/api/server/v2/generated/participating/public/routes.go
+++ b/daemon/algod/api/server/v2/generated/participating/public/routes.go
@@ -178,16 +178,16 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
var swaggerSpec = []string{
"H4sIAAAAAAAC/+x9/XPctpLgv4Kb3Srb2qEkfyT74qvUnmInedrYsctSsvvW8iUYsmcGTyTAB4DzEZ//",
- "9ys0ABIkwRmOpNjxbn6yNSSBRqPR6O9+P0lFUQoOXKvJ0/eTkkpagAaJf9E0FRXXCcvMXxmoVLJSM8En",
+ "9ys0ABIkwRmOJNvJbn6yNSSBRqPR6O9+P0lFUQoOXKvJ0/eTkkpagAaJf9E0FRXXCcvMXxmoVLJSM8En",
"T/0zorRkfDGZTpj5taR6OZlOOC2gecd8P51I+EfFJGSTp1pWMJ2odAkFNQPrbWnerkfaJAuRuCHO7BDn",
"zycfdjygWSZBqT6Ur3i+JYyneZUB0ZJyRVPzSJE100uil0wR9zFhnAgORMyJXrZeJnMGeaaO/SL/UYHc",
"Bqt0kw8v6UMDYiJFDn04n4lixjh4qKAGqt4QogXJYI4vLakmZgYDq39RC6KAynRJ5kLuAdUCEcILvCom",
"T99OFPAMJO5WCmyF/51LgN8g0VQuQE/eTWOLm2uQiWZFZGnnDvsSVJVrRfBdXOOCrYAT89UxeVkpTWZA",
"KCdvvntGHj9+/JVZSEG1hswR2eCqmtnDNdnPJ08nGdXgH/dpjeYLISnPkvr9N989w/kv3ALHvkWVgvhh",
- "OTNPyPnzoQX4DyMkxLiGBe5Di/rNF5FD0fw8g7mQMHJP7Mt3uinh/J90V1Kq02UpGNeRfSH4lNjHUR4W",
+ "OTNPyPnzoQX4DyMkxLiGBe5Di/rNF5FD0fw8g7mQMHJP7Mt3uinh/J91V1Kq02UpGNeRfSH4lNjHUR4W",
"fL6Lh9UAtN4vDaakGfTtafLVu/cPpw9PP/zT27Pkv9yfXzz+MHL5z+px92Ag+mJaSQk83SYLCRRPy5Ly",
"Pj7eOHpQS1HlGVnSFW4+LZDVu2+J+dayzhXNK0MnLJXiLF8IRagjowzmtMo18ROTiueGTZnRHLUTpkgp",
- "xYplkE0N910vWbokKVV2CHyPrFmeGxqsFGRDtBZf3Y7D9CFEiYHrRvjABf1xkdGsaw8mYIPcIElzoSDR",
+ "xYplkE0N910vWbokKVV2CHyPrFmeGxqsFGRDtBZf3Y7D9CFEiYHrRvjABf1+kdGsaw8mYIPcIElzoSDR",
"Ys/15G8cyjMSXijNXaUOu6zI5RIITm4e2MsWcccNTef5lmjc14xQRSjxV9OUsDnZioqscXNydo3fu9UY",
"rBXEIA03p3WPmsM7hL4eMiLImwmRA+WIPH/u+ijjc7aoJCiyXoJeujtPgioFV0DE7O+QarPt/37x6kci",
"JHkJStEFvKbpNQGeigyyY3I+J1zogDQcLSEOzZdD63BwxS75vythaKJQi5Km1/EbPWcFi6zqJd2woioI",
@@ -202,213 +202,214 @@ var swaggerSpec = []string{
"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",
- "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",
+ "nr20Yl7+q3s3JDPz+6iP/xgkFuJ2mLhQ0XKYszoO/hIoN/c7lNMnHGfuOSZn3W9vRjZmlB0Eo84bLN41",
+ "8eAvTEOh9lJCAFFATW57qJR0O3FCYoLCXp9MflJgKaSkC8YR2qlRnzgp6LXdD4F4N4QAqtaLLC1ZCbI2",
+ "oTqZ06H+uGdn+QNQa2xjvSRqJNWcKY16Nb5MlpCj4Ey5J+iQVG5EGSM2fMciapjXkpaWlt0TK3Yxjvq8",
+ "fcnCesuLd+SdGIU5YPfBRiNUN2bLe1lnFBLkGh0YvslFev1XqpZ3cMJnfqw+7eM0ZAk0A0mWVC0jB6dD",
+ "281oY+jbvIg0S2bBVMfNEvHvO1skjrZnmRnVNFimgz0uzQYwDiDCPhuDim+iCHghFuoOlp+LQ3h3WT6j",
+ "eW6m7vPszipx4FGcLM+JeZlAwdBj4DRn62KwCij5lqZLIxeRlOb5tLGViTLJYQU5EZIwzkFOiV5S3XA/",
+ "HNkrdshIFBhur4EEq3F2NrQxytoYI4EUFK/gwqhzZd7+pr5CFC2gIwaiSCAqNKMEmtb5c786WAFHplwP",
+ "jeDXa0RzVTj4sZnbPcKZubCLsyZQ7f2XNf5qhtkC2rzdCBS8mULIzBrttfmNSZIKaYewIo6b3PwHqGw+",
+ "tsfzfikhcUNIugKpaG5W11nUg5p87+rkfqwzO52kICNmqlf4H5oT89iIcYaSGuphKI2JwJ+cWcnEoMrO",
+ "ZF5Ag7MghbXlkpKm1wdB+ayZPM5eRp28b6352G2hW0S9Q5cblqm72iYcbGiv2ifEGu88O+oJYzuZTjDX",
+ "GARcipJY9tEBwXIKHM0iRGzu/F7/Rmyi3F5sene62MCd7IQZZzSz/0ZsnjvIhNyPeRx71HUmNoTTAhRe",
+ "7zxknGaWxjF5NhPyZuJU54LhpHG3EmpGDaTJaQdJ+GpVJu5sRlw29oXOQE2Ey24pqDt8DGMtLFxo+hGw",
+ "oMyod4GF9kB3jQVRlCyHOyD9ZVSKnVEFjx+Ri7+effHw0S+PvvjSkGQpxULSgsy2GhS57+ySROltDg+i",
+ "6iFKF/HRv3zinXTtcWPjKFHJFApa9oeyzj+r/tvXiHmvj7U2mnHVNYCjOCKYq82inVi/tgHtOcyqxQVo",
+ "bVT911LM75wb9maIQYcvvS6lESxU21HqpKWTzLxyAhst6UmJbwLPbKCFWQdTRgkuZndCVEMbnzWzZMRh",
+ "NIO9h+LQbWqm2YZbJbeyugv7DkgpZPQKLqXQIhV5YuQ8JiIWmtfuDeLe8NtVdn+30JI1VcTMje7bimcD",
+ "hhi94ePvLzv05YY3uNl5g9n1Rlbn5h2zL23kN1pICTLRG06QOlv2obkUBaEkww9R1vgetJW/WAEXmhbl",
+ "q/n8bsy9AgeKGLJYAcrMROwbRvpRkApuoxn32KzcqGPQ00WMd7PpYQAcRi62PEVf4V0c22FzXsE4Bi6o",
+ "LU8D256BMYds0SLL29vwhtBhp7qnIuAYdLzAx+iseA65pt8JedmIr99LUZV3zp67c45dDnWLce6QzHzr",
+ "7eCML/J2BO3CwH4cW+NnWdCz2ohg14DQI0W+YIulDvTF11J8hDsxOksMUHxgrWW5+aZvM/tRZIaZ6Erd",
+ "gSjZDNZwOEO3IV+jM1FpQgkXGeDmVyouZA7EXGKwF8ao6VBuRfsEU2QGhrpSWpnVViXBCKzefdF8mNDU",
+ "ntAEUaMG4k/qwCH7lp3OxvPlEmi2JTMATsTMBXm48BNcJMXwMe3FNCfiRvhFC65SihSUgixxtvi9oPn3",
+ "7NWhd+AJAUeA61mIEmRO5a2BvV7thfMatgkGOypy/4ef1YPPAK8WmuZ7EIvvxNDbtaf1oR43/S6C604e",
+ "kp211FmqNeKtYRA5aBhC4UE4Gdy/LkS9Xbw9WlYgMabmo1K8n+R2BFSD+pHp/bbQVuVACL9T042EZzaM",
+ "Uy68YBUbLKdKJ/vYsnmpZUswKwg4YYwT48ADgtcLqrSNA2M8Q5umvU5wHiuEmSmGAR5UQ8zIP3sNpD92",
+ "au5BripVqyOqKkshNWSxNaBLenCuH2FTzyXmwdi1zqMFqRTsG3kIS8H4DllOA8Y/qK4d0M6l3V8cBhWY",
+ "e34bRWULiAYRuwC58G8F2A3DmAcAYapBtCUcpjqUU8dOTydKi7I03EInFa+/G0LThX37TP/UvNsnLuvk",
+ "sPd2JkChA8W97yBfW8zaAPYlVcTB4WMM0JxjA9b6MJvDmCjGU0h2UT6qeOat8AjsPaRVuZA0gySDnG4j",
+ "0RH2MbGPdw2AO96ou0JDYiOR45veULIP/NwxtMDxVEx4JPiEpOYIGlWgIRD39Z6RM8CxY8zJ0dG9eiic",
+ "K7pFfjxctt3qyIh4G66ENjvu6AFBdhx9DMADeKiHvjkq8OOk0T27U/wNlJugliMOn2QLamgJzfgHLWDA",
+ "FuySvILz0mHvHQ4cZZuDbGwPHxk6sgOG6ddUapayEnWdH2B756pfd4Ko45xkoCnLISPBA6sGluH3xMbQ",
+ "dse8mSo4yvbWB79nfIssx8cptYG/hi3q3K9tckZg6rgLXTYyqrmfKCcIqA/5NiJ4+ApsaKrzrRHU9BK2",
+ "ZA0SiKpmNoSh70/RokzCAaL+mR0zOu9s1De60118gUMFy4sF21mdYDd8lx3FoIUOpwuUQuQjLGQ9ZEQh",
+ "GBU7Qkphdp25/C+fAeQpqQWkY9romq+v/3uqhWZcAfmbqEhKOapclYZaphESBQUUIM0MRgSr53TRmQ2G",
+ "IIcCrCaJT46Ougs/OnJ7zhSZw9onTZoXu+g4OkI7zmuhdOtw3YE91By388j1gY4rc/E5LaTLU/aHfLmR",
+ "x+zk687gtbfLnCmlHOGa5d+aAXRO5mbM2kMaGRfuhuOO8uW044N668Z9v2BFlVN9F14rWNE8ESuQkmWw",
+ "l5O7iZng365o/qr+DBNCITU0mkKSYhrjyLHg0nxjMx/NOIwzc4Bt1sNYgODcfnVhP9qjYjahuqwoIGNU",
+ "Q74lpYQUbMKfkRxVvdRjYlMB0iXlC1QYpKgWLrrXjoMMv1LWNCMr3hsiKlTpDU/QyB27AFyYms/5NOIU",
+ "UKPSdS3kVoFZ03o+l+Y75mYO9qDrMYg6yaaTQY3XIHXVaLwWOe3E1RGXQUveC/DTTDzSlYKoM7JPH1/h",
+ "tpjDZDb345jsm6FjUPYnDkKem4dDUc9G3c63dyD02IGIhFKCwisqNFMp+1TMwyR1Hyq4VRqKviXffvrL",
+ "wPF7M6gvCp4zDkkhOGyjdVkYh5f4MHqc8Joc+BgFlqFvuzpIC/4OWO15xlDjbfGLu909oV2PlfpOyLty",
+ "idoBR4v3IzyQe93tbsqb+klpnkdciy6FtcsA1LQO1mWSUKVEylBmO8/U1EUFW2+ky3dto/91nZhzB2ev",
+ "O27HhxZWR0AbMeQloSTNGVqQBVdaVqm+4hRtVMFSI0FcXhkftlo+86/EzaQRK6Yb6opTDOCrLVfRgI05",
+ "RMw03wF446WqFgtQuqPrzAGuuHuLcVJxpnGuwhyXxJ6XEiRGUh3bNwu6JXNDE1qQ30AKMqt0W/rHDG2l",
+ "WZ47h56Zhoj5Faea5ECVJi8Zv9zgcN7p748sB70W8rrGQvx2XwAHxVQSDzb73j7FxAa3/KVLcsBwd/vY",
+ "B502JSMmZpmtKjH/9/6/PX17lvwXTX47Tb76l5N37598eHDU+/HRh6+//n/tnx5/+PrBv/1zbKc87LH8",
+ "YQf5+XOnGZ8/R/UnCNXvwv7J7P8F40mUyMJojg5tkftYK8MR0IO2cUwv4YrrDTeEtKI5ywxvuQk5dG+Y",
+ "3lm0p6NDNa2N6BjD/FoPVCpuwWVIhMl0WOONpah+fGY8Ux+dki75Hs/LvOJ2K730bRNRfXyZmE/ragy2",
+ "UNtTgqn6S+qDPN2fj774cjJtUuzr55PpxD19F6Fklm1ihRQy2MR0xTBJ4p4iJd0q0HHugbBHQ+lsbEc4",
+ "bAHFDKRasvLTcwql2SzO4XzOlrM5bfg5twH+5vygi3PrPCdi/unh1hIgg1IvYwWcWoIavtXsJkAn7KSU",
+ "YgV8StgxHHdtPpnRF11QXw507gNTpRBjtKH6HFhC81QRYD1cyCjDSox+OukN7vJXd64OuYFjcHXnjEX0",
+ "3vv+20ty4himumdretihgyoMEVXaZY+2ApIMNwtzyq74FX8Oc7Q+CP70imdU05MZVSxVJ5UC+Q3NKU/h",
+ "eCHIU5+Q+pxqesV7ktZgZckga5yU1SxnKbkOFZKGPG21sP4IV1dvab4QV1fverEZffXBTRXlL3aCxAjC",
+ "otKJq3WUSFhTGfN9qbrWDY5si5ntmtUK2aKyBlJfS8mNH+d5tCxVt+ZFf/llmZvlB2SoXEUHs2VEaVHn",
+ "oxkBxeU0m/39UbiLQdK1t6tUChT5taDlW8b1O5JcVaenjzGzrykC8au78g1NbksYbV0ZrMnRNargwq1a",
+ "ibHqSUkXMRfb1dVbDbTE3Ud5uUAbR54T/KyVdegTDHCoZgF1jvfgBlg4Ds6OxsVd2K98Xcv4EvARbmE7",
+ "A/1W+xUUELjxdu0pQkArvUzM2Y6uShkS9ztTl7tbGCHLR2MotkBt1VUGnAFJl5Beu5JtUJR6O2197gN+",
+ "nKDpWQdTtpifzTDEclLooJgBqcqMOlGc8m23ro+yGRU46Bu4hu2laKpRHVLIp11XRg0dVKTUQLo0xBoe",
+ "WzdGd/NdVJlPNHXlWTB505PF05ou/DfDB9mKvHdwiGNE0ap7MoQIKiOIsMQ/gIIbLNSMdyvSjy2P8RS4",
+ "ZitIIGcLNovVIf6Pvj/Mw2qo0pVedFHI9YCKsDkxqvzMXqxOvZeUL8Bcz+ZKFYrmtqxsNGgD9aElUKln",
+ "QPVOOz8PK3J46FClXGPmNVr4pmYJsDH7zTRa7DisjVaBhiL7jotePh6OP7OAQ3ZDePznjaZwPKjrOtRF",
+ "Si76W7nGbq3WutC8kM4QLvu8AKzZKtZmXwwUwpUbtVVtgvulUnQBA7pL6L0bWRCk5fHDQfZJJFEZRMy7",
+ "okZPEoiCbF9OzJqjZxjME3OIUc3sBGT6mayD2PmMsIq4Q9gsRwG2jly1e09ly4tqyyIPgRZnLSB5Iwp6",
+ "MNoYCY/jkip/HLFgrOeyo6Szj1j3ZldtvvMgljCoCltX3vO3YZeD9vR+V6HPl+XztfhCpX9EXT2je2H6",
+ "Qmw7BEfRNIMcFnbh9mVPKE3FqGaDDByv5nPkLUksLDEwUAcCgJsDjOZyRIj1jZDRI8TIOAAbAx9wYPKj",
+ "CM8mXxwCJHcVr6gfG6+I4G+IJ/bZQH0jjIrSXK5swN+Yeg7gSlE0kkUnohqHIYxPiWFzK5obNud08WaQ",
+ "Xok4VCg6BeFc6M2DIUVjh2vKXvkHrckKCTdZTSjNeqDjovYOiGdik9gM5aguMtvMDL1HcxcwXzp2MG0x",
+ "vnuKzMQGw7nwarGx8ntgGYbDgxHYXjZMIb3id0NylgVm17S75dwYFSokGWdorcllSNAbM/WAbDlELveD",
+ "+no3AqBjhmqaVTizxF7zQVs86V/mza02berG+rSw2PEfOkLRXRrAX98+1q6I99em8uFwdTV/oj5JKcC+",
+ "Zek2JRrtx6Utu3hIhcYuObSA2IHV1105MIrWdqxXG68B1mKsxDDfvlOyjzYFOaASnLRE0+Q6FilgdHnA",
+ "e/zCfxYY63D3KN8+CAIIJSyY0tA4jXxc0Ocwx1OsHy3EfHh1upRzs743QtSXv3Wb44etZX7yFWAE/pxJ",
+ "pRP0uEWXYF76TqER6TvzalwCbYco2m4LLItzXJz2GrZJxvIqTq9u3h+em2l/rC8aVc3wFmPcBmjNsDtI",
+ "NHB5x9Q2tn3ngl/YBb+gd7becafBvGomloZc2nP8Qc5Fh4HtYgcRAowRR3/XBlG6g0EGCed97hhIo0FM",
+ "y/Eub0PvMGV+7L1Raj7tfejmtyNF1xKUAYxnCIrFAjJf3sz7w3hQRC4XfBG0sSrLXTXzjoktXYeV53YU",
+ "rXNh+DAUhB+I+wnjGWzi0IdaAULeZNZhwT2cZAHcliuJm4WiqAlD/PGNwFb3iX2h3QSAaBD0ZceZ3UQn",
+ "212qtxM3IAeaOZ1EgV/f7mPZ3xCHuulQ+HSr9OvuI4QDIk0xHXR26ZchGGDAtCxZtuk4nuyog0YwepB1",
+ "eUDaQtbiBtuDgXYQdJTgWrXEXai1M7CfoM57YrQyG3vtAosNfdPUJeBnlUQPRiuyuV+4vtbVRq79h58v",
+ "tJB0Ac4LlViQbjUELucQNARl4RXRzIaTZGw+h9D7om7iOWgB17OxZyNIN0JkcRdNxbj+8kmMjPZQTwPj",
+ "fpTFKSZCC0M++cu+l8vL9IEpqb4Sgq25gasqmq7/A2yTn2leGSWDSdWE5zq3U/vyPWDXV8UPsMWR90a9",
+ "GsD27Apant4A0mDM0l8/UkEF73uq1eMA1cvWFh6wU2fxXbqjrXFdKYaJv7llWl0b2ku5zcFogiQMLGN2",
+ "4yIem2BOD7QR3yXlfZvAsv0ySCDvh1Mx5Xt49q+iuhbFPtq9BJp74sXlTD5MJ7eLBIjdZm7EPbh+XV+g",
+ "UTxjpKn1DLcCew5EOS1LKVY0T1y8xNDlL8XKXf74ug+v+MSaTJyyL789e/Hagf9hOklzoDKpLQGDq8L3",
+ "yj/Mqmwfi91Xia327Qyd1lIUbH5dkTmMsVhjZe+OsanXFaaJnwmOoou5mMcD3vfyPhfqY5e4I+QHyjri",
+ "p/F52oCfdpAPXVGWe2ejh3YgOB0XN661UJQrhAPcOlgoiPlK7pTd9E53/HQ01LWHJ+Fcr7A0ZVzj4K5w",
+ "JbIiF/xD71x6+k7IFvN3mYnR4KGPJ1YZIdvicSBW2zfw7ApTx8QKXr8ufjWn8egoPGpHR1Pya+4eBADi",
+ "7zP3O+oXR0dR72HUjGWYBFqpOC3gQZ1lMbgRn1YB57Aed0GfrYpashTDZFhTqI0C8uheO+ytJXP4zNwv",
+ "GeRgfjoeo6SHm27RHQIz5gRdDGUi1kGmhe0Zqojg3ZhqTII1pIXM3rVksM7Y/hHiVYEOzETlLI2HdvCZ",
+ "MuyV22BK8zLBlwestWbEig3E5vKKBWOZ18bUTO0AGcwRRaaKlm1tcDcT7nhXnP2jAsIyo9XMGUi81zpX",
+ "nVcOcNSeQBq3i7mBrZ+qGf42dpAd/iZvC9plBNnpv3te+5T8QmNdjw6MAA9n7DHuHdHbjj4cNdtstmU7",
+ "BHOcHjOmd7xndM5ZNzBHtBc8U8lcit8g7ghB/1GkEIZ3fDI08/4GPBa512UptVO5aWnfzL5vu8frxkMb",
+ "f2td2C+6brt2k8s0fqoP28ibKL0qXq7ZIXlICQsjDNqpAQOsBY9XEAyLbVB89BHl9jzZKhCtDLP4qQxz",
+ "OU/s+M2pdDD38l9zup7RWI8YowsZmILtbcVJaUH8x34DVF3jwM5Oggju+l1mK8mVIBsfRL8q7Q31Gjvt",
+ "aI2mUWCQokLVZWrDFHIlIsNUfE25baNuvrP8yn2twLrgzVdrIbEOpIqHdGWQsiJqjr26epul/fCdjC2Y",
+ "7RBeKQhaULuBiC02iVTk2njXlTscas7n5HQa9MF3u5GxFVNslgO+8dC+MaMKr8vaHV5/YpYHXC8Vvv5o",
+ "xOvLimcSMr1UFrFKkFr3RCGvDkycgV4DcHKK7z38itzHkEzFVvDAYNEJQZOnD7/CgBr7x2nslnUd3nex",
+ "7Ax5tg/WjtMxxqTaMQyTdKPGo6/nEuA3GL4ddpwm++mYs4Rvugtl/1kqKKcLiOdnFHtgst/ibqI7v4MX",
+ "br0BoLQUW8J0fH7Q1PCngZxvw/4sGCQVRcF04QL3lCgMPTX9pe2kfjhsROb7RXm4/EOMfy19+F/H1vWJ",
+ "1RhaDORsYZTyj+ijDdE6JdQW/8xZE5nuG5aSc19bGBto1X2zLG7MXGbpKEtioPqclJJxjfaPSs+Tvxi1",
+ "WNLUsL/jIXCT2ZdPIo2o2r1a+GGAf3K8S1AgV3HUywGy9zKL+5bc54InheEo2YOmxkJwKgcDdeMhmUNx",
+ "obuHHiv5mlGSQXKrWuRGA059K8LjOwa8JSnW6zmIHg9e2SenzErGyYNWZod+evPCSRmFkLGGAc1xdxKH",
+ "BC0ZrDBjLr5JZsxb7oXMR+3CbaD/vPFPXuQMxDJ/lqOKQODR3JUsb6T4n182lc/RsWozETs2QCEj1k5n",
+ "t/vE0YaHWd26/lsbMIbPBjA3Gm04Sh8rA9H3Nry+/uZzxAt1QbJ73jI4PvyVSKODoxx/dIRAHx1NnRj8",
+ "66P2Y8vej47iBYijJjfza4OF22jE+G1sD78REQOY71pYBxS5+ggRA+TQJWUeGCY4c0NNSbtD3KeXIu4m",
+ "vysebRo/BVdXb/GJxwP+0UXEZ2aWuIFNlsLwYW93yIySTFY/D+LcKflGbMYSTucO8sTzO0DRAEpGmudw",
+ "Jb0OoFF3/d54kYBGzagzyIVRMsOmQKE9/4+DZ7P46Q5sVyzPfm5qu3UuEkl5uoxGCc/Mh79YGb11BVtW",
+ "Ge0zsqScQx4dzuq2v3gdOKKl/12MnadgfOS73Q60drmdxTWAt8H0QPkJDXqZzs0EIVbbZbPqsgz5QmQE",
+ "52maWjTMsd/KOdZCM5LfjMMWlXZxq5gL7goOzVmOYZhxvzG+mUiqBwpoYb9z31/IjIPtx5U1M9jRQRLK",
+ "CryYFS3KHPBkrkDSBX4qOHQ+xxJqOHLQsYKo0jzCN7FghSC6kpyI+TxYBnDNJOTbKSmpUnaQU7Ms2ODc",
+ "k6cPT0+jZi/EzoiVWiz6Zb5qlvLwBF+xT1yTJdsK4CBg98P6oaGoQza2Tziup+Q/KlA6xlPxgc1cRS+p",
+ "ubVtP8m69+kx+R4rHxkibpW6R3OlLyLcLqhZlbmg2RSLG19+e/aC2FntN7aFvO1nuUBrXZv8o+6V8QVG",
+ "fWWngco548fZXcrDrFrppG4/GatNaN5oGmSyTswN2vFC7ByT59aEWjfwt5MQLJEtC8iCbpdWiUfiMP/R",
+ "mqZLtE22JKBhXjm+EatnZ43nJsg+rLsfIcM2cLterLYV65QIvQS5ZgowIx9W0C6HWNcGdbZxXx6xvTxZ",
+ "cW4p5fgAYbTudXQo2j1wVpL1QQVRyDqIP9AyZfsxH9qX9gK/iudidJrcdrz+vrieL7FNXjrnQkq54CzF",
+ "VggxSRpLt41zU47oGhH3L6qJO6GRwxVtrVvnAjssDjbb9YzQIa7v8g+emk211GH/1LBxLdcWoJXjbJBN",
+ "fadr5xBjXIHrZmWIKOSTQkaCmqKJEHUAxYFkhFWZBiyc35lnPzr7NxbFuGYcLV0ObU4/sy6rXDH0THPC",
+ "NFkIUG497Wwe9dZ8c4xVGjPYvDt+IRYsvWALHMOG0Zll25jR/lBnPoLURWyad5+Zd13t/PrnVjiYnfSs",
+ "LN2kw33Qo4Kk3vBBBMfilnwgSYDcevxwtB3ktjP0G+9TQ2iwwqg1KPEe7hFG3Uu7Pcq3Rre0FIVvEJtR",
+ "GS2gy3gEjBeMexdq/IJIo1cCbgye14HvVCqptrrDKJ52CTQfSIDADGXrg7/tUN3OAQYluEY/x/A2Nm3A",
+ "BxhH/UIj8VO+Jf5QGOoOhIlnNK9DpyNNvVGqckJUhslFnTbfMcZhGHfiUyZb6Nqbvld/jt04Dr2JhmoU",
+ "zqpsATqhWRYrbfUNPiX41CeJwQbSqm5CVWcHtmuU96nNTZQKrqpix1z+hVtOF/TNj1BD2Lvf7zBW2plt",
+ "8d9YB6bhnXFB0wdn5foI6eywwvz9LOOY1GtoOlFskYzHBN4pt0dHM/XNCL35/k4p3afr/i6ycTtcLtyj",
+ "GH/71lwcYeHeXny6vVrquroYCy7wuS94VFeEbHMlvMp6fcYw6gE3L7JlHeD9i1HAVzQfyIQPfSX2frX+",
+ "g6F8+HSwfAPVrjyXpmQnCxoseWRjhTvel74LcSg+2IYH353Xwq11J0KHfXc/tDx1NkasYRaDHrqbOdGa",
+ "DT7Ui/bDaqhEgu/Tgc/DfiAuimfqysDDionKR1/5GGivEtpfXQmeVt+PgfVHMws+t9di0Mdy6frX2mU6",
+ "nfyHn60XlgDXcvs78Lj0Nr3bVCYi7VrzVPMKqVsfjmqF2LoVx/SwibVLcbKht5VZ1tKipV77mR5ZPR8j",
+ "DvTw8WE6Oc8OujBjLXcmdpTYsXvBFkuNFfv/CjQD+XpPR4KmCwEesVIo1nQgzc1grgTsEoc7HptsYAiY",
+ "hR0V+mP5INQVpBrbzjbBdRLgkP4KZjLv9PmzM8GwOl3nZLiGBLu6EPR7ze6543uFk4LiX7ZP5/H4mvtn",
+ "dQi1zQBbU9WUa+nkTI/O3JzPIcWqyDsLVf3HEnhQBGnq7TIIyzyoW8XqPCas63241bEBaFcdqZ3wBP11",
+ "bg3OUB77NWzvKdKihmjj0DqJ7yaFgxED1gXma0gPGZJd1BhTNWUgFnxIsCvF3DTHGKz5HJRdu+FcniTN",
+ "xdGUYtsxZbzp+ai5zKcHlX3ElJyhWlb9nsnD+sdzbFGtXIAcrQsPh1o6Oe83zlm7wsVYVqz2nfgSxqD8",
+ "b76GoJ0lZ9eufwBixXqq1lRm/o07KQpl7yYWB3pez8yaBI5+kEOkFQPmQqW5MGJEMpRQ1s6ZqAMO7ykb",
+ "GdoU8EG45iAlZLVLJBcKEi18wscuOHahwoa/3ggJarD9kQVusPT1m6a2N7aBo1jqmrqo13CBREJBDXQy",
+ "qMA9POcuZD+zz30Svm8DttfCVNPr/n60PnWHqR4SQ6qfE3db7k/uv4mxiXEOMvGep245bt6uyIZ1N7Mq",
+ "tRd0eDBqg9zo2jk7WEnUTpP2V9nREYIk+WvYnlglyDfy9TsYAm0lJwt6UHC0s8l3an5TMbgXdwLe560j",
+ "VwqRJwPOjvN+DfEuxV+z9BqwBmAd4j7Qo53cRxt77c1eL7e+ZnZZAofswTEhZ9wmFXnHdru9YGdyfk/v",
+ "mn+Ds2aVLevvjGrHVzyenYEF9+UtuZkfZjcPU2BY3S2nsoPsqVC94UMhN2sszt/u4nk8Vivvu5q7XeQb",
+ "orJQxGSSC+uxeoYHPWY4whIIQa0OdGRS4jxdROUiFst7kzINZqg4psLJECANfEy1gBoKN3gUAdG+6JFT",
+ "aEvfuaJ3Yk4kNE7km1b/67dwj2n03ZnrWdr8bi4ktJqxm69tpc868QXLaOJ/ZkxLKrc3qdHXayHfs54M",
+ "YnlvOFYdidUspInG6uMwz8U6QWaV1H0uYqqteU+1L2PfdK35zpzqGQRxXVQ5QW1LljQjqZAS0vCLeL6n",
+ "haoQEpJcYJhXzAM910buLjDJi5NcLIgoU5GB7RcTp6ChuSrOKYpNEETVRFFgaQezhe03AR2PnNLcqdaP",
+ "lKCotTigd34KNnO9qepkF51YX+ZAxDIoV8XJYci+3Id3R+//OG+esw3SDcjYkZ8TLSuYEvdGt0e2O/hU",
+ "AimYUhaUmpbWLM8xcZxtAs9rHbgQR+2A2HuOYZUrhrE37SICVhouzZ1XV1YIecBFWPaI6KUU1WIZFJiu",
+ "4fQqr6ycQhyO8pOqMDwKM8jMFE9IIZR2mqYdqVlyE3J2PxVcS5HnbaOUFdEXztL+km7O0lS/EOJ6RtPr",
+ "B6jXcqHrlWZTn1/dDQ5sZpKd0mLtCzix7cz3l+q172GonCPa0Qyyw+IObuwegPluPwfdb3M/6y+su642",
+ "M42rMWecUC0KlsbP1B8r2m4wRi7GoqI1y2xvRVtlAl/Dwx5eVnVwBbLIPpqB02hzuDPiGIFzMiO7Mf9F",
+ "Cbw7LpmDYzQDF2WfuTgpKkkHZb0OAAipTX3WlbQNGUNJrOYqYmFLJaCLvAvoyFsFI5FuB5sZ4c6B0nAr",
+ "oHrRjzWA963xYWpry9lIypnY+OcPmuJzNwL+w24qbzGPoRCvi4a0pA3y8oVqBjhCvMT1znioS0x7n42N",
+ "iqqb54684QMAhuOkWjCMipY6FIw5ZTlkSaz34nlto5oGmrZLzeq2RGfKcfKUVr71oRm7kuAKp1gRX7b9",
+ "XyU1pCTq1/uWZJ7BBmxex28ghe1pOA38L5DblocdY4AokxxW0Aofc9VcKhQ12Qr8t6r+mGQAJXojuzay",
+ "WFxUeJd3DCdu7UkQWTMGu1FLikWs3Smyx0wSNepseGKPiRp7lAxEK5ZVtIU/dajI0TYDmqMcQVVPR0i8",
+ "Hjl2mp/sCG/8AGf++5go4zHxbhwfOpgFxVG3iwHtjZOs1NCp5/EwybBUUe1gwdmy2hFrSbzhG6qkaz5s",
+ "kOyTfKNujdwnJniA2G83kKJU4/QdyJzGM+CkcFVPkNo5QGa1AvNJxNq+BE64CFpMrqmqVZWmhqL/wU6M",
+ "LzHutOkbOJWbaMbb7yzBwYjqFFMbVCRkTac3N89/lpO48yAOjhejEQUu/W+H/ctTt1M78AVs5c3NfhrZ",
+ "H5s0ulvMcfEpmVV+oDwXa9szMtRDn4P3g1rq8y4gJ5az+lr2UZtTV96za+pgQbx6QbdESPzHaJ3/qGjO",
+ "5lvkMxZ8/xlRS2pIyDlebUSAiwI1E+8Wr6YeMG9tEX4qu242dsxguK0ZJQDaXOS+uY8gBb2GcBsw2MHy",
+ "z1QbxqmqGVouzJXd2c4+FtzifYmWgmahpo+FIttt1H3pYPP1/25y4cKpfH23Mqep7xDqWhS1+Qx2AfbE",
+ "pZdQ7E6W7PM1TwJ1Z+GGaKXPrs9uYDI9kHXFMhCG2q+0wO51XO11nrnVMkZafjs9NnakmY5ayl3vwtio",
+ "mx7QYZ/GfeCHbSs/Df6jNVyHljEG/N8L3gca1Ybw2p60nwDLrQocEVittXomNomEudoXYGLN1Uadl03t",
+ "Dm9iZTyVQJWNuDl/5RTPpkQp40YRtjGhtU+zHiWDOeMNs2S8rHREj8FKpXwbICw0+iNaB1xoQ1KCESZX",
+ "NH+1AilZNrRx5nTYlo5hiwjv6HDfRkwY9Z3aH4CpRofD/MzGjB6+Zi5w24TKhmsqTXlGZRa+zjhJQZp7",
+ "n6zpVt3co1Q7B/b5lGggzbSrBgTeJSRtC0i+dU7hW/p7agDpHTp+RjhsMC444qyxph0tBvwzfRj+EA6b",
+ "gm6SXCwwi3DgQLjatOjhsyqg4GgGt/LZuHX7eRT7DXZPg2X5HSPSAmcdM8Xuc/8KtxLVyJ840ztPvrVR",
+ "dtM6bdytPZgeqXzRBP9bYumfx1gmriu+EmbjemHTp6p42oNgE2HAP9S2iw/sIoZBuDTu0Ag+vt1ZO9Ii",
+ "lu9rLQMJWgzUjvB+UE0oO01deFbflNYzNVikTF229IGWNmuf9/fSAHi2N7076+1p65AZM84hPeJ250cn",
+ "pSiTdEzMp+3ckTk3gYO0DeMAfQROgIF11+Exqu5l06p71Gpqc2ibvMGmOvu8XWW6S+kfMhMNcPS2C0LM",
+ "kZfZzu1o3cJMntqYMu3mmLXNYDWTIJRISCuJZuI13e5vOzZQMfrir2dfPHz0y6MvviTmBZKxBaim6nin",
+ "bVcTF8h41+7zaSMBe8vT8U3w1Qcs4rz/0SdV1ZvizprltqopKdprWnaIfTlyAUSOY6Rd1I32CsdpQvt/",
+ "X9sVW+Sd71gMBR9/z6TI83jXh1quijhQYrsVuFCMBlKCVExpwwjbHlCmm4hotUTzINb+XdlqMoKn4O3H",
+ "jgqYHgi5ii1kKKAW+RnmdjuvEYFNmTteZT09u9bl9DRroUOhEaNiZkBKUTrRns1JDCLMIJJBZq0zfKJF",
+ "PIiRrZmtjZaNEaKLPI+TXtgweze3bzdz1XFObzYxIl74Q3kD0hzyTwzXLbgJJ2lM+78b/hEpxHBnXKNe",
+ "7sfgFVH94GZN+UeB1k/Kj5AHAjCQbdvKkwwSxYJCxNJ6CdCf4B3IXfHjZeNY3psWgpD4D/aAF6bPNu/V",
+ "mQwOnM9c0fdljZRgKe+GKKG1/H0ZuZ711hdJsEXOaKI1KMuWRF8sDNKt1bM6i3lAK+klO0shNDGaaZ5H",
+ "kqStHQfPVEg4RiWQK5p/eq7xHZNKnyE+IHsznBoVZsqGSLaoVDer0/eCjpo7yIq9u6n5a0zM/g8wexS9",
+ "59xQzgnfu83QuIMd6xf+VrC53mSNY9ogq4dfkplrtlFKSJnqOvfXXjipE0NBsrkLaIWN3pOJum+dPwt9",
+ "CzKe+0gc8mPg3qp99g7C5oh+ZqYycHKjVB6jvh5ZRPAX41Fhc94918UtGzPcrOxLUMDtwLIv/bbDY5dn",
+ "S5uYS6dS0F/n6Nu6hdvIRd2sbWzNotH9Ha6u3urZmFJD8V4M5nOsdXQnTRkOasnwEaocWRy5Mdy8MYr5",
+ "eajura3tOlCbu7MfFcv3Bqy0Kq1/mE4WwEExhbXEf3G9Yz7tXeohsJUX+kfVwnqbcjEWMZG1tiYPpgpq",
+ "qI8on+4+i9S8xqzGtJJMb7FvsDegsV+i9Zi+r2t7uNowtS/N3X1aXEPdu72pBFIpf7t+L2iO95F18XFz",
+ "C4n8mHxrK3y7g/L1vdm/wuO/PMlOHz/819lfTr84TeHJF1+dntKvntCHXz1+CI/+8sWTU3g4//Kr2aPs",
+ "0ZNHsyePnnz5xVfp4ycPZ0++/Opf7xk+ZEC2gPrS/k8n/5mc5QuRnL0+Ty4NsA1OaMl+ALM3qCvPBfa1",
+ "NEhN8SRCQVk+eep/+j/+hB2nomiG979OXH+myVLrUj09OVmv18fhJycLTP1PtKjS5YmfB7sNtuSV1+d1",
+ "jL6Nw8EdbazHuKmOFM7w2ZtvLy7J2evz44ZgJk8np8enxw9da2tOSzZ5OnmMP+HpWeK+n2B9zRPlSuef",
+ "1LlaH6a9Z2VpC+ubR45G3V9LoDkW2DF/FKAlS/0jCTTbuv+rNV0sQB5j9ob9afXoxEsjJ+9d5YQPu56d",
+ "hJEhJ+9bBSayPV/6yId9r5y8961zdw/YapvqYs4MUqMuz+9Bu3JL1vYQqdWBngY3+pQorJtvfiolE+a8",
+ "Ts3lmwHGBWB4m8QC4lpWPLXOYjsFcPzvy7P/RIf5y7P/JF+T06lLOFCo0MSmtxnXNaGdZxbsfpyi+mZ7",
+ "VlczaZzrk6dvY0YmFyxaVrOcpcTKKXhQDRUG56geseGTaFGcqLq/ecP1DSc/Tb569/6Lv3yISZM92bhG",
+ "UlDgo+X1Fb7zKSKtoJuvh1C2cRHoZtx/VCC3zSIKupmEAPc9qJGqZz5ByDeADmMTg6jFf7949SMRkjjt",
+ "+TVNr+vkKJ8N12QAhslw5sshiN3FGgINvCrMHeWyrAq1KNsFgGs0v8NuiQgospNHp6eehzoNJTigJ+7c",
+ "BzN1zFp9QsMwncBQ2U+FVwQ2NNX5llAVxElg1KLvbNpJYRNl0gqk32ka7c/otiSahXBoNn6kQr3QNN8D",
+ "32WnC2QLHS7kpzSX7P709x4yohC8i4kR4dZ6Gvlzd/977G5fKiGlMGeaYVx2c+X466wFpJNF860Hd6DQ",
+ "yDH5m6hQdjRaQaUh1gMfZ7A+ETenq4sUBNI1qUP45Oiou/Cjoybsbw5rZLKU44tddBwdHZudenIgK9tp",
+ "p26VER51dg4ZrrdZL+mmjpqmhAuecFhQzVZAAoXzyenDP+wKz7mNUzfCshXqP0wnX/yBt+ycG8GG5gTf",
+ "tKt5/IddzQXIFUuBXEJRCkkly7fkJ14nAgQt1vvs7yd+zcWae0QYfbUqCiq3ToimNc+peND3Zyf/6VU4",
+ "agRt5KJ0oTAWBkVUK9P6Koh8MXn3wesAI3WPXa+dzLAD5thXIVRYhrUT9Eyok/doWx/8/cQ5SAceWr15",
+ "6DG6QOw7J74048CbtghX/GFLaXqvN2adu4cz7wTjpVSny6o8eY//QTU5WLCt6X+iN/wEQ0ZP3rfw5B73",
+ "8NT+vfk8fGNViAw8cGI+V6jm7Xp88t7+G0wEmxIkM7cV1tF0v9p6xyfYaHrb/3nL0+iP/XW0ar0O/Hzi",
+ "rTQxjbv95vvWn22SU8tKZ2IdzIL+Deuc60NmHlaq+/fJmjJtZChXYpTONcj+xxpofuL6CXV+bUr4955g",
+ "X4Lgx47UVQpbY6it8L6h68tWqqi0tTS+EWjHGOLHm2TGODKpkIk2Vkv7sK9B9Vjn5RJseK53/EZEVC3I",
+ "TAqapVRp84frvNVTnT/cUj3rlv44j7j1EEy0RvSrVRp2c7zX14PjjpFBg30h58/9hE1+2keX23oQfUMz",
+ "4otSJeQlzc2GQ0bOnHbQwsbHlrk+v5D0maWaTyaGfOMPnyIUK/S19EcZr6kTtMgbI3MYJdMwgAXwxLGg",
+ "ZCayretiNpF0rTe2hEeXuZ3Q9o3RtlNSSQs19PAOjJi/b8vlPoPln3bCP+2Ef1qS/rQT/rm7f9oJR9oJ",
+ "/7Si/WlF+x9pRTvEdBYTM535Z1jaxLbqtDWv1fto076iZvHt4mJM1zJZK8sUO2UwfUzIJVaGoeaWgBVI",
+ "mpOUKitduSpGBQZ/YokyyJ5e8aQFiQ2xNBPfb/5rY1uvqtPTx0BOH3S/UZrlecib+9+ivIuPbPrJ1+Rq",
+ "cjXpjSShECvIbK5sWD7dfrV32P9Vj/uq13cBk+Sx9I6vZEZUNZ+zlFmU54IvCF2IJi4b67VygU9AGuBs",
+ "9yrC9NTlsTCXPO2a27ervLcl974EcN5s4d6Igw65xIMNDOEdGGnwL2PCDP5HS+k3LXZ1W0a6c+weV/2T",
+ "q3wKrvLZ+cof3YcbmBb/W4qZT06f/GEXFBqifxSafIc5B7cTx1wd0TTaxOumgpavI+PNfU3cchgHjLdo",
+ "HQH89p25CBTIlb9gm7DWpycnWFhsKZQ+mZjrrx3yGj58V8P83t9OpWQr7BKN1k0h2YJxmicuLjRpQlcf",
+ "HZ9OPvz/AAAA//8ezQsLGSMBAA==",
}
// GetSwagger returns the content of the embedded swagger specification file
diff --git a/daemon/algod/api/server/v2/handlers.go b/daemon/algod/api/server/v2/handlers.go
index 9c5da32b3d..abeb15711b 100644
--- a/daemon/algod/api/server/v2/handlers.go
+++ b/daemon/algod/api/server/v2/handlers.go
@@ -64,8 +64,8 @@ import (
// MaxTealSourceBytes sets a size limit for TEAL source programs for requests
// Max TEAL program size is currently 8k
// but we allow for comments, spacing, and repeated consts
-// in the source TEAL, so we allow up to 200KB
-const MaxTealSourceBytes = 200_000
+// in the source TEAL. We have some indication that real TEAL programs with comments are about 20 times bigger than the bytecode they produce, and we may soon allow 16,000 byte logicsigs, implying a maximum of 320kb. Let's call it half a meg for a little room to spare.
+const MaxTealSourceBytes = 512 * 1024
// MaxTealDryrunBytes sets a size limit for dryrun requests
// With the ability to hold unlimited assets DryrunRequests can
@@ -316,7 +316,7 @@ func (v2 *Handlers) AddParticipationKey(ctx echo.Context) error {
partKeyBinary := buf.Bytes()
if len(partKeyBinary) == 0 {
- lenErr := fmt.Errorf(errRESTPayloadZeroLength)
+ lenErr := errors.New(errRESTPayloadZeroLength)
return badRequest(ctx, lenErr, lenErr.Error(), v2.Log)
}
@@ -838,6 +838,40 @@ func (v2 *Handlers) GetBlockHash(ctx echo.Context, round uint64) error {
return ctx.JSON(http.StatusOK, response)
}
+// GetBlockHeader gets the block header for the given round.
+// (GET /v2/blocks/{round}/header)
+func (v2 *Handlers) GetBlockHeader(ctx echo.Context, round uint64, params model.GetBlockHeaderParams) error {
+ handle, contentType, err := getCodecHandle((*string)(params.Format))
+ if err != nil {
+ return badRequest(ctx, err, errFailedParsingFormatOption, v2.Log)
+ }
+
+ ledger := v2.Node.LedgerForAPI()
+ block, err := ledger.BlockHdr(basics.Round(round))
+ if err != nil {
+ switch err.(type) {
+ case ledgercore.ErrNoEntry:
+ return notFound(ctx, err, errFailedLookingUpLedger, v2.Log)
+ default:
+ return internalError(ctx, err, errFailedLookingUpLedger, v2.Log)
+ }
+ }
+
+ // Encoding wasn't working well without embedding "real" objects.
+ response := struct {
+ BlockHeader bookkeeping.BlockHeader `codec:"block-header"`
+ }{
+ BlockHeader: block,
+ }
+
+ data, err := encode(handle, response)
+ if err != nil {
+ return internalError(ctx, err, errFailedToEncodeResponse, v2.Log)
+ }
+
+ return ctx.Blob(http.StatusOK, contentType, data)
+}
+
// GetTransactionProof generates a Merkle proof for a transaction in a block.
// (GET /v2/blocks/{round}/transactions/{txid}/proof)
func (v2 *Handlers) GetTransactionProof(ctx echo.Context, round uint64, txid string, params model.GetTransactionProofParams) error {
diff --git a/daemon/algod/api/server/v2/test/handlers_test.go b/daemon/algod/api/server/v2/test/handlers_test.go
index e830c4892c..4b97f8f3a4 100644
--- a/daemon/algod/api/server/v2/test/handlers_test.go
+++ b/daemon/algod/api/server/v2/test/handlers_test.go
@@ -28,6 +28,7 @@ import (
"net/http"
"net/http/httptest"
"reflect"
+ "slices"
"strings"
"testing"
"time"
@@ -37,7 +38,6 @@ import (
"github.com/algorand/go-algorand/daemon/algod/api/server"
"github.com/algorand/go-algorand/ledger/eval"
"github.com/algorand/go-algorand/ledger/ledgercore"
- "golang.org/x/exp/slices"
"github.com/labstack/echo/v4"
"github.com/stretchr/testify/assert"
@@ -158,6 +158,25 @@ func TestGetBlock(t *testing.T) {
getBlockTest(t, 0, "bad format", 400)
}
+func getBlockHeaderTest(t *testing.T, blockNum uint64, format string, expectedCode int) {
+ handler, c, rec, _, _, releasefunc := setupTestForMethodGet(t, cannedStatusReportGolden)
+ defer releasefunc()
+ err := handler.GetBlockHeader(c, blockNum, model.GetBlockHeaderParams{Format: (*model.GetBlockHeaderParamsFormat)(&format)})
+ require.NoError(t, err)
+ require.Equal(t, expectedCode, rec.Code)
+}
+
+func TestGetBlockHeader(t *testing.T) {
+ partitiontest.PartitionTest(t)
+ t.Parallel()
+
+ getBlockHeaderTest(t, 0, "json", 200)
+ getBlockHeaderTest(t, 0, "msgpack", 200)
+ getBlockHeaderTest(t, 1, "json", 404)
+ getBlockHeaderTest(t, 1, "msgpack", 404)
+ getBlockHeaderTest(t, 0, "bad format", 400)
+}
+
func testGetLedgerStateDelta(t *testing.T, round uint64, format string, expectedCode int) {
handler, c, rec, _, _, releasefunc := setupTestForMethodGet(t, cannedStatusReportGolden)
defer releasefunc()
@@ -956,7 +975,6 @@ func TestPostSimulateTransaction(t *testing.T) {
}
for i, testCase := range testCases {
- testCase := testCase
t.Run(fmt.Sprintf("i=%d", i), func(t *testing.T) {
t.Parallel()
simulateTransactionTest(t, testCase.txnIndex, testCase.format, testCase.expectedStatus)
diff --git a/daemon/algod/api/server/v2/utils.go b/daemon/algod/api/server/v2/utils.go
index 6f36784ee4..58120f46d8 100644
--- a/daemon/algod/api/server/v2/utils.go
+++ b/daemon/algod/api/server/v2/utils.go
@@ -20,15 +20,15 @@ import (
"encoding/base64"
"errors"
"fmt"
+ "maps"
"net/http"
+ "slices"
"strings"
"unicode"
"unicode/utf8"
"github.com/algorand/go-codec/codec"
"github.com/labstack/echo/v4"
- "golang.org/x/exp/maps"
- "golang.org/x/exp/slices"
"github.com/algorand/go-algorand/crypto"
"github.com/algorand/go-algorand/daemon/algod/api/server/v2/generated/model"
@@ -494,23 +494,23 @@ func convertUnnamedResourcesAccessed(resources *simulation.ResourceTracker) *mod
return nil
}
return &model.SimulateUnnamedResourcesAccessed{
- Accounts: sliceOrNil(stringSlice(maps.Keys(resources.Accounts))),
- Assets: sliceOrNil(uint64Slice(maps.Keys(resources.Assets))),
- Apps: sliceOrNil(uint64Slice(maps.Keys(resources.Apps))),
- Boxes: sliceOrNil(convertSlice(maps.Keys(resources.Boxes), func(box logic.BoxRef) model.BoxReference {
+ Accounts: sliceOrNil(stringSlice(slices.Collect(maps.Keys(resources.Accounts)))),
+ Assets: sliceOrNil(uint64Slice(slices.Collect(maps.Keys(resources.Assets)))),
+ Apps: sliceOrNil(uint64Slice(slices.Collect(maps.Keys(resources.Apps)))),
+ Boxes: sliceOrNil(convertSlice(slices.Collect(maps.Keys(resources.Boxes)), func(box logic.BoxRef) model.BoxReference {
return model.BoxReference{
App: uint64(box.App),
Name: []byte(box.Name),
}
})),
ExtraBoxRefs: omitEmpty(uint64(resources.NumEmptyBoxRefs)),
- AssetHoldings: sliceOrNil(convertSlice(maps.Keys(resources.AssetHoldings), func(holding ledgercore.AccountAsset) model.AssetHoldingReference {
+ AssetHoldings: sliceOrNil(convertSlice(slices.Collect(maps.Keys(resources.AssetHoldings)), func(holding ledgercore.AccountAsset) model.AssetHoldingReference {
return model.AssetHoldingReference{
Account: holding.Address.String(),
Asset: uint64(holding.Asset),
}
})),
- AppLocals: sliceOrNil(convertSlice(maps.Keys(resources.AppLocals), func(local ledgercore.AccountApp) model.ApplicationLocalReference {
+ AppLocals: sliceOrNil(convertSlice(slices.Collect(maps.Keys(resources.AppLocals)), func(local ledgercore.AccountApp) model.ApplicationLocalReference {
return model.ApplicationLocalReference{
Account: local.Address.String(),
App: uint64(local.App),
diff --git a/data/basics/teal.go b/data/basics/teal.go
index f3156ae4b8..7268c8aadf 100644
--- a/data/basics/teal.go
+++ b/data/basics/teal.go
@@ -19,9 +19,9 @@ package basics
import (
"encoding/hex"
"fmt"
+ "maps"
"github.com/algorand/go-algorand/config"
- "golang.org/x/exp/maps"
)
// DeltaAction is an enum of actions that may be performed when applying a
diff --git a/data/basics/userBalance.go b/data/basics/userBalance.go
index 85167dec29..a9efeca1cb 100644
--- a/data/basics/userBalance.go
+++ b/data/basics/userBalance.go
@@ -19,13 +19,13 @@ package basics
import (
"encoding/binary"
"fmt"
+ "slices"
"github.com/algorand/go-algorand/config"
"github.com/algorand/go-algorand/crypto"
"github.com/algorand/go-algorand/crypto/merklesignature"
"github.com/algorand/go-algorand/logging"
"github.com/algorand/go-algorand/protocol"
- "golang.org/x/exp/slices"
)
// Status is the delegation status of an account's MicroAlgos
diff --git a/data/pools/transactionPool.go b/data/pools/transactionPool.go
index a2eef08bc3..8446291973 100644
--- a/data/pools/transactionPool.go
+++ b/data/pools/transactionPool.go
@@ -62,6 +62,7 @@ type TransactionPool struct {
cond sync.Cond
expiredTxCount map[basics.Round]int
pendingBlockEvaluator BlockEvaluator
+ evalTracer logic.EvalTracer
numPendingWholeBlocks basics.Round
feePerByte atomic.Uint64
feeThresholdMultiplier uint64
@@ -140,6 +141,9 @@ func MakeTransactionPool(ledger *ledger.Ledger, cfg config.Local, log logging.Lo
log: log,
vac: vac,
}
+ if cfg.EnableDeveloperAPI {
+ pool.evalTracer = logic.EvalErrorDetailsTracer{}
+ }
pool.cond.L = &pool.mu
pool.assemblyCond.L = &pool.assemblyMu
pool.recomputeBlockEvaluator(nil, 0)
@@ -732,7 +736,7 @@ func (pool *TransactionPool) recomputeBlockEvaluator(committedTxIDs map[transact
if hint < 0 || int(knownCommitted) < 0 {
hint = 0
}
- pool.pendingBlockEvaluator, err = pool.ledger.StartEvaluator(next.BlockHeader, hint, 0, nil)
+ pool.pendingBlockEvaluator, err = pool.ledger.StartEvaluator(next.BlockHeader, hint, 0, pool.evalTracer)
if err != nil {
// The pendingBlockEvaluator is an interface, and in case of an evaluator error
// we want to remove the interface itself rather then keeping an interface
diff --git a/data/transactions/application.go b/data/transactions/application.go
index 48a5788c04..1cff14760d 100644
--- a/data/transactions/application.go
+++ b/data/transactions/application.go
@@ -18,9 +18,9 @@ package transactions
import (
"fmt"
+ "slices"
"github.com/algorand/go-algorand/data/basics"
- "golang.org/x/exp/slices"
)
const (
diff --git a/data/transactions/logic/assembler.go b/data/transactions/logic/assembler.go
index 9c625d3d56..cc8034fdfc 100644
--- a/data/transactions/logic/assembler.go
+++ b/data/transactions/logic/assembler.go
@@ -2269,7 +2269,7 @@ func define(ops *OpStream, tokens []token) *sourceError {
} else {
delete(ops.macros, name) // remove new macro that caused cycle
}
- return tokens[1].errorf("macro expansion cycle discovered: %s", strings.Join(found, " -> "))
+ return tokens[1].errorf("macro expansion cycle discovered: %s", strings.Join(found, " -> ")) //nolint:gosec // false positive, len(tokens) >= 3
}
return nil
}
@@ -2883,8 +2883,9 @@ func disassemble(dis *disassembleState, spec *OpSpec) (string, error) {
if err != nil {
return "", err
}
-
- dis.intc = intc
+ if spec.Name == "intcblock" {
+ dis.intc = intc
+ }
for i, iv := range intc {
if i != 0 {
out += " "
@@ -2897,7 +2898,9 @@ func disassemble(dis *disassembleState, spec *OpSpec) (string, error) {
if err != nil {
return "", err
}
- dis.bytec = bytec
+ if spec.Name == "bytecblock" {
+ dis.bytec = bytec
+ }
for i, bv := range bytec {
if i != 0 {
out += " "
diff --git a/data/transactions/logic/assembler_test.go b/data/transactions/logic/assembler_test.go
index 10d86f476a..d1ebeb3b4a 100644
--- a/data/transactions/logic/assembler_test.go
+++ b/data/transactions/logic/assembler_test.go
@@ -1746,7 +1746,6 @@ func TestAssembleDisassembleCycle(t *testing.T) {
// assembler pick it up.
require.LessOrEqual(t, LogicVersion, len(nonsense)) // Allow nonsense for future versions
for v, source := range nonsense {
- v, source := v, source
if v > LogicVersion {
continue // We allow them to be set, but can't test assembly beyond LogicVersion
}
@@ -2182,6 +2181,52 @@ label1:
}
}
+// TestDisassembleBytecblock asserts correct disassembly for
+// uses of bytecblock and intcblock, from examples in #6154
+func TestDisassembleBytecblock(t *testing.T) {
+ partitiontest.PartitionTest(t)
+ t.Parallel()
+
+ ver := uint64(AssemblerMaxVersion)
+ for _, prog := range []string{
+ `#pragma version %d
+intcblock 0 1 2 3 4 5
+intc_0 // 0
+intc_1 // 1
+intc_2 // 2
+intc_3 // 3
+intc 4 // 4
+pushints 6
+intc_0 // 0
+intc_1 // 1
+intc_2 // 2
+intc_3 // 3
+intc 4 // 4
+`,
+ `#pragma version %d
+bytecblock 0x6869 0x414243 0x74657374 0x666f7572 0x6c617374
+bytec_0 // "hi"
+bytec_1 // "ABC"
+bytec_2 // "test"
+bytec_3 // "four"
+bytec 4 // "last"
+pushbytess 0x6576696c
+bytec_0 // "hi"
+bytec_1 // "ABC"
+bytec_2 // "test"
+bytec_3 // "four"
+bytec 4 // "last"
+`,
+ } {
+ source := fmt.Sprintf(prog, ver)
+ ops, err := AssembleStringWithVersion(source, ver)
+ require.NoError(t, err)
+ dis, err := Disassemble(ops.Program)
+ require.NoError(t, err, dis)
+ require.Equal(t, source, dis)
+ }
+}
+
func TestAssembleOffsets(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()
diff --git a/data/transactions/logic/backwardCompat_test.go b/data/transactions/logic/backwardCompat_test.go
index fb11bc0b69..d2b46788e7 100644
--- a/data/transactions/logic/backwardCompat_test.go
+++ b/data/transactions/logic/backwardCompat_test.go
@@ -463,7 +463,6 @@ func TestBackwardCompatAssemble(t *testing.T) {
testProg(t, source, 1, exp(3, "label \"done\" is too far away", 5))
for v := uint64(2); v <= AssemblerMaxVersion; v++ {
- v := v
t.Run(fmt.Sprintf("v=%d", v), func(t *testing.T) {
t.Parallel()
testLogic(t, source, v, nil)
diff --git a/data/transactions/logic/blackbox_test.go b/data/transactions/logic/blackbox_test.go
index cdcf971a01..aac3d6260e 100644
--- a/data/transactions/logic/blackbox_test.go
+++ b/data/transactions/logic/blackbox_test.go
@@ -78,9 +78,7 @@ func TestNewAppEvalParams(t *testing.T) {
config.Consensus[protocol.ConsensusFuture],
}
for i, param := range params {
- param := param
for j, testCase := range cases {
- i, j, param, testCase := i, j, param, testCase
t.Run(fmt.Sprintf("i=%d,j=%d", i, j), func(t *testing.T) {
t.Parallel()
ep := logic.NewAppEvalParams(testCase.group, ¶m, nil)
diff --git a/data/transactions/logic/box_test.go b/data/transactions/logic/box_test.go
index 61609d5a96..cb948f51c1 100644
--- a/data/transactions/logic/box_test.go
+++ b/data/transactions/logic/box_test.go
@@ -34,7 +34,6 @@ func TestBoxNewDel(t *testing.T) {
t.Parallel()
for _, size := range []int{24, 0} {
- size := size
t.Run(fmt.Sprintf("box size=%d", size), func(t *testing.T) {
t.Parallel()
@@ -310,7 +309,6 @@ func TestBoxUnavailableWithClearState(t *testing.T) {
}
for name, program := range tests {
- name, program := name, program
t.Run(name, func(t *testing.T) {
t.Parallel()
ep, _, l := MakeSampleEnv()
@@ -618,7 +616,6 @@ func TestEarlyPanics(t *testing.T) {
}
for name, program := range tests {
- name, program := name, program
t.Run(name+"/zero", func(t *testing.T) {
t.Parallel()
ep, _, l := MakeSampleEnv()
@@ -629,7 +626,6 @@ func TestEarlyPanics(t *testing.T) {
big := strings.Repeat("x", 65)
for name, program := range tests {
- name, program := name, program
t.Run(name+"/long", func(t *testing.T) {
t.Parallel()
ep, _, l := MakeSampleEnv()
diff --git a/data/transactions/logic/crypto_test.go b/data/transactions/logic/crypto_test.go
index 1298f34c9f..31da47855d 100644
--- a/data/transactions/logic/crypto_test.go
+++ b/data/transactions/logic/crypto_test.go
@@ -25,11 +25,11 @@ import (
"encoding/hex"
"fmt"
"math/big"
+ "slices"
"strconv"
"testing"
"github.com/stretchr/testify/require"
- "golang.org/x/exp/slices"
"github.com/algorand/go-algorand/crypto"
"github.com/algorand/go-algorand/crypto/secp256k1"
@@ -425,11 +425,11 @@ byte 0x%s
{pkTampered2, false},
}
for i, test := range decompressTests {
- i, test, source := i, test, source
+ innerSource := source
t.Run(fmt.Sprintf("decompress/pass=%v", test.pass), func(t *testing.T) {
t.Parallel()
t.Log("decompressTests i", i)
- src := fmt.Sprintf(source, hex.EncodeToString(test.key), hex.EncodeToString(x), hex.EncodeToString(y))
+ src := fmt.Sprintf(innerSource, hex.EncodeToString(test.key), hex.EncodeToString(x), hex.EncodeToString(y))
if test.pass {
testAccepts(t, src, 5)
} else {
@@ -462,10 +462,10 @@ byte 0x%s
{"testdata1", r, false},
}
for _, test := range verifyTests {
- test, source := test, source
+ innerSource := source
t.Run(fmt.Sprintf("verify/pass=%v", test.pass), func(t *testing.T) {
t.Parallel()
- src := fmt.Sprintf(source, test.data, hex.EncodeToString(test.r), hex.EncodeToString(s), hex.EncodeToString(x), hex.EncodeToString(y))
+ src := fmt.Sprintf(innerSource, test.data, hex.EncodeToString(test.r), hex.EncodeToString(s), hex.EncodeToString(x), hex.EncodeToString(y))
if test.pass {
testAccepts(t, src, 5)
} else {
@@ -520,10 +520,10 @@ load 1
pkExpanded := secp256k1.S256().Marshal(key.PublicKey.X, key.PublicKey.Y)
for i, test := range recoverTests {
- i, test, source := i, test, source
+ innerSource := source
t.Run(fmt.Sprintf("recover/%d", i), func(t *testing.T) {
t.Parallel()
- src := fmt.Sprintf(source, hex.EncodeToString(msg[:]), test.v, hex.EncodeToString(r), hex.EncodeToString(s), hex.EncodeToString(x), hex.EncodeToString(y), hex.EncodeToString(pkExpanded))
+ src := fmt.Sprintf(innerSource, hex.EncodeToString(msg[:]), test.v, hex.EncodeToString(r), hex.EncodeToString(s), hex.EncodeToString(x), hex.EncodeToString(y), hex.EncodeToString(pkExpanded))
test.checker(t, src, 5)
})
}
@@ -580,11 +580,11 @@ byte 0x%s
{pkTampered2, false},
}
for i, test := range decompressTests {
- i, test, source := i, test, source
+ innerSource := source
t.Run(fmt.Sprintf("decompress/pass=%v", test.pass), func(t *testing.T) {
t.Parallel()
t.Log("decompressTests i", i)
- src := fmt.Sprintf(source, hex.EncodeToString(test.key), hex.EncodeToString(x), hex.EncodeToString(y))
+ src := fmt.Sprintf(innerSource, hex.EncodeToString(test.key), hex.EncodeToString(x), hex.EncodeToString(y))
if test.pass {
testAccepts(t, src, fidoVersion)
} else {
@@ -624,10 +624,10 @@ ecdsa_verify Secp256r1
{"testdata1", r, false},
}
for _, test := range verifyTests {
- test, source := test, source
+ innerSource := source
t.Run(fmt.Sprintf("verify/pass=%v", test.pass), func(t *testing.T) {
t.Parallel()
- src := fmt.Sprintf(source, test.data, hex.EncodeToString(test.r), hex.EncodeToString(s), hex.EncodeToString(x), hex.EncodeToString(y))
+ src := fmt.Sprintf(innerSource, test.data, hex.EncodeToString(test.r), hex.EncodeToString(s), hex.EncodeToString(x), hex.EncodeToString(y))
if test.pass {
testAccepts(t, src, fidoVersion)
} else {
diff --git a/data/transactions/logic/debugger_eval_test.go b/data/transactions/logic/debugger_eval_test.go
index b252e7f1a2..f2ffb80164 100644
--- a/data/transactions/logic/debugger_eval_test.go
+++ b/data/transactions/logic/debugger_eval_test.go
@@ -167,7 +167,6 @@ func TestDebuggerLogicSigEval(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()
for _, testCase := range debuggerTestCases {
- testCase := testCase
t.Run(testCase.name, func(t *testing.T) {
t.Parallel()
testDbg := testDebugger{}
@@ -187,7 +186,6 @@ func TestDebuggerTopLeveLAppEval(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()
for _, testCase := range debuggerTestCases {
- testCase := testCase
t.Run(testCase.name, func(t *testing.T) {
t.Parallel()
testDbg := testDebugger{}
@@ -208,8 +206,6 @@ func TestDebuggerInnerAppEval(t *testing.T) {
t.Parallel()
scenarios := mocktracer.GetTestScenarios()
for scenarioName, makeScenario := range scenarios {
- scenarioName := scenarioName
- makeScenario := makeScenario
t.Run(scenarioName, func(t *testing.T) {
t.Parallel()
testDbg := testDebugger{}
diff --git a/data/transactions/logic/eval.go b/data/transactions/logic/eval.go
index 4da436a1b6..ae8614e824 100644
--- a/data/transactions/logic/eval.go
+++ b/data/transactions/logic/eval.go
@@ -28,11 +28,10 @@ import (
"math/big"
"math/bits"
"runtime"
+ "slices"
"strconv"
"strings"
- "golang.org/x/exp/slices"
-
"github.com/algorand/go-algorand/config"
"github.com/algorand/go-algorand/crypto"
"github.com/algorand/go-algorand/data/basics"
@@ -1000,6 +999,7 @@ func (pe panicError) Error() string {
var errLogicSigNotSupported = errors.New("LogicSig not supported")
var errTooManyArgs = errors.New("LogicSig has too many arguments")
+var errLogicSigArgTooLarge = errors.New("LogicSig argument too large")
// EvalError indicates AVM evaluation failure
type EvalError struct {
@@ -1027,8 +1027,16 @@ func (err EvalError) Unwrap() error {
}
func (cx *EvalContext) evalError(err error) error {
- pc, det := cx.pcDetails()
- details := fmt.Sprintf("pc=%d, opcodes=%s", pc, det)
+ var pc int
+ var details string
+ if cx.Tracer != nil && cx.Tracer.DetailedEvalErrors() {
+ var det string
+ pc, det = cx.pcDetails()
+ details = fmt.Sprintf("pc=%d, opcodes=%s", pc, det)
+ } else {
+ pc = cx.pc
+ details = fmt.Sprintf("pc=%d", pc)
+ }
err = basics.Annotate(err,
"pc", pc,
@@ -1305,8 +1313,15 @@ func eval(program []byte, cx *EvalContext) (pass bool, err error) {
if (cx.EvalParams.Proto == nil) || (cx.EvalParams.Proto.LogicSigVersion == 0) {
return false, errLogicSigNotSupported
}
- if cx.txn.Lsig.Args != nil && len(cx.txn.Lsig.Args) > transactions.EvalMaxArgs {
- return false, errTooManyArgs
+ if cx.txn.Lsig.Args != nil {
+ if len(cx.txn.Lsig.Args) > transactions.EvalMaxArgs {
+ return false, errTooManyArgs
+ }
+ for _, arg := range cx.txn.Lsig.Args {
+ if len(arg) > transactions.MaxLogicSigArgSize {
+ return false, errLogicSigArgTooLarge
+ }
+ }
}
if verr != nil {
return false, verr
diff --git a/data/transactions/logic/evalAppTxn_test.go b/data/transactions/logic/evalAppTxn_test.go
index 562142fdec..600ab68029 100644
--- a/data/transactions/logic/evalAppTxn_test.go
+++ b/data/transactions/logic/evalAppTxn_test.go
@@ -1196,7 +1196,6 @@ func TestBigApplCreation(t *testing.T) {
// First, test normal accummulation
for _, pgm := range []string{"Approval", "ClearState"} {
- pgm := pgm
t.Run(pgm, func(t *testing.T) {
t.Parallel()
@@ -2001,7 +2000,6 @@ int 1
`
for _, unified := range []bool{true, false} {
- unified := unified
t.Run(fmt.Sprintf("unified=%t", unified), func(t *testing.T) {
t.Parallel()
ep, parentTx, ledger := MakeSampleEnv()
@@ -2329,7 +2327,6 @@ int 1
`
for _, unified := range []bool{true, false} {
- unified := unified
t.Run(fmt.Sprintf("unified=%t", unified), func(t *testing.T) {
t.Parallel()
ep, parentTx, ledger := MakeSampleEnv()
@@ -2467,7 +2464,6 @@ func TestInnerTxIDCaching(t *testing.T) {
childAppID := basics.AppIndex(222)
for _, unified := range []bool{true, false} {
- unified := unified
t.Run(fmt.Sprintf("unified=%t", unified), func(t *testing.T) {
t.Parallel()
ep, parentTx, ledger := MakeSampleEnv()
diff --git a/data/transactions/logic/evalStateful_test.go b/data/transactions/logic/evalStateful_test.go
index abff0ddb83..270925a84f 100644
--- a/data/transactions/logic/evalStateful_test.go
+++ b/data/transactions/logic/evalStateful_test.go
@@ -248,7 +248,6 @@ log
}
for mode, test := range tests {
- mode, test := mode, test
t.Run(fmt.Sprintf("opcodes_mode=%d", mode), func(t *testing.T) {
t.Parallel()
@@ -443,6 +442,7 @@ func testApps(t *testing.T, programs []string, txgroup []transactions.SignedTxn,
}
}
ep := NewAppEvalParams(transactions.WrapSignedTxnsWithAD(txgroup), proto, &transactions.SpecialAddresses{})
+ ep.Tracer = EvalErrorDetailsTracer{}
if ledger == nil {
ledger = NewLedger(nil)
}
@@ -1359,7 +1359,6 @@ func TestAssetDisambiguation(t *testing.T) {
// Make sure we don't treat slot indexes as asset IDs when
// ep.UnnamedResources is not nil.
for _, unnamedResources := range []bool{false, true} {
- unnamedResources := unnamedResources
t.Run(fmt.Sprintf("unnamedResources=%v", unnamedResources), func(t *testing.T) {
t.Parallel()
// It would be nice to start at 2, when apps were added, but `assert` is
@@ -1446,7 +1445,6 @@ func TestAppDisambiguation(t *testing.T) {
// Make sure we don't treat slot indexes as app IDs when
// ep.UnnamedResources is true.
for _, unnamedResources := range []bool{false, true} {
- unnamedResources := unnamedResources
t.Run(fmt.Sprintf("unnamedResources=%v", unnamedResources), func(t *testing.T) {
t.Parallel()
// It would be nice to start at 2, when apps were added, but `assert` is
@@ -1735,7 +1733,6 @@ intc_1
"delete": sourceDelete,
}
for name, source := range tests {
- name, source := name, source
t.Run(fmt.Sprintf("test=%s", name), func(t *testing.T) {
t.Parallel()
@@ -2871,7 +2868,6 @@ func TestUnnamedResourceAccess(t *testing.T) {
}
for _, tc := range testcases {
- tc := tc
t.Run(tc.policy.String(), func(t *testing.T) {
t.Parallel()
// start at 4 for directRefEnabledVersion
@@ -3293,7 +3289,6 @@ func TestReturnTypes(t *testing.T) {
if skipCmd[name] || spec.trusted {
continue
}
- m, name, spec := m, name, spec
t.Run(fmt.Sprintf("mode=%s,opcode=%s", m, name), func(t *testing.T) {
t.Parallel()
diff --git a/data/transactions/logic/eval_test.go b/data/transactions/logic/eval_test.go
index 6b664de684..27a64f1b82 100644
--- a/data/transactions/logic/eval_test.go
+++ b/data/transactions/logic/eval_test.go
@@ -258,6 +258,24 @@ func TestTooManyArgs(t *testing.T) {
}
}
+func TestArgTooLarge(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ t.Parallel()
+ for v := uint64(1); v <= AssemblerMaxVersion; v++ {
+ t.Run(fmt.Sprintf("v=%d", v), func(t *testing.T) {
+ ops := testProg(t, "int 1", v)
+ var txn transactions.SignedTxn
+ txn.Lsig.Logic = ops.Program
+ txn.Lsig.Args = [][]byte{make([]byte, transactions.MaxLogicSigArgSize+1)}
+ pass, err := EvalSignature(0, defaultSigParams(txn))
+ require.Error(t, err)
+ require.False(t, pass)
+ })
+ }
+
+}
+
func TestEmptyProgram(t *testing.T) {
partitiontest.PartitionTest(t)
@@ -1918,7 +1936,6 @@ func TestTxn(t *testing.T) {
clearOps := testProg(t, "int 1", 1)
for v, source := range tests {
- v, source := v, source
t.Run(fmt.Sprintf("v=%d", v), func(t *testing.T) {
t.Parallel()
ops := testProg(t, source, v)
@@ -2139,7 +2156,6 @@ gtxn 0 Sender
}
for v, source := range tests {
- v, source := v, source
t.Run(fmt.Sprintf("v=%d", v), func(t *testing.T) {
t.Parallel()
txn := makeSampleTxn()
@@ -2873,7 +2889,6 @@ func TestGload(t *testing.T) {
}
for i, testCase := range cases {
- i, testCase := i, testCase
t.Run(fmt.Sprintf("i=%d", i), func(t *testing.T) {
t.Parallel()
sources := testCase.tealSources
@@ -2921,7 +2936,6 @@ func TestGload(t *testing.T) {
failCases := []failureCase{nonAppCall, logicSigCall}
for j, failCase := range failCases {
- j, failCase := j, failCase
t.Run(fmt.Sprintf("j=%d", j), func(t *testing.T) {
t.Parallel()
@@ -3292,7 +3306,6 @@ func TestShortBytecblock2(t *testing.T) {
"0026efbfbdefbfbd30",
}
for _, src := range sources {
- src := src
t.Run(src, func(t *testing.T) {
t.Parallel()
program, err := hex.DecodeString(src)
@@ -3369,7 +3382,6 @@ func TestPanic(t *testing.T) { //nolint:paralleltest // Uses withPanicOpcode
logSink := logging.NewLogger()
logSink.SetOutput(io.Discard)
for v := uint64(1); v <= AssemblerMaxVersion; v++ {
- v := v
t.Run(fmt.Sprintf("v=%d", v), func(t *testing.T) { //nolint:paralleltest // Uses withPanicOpcode
withPanicOpcode(t, v, true, func(opcode byte) {
ops := testProg(t, `int 1`, v)
@@ -3533,7 +3545,6 @@ done:
intc_1
`
for _, line := range branches {
- line := line
t.Run(fmt.Sprintf("branch=%s", line), func(t *testing.T) {
t.Parallel()
source := fmt.Sprintf(template, line)
@@ -4406,7 +4417,6 @@ func TestAnyRekeyToOrApplicationRaisesMinAvmVersion(t *testing.T) {
}
for ci, cse := range cases {
- ci, cse := ci, cse
t.Run(fmt.Sprintf("ci=%d", ci), func(t *testing.T) {
t.Parallel()
sep, aep := defaultEvalParams(cse.group...)
@@ -5220,7 +5230,6 @@ func TestPcDetails(t *testing.T) {
{"b end; end:", 4, ""},
}
for i, test := range tests {
- i, test := i, test
t.Run(fmt.Sprintf("i=%d", i), func(t *testing.T) {
t.Parallel()
ops := testProg(t, test.source, LogicVersion)
diff --git a/data/transactions/logic/mocktracer/scenarios.go b/data/transactions/logic/mocktracer/scenarios.go
index 09a6a3a2d0..b555705a35 100644
--- a/data/transactions/logic/mocktracer/scenarios.go
+++ b/data/transactions/logic/mocktracer/scenarios.go
@@ -414,7 +414,6 @@ func GetTestScenarios() map[string]TestScenarioGenerator {
}
for _, shouldError := range []bool{true, false} {
- shouldError := shouldError
failureOps := "pushint 0\nreturn"
singleFailureOp := "pushint 0"
failureInnerProgramBytes := []byte{0x06, 0x80, 0x01, 0x78, 0xb0, 0x81, 0x00} // #pragma version 6; pushbytes "x"; log; pushint 0
diff --git a/data/transactions/logic/mocktracer/tracer.go b/data/transactions/logic/mocktracer/tracer.go
index 8ac31cb3a3..20ed108938 100644
--- a/data/transactions/logic/mocktracer/tracer.go
+++ b/data/transactions/logic/mocktracer/tracer.go
@@ -232,6 +232,9 @@ func (d *Tracer) AfterBlock(hdr *bookkeeping.BlockHeader) {
d.Events = append(d.Events, AfterBlock(hdr.Round))
}
+// DetailedEvalErrors returns true, enabling detailed errors in tests.
+func (d *Tracer) DetailedEvalErrors() bool { return true }
+
// copyDeltas makes a deep copy of the given ledgercore.StateDelta pointer, if it's not nil.
// This is inefficient, but it should only be used for testing.
func copyDeltas(deltas *ledgercore.StateDelta) *ledgercore.StateDelta {
diff --git a/data/transactions/logic/opcodes.go b/data/transactions/logic/opcodes.go
index f3f8bfe37d..419e937874 100644
--- a/data/transactions/logic/opcodes.go
+++ b/data/transactions/logic/opcodes.go
@@ -19,12 +19,12 @@ package logic
import (
"cmp"
"fmt"
+ "maps"
+ "slices"
"strconv"
"strings"
"github.com/algorand/go-algorand/data/basics"
- "golang.org/x/exp/maps"
- "golang.org/x/exp/slices"
)
// LogicVersion defines default assembler and max eval versions
@@ -838,11 +838,10 @@ func OpcodesByVersion(version uint64) []OpSpec {
}
}
}
- result := maps.Values(subv)
- slices.SortFunc(result, func(a, b OpSpec) int {
+ values := maps.Values(subv)
+ return slices.SortedFunc(values, func(a, b OpSpec) int {
return cmp.Compare(a.Opcode, b.Opcode)
})
- return result
}
// direct opcode bytes
diff --git a/data/transactions/logic/opcodes_test.go b/data/transactions/logic/opcodes_test.go
index 57a2d5eb76..a39be85106 100644
--- a/data/transactions/logic/opcodes_test.go
+++ b/data/transactions/logic/opcodes_test.go
@@ -19,11 +19,11 @@ package logic
import (
"fmt"
"reflect"
+ "slices"
"testing"
"github.com/algorand/go-algorand/test/partitiontest"
"github.com/stretchr/testify/require"
- "golang.org/x/exp/slices"
)
func TestOpSpecs(t *testing.T) {
diff --git a/data/transactions/logic/tracer.go b/data/transactions/logic/tracer.go
index c8996f316c..551ea67e10 100644
--- a/data/transactions/logic/tracer.go
+++ b/data/transactions/logic/tracer.go
@@ -162,6 +162,10 @@ type EvalTracer interface {
// AfterBlock is called after the block has finished evaluation. It will not be called in the event that an evalError
// stops evaluation of the block.
AfterBlock(hdr *bookkeeping.BlockHeader)
+
+ // DetailedEvalErrors permits the tracer to enable detailed EvalError messages (including PC with disassembled
+ // opcodes) by returning true.
+ DetailedEvalErrors() bool
}
// NullEvalTracer implements EvalTracer, but all of its hook methods do nothing
@@ -198,3 +202,12 @@ func (n NullEvalTracer) AfterOpcode(cx *EvalContext, evalError error) {}
// AfterBlock does nothing
func (n NullEvalTracer) AfterBlock(hdr *bookkeeping.BlockHeader) {}
+
+// DetailedEvalErrors does nothing
+func (n NullEvalTracer) DetailedEvalErrors() bool { return false }
+
+// EvalErrorDetailsTracer enables disassembled details in EvalError messages, and nothing else.
+type EvalErrorDetailsTracer struct{ NullEvalTracer }
+
+// DetailedEvalErrors returns true.
+func (EvalErrorDetailsTracer) DetailedEvalErrors() bool { return true }
diff --git a/data/transactions/logic/tracer_test.go b/data/transactions/logic/tracer_test.go
index 8e806e21d9..fd7f9d270e 100644
--- a/data/transactions/logic/tracer_test.go
+++ b/data/transactions/logic/tracer_test.go
@@ -101,7 +101,6 @@ func TestLogicSigEvalWithTracer(t *testing.T) {
t.Parallel()
testCases := getSimpleTracerTestCases(ModeSig)
for _, testCase := range testCases {
- testCase := testCase
t.Run(testCase.name, func(t *testing.T) {
t.Parallel()
mock := mocktracer.Tracer{}
@@ -119,7 +118,6 @@ func TestTopLevelAppEvalWithTracer(t *testing.T) {
t.Parallel()
testCases := getSimpleTracerTestCases(ModeApp)
for _, testCase := range testCases {
- testCase := testCase
t.Run(testCase.name, func(t *testing.T) {
t.Parallel()
mock := mocktracer.Tracer{}
@@ -137,7 +135,6 @@ func TestInnerAppEvalWithTracer(t *testing.T) {
t.Parallel()
scenarios := mocktracer.GetTestScenarios()
for name, makeScenario := range scenarios {
- makeScenario := makeScenario
t.Run(name, func(t *testing.T) {
t.Parallel()
mock := mocktracer.Tracer{}
@@ -223,7 +220,6 @@ func TestEvalWithTracerPanic(t *testing.T) {
t.Parallel()
for _, mode := range []RunMode{ModeSig, ModeApp} {
- mode := mode
t.Run(mode.String(), func(t *testing.T) {
t.Parallel()
tracer := panicTracer{}
diff --git a/data/transactions/logicsig.go b/data/transactions/logicsig.go
index 31a14ea1dc..15a828ca60 100644
--- a/data/transactions/logicsig.go
+++ b/data/transactions/logicsig.go
@@ -25,6 +25,11 @@ import (
// EvalMaxArgs is the maximum number of arguments to an LSig
const EvalMaxArgs = 255
+// MaxLogicSigArgSize is the maximum size of an argument to an LSig
+// We use 4096 to match the maximum size of a TEAL value
+// (as defined in `const maxStringSize` in package logic)
+const MaxLogicSigArgSize = 4096
+
// LogicSig contains logic for validating a transaction.
// LogicSig is signed by an account, allowing delegation of operations.
// OR
@@ -39,7 +44,7 @@ type LogicSig struct {
Msig crypto.MultisigSig `codec:"msig"`
// Args are not signed, but checked by Logic
- Args [][]byte `codec:"arg,allocbound=EvalMaxArgs,allocbound=config.MaxLogicSigMaxSize"`
+ Args [][]byte `codec:"arg,allocbound=EvalMaxArgs,allocbound=MaxLogicSigArgSize,maxtotalbytes=config.MaxLogicSigMaxSize"`
}
// Blank returns true if there is no content in this LogicSig
diff --git a/data/transactions/msgp_gen.go b/data/transactions/msgp_gen.go
index edc229bffe..0b644da818 100644
--- a/data/transactions/msgp_gen.go
+++ b/data/transactions/msgp_gen.go
@@ -3483,8 +3483,8 @@ func (z *LogicSig) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o
err = msgp.WrapError(err, "struct-from-array", "Args", zb0001)
return
}
- if zb0007 > config.MaxLogicSigMaxSize {
- err = msgp.ErrOverflow(uint64(zb0007), uint64(config.MaxLogicSigMaxSize))
+ if zb0007 > MaxLogicSigArgSize {
+ err = msgp.ErrOverflow(uint64(zb0007), uint64(MaxLogicSigArgSize))
return
}
(*z).Args[zb0001], bts, err = msgp.ReadBytesBytes(bts, (*z).Args[zb0001])
@@ -3572,8 +3572,8 @@ func (z *LogicSig) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o
err = msgp.WrapError(err, "Args", zb0001)
return
}
- if zb0011 > config.MaxLogicSigMaxSize {
- err = msgp.ErrOverflow(uint64(zb0011), uint64(config.MaxLogicSigMaxSize))
+ if zb0011 > MaxLogicSigArgSize {
+ err = msgp.ErrOverflow(uint64(zb0011), uint64(MaxLogicSigArgSize))
return
}
(*z).Args[zb0001], bts, err = msgp.ReadBytesBytes(bts, (*z).Args[zb0001])
@@ -3621,7 +3621,7 @@ func (z *LogicSig) MsgIsZero() bool {
func LogicSigMaxSize() (s int) {
s = 1 + 2 + msgp.BytesPrefixSize + config.MaxLogicSigMaxSize + 4 + crypto.SignatureMaxSize() + 5 + crypto.MultisigSigMaxSize() + 4
// Calculating size of slice: z.Args
- s += msgp.ArrayHeaderSize + ((EvalMaxArgs) * (msgp.BytesPrefixSize + config.MaxLogicSigMaxSize))
+ s += msgp.ArrayHeaderSize + config.MaxLogicSigMaxSize
return
}
diff --git a/data/transactions/teal.go b/data/transactions/teal.go
index bdb68b525d..fa25a71520 100644
--- a/data/transactions/teal.go
+++ b/data/transactions/teal.go
@@ -18,11 +18,11 @@ package transactions
import (
"bytes"
+ "maps"
+ "slices"
"github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/protocol"
- "golang.org/x/exp/maps"
- "golang.org/x/exp/slices"
)
// EvalDelta stores StateDeltas for an application's global key/value store, as
diff --git a/data/transactions/transaction.go b/data/transactions/transaction.go
index 65b9a4bbe2..83f9bc6f62 100644
--- a/data/transactions/transaction.go
+++ b/data/transactions/transaction.go
@@ -21,13 +21,13 @@ import (
"encoding/binary"
"errors"
"fmt"
+ "slices"
"sync"
"github.com/algorand/go-algorand/config"
"github.com/algorand/go-algorand/crypto"
"github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/protocol"
- "golang.org/x/exp/slices"
)
// Txid is a hash used to uniquely identify individual transactions
diff --git a/data/transactions/verify/txn.go b/data/transactions/verify/txn.go
index 518528a3bc..7862d71b89 100644
--- a/data/transactions/verify/txn.go
+++ b/data/transactions/verify/txn.go
@@ -92,7 +92,7 @@ type TxGroupErrorReason int
const (
// TxGroupErrorReasonGeneric is a generic (not tracked) reason code
TxGroupErrorReasonGeneric TxGroupErrorReason = iota
- // TxGroupErrorReasonNotWellFormed is txn.WellFormed failure
+ // TxGroupErrorReasonNotWellFormed is txn.WellFormed failure or malformed logic signature
TxGroupErrorReasonNotWellFormed
// TxGroupErrorReasonInvalidFee is invalid fee pooling in transaction group
TxGroupErrorReasonInvalidFee
@@ -213,6 +213,7 @@ func txnGroupBatchPrep(stxs []transactions.SignedTxn, contextHdr *bookkeeping.Bl
minFeeCount := uint64(0)
feesPaid := uint64(0)
+ lSigPooledSize := 0
for i, stxn := range stxs {
prepErr := txnBatchPrep(i, groupCtx, verifier)
if prepErr != nil {
@@ -221,6 +222,7 @@ func txnGroupBatchPrep(stxs []transactions.SignedTxn, contextHdr *bookkeeping.Bl
return nil, prepErr
}
feesPaid = basics.AddSaturate(feesPaid, stxn.Txn.Fee.Raw)
+ lSigPooledSize += stxn.Lsig.Len()
if stxn.Txn.Type == protocol.StateProofTx {
continue
}
@@ -230,6 +232,16 @@ func txnGroupBatchPrep(stxs []transactions.SignedTxn, contextHdr *bookkeeping.Bl
}
minFeeCount++
}
+ if groupCtx.consensusParams.EnableLogicSigSizePooling {
+ lSigMaxPooledSize := len(stxs) * int(groupCtx.consensusParams.LogicSigMaxSize)
+ if lSigPooledSize > lSigMaxPooledSize {
+ errorMsg := fmt.Errorf(
+ "txgroup had %d bytes of LogicSigs, more than the available pool of %d bytes",
+ lSigPooledSize, lSigMaxPooledSize,
+ )
+ return nil, &TxGroupError{err: errorMsg, GroupIndex: -1, Reason: TxGroupErrorReasonNotWellFormed}
+ }
+ }
feeNeeded, overflow := basics.OMul(groupCtx.consensusParams.MinTxnFee, minFeeCount)
if overflow {
err = &TxGroupError{err: errTxGroupInvalidFee, GroupIndex: -1, Reason: TxGroupErrorReasonInvalidFee}
@@ -365,8 +377,8 @@ func logicSigSanityCheckBatchPrep(gi int, groupCtx *GroupContext, batchVerifier
if version > groupCtx.consensusParams.LogicSigVersion {
return errors.New("LogicSig.Logic version too new")
}
- if uint64(lsig.Len()) > groupCtx.consensusParams.LogicSigMaxSize {
- return errors.New("LogicSig.Logic too long")
+ if !groupCtx.consensusParams.EnableLogicSigSizePooling && uint64(lsig.Len()) > groupCtx.consensusParams.LogicSigMaxSize {
+ return errors.New("LogicSig too long")
}
err := logic.CheckSignature(gi, groupCtx.evalParams)
diff --git a/data/transactions/verify/txn_test.go b/data/transactions/verify/txn_test.go
index 5946399d0b..7320151565 100644
--- a/data/transactions/verify/txn_test.go
+++ b/data/transactions/verify/txn_test.go
@@ -479,7 +479,6 @@ pushint 1`,
}
for _, testCase := range testCases {
- testCase := testCase
t.Run(testCase.name, func(t *testing.T) {
t.Parallel()
proto := config.Consensus[protocol.ConsensusCurrentVersion]
@@ -649,6 +648,70 @@ func BenchmarkPaysetGroups(b *testing.B) {
b.StopTimer()
}
+func TestLsigSize(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ secrets, addresses, _ := generateAccounts(2)
+
+ execPool := execpool.MakePool(t)
+ verificationPool := execpool.MakeBacklog(execPool, 64, execpool.LowPriority, t)
+ defer verificationPool.Shutdown()
+
+ // From consensus version 18, we have lsigs with a maximum size of 1000 bytes.
+ // We need to use pragma 1 for teal in v18
+ pragma := uint(1)
+ consensusVersionPreSizePooling := protocol.ConsensusV18
+ consensusVersionPostSizePooling := protocol.ConsensusFuture
+
+ // We will do tests based on a transaction group of 2 payment transactions,
+ // the first signed by a lsig and the second a vanilla payment transaction.
+ testCases := []struct {
+ consensusVersion protocol.ConsensusVersion
+ lsigSize uint
+ success bool
+ }{
+ {consensusVersionPreSizePooling, 1000, true},
+ {consensusVersionPreSizePooling, 1001, false},
+ {consensusVersionPostSizePooling, 2000, true},
+ {consensusVersionPostSizePooling, 2001, false},
+ }
+
+ blkHdr := createDummyBlockHeader()
+ for _, test := range testCases {
+ blkHdr.UpgradeState.CurrentProtocol = test.consensusVersion
+
+ lsig, err := txntest.GenerateProgramOfSize(test.lsigSize, pragma)
+ require.NoError(t, err)
+
+ lsigPay := txntest.Txn{
+ Type: protocol.PaymentTx,
+ Sender: basics.Address(logic.HashProgram(lsig)),
+ Receiver: addresses[0],
+ Fee: config.Consensus[test.consensusVersion].MinTxnFee,
+ }
+
+ vanillaPay := txntest.Txn{
+ Type: protocol.PaymentTx,
+ Sender: addresses[0],
+ Receiver: addresses[1],
+ Fee: config.Consensus[test.consensusVersion].MinTxnFee,
+ }
+
+ group := txntest.Group(&lsigPay, &vanillaPay)
+ group[0].Lsig = transactions.LogicSig{
+ Logic: lsig,
+ }
+ group[1].Sig = secrets[0].Sign(group[1].Txn)
+
+ err = PaysetGroups(context.Background(), [][]transactions.SignedTxn{group}, blkHdr, verificationPool, MakeVerifiedTransactionCache(50000), &DummyLedgerForSignature{})
+ if test.success {
+ require.NoError(t, err)
+ } else {
+ require.Error(t, err)
+ }
+ }
+}
+
func TestTxnGroupMixedSignatures(t *testing.T) {
partitiontest.PartitionTest(t)
diff --git a/data/txHandler.go b/data/txHandler.go
index ec3a84cc1f..ecea78f522 100644
--- a/data/txHandler.go
+++ b/data/txHandler.go
@@ -132,6 +132,7 @@ type TxHandler struct {
erl *util.ElasticRateLimiter
appLimiter *appRateLimiter
appLimiterBacklogThreshold int
+ appLimiterCountERLDrops bool
// batchVerifier provides synchronous verification of transaction groups, used only by pubsub validation in validateIncomingTxMessage.
batchVerifier verify.TxnGroupBatchSigVerifier
@@ -148,6 +149,11 @@ type TxHandlerOpts struct {
Config config.Local
}
+// HybridRelayer is an interface for relaying p2p transactions to WS network
+type HybridRelayer interface {
+ BridgeP2PToWS(ctx context.Context, tag protocol.Tag, data []byte, wait bool, except network.Peer) error
+}
+
// MakeTxHandler makes a new handler for transaction messages
func MakeTxHandler(opts TxHandlerOpts) (*TxHandler, error) {
@@ -209,6 +215,7 @@ func MakeTxHandler(opts TxHandlerOpts) (*TxHandler, error) {
)
// set appLimiter triggering threshold at 50% of the base backlog size
handler.appLimiterBacklogThreshold = int(float64(opts.Config.TxBacklogSize) * float64(opts.Config.TxBacklogRateLimitingCongestionPct) / 100)
+ handler.appLimiterCountERLDrops = opts.Config.TxBacklogAppRateLimitingCountERLDrops
}
}
@@ -622,6 +629,7 @@ func (handler *TxHandler) incomingMsgDupCheck(data []byte) (*crypto.Digest, bool
// - a boolean indicating if the sender is rate limited
func (handler *TxHandler) incomingMsgErlCheck(sender network.DisconnectablePeer) (*util.ErlCapacityGuard, bool) {
var capguard *util.ErlCapacityGuard
+ var isCMEnabled bool
var err error
if handler.erl != nil {
congestedERL := float64(cap(handler.backlogQueue))*handler.backlogCongestionThreshold < float64(len(handler.backlogQueue))
@@ -629,8 +637,9 @@ func (handler *TxHandler) incomingMsgErlCheck(sender network.DisconnectablePeer)
// if the elastic rate limiter cannot vend a capacity, the error it returns
// is sufficient to indicate that we should enable Congestion Control, because
// an issue in vending capacity indicates the underlying resource (TXBacklog) is full
- capguard, err = handler.erl.ConsumeCapacity(sender.(util.ErlClient))
- if err != nil {
+ capguard, isCMEnabled, err = handler.erl.ConsumeCapacity(sender.(util.ErlClient))
+ if err != nil || // did ERL ask to enable congestion control?
+ (!isCMEnabled && congestedERL) { // is CM not currently enabled, but queue is congested?
handler.erl.EnableCongestionControl()
// if there is no capacity, it is the same as if we failed to put the item onto the backlog, so report such
transactionMessagesDroppedFromBacklog.Inc(nil)
@@ -741,6 +750,12 @@ func (handler *TxHandler) processIncomingTxn(rawmsg network.IncomingMessage) net
}()
if shouldDrop {
+ if handler.appLimiterCountERLDrops {
+ // decode and let ARL count this txgroup, even though ERL is dropping it
+ if unverifiedTxGroup, _, invalid := decodeMsg(rawmsg.Data); !invalid {
+ handler.incomingTxGroupAppRateLimit(unverifiedTxGroup, rawmsg.Sender)
+ }
+ }
// this TX message was rate-limited by ERL
return network.OutgoingMessage{Action: network.Ignore}
}
@@ -858,6 +873,11 @@ func (handler *TxHandler) validateIncomingTxMessage(rawmsg network.IncomingMessa
if err != nil {
logging.Base().Infof("unable to pin transaction: %v", err)
}
+
+ if hybridNet, ok := handler.net.(HybridRelayer); ok {
+ _ = hybridNet.BridgeP2PToWS(handler.ctx, protocol.TxnTag, reencoded, false, wi.rawmsg.Sender)
+ }
+
return network.OutgoingMessage{
Action: network.Accept,
}
diff --git a/data/txntest/program.go b/data/txntest/program.go
new file mode 100644
index 0000000000..f0fa63dd81
--- /dev/null
+++ b/data/txntest/program.go
@@ -0,0 +1,51 @@
+// Copyright (C) 2019-2024 Algorand, Inc.
+// This file is part of go-algorand
+//
+// go-algorand is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// go-algorand is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with go-algorand. If not, see .
+
+package txntest
+
+import (
+ "fmt"
+
+ "github.com/algorand/go-algorand/data/transactions/logic"
+)
+
+// GenerateProgramOfSize return a TEAL bytecode of `size` bytes which always succeeds.
+// `size` must be at least 9 bytes
+func GenerateProgramOfSize(size uint, pragma uint) ([]byte, error) {
+ if size < 9 {
+ return nil, fmt.Errorf("size must be at least 9 bytes; got %d", size)
+ }
+ ls := fmt.Sprintf("#pragma version %d\n", pragma)
+ if size%2 == 0 {
+ ls += "int 10\npop\nint 1\npop\n"
+ } else {
+ ls += "int 1\npop\nint 1\npop\n"
+ }
+ for i := uint(11); i <= size; i += 2 {
+ ls = ls + "int 1\npop\n"
+ }
+ ls = ls + "int 1"
+ code, err := logic.AssembleString(ls)
+ if err != nil {
+ return nil, err
+ }
+ // panic if the function is not working as expected and needs to be updated
+ if len(code.Program) != int(size) {
+ panic(fmt.Sprintf("wanted to create a program of size %d but got a program of size %d",
+ size, len(code.Program)))
+ }
+ return code.Program, nil
+}
diff --git a/go.mod b/go.mod
index c53440ace7..9ec11b823e 100644
--- a/go.mod
+++ b/go.mod
@@ -1,15 +1,15 @@
module github.com/algorand/go-algorand
-go 1.21
+go 1.23
-toolchain go1.21.10
+toolchain go1.23.3
require (
github.com/DataDog/zstd v1.5.2
github.com/algorand/avm-abi v0.2.0
github.com/algorand/falcon v0.1.0
github.com/algorand/go-codec/codec v1.1.10
- github.com/algorand/go-deadlock v0.2.3
+ github.com/algorand/go-deadlock v0.2.4
github.com/algorand/go-sumhash v0.1.0
github.com/algorand/graphtrace v0.1.0
github.com/algorand/msgp v1.1.60
@@ -34,27 +34,27 @@ require (
github.com/jsimonetti/rtnetlink v1.4.2
github.com/karalabe/usb v0.0.3-0.20230711191512-61db3e06439c
github.com/labstack/echo/v4 v4.9.1
- github.com/libp2p/go-libp2p v0.36.2
- github.com/libp2p/go-libp2p-kad-dht v0.26.1
+ github.com/libp2p/go-libp2p v0.37.0
+ github.com/libp2p/go-libp2p-kad-dht v0.28.0
github.com/libp2p/go-libp2p-pubsub v0.12.0
github.com/libp2p/go-yamux/v4 v4.0.1
github.com/mattn/go-sqlite3 v1.14.16
github.com/miekg/dns v1.1.62
github.com/multiformats/go-multiaddr v0.13.0
- github.com/multiformats/go-multiaddr-dns v0.3.1
+ github.com/multiformats/go-multiaddr-dns v0.4.0
github.com/olivere/elastic v6.2.14+incompatible
- github.com/prometheus/client_golang v1.20.0
+ github.com/prometheus/client_golang v1.20.5
github.com/prometheus/client_model v0.6.1
github.com/sirupsen/logrus v1.8.1
github.com/spf13/cobra v1.5.0
github.com/stretchr/testify v1.9.0
go.opencensus.io v0.24.0
go.uber.org/zap v1.27.0
- golang.org/x/crypto v0.26.0
- golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa
- golang.org/x/sync v0.8.0
- golang.org/x/sys v0.24.0
- golang.org/x/text v0.17.0
+ golang.org/x/crypto v0.29.0
+ golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c
+ golang.org/x/sync v0.9.0
+ golang.org/x/sys v0.27.0
+ golang.org/x/text v0.20.0
gopkg.in/sohlich/elogrus.v3 v3.0.0-20180410122755-1fa29e2f2009
pgregory.net/rapid v0.6.2
)
@@ -91,7 +91,7 @@ require (
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/google/gopacket v1.1.19 // indirect
- github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect
+ github.com/google/pprof v0.0.0-20241017200806-017d972448fc // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
@@ -101,7 +101,7 @@ require (
github.com/huin/goupnp v1.3.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/invopop/yaml v0.1.0 // indirect
- github.com/ipfs/boxo v0.21.0 // indirect
+ github.com/ipfs/boxo v0.24.3 // indirect
github.com/ipfs/go-cid v0.4.1 // indirect
github.com/ipfs/go-datastore v0.6.0 // indirect
github.com/ipld/go-ipld-prime v0.21.0 // indirect
@@ -111,7 +111,7 @@ require (
github.com/jmespath/go-jmespath v0.3.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/josharian/native v1.1.0 // indirect
- github.com/klauspost/compress v1.17.9 // indirect
+ github.com/klauspost/compress v1.17.11 // indirect
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
github.com/koron/go-ssdp v0.0.4 // indirect
github.com/kr/pretty v0.3.1 // indirect
@@ -119,9 +119,9 @@ require (
github.com/labstack/gommon v0.4.0 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/libp2p/go-cidranger v1.1.0 // indirect
- github.com/libp2p/go-flow-metrics v0.1.0 // indirect
+ github.com/libp2p/go-flow-metrics v0.2.0 // indirect
github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect
- github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect
+ github.com/libp2p/go-libp2p-kbucket v0.6.4 // indirect
github.com/libp2p/go-libp2p-record v0.2.0 // indirect
github.com/libp2p/go-libp2p-routing-helpers v0.7.4 // indirect
github.com/libp2p/go-msgio v0.3.0 // indirect
@@ -149,15 +149,15 @@ require (
github.com/multiformats/go-multistream v0.5.0 // indirect
github.com/multiformats/go-varint v0.0.7 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
- github.com/onsi/ginkgo/v2 v2.20.0 // indirect
+ github.com/onsi/ginkgo/v2 v2.20.2 // indirect
github.com/opencontainers/runtime-spec v1.2.0 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
- github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
- github.com/pion/datachannel v1.5.8 // indirect
+ github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274 // indirect
+ github.com/pion/datachannel v1.5.9 // indirect
github.com/pion/dtls/v2 v2.2.12 // indirect
- github.com/pion/ice/v2 v2.3.34 // indirect
- github.com/pion/interceptor v0.1.30 // indirect
+ github.com/pion/ice/v2 v2.3.36 // indirect
+ github.com/pion/interceptor v0.1.37 // indirect
github.com/pion/logging v0.2.2 // indirect
github.com/pion/mdns v0.0.12 // indirect
github.com/pion/randutil v0.1.0 // indirect
@@ -169,15 +169,15 @@ require (
github.com/pion/stun v0.6.1 // indirect
github.com/pion/transport/v2 v2.2.10 // indirect
github.com/pion/turn/v2 v2.1.6 // indirect
- github.com/pion/webrtc/v3 v3.3.0 // indirect
+ github.com/pion/webrtc/v3 v3.3.4 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/polydawn/refmt v0.89.0 // indirect
- github.com/prometheus/common v0.55.0 // indirect
+ github.com/prometheus/common v0.60.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
- github.com/quic-go/qpack v0.4.0 // indirect
- github.com/quic-go/quic-go v0.46.0 // indirect
- github.com/quic-go/webtransport-go v0.8.0 // indirect
+ github.com/quic-go/qpack v0.5.1 // indirect
+ github.com/quic-go/quic-go v0.48.1 // indirect
+ github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 // indirect
github.com/raulk/go-watchdog v1.3.0 // indirect
github.com/rogpeppe/go-internal v1.10.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
@@ -187,21 +187,21 @@ require (
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.1 // indirect
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect
- github.com/wlynxg/anet v0.0.4 // indirect
- go.opentelemetry.io/otel v1.27.0 // indirect
- go.opentelemetry.io/otel/metric v1.27.0 // indirect
- go.opentelemetry.io/otel/trace v1.27.0 // indirect
+ github.com/wlynxg/anet v0.0.5 // indirect
+ go.opentelemetry.io/otel v1.31.0 // indirect
+ go.opentelemetry.io/otel/metric v1.31.0 // indirect
+ go.opentelemetry.io/otel/trace v1.31.0 // indirect
go.uber.org/dig v1.18.0 // indirect
- go.uber.org/fx v1.22.2 // indirect
- go.uber.org/mock v0.4.0 // indirect
+ go.uber.org/fx v1.23.0 // indirect
+ go.uber.org/mock v0.5.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
- golang.org/x/mod v0.20.0 // indirect
- golang.org/x/net v0.28.0 // indirect
- golang.org/x/term v0.23.0 // indirect
+ golang.org/x/mod v0.21.0 // indirect
+ golang.org/x/net v0.30.0 // indirect
+ golang.org/x/term v0.26.0 // indirect
golang.org/x/time v0.5.0 // indirect
- golang.org/x/tools v0.24.0 // indirect
+ golang.org/x/tools v0.26.0 // indirect
gonum.org/v1/gonum v0.15.0 // indirect
- google.golang.org/protobuf v1.34.2 // indirect
+ google.golang.org/protobuf v1.35.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
lukechampine.com/blake3 v1.3.0 // indirect
diff --git a/go.sum b/go.sum
index 4b3862b620..fdee6063f8 100644
--- a/go.sum
+++ b/go.sum
@@ -24,8 +24,8 @@ github.com/algorand/falcon v0.1.0 h1:xl832kfZ7hHG6B4p90DQynjfKFGbIUgUOnsRiMZXfAo
github.com/algorand/falcon v0.1.0/go.mod h1:OkQyHlGvS0kLNcIWbC21/uQcnbfwSOQm+wiqWwBG9pQ=
github.com/algorand/go-codec/codec v1.1.10 h1:zmWYU1cp64jQVTOG8Tw8wa+k0VfwgXIPbnDfiVa+5QA=
github.com/algorand/go-codec/codec v1.1.10/go.mod h1:YkEx5nmr/zuCeaDYOIhlDg92Lxju8tj2d2NrYqP7g7k=
-github.com/algorand/go-deadlock v0.2.3 h1:ek9rjUyUF1HhUm0I2DyaCN8+3S850ONJNl5jQr9kZOA=
-github.com/algorand/go-deadlock v0.2.3/go.mod h1:Gli2d0Cb7kgXzSpJLC4Vn0DCLgjNVi6fNldY/mOtO/U=
+github.com/algorand/go-deadlock v0.2.4 h1:UMs6GwE2wHC6BUZo5z32/+SrBey1LQjbkZQ3V7DoGVA=
+github.com/algorand/go-deadlock v0.2.4/go.mod h1:tewhAviZpVq2cnGHmfT50l6RwWLnuygnfNntCN2fz0M=
github.com/algorand/go-sumhash v0.1.0 h1:b/QRhyLuF//vOcicBIxBXYW8bERNoeLxieht/dUYpVg=
github.com/algorand/go-sumhash v0.1.0/go.mod h1:OOe7jdDWUhLkuP1XytkK5gnLu9entAviN5DfDZh6XAc=
github.com/algorand/graphtrace v0.1.0 h1:QemP1iT0W56SExD0NfiU6rsG34/v0Je6bg5UZnptEUM=
@@ -230,8 +230,8 @@ github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
-github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k=
-github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
+github.com/google/pprof v0.0.0-20241017200806-017d972448fc h1:NGyrhhFhwvRAZg02jnYVg3GBQy0qGBKmFQJwaPmpmxs=
+github.com/google/pprof v0.0.0-20241017200806-017d972448fc/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -271,8 +271,10 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/invopop/yaml v0.1.0 h1:YW3WGUoJEXYfzWBjn00zIlrw7brGVD0fUKRYDPAPhrc=
github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
-github.com/ipfs/boxo v0.21.0 h1:XpGXb+TQQ0IUdYaeAxGzWjSs6ow/Lce148A/2IbRDVE=
-github.com/ipfs/boxo v0.21.0/go.mod h1:NmweAYeY1USOaJJxouy7DLr/Y5M8UBSsCI2KRivO+TY=
+github.com/ipfs/boxo v0.24.3 h1:gldDPOWdM3Rz0v5LkVLtZu7A7gFNvAlWcmxhCqlHR3c=
+github.com/ipfs/boxo v0.24.3/go.mod h1:h0DRzOY1IBFDHp6KNvrJLMFdSXTYID0Zf+q7X05JsNg=
+github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs=
+github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM=
github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s=
github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk=
github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk=
@@ -286,6 +288,8 @@ github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JP
github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g=
github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY=
github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI=
+github.com/ipfs/go-test v0.0.4 h1:DKT66T6GBB6PsDFLoO56QZPrOmzJkqU1FZH5C9ySkew=
+github.com/ipfs/go-test v0.0.4/go.mod h1:qhIM1EluEfElKKM6fnWxGn822/z9knUGM1+I/OAQNKI=
github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E=
github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ=
github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI=
@@ -330,8 +334,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
-github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
-github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
+github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
@@ -360,16 +364,16 @@ github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c=
github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic=
-github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM=
-github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro=
-github.com/libp2p/go-libp2p v0.36.2 h1:BbqRkDaGC3/5xfaJakLV/BrpjlAuYqSB0lRvtzL3B/U=
-github.com/libp2p/go-libp2p v0.36.2/go.mod h1:XO3joasRE4Eup8yCTTP/+kX+g92mOgRaadk46LmPhHY=
+github.com/libp2p/go-flow-metrics v0.2.0 h1:EIZzjmeOE6c8Dav0sNv35vhZxATIXWZg6j/C08XmmDw=
+github.com/libp2p/go-flow-metrics v0.2.0/go.mod h1:st3qqfu8+pMfh+9Mzqb2GTiwrAGjIPszEjZmtksN8Jc=
+github.com/libp2p/go-libp2p v0.37.0 h1:8K3mcZgwTldydMCNOiNi/ZJrOB9BY+GlI3UxYzxBi9A=
+github.com/libp2p/go-libp2p v0.37.0/go.mod h1:GOKmSN99scDuYGTwaTbQPR8Nt6dxrK3ue7OjW2NGDg4=
github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94=
github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8=
-github.com/libp2p/go-libp2p-kad-dht v0.26.1 h1:AazV3LCImYVkDUGAHx5lIEgZ9iUI2QQKH5GMRQU8uEA=
-github.com/libp2p/go-libp2p-kad-dht v0.26.1/go.mod h1:mqRUGJ/+7ziQ3XknU2kKHfsbbgb9xL65DXjPOJwmZF8=
-github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0=
-github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0=
+github.com/libp2p/go-libp2p-kad-dht v0.28.0 h1:sDqfW784w7CZQLlnMUwfeqWfXcpedKeZIM/B9/w0Tbk=
+github.com/libp2p/go-libp2p-kad-dht v0.28.0/go.mod h1:0wHURlSFdAC42+wF7GEmpLoARw8JuS8do2guCtc/Y/w=
+github.com/libp2p/go-libp2p-kbucket v0.6.4 h1:OjfiYxU42TKQSB8t8WYd8MKhYhMJeO2If+NiuKfb6iQ=
+github.com/libp2p/go-libp2p-kbucket v0.6.4/go.mod h1:jp6w82sczYaBsAypt5ayACcRJi0lgsba7o4TzJKEfWA=
github.com/libp2p/go-libp2p-pubsub v0.12.0 h1:PENNZjSfk8KYxANRlpipdS7+BfLmOl3L2E/6vSNjbdI=
github.com/libp2p/go-libp2p-pubsub v0.12.0/go.mod h1:Oi0zw9aw8/Y5GC99zt+Ef2gYAl+0nZlwdJonDyOz/sE=
github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0=
@@ -422,7 +426,6 @@ github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.
github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ=
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
-github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8=
@@ -453,11 +456,10 @@ github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYg
github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4=
github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo=
-github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4=
github.com/multiformats/go-multiaddr v0.13.0 h1:BCBzs61E3AGHcYYTv8dqRH43ZfyrqM8RXVPT8t13tLQ=
github.com/multiformats/go-multiaddr v0.13.0/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII=
-github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A=
-github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk=
+github.com/multiformats/go-multiaddr-dns v0.4.0 h1:P76EJ3qzBXpUXZ3twdCDx/kvagMsNo0LMFXpyms/zgU=
+github.com/multiformats/go-multiaddr-dns v0.4.0/go.mod h1:7hfthtB4E4pQwirrz+J0CcDUfbWzTqEzVyYKKIKpgkc=
github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E=
github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo=
github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g=
@@ -469,7 +471,6 @@ github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7B
github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM=
github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE=
github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dydlEqV3l6N3/GBsX6ILA=
-github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8=
github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
@@ -485,8 +486,8 @@ github.com/olivere/elastic v6.2.14+incompatible/go.mod h1:J+q1zQJTgAz9woqsbVRqGe
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0=
-github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw=
-github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI=
+github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4=
+github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
@@ -500,19 +501,19 @@ github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTm
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0=
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
-github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ=
-github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o=
+github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274 h1:qli3BGQK0tYDkSEvZ/FzZTi9ZrOX86Q6CIhKLGc489A=
+github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
-github.com/pion/datachannel v1.5.8 h1:ph1P1NsGkazkjrvyMfhRBUAWMxugJjq2HfQifaOoSNo=
-github.com/pion/datachannel v1.5.8/go.mod h1:PgmdpoaNBLX9HNzNClmdki4DYW5JtI7Yibu8QzbL3tI=
+github.com/pion/datachannel v1.5.9 h1:LpIWAOYPyDrXtU+BW7X0Yt/vGtYxtXQ8ql7dFfYUVZA=
+github.com/pion/datachannel v1.5.9/go.mod h1:kDUuk4CU4Uxp82NH4LQZbISULkX/HtzKa4P7ldf9izE=
github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk=
github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE=
-github.com/pion/ice/v2 v2.3.34 h1:Ic1ppYCj4tUOcPAp76U6F3fVrlSw8A9JtRXLqw6BbUM=
-github.com/pion/ice/v2 v2.3.34/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ=
-github.com/pion/interceptor v0.1.30 h1:au5rlVHsgmxNi+v/mjOPazbW1SHzfx7/hYOEYQnUcxA=
-github.com/pion/interceptor v0.1.30/go.mod h1:RQuKT5HTdkP2Fi0cuOS5G5WNymTjzXaGF75J4k7z2nc=
+github.com/pion/ice/v2 v2.3.36 h1:SopeXiVbbcooUg2EIR8sq4b13RQ8gzrkkldOVg+bBsc=
+github.com/pion/ice/v2 v2.3.36/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ=
+github.com/pion/interceptor v0.1.37 h1:aRA8Zpab/wE7/c0O3fh1PqY0AJI3fCSEM5lRWJVorwI=
+github.com/pion/interceptor v0.1.37/go.mod h1:JzxbJ4umVTlZAf+/utHzNesY8tmRkM2lVmkS82TTj8Y=
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8=
@@ -544,8 +545,8 @@ github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uP
github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc=
github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
-github.com/pion/webrtc/v3 v3.3.0 h1:Rf4u6n6U5t5sUxhYPQk/samzU/oDv7jk6BA5hyO2F9I=
-github.com/pion/webrtc/v3 v3.3.0/go.mod h1:hVmrDJvwhEertRWObeb1xzulzHGeVUoPlWvxdGzcfU0=
+github.com/pion/webrtc/v3 v3.3.4 h1:v2heQVnXTSqNRXcaFQVOhIOYkLMxOu1iJG8uy1djvkk=
+github.com/pion/webrtc/v3 v3.3.4/go.mod h1:liNa+E1iwyzyXqNUwvoMRNQ10x8h8FOeJKL8RkIbamE=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -555,24 +556,24 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4=
github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw=
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
-github.com/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI=
-github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
+github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
+github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
-github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
-github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
+github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA=
+github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw=
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
-github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
-github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
-github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y=
-github.com/quic-go/quic-go v0.46.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI=
-github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg=
-github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM=
+github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
+github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
+github.com/quic-go/quic-go v0.48.1 h1:y/8xmfWI9qmGTc+lBr4jKRUWLGSlSigv847ULJ4hYXA=
+github.com/quic-go/quic-go v0.48.1/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs=
+github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 h1:4WFk6u3sOT6pLa1kQ50ZVdm8BQFgJNA117cepZxtLIg=
+github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66/go.mod h1:Vp72IJajgeOL6ddqrAhmp7IM9zbTcgkQxD/YdxrVwMw=
github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk=
github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
@@ -671,8 +672,8 @@ github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvS
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k=
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc=
github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
-github.com/wlynxg/anet v0.0.4 h1:0de1OFQxnNqAu+x2FAKKCVIrnfGKQbs7FQz++tB0+Uw=
-github.com/wlynxg/anet v0.0.4/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
+github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU=
+github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
@@ -689,23 +690,23 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
-go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg=
-go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ=
-go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik=
-go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak=
-go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw=
-go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4=
+go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY=
+go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE=
+go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE=
+go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY=
+go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys=
+go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw=
go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
-go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw=
-go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU=
+go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg=
+go.uber.org/fx v1.23.0/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU=
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
-go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
-go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
+go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
+go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
@@ -732,11 +733,11 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
-golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
-golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
+golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
+golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI=
-golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
+golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=
+golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -751,8 +752,8 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
-golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
+golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -783,8 +784,8 @@ golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
-golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
-golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
+golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
+golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -800,8 +801,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
-golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
+golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -825,7 +826,6 @@ golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -843,8 +843,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
-golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
+golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -852,8 +852,8 @@ golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
-golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
-golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
+golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU=
+golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@@ -864,8 +864,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
-golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
-golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
+golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
+golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
@@ -892,8 +892,8 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
-golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
-golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
+golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
+golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -934,8 +934,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
-google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
-google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
+google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
+google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/installer/config.json.example b/installer/config.json.example
index 8e93d95e28..1e7937d455 100644
--- a/installer/config.json.example
+++ b/installer/config.json.example
@@ -1,5 +1,5 @@
{
- "Version": 34,
+ "Version": 35,
"AccountUpdatesStatsInterval": 5000000000,
"AccountsRebuildSynchronousMode": 1,
"AgreementIncomingBundlesQueueLength": 15,
@@ -90,7 +90,7 @@
"MaxAcctLookback": 4,
"MaxBlockHistoryLookback": 0,
"MaxCatchpointDownloadDuration": 43200000000000,
- "MaxConnectionsPerIP": 15,
+ "MaxConnectionsPerIP": 8,
"MinCatchpointFileDownloadBytesPerSecond": 20480,
"NetAddress": "",
"NetworkMessageTraceServer": "",
@@ -127,6 +127,7 @@
"TrackerDBDir": "",
"TransactionSyncDataExchangeRate": 0,
"TransactionSyncSignificantMessageThreshold": 0,
+ "TxBacklogAppRateLimitingCountERLDrops": false,
"TxBacklogAppTxPerSecondRate": 100,
"TxBacklogAppTxRateLimiterMaxSize": 1048576,
"TxBacklogRateLimitingCongestionPct": 50,
diff --git a/installer/rpm/algorand-devtools/algorand-devtools.spec b/installer/rpm/algorand-devtools/algorand-devtools.spec
index ad5b5a1cd5..5c2490653c 100644
--- a/installer/rpm/algorand-devtools/algorand-devtools.spec
+++ b/installer/rpm/algorand-devtools/algorand-devtools.spec
@@ -8,6 +8,7 @@ Requires: @REQUIRED_ALGORAND_PKG@ >= @VER@
%define SRCDIR go-algorand-rpmbuild
%define _buildshell /bin/bash
+%define __os_install_post %{?__brp-compress}
%description
This package provides development tools for the Algorand blockchain.
diff --git a/installer/rpm/algorand/algorand.spec b/installer/rpm/algorand/algorand.spec
index ef58c0db1a..02e0909a78 100644
--- a/installer/rpm/algorand/algorand.spec
+++ b/installer/rpm/algorand/algorand.spec
@@ -11,6 +11,7 @@ Requires(pre): shadow-utils
%define SRCDIR go-algorand-rpmbuild
%define _buildshell /bin/bash
+%define __os_install_post %{?__brp-compress}
%description
This package provides an implementation of the Algorand protocol.
diff --git a/ledger/apply/application_test.go b/ledger/apply/application_test.go
index dfc298bf84..77efd5b075 100644
--- a/ledger/apply/application_test.go
+++ b/ledger/apply/application_test.go
@@ -18,11 +18,11 @@ package apply
import (
"fmt"
+ "maps"
"math/rand"
"testing"
"github.com/stretchr/testify/require"
- "golang.org/x/exp/maps"
"github.com/algorand/go-algorand/config"
"github.com/algorand/go-algorand/crypto"
diff --git a/ledger/apply/mockBalances_test.go b/ledger/apply/mockBalances_test.go
index a18500341e..312f37e76d 100644
--- a/ledger/apply/mockBalances_test.go
+++ b/ledger/apply/mockBalances_test.go
@@ -18,6 +18,7 @@ package apply
import (
"fmt"
+ "maps"
"github.com/algorand/go-algorand/config"
"github.com/algorand/go-algorand/data/basics"
@@ -26,7 +27,6 @@ import (
"github.com/algorand/go-algorand/data/transactions/logic"
"github.com/algorand/go-algorand/ledger/ledgercore"
"github.com/algorand/go-algorand/protocol"
- "golang.org/x/exp/maps"
)
type mockBalances struct {
diff --git a/ledger/eval/cow.go b/ledger/eval/cow.go
index c628b15224..68bc5bb124 100644
--- a/ledger/eval/cow.go
+++ b/ledger/eval/cow.go
@@ -28,7 +28,6 @@ import (
"github.com/algorand/go-algorand/data/transactions"
"github.com/algorand/go-algorand/ledger/ledgercore"
"github.com/algorand/go-algorand/protocol"
- "golang.org/x/exp/maps"
)
// ___________________
@@ -357,9 +356,9 @@ func (cb *roundCowState) reset() {
cb.proto = config.ConsensusParams{}
cb.mods.Reset()
cb.txnCount = 0
- maps.Clear(cb.sdeltas)
+ clear(cb.sdeltas)
cb.compatibilityMode = false
- maps.Clear(cb.compatibilityGetKeyCache)
+ clear(cb.compatibilityGetKeyCache)
cb.prevTotals = ledgercore.AccountTotals{}
cb.feesCollected = basics.MicroAlgos{}
}
diff --git a/ledger/eval/eval_test.go b/ledger/eval/eval_test.go
index d92ff31f1b..6ff50de2cd 100644
--- a/ledger/eval/eval_test.go
+++ b/ledger/eval/eval_test.go
@@ -273,7 +273,6 @@ func TestTransactionGroupWithTracer(t *testing.T) {
}
for _, testCase := range testCases {
- testCase := testCase
t.Run(testCase.name, func(t *testing.T) {
t.Parallel()
genesisInitState, addrs, keys := ledgertesting.Genesis(10)
diff --git a/ledger/eval/txntracer.go b/ledger/eval/txntracer.go
index 96d307390a..9d19d42e69 100644
--- a/ledger/eval/txntracer.go
+++ b/ledger/eval/txntracer.go
@@ -18,10 +18,10 @@ package eval
import (
"fmt"
+ "maps"
+ "slices"
"github.com/algorand/go-deadlock"
- "golang.org/x/exp/maps"
- "golang.org/x/exp/slices"
"github.com/algorand/go-algorand/crypto"
"github.com/algorand/go-algorand/data/basics"
diff --git a/ledger/eval/txntracer_test.go b/ledger/eval/txntracer_test.go
index 6875c99c38..5bcf54f250 100644
--- a/ledger/eval/txntracer_test.go
+++ b/ledger/eval/txntracer_test.go
@@ -59,7 +59,6 @@ func TestTransactionGroupWithDeltaTracer(t *testing.T) {
}
for _, testCase := range testCases {
- testCase := testCase
t.Run(testCase.name, func(t *testing.T) {
t.Parallel()
// SETUP THE BLOCK
diff --git a/ledger/ledger_test.go b/ledger/ledger_test.go
index a3d5dc2622..8941452d4c 100644
--- a/ledger/ledger_test.go
+++ b/ledger/ledger_test.go
@@ -25,11 +25,11 @@ import (
"os"
"path/filepath"
"runtime"
+ "slices"
"sort"
"testing"
"github.com/stretchr/testify/require"
- "golang.org/x/exp/slices"
"github.com/algorand/go-algorand/agreement"
"github.com/algorand/go-algorand/config"
diff --git a/ledger/ledgercore/statedelta.go b/ledger/ledgercore/statedelta.go
index 1d2562ca4f..90bf7afeaf 100644
--- a/ledger/ledgercore/statedelta.go
+++ b/ledger/ledgercore/statedelta.go
@@ -18,11 +18,11 @@ package ledgercore
import (
"fmt"
+ "maps"
"github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/data/bookkeeping"
"github.com/algorand/go-algorand/data/transactions"
- "golang.org/x/exp/maps"
)
const (
@@ -294,24 +294,24 @@ func (ad *AccountDeltas) Dehydrate() {
if ad.acctsCache == nil {
ad.acctsCache = make(map[basics.Address]int)
}
- maps.Clear(ad.acctsCache)
+ clear(ad.acctsCache)
if ad.appResourcesCache == nil {
ad.appResourcesCache = make(map[AccountApp]int)
}
- maps.Clear(ad.appResourcesCache)
+ clear(ad.appResourcesCache)
if ad.assetResourcesCache == nil {
ad.assetResourcesCache = make(map[AccountAsset]int)
}
- maps.Clear(ad.assetResourcesCache)
+ clear(ad.assetResourcesCache)
}
// Reset resets the StateDelta for re-use with sync.Pool
func (sd *StateDelta) Reset() {
sd.Accts.reset()
- maps.Clear(sd.Txids)
- maps.Clear(sd.Txleases)
- maps.Clear(sd.Creatables)
- maps.Clear(sd.KvMods)
+ clear(sd.Txids)
+ clear(sd.Txleases)
+ clear(sd.Creatables)
+ clear(sd.KvMods)
sd.Totals = AccountTotals{}
// these fields are going to be populated on next use but resetting them anyway for safety.
@@ -329,9 +329,9 @@ func (ad *AccountDeltas) reset() {
ad.AssetResources = ad.AssetResources[:0]
// reset the maps
- maps.Clear(ad.acctsCache)
- maps.Clear(ad.appResourcesCache)
- maps.Clear(ad.assetResourcesCache)
+ clear(ad.acctsCache)
+ clear(ad.appResourcesCache)
+ clear(ad.assetResourcesCache)
}
// notAllocated returns true if any of the fields allocated by MakeAccountDeltas is nil
diff --git a/ledger/simple_test.go b/ledger/simple_test.go
index 328f6f1528..045a1de477 100644
--- a/ledger/simple_test.go
+++ b/ledger/simple_test.go
@@ -29,6 +29,7 @@ import (
"github.com/algorand/go-algorand/data/bookkeeping"
"github.com/algorand/go-algorand/data/committee"
"github.com/algorand/go-algorand/data/transactions"
+ "github.com/algorand/go-algorand/data/transactions/logic"
"github.com/algorand/go-algorand/data/transactions/verify"
"github.com/algorand/go-algorand/data/txntest"
"github.com/algorand/go-algorand/ledger/eval"
@@ -91,6 +92,7 @@ func nextBlock(t testing.TB, ledger *Ledger) *eval.BlockEvaluator {
eval, err := eval.StartEvaluator(ledger, nextHdr, eval.EvaluatorOptions{
Generate: true,
Validate: true, // Do the complete checks that a new txn would be subject to
+ Tracer: logic.EvalErrorDetailsTracer{},
})
require.NoError(t, err)
return eval
diff --git a/ledger/simulation/simulation_eval_test.go b/ledger/simulation/simulation_eval_test.go
index 0399c8215a..ef81a8a10e 100644
--- a/ledger/simulation/simulation_eval_test.go
+++ b/ledger/simulation/simulation_eval_test.go
@@ -21,11 +21,10 @@ import (
"encoding/hex"
"fmt"
"math"
+ "slices"
"strings"
"testing"
- "golang.org/x/exp/slices"
-
"github.com/algorand/go-algorand/crypto"
"github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/data/transactions"
@@ -365,7 +364,6 @@ func TestWrongAuthorizerTxn(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()
for _, optionalSigs := range []bool{false, true} {
- optionalSigs := optionalSigs
t.Run(fmt.Sprintf("optionalSigs=%t", optionalSigs), func(t *testing.T) {
t.Parallel()
simulationTest(t, func(env simulationtesting.Environment) simulationTestCase {
@@ -591,7 +589,6 @@ btoi`)
}
for _, testCase := range testCases {
- testCase := testCase
t.Run(testCase.name, func(t *testing.T) {
t.Parallel()
simulationTest(t, func(env simulationtesting.Environment) simulationTestCase {
@@ -4244,7 +4241,6 @@ func TestAppLocalGlobalStateChangeClearStateRollback(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()
for _, shouldError := range []bool{false, true} {
- shouldError := shouldError
t.Run(fmt.Sprintf("shouldError=%v", shouldError), func(t *testing.T) {
t.Parallel()
simulationTest(t, func(env simulationtesting.Environment) simulationTestCase {
@@ -6323,7 +6319,6 @@ func TestOptionalSignatures(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()
for _, signed := range []bool{true, false} {
- signed := signed
t.Run(fmt.Sprintf("signed=%t", signed), func(t *testing.T) {
simulationTest(t, func(env simulationtesting.Environment) simulationTestCase {
sender := env.Accounts[0]
@@ -6858,7 +6853,6 @@ func TestMockTracerScenarios(t *testing.T) {
scenarios := mocktracer.GetTestScenarios()
for name, scenarioFn := range scenarios {
- scenarioFn := scenarioFn
t.Run(name, func(t *testing.T) {
t.Parallel()
simulationTest(t, func(env simulationtesting.Environment) simulationTestCase {
@@ -6939,7 +6933,6 @@ func TestUnnamedResources(t *testing.T) {
// Start with directRefEnabledVersion (4), since prior to that all restricted references had to
// be indexes into the foreign arrays, meaning we can't test the unnamed case.
for v := 4; v <= logic.LogicVersion; v++ {
- v := v
t.Run(fmt.Sprintf("v%d", v), func(t *testing.T) {
t.Parallel()
simulationTest(t, func(env simulationtesting.Environment) simulationTestCase {
@@ -7197,7 +7190,6 @@ func TestUnnamedResourcesAccountLocalWrite(t *testing.T) {
// Start with directRefEnabledVersion (4), since prior to that all restricted references had to
// be indexes into the foreign arrays, meaning we can't test the unnamed case.
for v := 4; v <= logic.LogicVersion; v++ {
- v := v
t.Run(fmt.Sprintf("v%d", v), func(t *testing.T) {
t.Parallel()
simulationTest(t, func(env simulationtesting.Environment) simulationTestCase {
@@ -7343,7 +7335,6 @@ func TestUnnamedResourcesCreatedAppsAndAssets(t *testing.T) {
t.Parallel()
// Start with v9, since that's when we first track cross-product references indepdently.
for v := 9; v <= logic.LogicVersion; v++ {
- v := v
t.Run(fmt.Sprintf("v%d", v), func(t *testing.T) {
t.Parallel()
simulationTest(t, func(env simulationtesting.Environment) simulationTestCase {
@@ -7706,7 +7697,6 @@ func TestUnnamedResourcesBoxIOBudget(t *testing.T) {
t.Parallel()
// Boxes introduced in v8
for v := 8; v <= logic.LogicVersion; v++ {
- v := v
t.Run(fmt.Sprintf("v%d", v), func(t *testing.T) {
t.Parallel()
env := simulationtesting.PrepareSimulatorTest(t)
@@ -8591,7 +8581,6 @@ func TestUnnamedResourcesLimits(t *testing.T) {
// Start with v5, since that introduces the `txnas` opcode, needed for dynamic indexing into app
// args array.
for v := 5; v <= logic.LogicVersion; v++ {
- v := v
t.Run(fmt.Sprintf("v%d", v), func(t *testing.T) {
t.Parallel()
env := simulationtesting.PrepareSimulatorTest(t)
@@ -8758,7 +8747,6 @@ func TestUnnamedResourcesCrossProductLimits(t *testing.T) {
t.Parallel()
// Start with v9, since that's when we first track cross-product references indepdently.
for v := 9; v <= logic.LogicVersion; v++ {
- v := v
t.Run(fmt.Sprintf("v%d", v), func(t *testing.T) {
t.Parallel()
env := simulationtesting.PrepareSimulatorTest(t)
diff --git a/ledger/simulation/tracer.go b/ledger/simulation/tracer.go
index 94fa1394f7..8a9b7dda7b 100644
--- a/ledger/simulation/tracer.go
+++ b/ledger/simulation/tracer.go
@@ -555,3 +555,5 @@ func (tracer *evalTracer) AfterProgram(cx *logic.EvalContext, pass bool, evalErr
}
}
}
+
+func (tracer *evalTracer) DetailedEvalErrors() bool { return true }
diff --git a/ledger/simulation/tracer_test.go b/ledger/simulation/tracer_test.go
index b62f52fefa..8a76a508a3 100644
--- a/ledger/simulation/tracer_test.go
+++ b/ledger/simulation/tracer_test.go
@@ -217,7 +217,6 @@ func TestCursorEvalTracer(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
var tracer cursorEvalTracer
diff --git a/ledger/tracker.go b/ledger/tracker.go
index 051d045205..7509c8cff4 100644
--- a/ledger/tracker.go
+++ b/ledger/tracker.go
@@ -590,7 +590,7 @@ func (tr *trackerRegistry) commitRound(dcc *deferredCommitContext) error {
for _, lt := range tr.trackers {
err = lt.prepareCommit(dcc)
if err != nil {
- tr.log.Errorf(err.Error())
+ tr.log.Error(err.Error())
break
}
}
diff --git a/libgoal/participation/participation_test.go b/libgoal/participation/participation_test.go
index ff6976b98e..b8f2f1929c 100644
--- a/libgoal/participation/participation_test.go
+++ b/libgoal/participation/participation_test.go
@@ -47,7 +47,6 @@ func TestGenParticipationKeysTo_Install(t *testing.T) {
}
for _, tc := range testcases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
@@ -93,7 +92,6 @@ func TestGenParticipationKeysTo_DefaultKeyDilution(t *testing.T) {
}
for _, tc := range testcases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
diff --git a/netdeploy/network.go b/netdeploy/network.go
index 6f31673a54..1ca99239f4 100644
--- a/netdeploy/network.go
+++ b/netdeploy/network.go
@@ -20,8 +20,10 @@ import (
"encoding/json"
"fmt"
"io"
+ "maps"
"os"
"path/filepath"
+ "slices"
"sort"
"strings"
"time"
@@ -34,7 +36,6 @@ import (
"github.com/algorand/go-algorand/nodecontrol"
"github.com/algorand/go-algorand/protocol"
"github.com/algorand/go-algorand/util"
- "golang.org/x/exp/maps"
)
const configFileName = "network.json"
@@ -365,7 +366,7 @@ func (n Network) GetPeerAddresses(binDir string) []string {
}
func (n Network) startNodes(binDir string, relayNameToAddress map[string]string, redirectOutput bool) error {
- allRelaysAddresses := strings.Join(maps.Values(relayNameToAddress), ";")
+ allRelaysAddresses := strings.Join(slices.Collect(maps.Values(relayNameToAddress)), ";")
nodeConfigToEntry := make(map[string]remote.NodeConfigGoal, len(n.cfg.Template.Nodes))
for _, n := range n.cfg.Template.Nodes {
diff --git a/network/gossipNode.go b/network/gossipNode.go
index 91fb3506bc..68a5e36d88 100644
--- a/network/gossipNode.go
+++ b/network/gossipNode.go
@@ -231,17 +231,6 @@ func Propagate(msg IncomingMessage) OutgoingMessage {
return OutgoingMessage{Action: Broadcast, Tag: msg.Tag, Payload: msg.Data, Topics: nil}
}
-// find the max value across the given uint64 numbers.
-func max(numbers ...uint64) (maxNum uint64) {
- maxNum = 0 // this is the lowest uint64 value.
- for _, num := range numbers {
- if num > maxNum {
- maxNum = num
- }
- }
- return
-}
-
// SubstituteGenesisID substitutes the "{genesisID}" with their network-specific genesisID.
func SubstituteGenesisID(net GossipNode, rawURL string) string {
return strings.Replace(rawURL, "{genesisID}", net.GetGenesisID(), -1)
diff --git a/network/hybridNetwork.go b/network/hybridNetwork.go
index 5f31436fb8..c62c01c5d6 100644
--- a/network/hybridNetwork.go
+++ b/network/hybridNetwork.go
@@ -125,6 +125,11 @@ func (n *HybridP2PNetwork) Relay(ctx context.Context, tag protocol.Tag, data []b
})
}
+// BridgeP2PToWS skips Relay/Broadcast to both networks and only sends to WS
+func (n *HybridP2PNetwork) BridgeP2PToWS(ctx context.Context, tag protocol.Tag, data []byte, wait bool, except Peer) error {
+ return n.wsNetwork.Relay(ctx, tag, data, wait, except)
+}
+
// Disconnect implements GossipNode
func (n *HybridP2PNetwork) Disconnect(badnode DisconnectablePeer) {
net := badnode.GetNetwork()
diff --git a/network/metrics.go b/network/metrics.go
index a1e92b2424..fe62434095 100644
--- a/network/metrics.go
+++ b/network/metrics.go
@@ -90,6 +90,8 @@ var networkBroadcastSendMicros = metrics.MakeCounter(metrics.MetricName{Name: "a
var networkBroadcastsDropped = metrics.MakeCounter(metrics.MetricName{Name: "algod_broadcasts_dropped_total", Description: "number of broadcast messages not sent to any peer"})
var networkPeerBroadcastDropped = metrics.MakeCounter(metrics.MetricName{Name: "algod_peer_broadcast_dropped_total", Description: "number of broadcast messages not sent to some peer"})
+var networkP2PPeerBroadcastDropped = metrics.MakeCounter(metrics.MetricName{Name: "algod_peer_p2p_broadcast_dropped_total", Description: "number of broadcast messages not sent to some p2p peer"})
+
var networkPeerIdentityDisconnect = metrics.MakeCounter(metrics.MetricName{Name: "algod_network_identity_duplicate", Description: "number of times identity challenge cause us to disconnect a peer"})
var networkPeerIdentityError = metrics.MakeCounter(metrics.MetricName{Name: "algod_network_identity_error", Description: "number of times an error occurs (besides expected) when processing identity challenges"})
var networkPeerAlreadyClosed = metrics.MakeCounter(metrics.MetricName{Name: "algod_network_peer_already_closed", Description: "number of times a peer would be added but the peer connection is already closed"})
@@ -109,6 +111,8 @@ var transactionMessagesP2PUnderdeliverableMessage = metrics.MakeCounter(metrics.
var networkP2PGossipSubSentBytesTotal = metrics.MakeCounter(metrics.MetricName{Name: "algod_network_p2p_gs_sent_bytes_total", Description: "Total number of bytes sent through gossipsub"})
var networkP2PGossipSubReceivedBytesTotal = metrics.MakeCounter(metrics.MetricName{Name: "algod_network_p2p_gs_received_bytes_total", Description: "Total number of bytes received through gossipsub"})
+// var networkP2PGossipSubSentMsgs = metrics.MakeCounter(metrics.MetricName{Name: "algod_network_p2p_gs_message_sent", Description: "Number of complete messages that were sent to the network through gossipsub"})
+
var _ = pubsub.RawTracer(pubsubMetricsTracer{})
// pubsubMetricsTracer is a tracer for pubsub events used to track metrics.
@@ -134,14 +138,6 @@ func (t pubsubMetricsTracer) Prune(p peer.ID, topic string) {}
// ValidateMessage is invoked when a message first enters the validation pipeline.
func (t pubsubMetricsTracer) ValidateMessage(msg *pubsub.Message) {
- if msg != nil && msg.Topic != nil {
- switch *msg.Topic {
- case p2p.TXTopicName:
- networkP2PReceivedBytesTotal.AddUint64(uint64(len(msg.Data)), nil)
- networkP2PReceivedBytesByTag.Add(string(protocol.TxnTag), uint64(len(msg.Data)))
- networkP2PMessageReceivedByTag.Add(string(protocol.TxnTag), 1)
- }
- }
}
// DeliverMessage is invoked when a message is delivered
@@ -178,6 +174,17 @@ func (t pubsubMetricsTracer) ThrottlePeer(p peer.ID) {}
// RecvRPC is invoked when an incoming RPC is received.
func (t pubsubMetricsTracer) RecvRPC(rpc *pubsub.RPC) {
+ for i := range rpc.GetPublish() {
+ if rpc.Publish[i] != nil && rpc.Publish[i].Topic != nil {
+ switch *rpc.Publish[i].Topic {
+ case p2p.TXTopicName:
+ networkP2PReceivedBytesTotal.AddUint64(uint64(len(rpc.Publish[i].Data)), nil)
+ networkP2PReceivedBytesByTag.Add(string(protocol.TxnTag), uint64(len(rpc.Publish[i].Data)))
+ networkP2PMessageReceivedByTag.Add(string(protocol.TxnTag), 1)
+ }
+ }
+ }
+ // service gossipsub traffic = networkP2PGossipSubReceivedBytesTotal - networkP2PReceivedBytesByTag_TX
networkP2PGossipSubReceivedBytesTotal.AddUint64(uint64(rpc.Size()), nil)
}
@@ -197,7 +204,9 @@ func (t pubsubMetricsTracer) SendRPC(rpc *pubsub.RPC, p peer.ID) {
}
// DropRPC is invoked when an outbound RPC is dropped, typically because of a queue full.
-func (t pubsubMetricsTracer) DropRPC(rpc *pubsub.RPC, p peer.ID) {}
+func (t pubsubMetricsTracer) DropRPC(rpc *pubsub.RPC, p peer.ID) {
+ networkP2PPeerBroadcastDropped.Inc(nil)
+}
// UndeliverableMessage is invoked when the consumer of Subscribe is not reading messages fast enough and
// the pressure release mechanism trigger, dropping messages.
diff --git a/network/metrics_test.go b/network/metrics_test.go
index 857ab57051..ea0448ebc6 100644
--- a/network/metrics_test.go
+++ b/network/metrics_test.go
@@ -55,7 +55,7 @@ func TestMetrics_PubsubTracer_TagList(t *testing.T) {
return true
})
}
- if stmt.Name.Name == "ValidateMessage" {
+ if stmt.Name.Name == "RecvRPC" {
ast.Inspect(stmt.Body, func(n ast.Node) bool {
if switchStmt, ok := n.(*ast.SwitchStmt); ok {
for _, stmt := range switchStmt.Body.List {
diff --git a/network/p2p/peerstore/peerstore.go b/network/p2p/peerstore/peerstore.go
index 5ae9c6aa04..4a4e7e6ddf 100644
--- a/network/p2p/peerstore/peerstore.go
+++ b/network/p2p/peerstore/peerstore.go
@@ -20,12 +20,12 @@ import (
"fmt"
"math"
"math/rand"
+ "slices"
"time"
"github.com/libp2p/go-libp2p/core/peer"
libp2p "github.com/libp2p/go-libp2p/core/peerstore"
mempstore "github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem"
- "golang.org/x/exp/slices"
"github.com/algorand/go-algorand/network/phonebook"
"github.com/algorand/go-deadlock"
diff --git a/network/p2p/peerstore/utils_test.go b/network/p2p/peerstore/utils_test.go
index d0d67f4fe0..1609b41769 100644
--- a/network/p2p/peerstore/utils_test.go
+++ b/network/p2p/peerstore/utils_test.go
@@ -44,7 +44,6 @@ func TestPeerInfoFromAddr(t *testing.T) {
{"ipv4", "/ip4/147.75.83.83/tcp/4001/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Na", ""},
}
for _, tc := range testcases {
- tc := tc
t.Run(fmt.Sprintf("test %s", tc.name), func(t *testing.T) {
t.Parallel()
_, err := PeerInfoFromAddr(tc.addr)
diff --git a/network/p2p/pubsub.go b/network/p2p/pubsub.go
index a592657010..3dfe08301f 100644
--- a/network/p2p/pubsub.go
+++ b/network/p2p/pubsub.go
@@ -153,7 +153,7 @@ func (s *serviceImpl) Subscribe(topic string, val pubsub.ValidatorEx) (SubNextCa
return nil, err
}
// t.SetScoreParams() // already set in makePubSub
- return t.Subscribe()
+ return t.Subscribe(pubsub.WithBufferSize(32768))
}
// Publish publishes data to the given topic
diff --git a/network/phonebook/phonebook.go b/network/phonebook/phonebook.go
index b3aeafb0fa..100d624c04 100644
--- a/network/phonebook/phonebook.go
+++ b/network/phonebook/phonebook.go
@@ -19,10 +19,10 @@ package phonebook
import (
"math"
"math/rand"
+ "slices"
"time"
"github.com/algorand/go-deadlock"
- "golang.org/x/exp/slices"
)
// getAllAddresses when using GetAddresses with getAllAddresses, all the addresses will be retrieved, regardless
diff --git a/network/wsNetwork.go b/network/wsNetwork.go
index 1c5774aa6e..675e425573 100644
--- a/network/wsNetwork.go
+++ b/network/wsNetwork.go
@@ -1493,13 +1493,6 @@ type meshRequest struct {
done chan struct{}
}
-func imin(a, b int) int {
- if a < b {
- return a
- }
- return b
-}
-
// meshThread maintains the network, e.g. that we have sufficient connectivity to peers
func (wn *WebsocketNetwork) meshThread() {
defer wn.wg.Done()
@@ -1568,7 +1561,7 @@ func (wn *WebsocketNetwork) refreshRelayArchivePhonebookAddresses() {
func (wn *WebsocketNetwork) updatePhonebookAddresses(relayAddrs []string, archiveAddrs []string) {
if len(relayAddrs) > 0 {
- wn.log.Debugf("got %d relay dns addrs, %#v", len(relayAddrs), relayAddrs[:imin(5, len(relayAddrs))])
+ wn.log.Debugf("got %d relay dns addrs, %#v", len(relayAddrs), relayAddrs[:min(5, len(relayAddrs))])
wn.phonebook.ReplacePeerList(relayAddrs, string(wn.NetworkID), phonebook.PhoneBookEntryRelayRole)
} else {
wn.log.Infof("got no relay DNS addrs for network %s", wn.NetworkID)
diff --git a/node/follower_node.go b/node/follower_node.go
index 7d8fc64388..91bfa4e8e0 100644
--- a/node/follower_node.go
+++ b/node/follower_node.go
@@ -361,7 +361,7 @@ func (node *AlgorandFollowerNode) StartCatchup(catchpoint string) error {
}
err = node.catchpointCatchupService.Start(node.ctx)
if err != nil {
- node.log.Warnf(err.Error())
+ node.log.Warn(err.Error())
return MakeStartCatchpointError(catchpoint, err)
}
node.log.Infof("starting catching up toward catchpoint %s", catchpoint)
diff --git a/node/node.go b/node/node.go
index f536742c22..e5792c994a 100644
--- a/node/node.go
+++ b/node/node.go
@@ -1176,7 +1176,7 @@ func (node *AlgorandFullNode) StartCatchup(catchpoint string) error {
}
err = node.catchpointCatchupService.Start(node.ctx)
if err != nil {
- node.log.Warnf(err.Error())
+ node.log.Warn(err.Error())
return MakeStartCatchpointError(catchpoint, err)
}
node.log.Infof("starting catching up toward catchpoint %s", catchpoint)
diff --git a/node/node_test.go b/node/node_test.go
index 387ea58aa8..cc4a795c82 100644
--- a/node/node_test.go
+++ b/node/node_test.go
@@ -207,7 +207,7 @@ func setupFullNodesEx(
genesis[short] = data
}
genesis[poolAddr] = basics.AccountData{
- Status: basics.Online,
+ Status: basics.Offline,
MicroAlgos: basics.MicroAlgos{Raw: uint64(100000)},
}
@@ -241,7 +241,7 @@ func setupFullNodesEx(
cfg, err := config.LoadConfigFromDisk(rootDirectory)
phonebook := phonebookHook(nodeInfos, i)
require.NoError(t, err)
- node, err := MakeFull(logging.Base(), rootDirectory, cfg, phonebook, g)
+ node, err := MakeFull(logging.Base().With("net", fmt.Sprintf("node%d", i)), rootDirectory, cfg, phonebook, g)
nodes[i] = node
require.NoError(t, err)
}
@@ -819,10 +819,10 @@ func TestMaxSizesCorrect(t *testing.T) {
maxCombinedTxnSize := uint64(transactions.SignedTxnMaxSize())
// subtract out the two smaller signature sizes (logicsig is biggest, it can *contain* the others)
maxCombinedTxnSize -= uint64(crypto.SignatureMaxSize() + crypto.MultisigSigMaxSize())
- // the logicsig size is *also* an overestimate, because it thinks each
- // logicsig arg can be big, but really the sum of the args and the program
- // has a max size.
- maxCombinedTxnSize -= uint64(transactions.EvalMaxArgs * config.MaxLogicSigMaxSize)
+ // the logicsig size is *also* an overestimate, because it thinks that the logicsig and
+ // the logicsig args can both be up to to MaxLogicSigMaxSize, but that's the max for
+ // them combined, so it double counts and we have to subtract one.
+ maxCombinedTxnSize -= uint64(config.MaxLogicSigMaxSize)
// maxCombinedTxnSize is still an overestimate because it assumes all txn
// type fields can be in the same txn. That's not true, but it provides an
@@ -861,7 +861,7 @@ func TestMaxSizesCorrect(t *testing.T) {
// N -- R -- A and ensures N can discover A and download blocks from it.
//
// N is a non-part node that joins the network later
-// R is a non-archival relay node with block service disabled. It MUST NOT service blocks to force N to discover A.
+// R is a non-archival relay node with block service disabled. It MUST NOT serve blocks to force N to discover A.
// A is a archival node that can only provide blocks.
// Nodes N and A have only R in their initial phonebook, and all nodes are in hybrid mode.
func TestNodeHybridTopology(t *testing.T) {
@@ -1112,3 +1112,153 @@ func TestNodeSetCatchpointCatchupMode(t *testing.T) {
})
}
}
+
+// TestNodeHybridP2PGossipSend set ups 3 nodes network with the following topology:
+// N0 -- R -- N2 where N0 is wsnet only, R is a relay hybrid node, and N2 is p2pnet only.
+//
+// N0 is the only blocks producer, and N2 is the only transaction supplier.
+// Test ensures that a hybrid R relay can properly deliver transactions to N0.
+func TestNodeHybridP2PGossipSend(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ const consensusTest0 = protocol.ConsensusVersion("test0")
+
+ configurableConsensus := make(config.ConsensusProtocols)
+
+ testParams0 := config.Consensus[protocol.ConsensusCurrentVersion]
+ testParams0.AgreementFilterTimeoutPeriod0 = 500 * time.Millisecond
+ configurableConsensus[consensusTest0] = testParams0
+
+ // configure the stake to have R and A producing and confirming blocks
+ const totalStake = 100_000_000_000
+ const npnStake = 1_000_000
+ const nodeStake = totalStake - npnStake
+ const numAccounts = 3
+ acctStake := make([]basics.MicroAlgos, numAccounts)
+ acctStake[0] = basics.MicroAlgos{Raw: nodeStake}
+ acctStake[1] = basics.MicroAlgos{}
+ acctStake[2] = basics.MicroAlgos{Raw: npnStake}
+
+ configHook := func(ni nodeInfo, cfg config.Local) (nodeInfo, config.Local) {
+ cfg = config.GetDefaultLocal()
+ cfg.CatchpointInterval = 0
+ cfg.BaseLoggerDebugLevel = uint32(logging.Debug)
+ if ni.idx == 0 {
+ // node 0 is ws node only
+ cfg.EnableP2PHybridMode = false
+ cfg.EnableP2P = false
+ }
+
+ if ni.idx == 1 {
+ // node 1 is a hybrid relay
+ cfg.EnableBlockService = true
+ cfg.EnableGossipBlockService = true
+ cfg.NetAddress = ni.wsNetAddr()
+ cfg.EnableP2PHybridMode = true
+ cfg.PublicAddress = ni.wsNetAddr()
+ cfg.P2PPersistPeerID = true
+ privKey, err := p2p.GetPrivKey(cfg, ni.rootDir)
+ require.NoError(t, err)
+ ni.p2pID, err = p2p.PeerIDFromPublicKey(privKey.GetPublic())
+ require.NoError(t, err)
+
+ cfg.P2PHybridNetAddress = ni.p2pNetAddr()
+ }
+ if ni.idx == 2 {
+ // node 2 is p2p only
+ cfg.EnableP2PHybridMode = false
+ cfg.EnableP2P = true
+ }
+ return ni, cfg
+ }
+
+ phonebookHook := func(ni []nodeInfo, i int) []string {
+ switch i {
+ case 0:
+ // node 0 (N0) connects to R
+ t.Logf("Node%d phonebook: %s, %s", i, ni[1].wsNetAddr(), ni[1].p2pMultiAddr())
+ return []string{ni[1].wsNetAddr(), ni[1].p2pMultiAddr()}
+ case 1:
+ // node 1 (R) is a relay accepting connections from all
+ t.Logf("Node%d phonebook: empty", i)
+ return []string{}
+ case 2:
+ // node 2 (A) connects to R
+ t.Logf("Node%d phonebook: %s, %s", i, ni[1].wsNetAddr(), ni[1].p2pMultiAddr())
+ return []string{ni[1].wsNetAddr(), ni[1].p2pMultiAddr()}
+ default:
+ t.Errorf("not expected number of nodes: %d", i)
+ t.FailNow()
+ }
+ return nil
+ }
+
+ nodes, wallets := setupFullNodesEx(t, consensusTest0, configurableConsensus, acctStake, configHook, phonebookHook)
+ require.Len(t, nodes, 3)
+ require.Len(t, wallets, 3)
+ for i := 0; i < len(nodes); i++ {
+ defer os.Remove(wallets[i])
+ defer nodes[i].Stop()
+ }
+
+ startAndConnectNodes(nodes, nodelayFirstNodeStartDelay)
+
+ // ensure the initial connectivity topology
+ require.Eventually(t, func() bool {
+ node0Conn := len(nodes[0].net.GetPeers(network.PeersConnectedOut)) > 0 // connected to 1
+ node1Conn := len(nodes[1].net.GetPeers(network.PeersConnectedOut, network.PeersConnectedIn)) == 2 // connected from 0 and 2
+ node2Conn := len(nodes[2].net.GetPeers(network.PeersConnectedOut)) > 0 // connected to 1
+ return node0Conn && node1Conn && node2Conn
+ }, 60*time.Second, 500*time.Millisecond)
+
+ // now wait 2x heartbeat interval (GossipSubHeartbeatInterval) to ensure the meshsub is built
+ time.Sleep(2 * time.Second)
+
+ filename := filepath.Join(nodes[2].genesisDirs.RootGenesisDir, wallets[2])
+ access, err := db.MakeAccessor(filename, false, false)
+ require.NoError(t, err)
+ root, err := account.RestoreRoot(access)
+ access.Close()
+ require.NoError(t, err)
+
+ addr2 := root.Address()
+ secrets2 := root.Secrets()
+
+ txn := transactions.Transaction{
+ Type: protocol.PaymentTx,
+ Header: transactions.Header{
+ Sender: addr2,
+ FirstValid: 1,
+ LastValid: 100,
+ Fee: basics.MicroAlgos{Raw: 1000},
+ GenesisID: nodes[2].genesisID,
+ GenesisHash: nodes[2].genesisHash,
+ },
+ PaymentTxnFields: transactions.PaymentTxnFields{
+ Receiver: addr2,
+ Amount: basics.MicroAlgos{Raw: 0},
+ },
+ }
+ signature := secrets2.Sign(txn)
+ stxn := transactions.SignedTxn{
+ Sig: signature,
+ Txn: txn,
+ }
+
+ err = nodes[2].BroadcastSignedTxGroup([]transactions.SignedTxn{stxn})
+ require.NoError(t, err)
+
+ initialRound := nodes[0].ledger.NextRound()
+ targetRound := initialRound + 10
+ t.Logf("Waiting for round %d (initial %d)", targetRound, initialRound)
+
+ // ensure tx properly propagated to node 0
+ select {
+ case <-nodes[0].ledger.Wait(targetRound):
+ b, err := nodes[0].ledger.Block(targetRound)
+ require.NoError(t, err)
+ require.Greater(t, b.TxnCounter, uint64(1000)) // new initial value after AppForbidLowResources
+ case <-time.After(1 * time.Minute):
+ require.Fail(t, fmt.Sprintf("no block notification for wallet: %v.", wallets[0]))
+ }
+}
diff --git a/rpcs/ledgerService.go b/rpcs/ledgerService.go
index d76273de62..d8f45b3a05 100644
--- a/rpcs/ledgerService.go
+++ b/rpcs/ledgerService.go
@@ -108,7 +108,7 @@ func (ls *LedgerService) Stop() {
}
}
-// ServerHTTP returns ledgers for a particular round
+// ServeHTTP returns ledgers for a particular round
// Either /v{version}/{genesisID}/ledger/{round} or ?r={round}&v={version}
// Uses gorilla/mux for path argument parsing.
func (ls *LedgerService) ServeHTTP(response http.ResponseWriter, request *http.Request) {
diff --git a/scripts/build_packages.sh b/scripts/build_packages.sh
index b434c485dc..8a5e75a5b6 100755
--- a/scripts/build_packages.sh
+++ b/scripts/build_packages.sh
@@ -97,10 +97,14 @@ for var in "${VARIATION_ARRAY[@]}"; do
pushd ${PLATFORM_ROOT}
tar --exclude=tools -zcf ${PKG_ROOT}/node_${CHANNEL}_${PKG_NAME}_${FULLVERSION}.tar.gz * >/dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ echo "Error creating node tar file for package ${PLATFORM}. Aborting..."
+ exit 1
+ fi
cd bin
tar -zcf ${PKG_ROOT}/install_${CHANNEL}_${PKG_NAME}_${FULLVERSION}.tar.gz updater update.sh >/dev/null 2>&1
if [ $? -ne 0 ]; then
- echo "Error creating tar file for package ${PLATFORM}. Aborting..."
+ echo "Error creating install tar file for package ${PLATFORM}. Aborting..."
exit 1
fi
diff --git a/scripts/buildtools/versions b/scripts/buildtools/versions
index 61dd519985..e34ad22500 100644
--- a/scripts/buildtools/versions
+++ b/scripts/buildtools/versions
@@ -1,7 +1,7 @@
-golang.org/x/lint v0.0.0-20210508222113-6edffad5e616
-golang.org/x/tools v0.20.0
+golang.org/x/lint v0.0.0-20241112194109-818c5a804067
+golang.org/x/tools v0.27.0
github.com/algorand/msgp v1.1.60
github.com/algorand/oapi-codegen v1.12.0-algorand.0
-github.com/go-swagger/go-swagger v0.30.4
-gotest.tools/gotestsum v1.10.0
-github.com/golangci/golangci-lint/cmd/golangci-lint v1.58.0
+github.com/go-swagger/go-swagger v0.31.0
+gotest.tools/gotestsum v1.12.0
+github.com/golangci/golangci-lint/cmd/golangci-lint v1.62.0
diff --git a/scripts/get_golang_version.sh b/scripts/get_golang_version.sh
index 256683831c..fa93723936 100755
--- a/scripts/get_golang_version.sh
+++ b/scripts/get_golang_version.sh
@@ -11,9 +11,9 @@
# Our build task-runner `mule` will refer to this script and will automatically
# build a new image whenever the version number has been changed.
-BUILD=1.21.10
- MIN=1.21
- GO_MOD_SUPPORT=1.21
+BUILD=1.23.3
+ MIN=1.23
+ GO_MOD_SUPPORT=1.23
if [ "$1" = all ]
then
diff --git a/scripts/install_linux_deps.sh b/scripts/install_linux_deps.sh
index 2f5096f0b0..391aa97e7f 100755
--- a/scripts/install_linux_deps.sh
+++ b/scripts/install_linux_deps.sh
@@ -7,14 +7,18 @@ DISTRIB=$ID
ARCH_DEPS="expect jq autoconf shellcheck sqlite python-virtualenv"
UBUNTU_DEPS="libtool expect jq autoconf automake shellcheck sqlite3 python3-venv build-essential"
FEDORA_DEPS="expect jq autoconf ShellCheck sqlite python-virtualenv"
+OPENSUSE_TUMBLEWEED_DEPS="make gcc-c++ python3 glibc-devel-static libtool expect jq autoconf ShellCheck sqlite3 python312-virtualenv"
-case $DISTRIB in
+case $DISTRIB in
"arch" | "manjaro")
pacman -S --refresh --needed --noconfirm $ARCH_DEPS
;;
"fedora")
dnf -y install $FEDORA_DEPS
;;
+ "opensuse-tumbleweed")
+ zypper --non-interactive install $OPENSUSE_TUMBLEWEED_DEPS
+ ;;
*)
apt-get update
apt-get -y install $UBUNTU_DEPS
diff --git a/scripts/release/mule/sign/sign.sh b/scripts/release/mule/sign/sign.sh
index 89baedb9ce..ab7f3899e7 100755
--- a/scripts/release/mule/sign/sign.sh
+++ b/scripts/release/mule/sign/sign.sh
@@ -1,8 +1,6 @@
#!/usr/bin/env bash
# shellcheck disable=2035,2129
-# TODO: This needs to be reworked a bit to support Darwin.
-
set -exo pipefail
shopt -s nullglob
@@ -14,8 +12,8 @@ CHANNEL=${CHANNEL:-$(./scripts/release/mule/common/get_channel.sh "$NETWORK")}
VERSION=${VERSION:-$(./scripts/compute_build_number.sh -f)}
PKG_DIR="./tmp/node_pkgs"
SIGNING_KEY_ADDR=dev@algorand.com
-OS_TYPE=$(./scripts/release/mule/common/ostype.sh)
-ARCHS=(amd64 arm64)
+OS_TYPES=(linux darwin)
+ARCHS=(amd64 arm64 universal)
ARCH_BITS=(x86_64 aarch64)
# Note that we don't want to use $GNUPGHOME here because that is a documented env var for the gnupg
# project and if it's set in the environment mule will automatically pick it up, which could have
@@ -47,17 +45,19 @@ popd
if [ -n "$S3_SOURCE" ]
then
i=0
- for arch in "${ARCHS[@]}"; do
- arch_bit="${ARCH_BITS[$i]}"
- (
+ for os in "${OS_TYPES[@]}"; do
+ for arch in "${ARCHS[@]}"; do
mkdir -p "$PKG_DIR/$OS_TYPE/$arch"
- cd "$PKG_DIR"
- # Note the underscore after ${arch}!
- # Recall that rpm packages have the arch bit in the filenames (i.e., "x86_64" rather than "amd64").
- # Also, the order of the includes/excludes is important!
- aws s3 cp --recursive --exclude "*" --include "*${arch}_*" --include "*$arch_bit.rpm" --exclude "*.sig" --exclude "*.asc" --exclude "*.asc.gz" "s3://$S3_SOURCE/$CHANNEL/$VERSION" .
- )
- i=$((i + 1))
+ arch_bit="${ARCH_BITS[$i]}"
+ (
+ cd "$PKG_DIR"
+ # Note the underscore after ${arch}!
+ # Recall that rpm packages have the arch bit in the filenames (i.e., "x86_64" rather than "amd64").
+ # Also, the order of the includes/excludes is important!
+ aws s3 cp --recursive --exclude "*" --include "*${arch}_*" --include "*$arch_bit.rpm" --exclude "*.sig" --exclude "*.asc" --exclude "*.asc.gz" "s3://$S3_SOURCE/$CHANNEL/$VERSION" .
+ )
+ i=$((i + 1))
+ done
done
fi
@@ -69,7 +69,6 @@ cd "$PKG_DIR"
# Grab the directories directly underneath (max-depth 1) ./tmp/node_pkgs/ into a space-delimited string.
# This will help us target `linux`, `darwin` and (possibly) `windows` build assets.
# Note the surrounding parens turns the string created by `find` into an array.
-OS_TYPES=($(find . -mindepth 1 -maxdepth 1 -type d -printf '%f\n'))
for os in "${OS_TYPES[@]}"; do
for arch in "${ARCHS[@]}"; do
if [ -d "$os/$arch" ]
diff --git a/stateproof/builder.go b/stateproof/builder.go
index a97ec752c6..3f2e61d695 100644
--- a/stateproof/builder.go
+++ b/stateproof/builder.go
@@ -22,6 +22,8 @@ import (
"encoding/binary"
"errors"
"fmt"
+ "maps"
+ "slices"
"github.com/algorand/go-algorand/config"
"github.com/algorand/go-algorand/crypto/stateproof"
@@ -34,8 +36,6 @@ import (
"github.com/algorand/go-algorand/network"
"github.com/algorand/go-algorand/protocol"
"github.com/algorand/go-algorand/stateproof/verify"
- "golang.org/x/exp/maps"
- "golang.org/x/exp/slices"
)
var errVotersNotTracked = errors.New("voters not tracked for the given lookback round")
@@ -642,8 +642,7 @@ func (spw *Worker) tryBroadcast() {
spw.mu.Lock()
defer spw.mu.Unlock()
- sortedRounds := maps.Keys(spw.provers)
- slices.Sort(sortedRounds)
+ sortedRounds := slices.Sorted(maps.Keys(spw.provers))
for _, rnd := range sortedRounds {
// Iterate over the provers in a sequential manner. If the earlist state proof is not ready/rejected
diff --git a/test/e2e-go/cli/goal/expect/tealConsensusTest.exp b/test/e2e-go/cli/goal/expect/tealConsensusTest.exp
index a4231acd96..9df3d4abe9 100644
--- a/test/e2e-go/cli/goal/expect/tealConsensusTest.exp
+++ b/test/e2e-go/cli/goal/expect/tealConsensusTest.exp
@@ -54,15 +54,6 @@ if { [catch {
"\n" { ::AlgorandGoal::Abort $expect_out(buffer) }
}
- teal "$TEST_ROOT_DIR/big-sig.teal" 2 1001 1
- spawn goal clerk compile "$TEST_ROOT_DIR/big-sig.teal"
- expect {
- -re {[A-Z2-9]{58}} { ::AlgorandGoal::Abort "hash" }
- -re {.*logicsig program size too large} { puts "bigsigcheck: pass" }
- eof { ::AlgorandGoal::Abort $expect_out(buffer) }
- "\n" { ::AlgorandGoal::Abort $expect_out(buffer) }
- }
-
teal "$TEST_ROOT_DIR/barely-fits-app.teal" 2 4090 1 "int 0\nbalance\npop\n"
spawn goal clerk compile "$TEST_ROOT_DIR/barely-fits-app.teal"
expect {
@@ -71,16 +62,6 @@ if { [catch {
"\n" { ::AlgorandGoal::Abort $expect_out(buffer) }
}
- # MaxAppProgramLen = 2K * (1 + 3 pages max)
- teal "$TEST_ROOT_DIR/big-app.teal" 2 8192 1 "int 0\nbalance\npop\n"
- spawn goal clerk compile "$TEST_ROOT_DIR/big-app.teal"
- expect {
- -re {[A-Z2-9]{58}} { ::AlgorandGoal::Abort "hash" }
- -re {.*app program size too large} { puts "bigappcheck: pass" }
- eof { ::AlgorandGoal::Abort $expect_out(buffer) }
- "\n" { ::AlgorandGoal::Abort $expect_out(buffer) }
- }
-
# Test cost limits during dryrun
exec goal clerk send -F "$TEST_ROOT_DIR/small-sig.teal" -t GXBNLU4AXQABPLHXJDMTG2YXSDT4EWUZACT7KTPFXDQW52XPTIUS5OZ5HQ -a 100 -d $TEST_PRIMARY_NODE_DIR -o $TEST_ROOT_DIR/small-sig.tx
spawn goal clerk dryrun -t $TEST_ROOT_DIR/small-sig.tx
diff --git a/test/e2e-go/features/transactions/logicsig_test.go b/test/e2e-go/features/transactions/logicsig_test.go
new file mode 100644
index 0000000000..8958b5561f
--- /dev/null
+++ b/test/e2e-go/features/transactions/logicsig_test.go
@@ -0,0 +1,138 @@
+// Copyright (C) 2019-2024 Algorand, Inc.
+// This file is part of go-algorand
+//
+// go-algorand is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// go-algorand is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with go-algorand. If not, see .
+
+package transactions
+
+import (
+ "path/filepath"
+ "testing"
+
+ "github.com/algorand/go-algorand/data/transactions"
+ "github.com/algorand/go-algorand/data/txntest"
+ "github.com/algorand/go-algorand/test/framework/fixtures"
+ "github.com/algorand/go-algorand/test/partitiontest"
+ "github.com/stretchr/testify/require"
+)
+
+func TestLogicSigSizeBeforePooling(t *testing.T) {
+ partitiontest.PartitionTest(t)
+ defer fixtures.ShutdownSynchronizedTest(t)
+ a := require.New(fixtures.SynchronizedTest(t))
+
+ // From consensus version 18, we have lsigs with a maximum size of 1000 bytes.
+ // We need to use pragma 1 for teal in v18
+ pragma := uint(1)
+ tealOK, err := txntest.GenerateProgramOfSize(1000, pragma)
+ a.NoError(err)
+ tealTooLong, err := txntest.GenerateProgramOfSize(1001, pragma)
+ a.NoError(err)
+
+ testLogicSize(t, tealOK, tealTooLong, filepath.Join("nettemplates", "TwoNodes50EachV18.json"))
+}
+
+func TestLogicSigSizeAfterPooling(t *testing.T) {
+ partitiontest.PartitionTest(t)
+ defer fixtures.ShutdownSynchronizedTest(t)
+ a := require.New(fixtures.SynchronizedTest(t))
+
+ pragma := uint(1)
+ tealOK, err := txntest.GenerateProgramOfSize(2000, pragma)
+ a.NoError(err)
+ tealTooLong, err := txntest.GenerateProgramOfSize(2001, pragma)
+ a.NoError(err)
+
+ // TODO: Update this when lsig pooling graduates from vFuture
+ testLogicSize(t, tealOK, tealTooLong, filepath.Join("nettemplates", "TwoNodes50EachFuture.json"))
+}
+
+// testLogicSize takes two TEAL programs, one expected to be ok and one expected to be too long
+// and thus to be rejected, and tests that's indeed the case.
+func testLogicSize(t *testing.T, tealOK, tealTooLong []byte,
+ networkTemplate string) {
+
+ t.Parallel()
+ a := require.New(fixtures.SynchronizedTest(t))
+
+ var fixture fixtures.RestClientFixture
+ fixture.Setup(t, networkTemplate)
+ defer fixture.Shutdown()
+
+ client := fixture.LibGoalClient
+ accountList, err := fixture.GetWalletsSortedByBalance()
+ a.NoError(err)
+ baseAcct := accountList[0].Address
+
+ walletHandler, err := client.GetUnencryptedWalletHandle()
+ a.NoError(err)
+
+ signatureOK, err := client.SignProgramWithWallet(walletHandler, nil, baseAcct, tealOK)
+ a.NoError(err)
+ lsigOK := transactions.LogicSig{Logic: tealOK, Sig: signatureOK}
+
+ signatureTooLong, err := client.SignProgramWithWallet(walletHandler, nil, baseAcct, tealTooLong)
+ a.NoError(err)
+ lsigTooLong := transactions.LogicSig{Logic: tealTooLong, Sig: signatureTooLong}
+
+ // We build two transaction groups of two transactions each.
+ // The first txn will be either signed by an ok lsig or a too long one.
+ // The second is a vanilla payment transaction to complete the group.
+ var txn1Success, txn2Success, txn1Fail, txn2Fail transactions.Transaction
+ for i, txn := range []*transactions.Transaction{&txn1Success, &txn2Success, &txn1Fail, &txn2Fail} {
+ *txn, err = client.ConstructPayment(baseAcct, baseAcct, 0, uint64(i), nil, "", [32]byte{}, 0, 0)
+ a.NoError(err)
+ }
+
+ // success group
+ gidSuccess, err := client.GroupID([]transactions.Transaction{txn1Success, txn2Success})
+ a.NoError(err)
+
+ txn1Success.Group = gidSuccess
+ stxn1Success := transactions.SignedTxn{Txn: txn1Success, Lsig: lsigOK}
+
+ txn2Success.Group = gidSuccess
+ stxn2Success, err := client.SignTransactionWithWallet(walletHandler, nil, txn2Success)
+ a.NoError(err)
+
+ err = client.BroadcastTransactionGroup([]transactions.SignedTxn{stxn1Success, stxn2Success})
+ a.NoError(err)
+
+ // fail group
+ gidFail, err := client.GroupID([]transactions.Transaction{txn1Fail, txn2Fail})
+ a.NoError(err)
+
+ txn1Fail.Group = gidFail
+ stxn1Fail := transactions.SignedTxn{Txn: txn1Fail, Lsig: lsigTooLong}
+
+ txn2Fail.Group = gidFail
+ stxn2Fail, err := client.SignTransactionWithWallet(walletHandler, nil, txn2Fail)
+ a.NoError(err)
+
+ cp, err := client.ConsensusParams(0)
+ a.NoError(err)
+
+ err = client.BroadcastTransactionGroup([]transactions.SignedTxn{stxn1Fail, stxn2Fail})
+ if cp.EnableLogicSigSizePooling {
+ a.ErrorContains(err, "more than the available pool")
+ } else {
+ a.ErrorContains(err, "LogicSig too long")
+ }
+
+ // wait for the second transaction in the successful group to confirm
+ txn2SuccessID := txn2Success.ID().String()
+ _, curRound := fixture.GetBalanceAndRound(baseAcct)
+ confirmed := fixture.WaitForTxnConfirmation(curRound+5, txn2SuccessID)
+ a.True(confirmed)
+}
diff --git a/test/heapwatch/metrics_aggs.py b/test/heapwatch/metrics_aggs.py
index 33379766a6..6bc7967867 100644
--- a/test/heapwatch/metrics_aggs.py
+++ b/test/heapwatch/metrics_aggs.py
@@ -164,7 +164,7 @@ def main():
mmax = max(rw)
mmin = min(rw)
print(f'{nick}: {metric_name}: count {len(rw)}, max {mmax}, min {mmin}, min-max {mmax - mmin}')
- metric = Metric(metric_name, 0, MetricType.COUNTER)
+ metric = Metric(metric_name, 0, '', MetricType.COUNTER)
if metric.short_name() not in metric_names_nick_max_avg:
metric_names_nick_max_avg[metric.short_name()] = []
if args.avg_max_min:
diff --git a/test/heapwatch/metrics_gra.py b/test/heapwatch/metrics_gra.py
new file mode 100644
index 0000000000..8e6cf8ce95
--- /dev/null
+++ b/test/heapwatch/metrics_gra.py
@@ -0,0 +1,93 @@
+#!/usr/bin/env python3
+# Copyright (C) 2019-2024 Algorand, Inc.
+# This file is part of go-algorand
+#
+# go-algorand is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# go-algorand is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with go-algorand. If not, see .
+#
+###
+#
+# Convert metrics collected by heapWatch.py from prometheus format to prometheus + timestamp format.
+# See https://prometheus.io/docs/prometheus/latest/storage/#backfilling-from-openmetrics-format
+#
+# Usage:
+# python3 /data/go-algorand/test/heapwatch/metrics_gra.py -d metrics/500x15/ -o prom-metrics.txt
+#
+# Local Grafana setup:
+# 1. Download standalone and unpack from https://grafana.com/grafana/download
+# 2. Run ./grafana-v11.2.2/bin/grafana server -config ./grafana-v11.2.2/conf/defaults.ini -homepath ./grafana-v11.2.2
+# 3. Open http://localhost:3000/ in web browser
+#
+# Prometheus setup:
+# 1. Download and unpack from https://prometheus.io/download/
+#
+# Apply prom-metrics.txt to prometheus:
+# (cd ./prometheus-2.54.1.linux-amd64 && ./promtool tsdb create-blocks-from openmetrics prom-metrics.txt)
+# Start Prometheus
+# ./prometheus-2.54.1.linux-amd64/prometheus --config.file=./prometheus-2.54.1.linux-amd64/prometheus.yml --storage.tsdb.path=./prometheus-2.54.1.linux-amd64/data --storage.tsdb.retention.time=60d --storage.tsdb.retention.size=500MB
+# This should import the data into ./prometheus-2.54.1.linux-amd64/data and have them available for plotting. Use https://127.0.0.1:9090/ as Prometheus data source location in Grafana.
+# Then create new or import dashboards from internal Grafana.
+###
+
+import argparse
+import glob
+import logging
+import os
+import sys
+
+from metrics_lib import gather_metrics_files_by_nick, parse_metrics
+
+logger = logging.getLogger(__name__)
+
+def main():
+ ap = argparse.ArgumentParser()
+ ap.add_argument('-d', '--dir', type=str, default=None, help='dir path to find /*.metrics in')
+ ap.add_argument('--nick-re', action='append', default=[], help='regexp to filter node names, may be repeated')
+ ap.add_argument('--nick-lre', action='append', default=[], help='label:regexp to filter node names, may be repeated')
+ ap.add_argument('-o', '--output', type=str, default=None, help='output file to write to')
+ ap.add_argument('--verbose', default=False, action='store_true')
+ args = ap.parse_args()
+ if args.verbose:
+ logging.basicConfig(level=logging.DEBUG)
+ else:
+ logging.basicConfig(level=logging.INFO)
+
+ if not args.dir:
+ logging.error('need at least one dir set with -d/--dir')
+ return 1
+
+ metrics_files = sorted(glob.glob(os.path.join(args.dir, '*.metrics')))
+ metrics_files.extend(glob.glob(os.path.join(args.dir, 'terraform-inventory.host')))
+ filesByNick = gather_metrics_files_by_nick(metrics_files, args.nick_re, args.nick_lre)
+
+ outf = sys.stdout
+ if args.output:
+ outf = open(args.output, 'wt')
+
+ for nick, files_by_ts in filesByNick.items():
+ for ts, metrics_file in files_by_ts.items():
+ with open(metrics_file, 'rt') as fin:
+ metrics = parse_metrics(fin, nick)
+ for metric_seq in metrics.values():
+ for metric in metric_seq:
+ print('# TYPE', metric.short_name(), metric.type, file=outf)
+ print('# HELP', metric.short_name(), metric.desc, file=outf)
+ print(metric.string(with_role=True, quote=True), metric.value, int(ts.timestamp()), file=outf)
+
+ print('# EOF', file=outf)
+
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/test/heapwatch/metrics_lib.py b/test/heapwatch/metrics_lib.py
index 1ac0d85bd7..0f6f603cb6 100644
--- a/test/heapwatch/metrics_lib.py
+++ b/test/heapwatch/metrics_lib.py
@@ -166,13 +166,17 @@ class MetricType(Enum):
GAUGE = 0
COUNTER = 1
+ def __str__(self):
+ return self.name.lower()
+
class Metric:
"""Metric with tags"""
- def __init__(self, metric_name: str, type: MetricType, value: Union[int, float]):
+ def __init__(self, metric_name: str, type: MetricType, desc: str, value: Union[int, float]):
full_name = metric_name.strip()
self.name = full_name
self.value = value
self.type = type
+ self.desc = desc
self.tags: Dict[str, str] = {}
self.tag_keys: set = set()
@@ -187,6 +191,8 @@ def __init__(self, metric_name: str, type: MetricType, value: Union[int, float])
tags = raw_tags.split(',')
for tag in tags:
key, value = tag.split('=')
+ if not value:
+ continue
if value[0] == '"' and value[-1] == '"':
value = value[1:-1]
self.tags[key] = value
@@ -198,12 +204,20 @@ def short_name(self):
def __str__(self):
return self.string()
- def string(self, tags: Optional[set[str]]=None):
+ def string(self, tags: Optional[set[str]]=None, with_role=False, quote=False) -> str:
result = self.name
- if self.tags:
+
+ if with_role:
+ node = self.tags.get('n')
+ if node:
+ role = 'relay' if node.startswith('r') else 'npn' if node.startswith('npn') else 'node'
+ self.add_tag('role', role)
+
+ if self.tags or tags:
if not tags:
tags = self.tags
- result += '{' + ','.join([f'{k}={v}' for k, v in sorted(self.tags.items()) if k in tags]) + '}'
+ esc = '"' if quote else ''
+ result += '{' + ','.join([f'{k}={esc}{v}{esc}' for k, v in sorted(self.tags.items()) if k in tags]) + '}'
return result
def add_tag(self, key: str, value: str):
@@ -231,6 +245,7 @@ def parse_metrics(
out = {}
try:
last_type = None
+ last_desc = None
for line in fin:
if not line:
continue
@@ -244,6 +259,8 @@ def parse_metrics(
last_type = MetricType.GAUGE
elif tpe == 'counter':
last_type = MetricType.COUNTER
+ elif line.startswith('# HELP'):
+ last_desc = line.split(None, 3)[-1] # skip first 3 words (#, HELP, metric name)
continue
m = metric_line_re.match(line)
if m:
@@ -254,7 +271,7 @@ def parse_metrics(
name = ab[0]
value = num(ab[1])
- metric = Metric(name, last_type, value)
+ metric = Metric(name, last_type, last_desc, value)
metric.add_tag('n', nick)
if not metrics_names or metric.name in metrics_names:
if metric.name not in out:
@@ -267,8 +284,8 @@ def parse_metrics(
if diff and metrics_names and len(metrics_names) == 2 and len(out) == 2:
m = list(out.keys())
name = f'{m[0]}_-_{m[1]}'
- metric = Metric(name, MetricType.GAUGE, out[m[0]].value - out[m[1]].value)
- out = [{name: metric}]
+ metric = Metric(name, MetricType.GAUGE, f'Diff of {m[0]} and {m[1]}', out[m[0]][0].value - out[m[1]][0].value)
+ out = {name: [metric]}
return out
diff --git a/test/reflectionhelpers/helpers.go b/test/reflectionhelpers/helpers.go
index de11d3c9e9..d3a7122042 100644
--- a/test/reflectionhelpers/helpers.go
+++ b/test/reflectionhelpers/helpers.go
@@ -19,9 +19,8 @@ package reflectionhelpers
import (
"fmt"
"reflect"
+ "slices"
"strings"
-
- "golang.org/x/exp/slices"
)
// TypeSegmentKind is a enum for the types of TypeSegment
diff --git a/test/testdata/configs/config-v34.json b/test/testdata/configs/config-v34.json
index 8e93d95e28..db4420ed9d 100644
--- a/test/testdata/configs/config-v34.json
+++ b/test/testdata/configs/config-v34.json
@@ -57,7 +57,6 @@
"EnableP2P": false,
"EnableP2PHybridMode": false,
"EnablePingHandler": true,
- "EnablePrivateNetworkAccessHeader": false,
"EnableProcessBlockStats": false,
"EnableProfiler": false,
"EnableRequestLogger": false,
diff --git a/test/testdata/configs/config-v35.json b/test/testdata/configs/config-v35.json
new file mode 100644
index 0000000000..1e7937d455
--- /dev/null
+++ b/test/testdata/configs/config-v35.json
@@ -0,0 +1,146 @@
+{
+ "Version": 35,
+ "AccountUpdatesStatsInterval": 5000000000,
+ "AccountsRebuildSynchronousMode": 1,
+ "AgreementIncomingBundlesQueueLength": 15,
+ "AgreementIncomingProposalsQueueLength": 50,
+ "AgreementIncomingVotesQueueLength": 20000,
+ "AnnounceParticipationKey": true,
+ "Archival": false,
+ "BaseLoggerDebugLevel": 4,
+ "BlockDBDir": "",
+ "BlockServiceCustomFallbackEndpoints": "",
+ "BlockServiceMemCap": 500000000,
+ "BroadcastConnectionsLimit": -1,
+ "CadaverDirectory": "",
+ "CadaverSizeTarget": 0,
+ "CatchpointDir": "",
+ "CatchpointFileHistoryLength": 365,
+ "CatchpointInterval": 10000,
+ "CatchpointTracking": 0,
+ "CatchupBlockDownloadRetryAttempts": 1000,
+ "CatchupBlockValidateMode": 0,
+ "CatchupFailurePeerRefreshRate": 10,
+ "CatchupGossipBlockFetchTimeoutSec": 4,
+ "CatchupHTTPBlockFetchTimeoutSec": 4,
+ "CatchupLedgerDownloadRetryAttempts": 50,
+ "CatchupParallelBlocks": 16,
+ "ColdDataDir": "",
+ "ConnectionsRateLimitingCount": 60,
+ "ConnectionsRateLimitingWindowSeconds": 1,
+ "CrashDBDir": "",
+ "DNSBootstrapID": ".algorand.network?backup=.algorand.net&dedup=.algorand-.(network|net)",
+ "DNSSecurityFlags": 9,
+ "DeadlockDetection": 0,
+ "DeadlockDetectionThreshold": 30,
+ "DisableAPIAuth": false,
+ "DisableLedgerLRUCache": false,
+ "DisableLocalhostConnectionRateLimit": true,
+ "DisableNetworking": false,
+ "DisableOutgoingConnectionThrottling": false,
+ "EnableAccountUpdatesStats": false,
+ "EnableAgreementReporting": false,
+ "EnableAgreementTimeMetrics": false,
+ "EnableAssembleStats": false,
+ "EnableBlockService": false,
+ "EnableDHTProviders": false,
+ "EnableDeveloperAPI": false,
+ "EnableExperimentalAPI": false,
+ "EnableFollowMode": false,
+ "EnableGossipBlockService": true,
+ "EnableGossipService": true,
+ "EnableIncomingMessageFilter": false,
+ "EnableLedgerService": false,
+ "EnableMetricReporting": false,
+ "EnableNetDevMetrics": false,
+ "EnableOutgoingNetworkMessageFiltering": true,
+ "EnableP2P": false,
+ "EnableP2PHybridMode": false,
+ "EnablePingHandler": true,
+ "EnablePrivateNetworkAccessHeader": false,
+ "EnableProcessBlockStats": false,
+ "EnableProfiler": false,
+ "EnableRequestLogger": false,
+ "EnableRuntimeMetrics": false,
+ "EnableTopAccountsReporting": false,
+ "EnableTxBacklogAppRateLimiting": true,
+ "EnableTxBacklogRateLimiting": true,
+ "EnableTxnEvalTracer": false,
+ "EnableUsageLog": false,
+ "EnableVerbosedTransactionSyncLogging": false,
+ "EndpointAddress": "127.0.0.1:0",
+ "FallbackDNSResolverAddress": "",
+ "ForceFetchTransactions": false,
+ "ForceRelayMessages": false,
+ "GoMemLimit": 0,
+ "GossipFanout": 4,
+ "HeartbeatUpdateInterval": 600,
+ "HotDataDir": "",
+ "IncomingConnectionsLimit": 2400,
+ "IncomingMessageFilterBucketCount": 5,
+ "IncomingMessageFilterBucketSize": 512,
+ "LedgerSynchronousMode": 2,
+ "LogArchiveDir": "",
+ "LogArchiveMaxAge": "",
+ "LogArchiveName": "node.archive.log",
+ "LogFileDir": "",
+ "LogSizeLimit": 1073741824,
+ "MaxAPIBoxPerApplication": 100000,
+ "MaxAPIResourcesPerAccount": 100000,
+ "MaxAcctLookback": 4,
+ "MaxBlockHistoryLookback": 0,
+ "MaxCatchpointDownloadDuration": 43200000000000,
+ "MaxConnectionsPerIP": 8,
+ "MinCatchpointFileDownloadBytesPerSecond": 20480,
+ "NetAddress": "",
+ "NetworkMessageTraceServer": "",
+ "NetworkProtocolVersion": "",
+ "NodeExporterListenAddress": ":9100",
+ "NodeExporterPath": "./node_exporter",
+ "OptimizeAccountsDatabaseOnStartup": false,
+ "OutgoingMessageFilterBucketCount": 3,
+ "OutgoingMessageFilterBucketSize": 128,
+ "P2PHybridIncomingConnectionsLimit": 1200,
+ "P2PHybridNetAddress": "",
+ "P2PPersistPeerID": false,
+ "P2PPrivateKeyLocation": "",
+ "ParticipationKeysRefreshInterval": 60000000000,
+ "PeerConnectionsUpdateInterval": 3600,
+ "PeerPingPeriodSeconds": 0,
+ "PriorityPeers": {},
+ "ProposalAssemblyTime": 500000000,
+ "PublicAddress": "",
+ "ReconnectTime": 60000000000,
+ "ReservedFDs": 256,
+ "RestConnectionsHardLimit": 2048,
+ "RestConnectionsSoftLimit": 1024,
+ "RestReadTimeoutSeconds": 15,
+ "RestWriteTimeoutSeconds": 120,
+ "RunHosted": false,
+ "StateproofDir": "",
+ "StorageEngine": "sqlite",
+ "SuggestedFeeBlockHistory": 3,
+ "SuggestedFeeSlidingWindowSize": 50,
+ "TLSCertFile": "",
+ "TLSKeyFile": "",
+ "TelemetryToLog": true,
+ "TrackerDBDir": "",
+ "TransactionSyncDataExchangeRate": 0,
+ "TransactionSyncSignificantMessageThreshold": 0,
+ "TxBacklogAppRateLimitingCountERLDrops": false,
+ "TxBacklogAppTxPerSecondRate": 100,
+ "TxBacklogAppTxRateLimiterMaxSize": 1048576,
+ "TxBacklogRateLimitingCongestionPct": 50,
+ "TxBacklogReservedCapacityPerPeer": 20,
+ "TxBacklogServiceRateWindowSeconds": 10,
+ "TxBacklogSize": 26000,
+ "TxIncomingFilterMaxSize": 500000,
+ "TxIncomingFilteringFlags": 1,
+ "TxPoolExponentialIncreaseFactor": 2,
+ "TxPoolSize": 75000,
+ "TxSyncIntervalSeconds": 60,
+ "TxSyncServeResponseSize": 1000000,
+ "TxSyncTimeoutSeconds": 30,
+ "UseXForwardedForAddressField": "",
+ "VerifiedTranscationsCacheSize": 150000
+}
diff --git a/test/testdata/nettemplates/TwoNodes50EachV18.json b/test/testdata/nettemplates/TwoNodes50EachV18.json
new file mode 100644
index 0000000000..198a4f0f99
--- /dev/null
+++ b/test/testdata/nettemplates/TwoNodes50EachV18.json
@@ -0,0 +1,36 @@
+{
+ "Genesis": {
+ "NetworkName": "tbd",
+ "ConsensusProtocol": "https://github.com/algorandfoundation/specs/tree/6c6bd668be0ab14098e51b37e806c509f7b7e31f",
+ "LastPartKeyRound": 3000,
+ "Wallets": [
+ {
+ "Name": "Wallet1",
+ "Stake": 50,
+ "Online": true
+ },
+ {
+ "Name": "Wallet2",
+ "Stake": 50,
+ "Online": true
+ }
+ ]
+ },
+ "Nodes": [
+ {
+ "Name": "Primary",
+ "IsRelay": true,
+ "Wallets": [
+ { "Name": "Wallet1",
+ "ParticipationOnly": false }
+ ]
+ },
+ {
+ "Name": "Node",
+ "Wallets": [
+ { "Name": "Wallet2",
+ "ParticipationOnly": false }
+ ]
+ }
+ ]
+}
diff --git a/tools/block-generator/go.mod b/tools/block-generator/go.mod
index 352794ad6f..e0a4101d05 100644
--- a/tools/block-generator/go.mod
+++ b/tools/block-generator/go.mod
@@ -2,15 +2,15 @@ module github.com/algorand/go-algorand/tools/block-generator
replace github.com/algorand/go-algorand => ../..
-go 1.21
+go 1.23
-toolchain go1.21.10
+toolchain go1.23.3
require (
github.com/algorand/avm-abi v0.2.0
github.com/algorand/go-algorand v0.0.0
github.com/algorand/go-codec/codec v1.1.10
- github.com/algorand/go-deadlock v0.2.3
+ github.com/algorand/go-deadlock v0.2.4
github.com/lib/pq v1.10.9
github.com/spf13/cobra v1.7.0
github.com/stretchr/testify v1.9.0
@@ -57,7 +57,7 @@ require (
github.com/golang/snappy v0.0.4 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gopacket v1.1.19 // indirect
- github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect
+ github.com/google/pprof v0.0.0-20241017200806-017d972448fc // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
@@ -67,10 +67,9 @@ require (
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/huin/goupnp v1.3.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
- github.com/ipfs/boxo v0.21.0 // indirect
+ github.com/ipfs/boxo v0.24.3 // indirect
github.com/ipfs/go-cid v0.4.1 // indirect
github.com/ipfs/go-datastore v0.6.0 // indirect
- github.com/ipfs/go-log v1.0.5 // indirect
github.com/ipfs/go-log/v2 v2.5.1 // indirect
github.com/ipld/go-ipld-prime v0.21.0 // indirect
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
@@ -80,18 +79,18 @@ require (
github.com/josharian/intern v1.0.0 // indirect
github.com/josharian/native v1.1.0 // indirect
github.com/jsimonetti/rtnetlink v1.4.2 // indirect
- github.com/klauspost/compress v1.17.9 // indirect
+ github.com/klauspost/compress v1.17.11 // indirect
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
github.com/koron/go-ssdp v0.0.4 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/libp2p/go-cidranger v1.1.0 // indirect
- github.com/libp2p/go-flow-metrics v0.1.0 // indirect
- github.com/libp2p/go-libp2p v0.36.2 // indirect
+ github.com/libp2p/go-flow-metrics v0.2.0 // indirect
+ github.com/libp2p/go-libp2p v0.37.0 // indirect
github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect
- github.com/libp2p/go-libp2p-kad-dht v0.26.1 // indirect
- github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect
+ github.com/libp2p/go-libp2p-kad-dht v0.28.0 // indirect
+ github.com/libp2p/go-libp2p-kbucket v0.6.4 // indirect
github.com/libp2p/go-libp2p-pubsub v0.12.0 // indirect
github.com/libp2p/go-libp2p-record v0.2.0 // indirect
github.com/libp2p/go-libp2p-routing-helpers v0.7.4 // indirect
@@ -115,7 +114,7 @@ require (
github.com/multiformats/go-base32 v0.1.0 // indirect
github.com/multiformats/go-base36 v0.2.0 // indirect
github.com/multiformats/go-multiaddr v0.13.0 // indirect
- github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect
+ github.com/multiformats/go-multiaddr-dns v0.4.0 // indirect
github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect
github.com/multiformats/go-multibase v0.2.0 // indirect
github.com/multiformats/go-multicodec v0.9.0 // indirect
@@ -124,15 +123,14 @@ require (
github.com/multiformats/go-varint v0.0.7 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/olivere/elastic v6.2.14+incompatible // indirect
- github.com/onsi/ginkgo/v2 v2.20.0 // indirect
+ github.com/onsi/ginkgo/v2 v2.20.2 // indirect
github.com/opencontainers/runtime-spec v1.2.0 // indirect
- github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
- github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
- github.com/pion/datachannel v1.5.8 // indirect
+ github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274 // indirect
+ github.com/pion/datachannel v1.5.9 // indirect
github.com/pion/dtls/v2 v2.2.12 // indirect
- github.com/pion/ice/v2 v2.3.34 // indirect
- github.com/pion/interceptor v0.1.30 // indirect
+ github.com/pion/ice/v2 v2.3.36 // indirect
+ github.com/pion/interceptor v0.1.37 // indirect
github.com/pion/logging v0.2.2 // indirect
github.com/pion/mdns v0.0.12 // indirect
github.com/pion/randutil v0.1.0 // indirect
@@ -144,43 +142,43 @@ require (
github.com/pion/stun v0.6.1 // indirect
github.com/pion/transport/v2 v2.2.10 // indirect
github.com/pion/turn/v2 v2.1.6 // indirect
- github.com/pion/webrtc/v3 v3.3.0 // indirect
+ github.com/pion/webrtc/v3 v3.3.4 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/polydawn/refmt v0.89.0 // indirect
- github.com/prometheus/client_golang v1.20.0 // indirect
+ github.com/prometheus/client_golang v1.20.5 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
- github.com/prometheus/common v0.55.0 // indirect
+ github.com/prometheus/common v0.60.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
- github.com/quic-go/qpack v0.4.0 // indirect
- github.com/quic-go/quic-go v0.46.0 // indirect
- github.com/quic-go/webtransport-go v0.8.0 // indirect
+ github.com/quic-go/qpack v0.5.1 // indirect
+ github.com/quic-go/quic-go v0.48.1 // indirect
+ github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 // indirect
github.com/raulk/go-watchdog v1.3.0 // indirect
github.com/rogpeppe/go-internal v1.10.0 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect
- github.com/wlynxg/anet v0.0.4 // indirect
+ github.com/wlynxg/anet v0.0.5 // indirect
go.opencensus.io v0.24.0 // indirect
- go.opentelemetry.io/otel v1.27.0 // indirect
- go.opentelemetry.io/otel/metric v1.27.0 // indirect
- go.opentelemetry.io/otel/trace v1.27.0 // indirect
+ go.opentelemetry.io/otel v1.31.0 // indirect
+ go.opentelemetry.io/otel/metric v1.31.0 // indirect
+ go.opentelemetry.io/otel/trace v1.31.0 // indirect
go.uber.org/dig v1.18.0 // indirect
- go.uber.org/fx v1.22.2 // indirect
- go.uber.org/mock v0.4.0 // indirect
+ go.uber.org/fx v1.23.0 // indirect
+ go.uber.org/mock v0.5.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
- golang.org/x/crypto v0.26.0 // indirect
- golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect
- golang.org/x/mod v0.20.0 // indirect
- golang.org/x/net v0.28.0 // indirect
- golang.org/x/sync v0.8.0 // indirect
- golang.org/x/sys v0.24.0 // indirect
- golang.org/x/text v0.17.0 // indirect
- golang.org/x/tools v0.24.0 // indirect
+ golang.org/x/crypto v0.29.0 // indirect
+ golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect
+ golang.org/x/mod v0.22.0 // indirect
+ golang.org/x/net v0.31.0 // indirect
+ golang.org/x/sync v0.9.0 // indirect
+ golang.org/x/sys v0.27.0 // indirect
+ golang.org/x/text v0.20.0 // indirect
+ golang.org/x/tools v0.27.0 // indirect
gonum.org/v1/gonum v0.15.0 // indirect
- google.golang.org/protobuf v1.34.2 // indirect
+ google.golang.org/protobuf v1.35.1 // indirect
gopkg.in/sohlich/elogrus.v3 v3.0.0-20180410122755-1fa29e2f2009 // indirect
lukechampine.com/blake3 v1.3.0 // indirect
rsc.io/tmplfunc v0.0.3 // indirect
diff --git a/tools/block-generator/go.sum b/tools/block-generator/go.sum
index c63c41b468..19c67b5d26 100644
--- a/tools/block-generator/go.sum
+++ b/tools/block-generator/go.sum
@@ -23,8 +23,8 @@ github.com/algorand/falcon v0.1.0 h1:xl832kfZ7hHG6B4p90DQynjfKFGbIUgUOnsRiMZXfAo
github.com/algorand/falcon v0.1.0/go.mod h1:OkQyHlGvS0kLNcIWbC21/uQcnbfwSOQm+wiqWwBG9pQ=
github.com/algorand/go-codec/codec v1.1.10 h1:zmWYU1cp64jQVTOG8Tw8wa+k0VfwgXIPbnDfiVa+5QA=
github.com/algorand/go-codec/codec v1.1.10/go.mod h1:YkEx5nmr/zuCeaDYOIhlDg92Lxju8tj2d2NrYqP7g7k=
-github.com/algorand/go-deadlock v0.2.3 h1:ek9rjUyUF1HhUm0I2DyaCN8+3S850ONJNl5jQr9kZOA=
-github.com/algorand/go-deadlock v0.2.3/go.mod h1:Gli2d0Cb7kgXzSpJLC4Vn0DCLgjNVi6fNldY/mOtO/U=
+github.com/algorand/go-deadlock v0.2.4 h1:UMs6GwE2wHC6BUZo5z32/+SrBey1LQjbkZQ3V7DoGVA=
+github.com/algorand/go-deadlock v0.2.4/go.mod h1:tewhAviZpVq2cnGHmfT50l6RwWLnuygnfNntCN2fz0M=
github.com/algorand/go-sumhash v0.1.0 h1:b/QRhyLuF//vOcicBIxBXYW8bERNoeLxieht/dUYpVg=
github.com/algorand/go-sumhash v0.1.0/go.mod h1:OOe7jdDWUhLkuP1XytkK5gnLu9entAviN5DfDZh6XAc=
github.com/algorand/msgp v1.1.60 h1:+IVUC34+tSj1P2M1mkYtl4GLyfzdzXfBLSw6TDT19M8=
@@ -208,9 +208,8 @@ github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
-github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k=
-github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
-github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/pprof v0.0.0-20241017200806-017d972448fc h1:NGyrhhFhwvRAZg02jnYVg3GBQy0qGBKmFQJwaPmpmxs=
+github.com/google/pprof v0.0.0-20241017200806-017d972448fc/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -247,8 +246,10 @@ github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/C
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
-github.com/ipfs/boxo v0.21.0 h1:XpGXb+TQQ0IUdYaeAxGzWjSs6ow/Lce148A/2IbRDVE=
-github.com/ipfs/boxo v0.21.0/go.mod h1:NmweAYeY1USOaJJxouy7DLr/Y5M8UBSsCI2KRivO+TY=
+github.com/ipfs/boxo v0.24.3 h1:gldDPOWdM3Rz0v5LkVLtZu7A7gFNvAlWcmxhCqlHR3c=
+github.com/ipfs/boxo v0.24.3/go.mod h1:h0DRzOY1IBFDHp6KNvrJLMFdSXTYID0Zf+q7X05JsNg=
+github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs=
+github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM=
github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s=
github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk=
github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk=
@@ -259,9 +260,10 @@ github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCm
github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs=
github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8=
github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo=
-github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g=
github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY=
github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI=
+github.com/ipfs/go-test v0.0.4 h1:DKT66T6GBB6PsDFLoO56QZPrOmzJkqU1FZH5C9ySkew=
+github.com/ipfs/go-test v0.0.4/go.mod h1:qhIM1EluEfElKKM6fnWxGn822/z9knUGM1+I/OAQNKI=
github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E=
github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ=
github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI=
@@ -301,8 +303,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
-github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
-github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
+github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
@@ -327,16 +329,16 @@ github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c=
github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic=
-github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM=
-github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro=
-github.com/libp2p/go-libp2p v0.36.2 h1:BbqRkDaGC3/5xfaJakLV/BrpjlAuYqSB0lRvtzL3B/U=
-github.com/libp2p/go-libp2p v0.36.2/go.mod h1:XO3joasRE4Eup8yCTTP/+kX+g92mOgRaadk46LmPhHY=
+github.com/libp2p/go-flow-metrics v0.2.0 h1:EIZzjmeOE6c8Dav0sNv35vhZxATIXWZg6j/C08XmmDw=
+github.com/libp2p/go-flow-metrics v0.2.0/go.mod h1:st3qqfu8+pMfh+9Mzqb2GTiwrAGjIPszEjZmtksN8Jc=
+github.com/libp2p/go-libp2p v0.37.0 h1:8K3mcZgwTldydMCNOiNi/ZJrOB9BY+GlI3UxYzxBi9A=
+github.com/libp2p/go-libp2p v0.37.0/go.mod h1:GOKmSN99scDuYGTwaTbQPR8Nt6dxrK3ue7OjW2NGDg4=
github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94=
github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8=
-github.com/libp2p/go-libp2p-kad-dht v0.26.1 h1:AazV3LCImYVkDUGAHx5lIEgZ9iUI2QQKH5GMRQU8uEA=
-github.com/libp2p/go-libp2p-kad-dht v0.26.1/go.mod h1:mqRUGJ/+7ziQ3XknU2kKHfsbbgb9xL65DXjPOJwmZF8=
-github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0=
-github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0=
+github.com/libp2p/go-libp2p-kad-dht v0.28.0 h1:sDqfW784w7CZQLlnMUwfeqWfXcpedKeZIM/B9/w0Tbk=
+github.com/libp2p/go-libp2p-kad-dht v0.28.0/go.mod h1:0wHURlSFdAC42+wF7GEmpLoARw8JuS8do2guCtc/Y/w=
+github.com/libp2p/go-libp2p-kbucket v0.6.4 h1:OjfiYxU42TKQSB8t8WYd8MKhYhMJeO2If+NiuKfb6iQ=
+github.com/libp2p/go-libp2p-kbucket v0.6.4/go.mod h1:jp6w82sczYaBsAypt5ayACcRJi0lgsba7o4TzJKEfWA=
github.com/libp2p/go-libp2p-pubsub v0.12.0 h1:PENNZjSfk8KYxANRlpipdS7+BfLmOl3L2E/6vSNjbdI=
github.com/libp2p/go-libp2p-pubsub v0.12.0/go.mod h1:Oi0zw9aw8/Y5GC99zt+Ef2gYAl+0nZlwdJonDyOz/sE=
github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0=
@@ -381,7 +383,6 @@ github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.
github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ=
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
-github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8=
@@ -410,11 +411,10 @@ github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYg
github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4=
github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo=
-github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4=
github.com/multiformats/go-multiaddr v0.13.0 h1:BCBzs61E3AGHcYYTv8dqRH43ZfyrqM8RXVPT8t13tLQ=
github.com/multiformats/go-multiaddr v0.13.0/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII=
-github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A=
-github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk=
+github.com/multiformats/go-multiaddr-dns v0.4.0 h1:P76EJ3qzBXpUXZ3twdCDx/kvagMsNo0LMFXpyms/zgU=
+github.com/multiformats/go-multiaddr-dns v0.4.0/go.mod h1:7hfthtB4E4pQwirrz+J0CcDUfbWzTqEzVyYKKIKpgkc=
github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E=
github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo=
github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g=
@@ -426,7 +426,6 @@ github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7B
github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM=
github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE=
github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dydlEqV3l6N3/GBsX6ILA=
-github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8=
github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
@@ -442,8 +441,8 @@ github.com/olivere/elastic v6.2.14+incompatible/go.mod h1:J+q1zQJTgAz9woqsbVRqGe
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0=
-github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw=
-github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI=
+github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4=
+github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
@@ -457,19 +456,19 @@ github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTm
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0=
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
-github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ=
-github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o=
+github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274 h1:qli3BGQK0tYDkSEvZ/FzZTi9ZrOX86Q6CIhKLGc489A=
+github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
-github.com/pion/datachannel v1.5.8 h1:ph1P1NsGkazkjrvyMfhRBUAWMxugJjq2HfQifaOoSNo=
-github.com/pion/datachannel v1.5.8/go.mod h1:PgmdpoaNBLX9HNzNClmdki4DYW5JtI7Yibu8QzbL3tI=
+github.com/pion/datachannel v1.5.9 h1:LpIWAOYPyDrXtU+BW7X0Yt/vGtYxtXQ8ql7dFfYUVZA=
+github.com/pion/datachannel v1.5.9/go.mod h1:kDUuk4CU4Uxp82NH4LQZbISULkX/HtzKa4P7ldf9izE=
github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk=
github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE=
-github.com/pion/ice/v2 v2.3.34 h1:Ic1ppYCj4tUOcPAp76U6F3fVrlSw8A9JtRXLqw6BbUM=
-github.com/pion/ice/v2 v2.3.34/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ=
-github.com/pion/interceptor v0.1.30 h1:au5rlVHsgmxNi+v/mjOPazbW1SHzfx7/hYOEYQnUcxA=
-github.com/pion/interceptor v0.1.30/go.mod h1:RQuKT5HTdkP2Fi0cuOS5G5WNymTjzXaGF75J4k7z2nc=
+github.com/pion/ice/v2 v2.3.36 h1:SopeXiVbbcooUg2EIR8sq4b13RQ8gzrkkldOVg+bBsc=
+github.com/pion/ice/v2 v2.3.36/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ=
+github.com/pion/interceptor v0.1.37 h1:aRA8Zpab/wE7/c0O3fh1PqY0AJI3fCSEM5lRWJVorwI=
+github.com/pion/interceptor v0.1.37/go.mod h1:JzxbJ4umVTlZAf+/utHzNesY8tmRkM2lVmkS82TTj8Y=
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8=
@@ -501,8 +500,8 @@ github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uP
github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc=
github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
-github.com/pion/webrtc/v3 v3.3.0 h1:Rf4u6n6U5t5sUxhYPQk/samzU/oDv7jk6BA5hyO2F9I=
-github.com/pion/webrtc/v3 v3.3.0/go.mod h1:hVmrDJvwhEertRWObeb1xzulzHGeVUoPlWvxdGzcfU0=
+github.com/pion/webrtc/v3 v3.3.4 h1:v2heQVnXTSqNRXcaFQVOhIOYkLMxOu1iJG8uy1djvkk=
+github.com/pion/webrtc/v3 v3.3.4/go.mod h1:liNa+E1iwyzyXqNUwvoMRNQ10x8h8FOeJKL8RkIbamE=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -512,27 +511,26 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4=
github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw=
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
-github.com/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI=
-github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
+github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
+github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
-github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
-github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
+github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA=
+github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw=
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
-github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
-github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
-github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y=
-github.com/quic-go/quic-go v0.46.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI=
-github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg=
-github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM=
+github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
+github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
+github.com/quic-go/quic-go v0.48.1 h1:y/8xmfWI9qmGTc+lBr4jKRUWLGSlSigv847ULJ4hYXA=
+github.com/quic-go/quic-go v0.48.1/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs=
+github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 h1:4WFk6u3sOT6pLa1kQ50ZVdm8BQFgJNA117cepZxtLIg=
+github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66/go.mod h1:Vp72IJajgeOL6ddqrAhmp7IM9zbTcgkQxD/YdxrVwMw=
github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk=
github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU=
-github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
@@ -623,8 +621,8 @@ github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvS
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k=
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc=
github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
-github.com/wlynxg/anet v0.0.4 h1:0de1OFQxnNqAu+x2FAKKCVIrnfGKQbs7FQz++tB0+Uw=
-github.com/wlynxg/anet v0.0.4/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
+github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU=
+github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
@@ -641,29 +639,25 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
-go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg=
-go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ=
-go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik=
-go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak=
-go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw=
-go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4=
-go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY=
+go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE=
+go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE=
+go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY=
+go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys=
+go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw=
go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
-go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw=
-go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU=
+go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg=
+go.uber.org/fx v1.23.0/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU=
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
-go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
-go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
-go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
+go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
+go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
-go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
-go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
@@ -673,7 +667,6 @@ golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -684,18 +677,17 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
-golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
-golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
+golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
+golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI=
-golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
+golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=
+golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@@ -703,8 +695,8 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
-golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
+golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -735,8 +727,8 @@ golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
-golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
-golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
+golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
+golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -752,8 +744,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
-golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
+golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -775,7 +767,6 @@ golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -791,8 +782,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
-golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
+golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -810,8 +801,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
-golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
-golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
+golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
+golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
@@ -827,9 +818,6 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3
golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@@ -838,8 +826,8 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
-golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
-golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
+golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o=
+golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -880,14 +868,13 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
-google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
-google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
+google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
+google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
-gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
@@ -912,7 +899,6 @@ honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE=
lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
pgregory.net/rapid v0.6.2 h1:ErW5sL+UKtfBfUTsWHDCoeB+eZKLKMxrSd1VJY6W4bw=
diff --git a/tools/x-repo-types/go.mod b/tools/x-repo-types/go.mod
index faeadd4589..094c52ea8c 100644
--- a/tools/x-repo-types/go.mod
+++ b/tools/x-repo-types/go.mod
@@ -1,8 +1,8 @@
module github.com/algorand/go-algorand/tools/x-repo-types
-go 1.21
+go 1.23
-toolchain go1.21.10
+toolchain go1.23.3
replace github.com/algorand/go-algorand => ../..
diff --git a/util/codecs/json_test.go b/util/codecs/json_test.go
index 18745c7f6e..efe34c2f5f 100644
--- a/util/codecs/json_test.go
+++ b/util/codecs/json_test.go
@@ -158,7 +158,6 @@ func TestWriteNonDefaultValue(t *testing.T) {
}
for _, tc := range testcases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
a := require.New(t)
diff --git a/util/db/initialize_test.go b/util/db/initialize_test.go
index c0588d9cba..52405d7bcc 100644
--- a/util/db/initialize_test.go
+++ b/util/db/initialize_test.go
@@ -104,7 +104,6 @@ func TestInitialize(t *testing.T) {
}
for _, testcase := range testcases {
- testcase := testcase
t.Run(testcase.name, func(t *testing.T) {
t.Parallel()
diff --git a/util/execpool/backlog.go b/util/execpool/backlog.go
index c98a2fd427..969587de68 100644
--- a/util/execpool/backlog.go
+++ b/util/execpool/backlog.go
@@ -102,7 +102,7 @@ func (b *backlog) BufferSize() (length, capacity int) {
return len(b.buffer), cap(b.buffer)
}
-// Enqueue enqueues a single task into the backlog
+// EnqueueBacklog enqueues a single task into the backlog
func (b *backlog) EnqueueBacklog(enqueueCtx context.Context, t ExecFunc, arg interface{}, out chan interface{}) error {
select {
case b.buffer <- backlogItemTask{
diff --git a/util/metrics/opencensus.go b/util/metrics/opencensus.go
index fefb1d054b..d61c6206cd 100644
--- a/util/metrics/opencensus.go
+++ b/util/metrics/opencensus.go
@@ -21,11 +21,11 @@ package metrics
import (
"context"
+ "slices"
"strings"
"go.opencensus.io/metric/metricdata"
"go.opencensus.io/metric/metricexport"
- "golang.org/x/exp/slices"
)
type defaultOpencensusGatherer struct {
diff --git a/util/metrics/tagcounter.go b/util/metrics/tagcounter.go
index c2b5fcb9bb..d12f10ead5 100644
--- a/util/metrics/tagcounter.go
+++ b/util/metrics/tagcounter.go
@@ -17,12 +17,12 @@
package metrics
import (
+ "maps"
"strconv"
"strings"
"sync/atomic"
"github.com/algorand/go-deadlock"
- "golang.org/x/exp/maps"
)
// NewTagCounterFiltered makes a set of metrics under rootName for tagged counting.
diff --git a/util/rateLimit.go b/util/rateLimit.go
index 8db9763474..3fea7f8912 100644
--- a/util/rateLimit.go
+++ b/util/rateLimit.go
@@ -170,16 +170,16 @@ func (erl *ElasticRateLimiter) DisableCongestionControl() {
// Returns an error if the capacity could not be vended, which could be:
// - there is not sufficient free capacity to assign a reserved capacity block
// - there is no reserved or shared capacity available for the client
-func (erl *ElasticRateLimiter) ConsumeCapacity(c ErlClient) (*ErlCapacityGuard, error) {
+func (erl *ElasticRateLimiter) ConsumeCapacity(c ErlClient) (*ErlCapacityGuard, bool, error) {
var cg ErlCapacityGuard
var q capacityQueue
var err error
var exists bool
- var enableCM bool
+ var isCMEnabled bool
// get the client's queue
erl.clientLock.RLock()
q, exists = erl.capacityByClient[c]
- enableCM = erl.enableCM
+ isCMEnabled = erl.enableCM
erl.clientLock.RUnlock()
// Step 0: Check for, and create a capacity reservation if needed
@@ -187,14 +187,14 @@ func (erl *ElasticRateLimiter) ConsumeCapacity(c ErlClient) (*ErlCapacityGuard,
if !exists && erl.CapacityPerReservation > 0 {
q, err = erl.openReservation(c)
if err != nil {
- return nil, err
+ return nil, isCMEnabled, err
}
// if the client has been given a new reservation, make sure it cleans up OnClose
c.OnClose(func() { erl.closeReservation(c) })
// if this reservation is newly created, directly (blocking) take a capacity
q.blockingConsume()
- return &ErlCapacityGuard{cq: q, cm: erl.cm}, nil
+ return &ErlCapacityGuard{cq: q, cm: erl.cm}, isCMEnabled, nil
}
// Step 1: Attempt consumption from the reserved queue if one exists
@@ -204,29 +204,29 @@ func (erl *ElasticRateLimiter) ConsumeCapacity(c ErlClient) (*ErlCapacityGuard,
if erl.cm != nil {
erl.cm.Consumed(c, time.Now()) // notify the congestion manager that this client consumed from this queue
}
- return &cg, nil
+ return &cg, isCMEnabled, nil
}
}
// Step 2: Potentially gate shared queue access if the congestion manager disallows it
if erl.cm != nil &&
- enableCM &&
+ isCMEnabled &&
erl.cm.ShouldDrop(c) {
if erl.congestionControlCounter != nil {
erl.congestionControlCounter.Inc(nil)
}
- return nil, errConManDropped
+ return nil, isCMEnabled, errConManDropped
}
// Step 3: Attempt consumption from the shared queue
cg, err = erl.sharedCapacity.consume(erl.cm)
if err != nil {
- return nil, err
+ return nil, isCMEnabled, err
}
if erl.cm != nil {
erl.cm.Consumed(c, time.Now()) // notify the congestion manager that this client consumed from this queue
}
- return &cg, nil
+ return &cg, isCMEnabled, nil
}
// openReservation creates an entry in the ElasticRateLimiter's reservedCapacity map,
diff --git a/util/rateLimit_test.go b/util/rateLimit_test.go
index 2794c9a40a..8888bfcf4c 100644
--- a/util/rateLimit_test.go
+++ b/util/rateLimit_test.go
@@ -53,7 +53,7 @@ func TestElasticRateLimiterCongestionControlled(t *testing.T) {
// give the ERL a congestion controler with well defined behavior for testing
erl.cm = mockCongestionControl{}
- _, err := erl.ConsumeCapacity(client)
+ _, _, err := erl.ConsumeCapacity(client)
// because the ERL gives capacity to a reservation, and then asynchronously drains capacity from the share,
// wait a moment before testing the size of the sharedCapacity
time.Sleep(100 * time.Millisecond)
@@ -62,18 +62,18 @@ func TestElasticRateLimiterCongestionControlled(t *testing.T) {
assert.NoError(t, err)
erl.EnableCongestionControl()
- _, err = erl.ConsumeCapacity(client)
+ _, _, err = erl.ConsumeCapacity(client)
assert.Equal(t, 0, len(erl.capacityByClient[client]))
assert.Equal(t, 1, len(erl.sharedCapacity))
assert.NoError(t, err)
- _, err = erl.ConsumeCapacity(client)
+ _, _, err = erl.ConsumeCapacity(client)
assert.Equal(t, 0, len(erl.capacityByClient[client]))
assert.Equal(t, 1, len(erl.sharedCapacity))
assert.Error(t, err)
erl.DisableCongestionControl()
- _, err = erl.ConsumeCapacity(client)
+ _, _, err = erl.ConsumeCapacity(client)
assert.Equal(t, 0, len(erl.capacityByClient[client]))
assert.Equal(t, 0, len(erl.sharedCapacity))
assert.NoError(t, err)
@@ -85,14 +85,14 @@ func TestReservations(t *testing.T) {
client2 := mockClient("client2")
erl := NewElasticRateLimiter(4, 1, time.Second, nil)
- _, err := erl.ConsumeCapacity(client1)
+ _, _, err := erl.ConsumeCapacity(client1)
// because the ERL gives capacity to a reservation, and then asynchronously drains capacity from the share,
// wait a moment before testing the size of the sharedCapacity
time.Sleep(100 * time.Millisecond)
assert.Equal(t, 1, len(erl.capacityByClient))
assert.NoError(t, err)
- _, err = erl.ConsumeCapacity(client2)
+ _, _, err = erl.ConsumeCapacity(client2)
// because the ERL gives capacity to a reservation, and then asynchronously drains capacity from the share,
// wait a moment before testing the size of the sharedCapacity
time.Sleep(100 * time.Millisecond)
@@ -113,12 +113,12 @@ func TestZeroSizeReservations(t *testing.T) {
client2 := mockClient("client2")
erl := NewElasticRateLimiter(4, 0, time.Second, nil)
- _, err := erl.ConsumeCapacity(client1)
+ _, _, err := erl.ConsumeCapacity(client1)
time.Sleep(100 * time.Millisecond)
assert.Equal(t, 0, len(erl.capacityByClient))
assert.NoError(t, err)
- _, err = erl.ConsumeCapacity(client2)
+ _, _, err = erl.ConsumeCapacity(client2)
time.Sleep(100 * time.Millisecond)
assert.Equal(t, 0, len(erl.capacityByClient))
assert.NoError(t, err)
@@ -134,7 +134,7 @@ func TestConsumeReleaseCapacity(t *testing.T) {
client := mockClient("client")
erl := NewElasticRateLimiter(4, 3, time.Second, nil)
- c1, err := erl.ConsumeCapacity(client)
+ c1, _, err := erl.ConsumeCapacity(client)
// because the ERL gives capacity to a reservation, and then asynchronously drains capacity from the share,
// wait a moment before testing the size of the sharedCapacity
time.Sleep(100 * time.Millisecond)
@@ -142,23 +142,23 @@ func TestConsumeReleaseCapacity(t *testing.T) {
assert.Equal(t, 1, len(erl.sharedCapacity))
assert.NoError(t, err)
- _, err = erl.ConsumeCapacity(client)
+ _, _, err = erl.ConsumeCapacity(client)
assert.Equal(t, 1, len(erl.capacityByClient[client]))
assert.Equal(t, 1, len(erl.sharedCapacity))
assert.NoError(t, err)
- _, err = erl.ConsumeCapacity(client)
+ _, _, err = erl.ConsumeCapacity(client)
assert.Equal(t, 0, len(erl.capacityByClient[client]))
assert.Equal(t, 1, len(erl.sharedCapacity))
assert.NoError(t, err)
// remember this capacity, as it is a shared capacity
- c4, err := erl.ConsumeCapacity(client)
+ c4, _, err := erl.ConsumeCapacity(client)
assert.Equal(t, 0, len(erl.capacityByClient[client]))
assert.Equal(t, 0, len(erl.sharedCapacity))
assert.NoError(t, err)
- _, err = erl.ConsumeCapacity(client)
+ _, _, err = erl.ConsumeCapacity(client)
assert.Equal(t, 0, len(erl.capacityByClient[client]))
assert.Equal(t, 0, len(erl.sharedCapacity))
assert.Error(t, err)