diff --git a/catchup/universalFetcher_test.go b/catchup/universalFetcher_test.go
index bf74c95702..836360139f 100644
--- a/catchup/universalFetcher_test.go
+++ b/catchup/universalFetcher_test.go
@@ -94,7 +94,6 @@ func TestUGetBlockHTTP(t *testing.T) {
blockServiceConfig := config.GetDefaultLocal()
blockServiceConfig.EnableBlockService = true
- blockServiceConfig.EnableBlockServiceFallbackToArchiver = false
net := &httpTestPeerSource{}
ls := rpcs.MakeBlockService(logging.Base(), blockServiceConfig, ledger, net, "test genesisID")
diff --git a/cmd/goal/network.go b/cmd/goal/network.go
index 5c32b68e36..efc7117edb 100644
--- a/cmd/goal/network.go
+++ b/cmd/goal/network.go
@@ -28,6 +28,7 @@ import (
"github.com/algorand/go-algorand/cmd/util/datadir"
"github.com/algorand/go-algorand/config"
+ "github.com/algorand/go-algorand/gen"
"github.com/algorand/go-algorand/netdeploy"
"github.com/algorand/go-algorand/util"
)
@@ -40,11 +41,11 @@ var noImportKeys bool
var noClean bool
var devModeOverride bool
var startOnCreation bool
+var pregenDir string
func init() {
networkCmd.AddCommand(networkCreateCmd)
networkCmd.PersistentFlags().StringVarP(&networkRootDir, "rootdir", "r", "", "Root directory for the private network directories")
- networkCmd.MarkPersistentFlagRequired("rootdir")
networkCreateCmd.Flags().StringVarP(&networkName, "network", "n", "", "Specify the name to use for the private network")
networkCreateCmd.Flags().StringVarP(&networkTemplateFile, "template", "t", "", "Specify the path to the template file for the network")
@@ -52,14 +53,34 @@ func init() {
networkCreateCmd.Flags().BoolVar(&noClean, "noclean", false, "Prevents auto-cleanup on error - for diagnosing problems")
networkCreateCmd.Flags().BoolVar(&devModeOverride, "devMode", false, "Forces the configuration to enable DevMode, returns an error if the template is not compatible with DevMode.")
networkCreateCmd.Flags().BoolVarP(&startOnCreation, "start", "s", false, "Automatically start the network after creating it.")
+ networkCreateCmd.Flags().StringVarP(&pregenDir, "pregendir", "p", "", "Specify the path to the directory with pregenerated genesis.json, root and partkeys to import into the network directory. By default, the genesis.json and keys will be generated on start. This should only be used on private networks.")
+ networkCreateCmd.MarkFlagRequired("rootdir")
+ networkCmd.AddCommand(networkStartCmd)
networkStartCmd.Flags().StringVarP(&startNode, "node", "n", "", "Specify the name of a specific node to start")
+ networkStartCmd.MarkFlagRequired("rootdir")
- networkCmd.AddCommand(networkStartCmd)
networkCmd.AddCommand(networkRestartCmd)
+ networkRestartCmd.MarkFlagRequired("rootdir")
+
networkCmd.AddCommand(networkStopCmd)
+ networkStopCmd.MarkFlagRequired("rootdir")
+
networkCmd.AddCommand(networkStatusCmd)
+ networkStatusCmd.MarkFlagRequired("rootdir")
+
networkCmd.AddCommand(networkDeleteCmd)
+ networkDeleteCmd.MarkFlagRequired("rootdir")
+
+ networkCmd.AddCommand(networkPregenCmd)
+ networkPregenCmd.Flags().StringVarP(&networkTemplateFile, "template", "t", "", "Specify the path to the template file for the network")
+ networkPregenCmd.Flags().StringVarP(&pregenDir, "pregendir", "p", "", "Specify the path to the directory to export genesis.json, root and partkey files. This should only be used on private networks.")
+ networkPregenCmd.MarkFlagRequired("pregendir")
+ // Hide rootdir flag as it is unused and will error if used with this command.
+ networkPregenCmd.SetHelpFunc(func(command *cobra.Command, strings []string) {
+ _ = command.Flags().MarkHidden("rootdir")
+ command.Parent().HelpFunc()(command, strings)
+ })
}
var networkCmd = &cobra.Command{
@@ -112,6 +133,18 @@ var networkCreateCmd = &cobra.Command{
reportErrorf(infoNetworkAlreadyExists, networkRootDir)
}
+ // If pregendir is specified, copy files over
+ if pregenDir != "" {
+ pregenDir, err = filepath.Abs(pregenDir)
+ if err != nil {
+ panic(err)
+ }
+ err = util.CopyFolder(pregenDir, networkRootDir)
+ if err != nil {
+ panic(err)
+ }
+ }
+
binDir, err := util.ExeDir()
if err != nil {
panic(err)
@@ -246,3 +279,64 @@ var networkDeleteCmd = &cobra.Command{
reportInfof(infoNetworkDeleted, networkRootDir)
},
}
+
+var networkPregenCmd = &cobra.Command{
+ Use: "pregen",
+ Short: "Pregenerates the genesis.json, root and participation keys for a wallet",
+ Args: validateNoPosArgsFn,
+ Run: func(cmd *cobra.Command, _ []string) {
+ var err error
+ if networkRootDir != "" {
+ reportErrorf("This command does not take a network directory as an argument. Use --pregendir flag instead.")
+ }
+
+ pregenDir, err = filepath.Abs(pregenDir)
+ if err != nil {
+ panic(err)
+ }
+
+ var templateReader io.Reader
+
+ if networkTemplateFile == "" {
+ templateReader = strings.NewReader(defaultNetworkTemplate)
+ } else {
+ networkTemplateFile, err = filepath.Abs(networkTemplateFile)
+ if err != nil {
+ panic(err)
+ }
+ file, osErr := os.Open(networkTemplateFile)
+ if osErr != nil {
+ reportErrorf(errorCreateNetwork, osErr)
+ }
+
+ defer file.Close()
+ templateReader = file
+ }
+
+ // Make sure target directory does not exist or is empty
+ if util.FileExists(pregenDir) && !util.IsEmpty(pregenDir) {
+ reportErrorf(infoNetworkAlreadyExists, pregenDir)
+ }
+
+ var template netdeploy.NetworkTemplate
+ err = netdeploy.LoadTemplateFromReader(templateReader, &template)
+ if err != nil {
+ reportErrorf("Error in loading template: %v\n", err)
+ }
+
+ dataDir := datadir.MaybeSingleDataDir()
+ var consensus config.ConsensusProtocols
+ if dataDir != "" {
+ // try to load the consensus from there. If there is none, we can just use the built in one.
+ consensus, _ = config.PreloadConfigurableConsensusProtocols(dataDir)
+ }
+ if err = template.Validate(); err != nil {
+ reportErrorf("Error in template validation: %v\n", err)
+ }
+
+ err = gen.GenerateGenesisFiles(template.Genesis, config.Consensus.Merge(consensus), pregenDir, os.Stdout)
+ if err != nil {
+ reportErrorf("Cannot write genesis files: %s", err)
+ }
+ },
+}
diff --git a/config/config.go b/config/config.go
index fc2dd30050..ad363f3644 100644
--- a/config/config.go
+++ b/config/config.go
@@ -89,6 +89,21 @@ const MaxGenesisIDLen = 128
// MaxEvalDeltaTotalLogSize is the maximum size of the sum of all log sizes in a single eval delta.
const MaxEvalDeltaTotalLogSize = 1024
+// CatchpointTrackingModeUntracked defines the CatchpointTracking mode that does _not_ track catchpoints
+const CatchpointTrackingModeUntracked = -1
+
+// CatchpointTrackingModeAutomatic defines the CatchpointTracking mode that automatically determines catchpoint tracking
+// and storage based on the Archival property and CatchpointInterval.
+const CatchpointTrackingModeAutomatic = 0
+
+// CatchpointTrackingModeTracked defines the CatchpointTracking mode that tracks catchpoint
+// as long as CatchpointInterval > 0
+const CatchpointTrackingModeTracked = 1
+
+// CatchpointTrackingModeStored defines the CatchpointTracking mode that tracks and stores catchpoints
+// as long as CatchpointInterval > 0
+const CatchpointTrackingModeStored = 2
+
// LoadConfigFromDisk returns a Local config structure based on merging the defaults
// with settings loaded from the config file from the custom dir. If the custom file
// cannot be loaded, the default config is returned (with the error from loading the
diff --git a/config/config_test.go b/config/config_test.go
index c88b53834e..87b4cc4d43 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -803,3 +803,129 @@ func TestResolveLogPaths(t *testing.T) {
require.Equal(t, "mycoolLogDir/node.log", log)
require.Equal(t, "myCoolLogArchive/node.archive.log", archive)
}
+
+func TestStoresCatchpoints(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ var tests = []struct {
+ name string
+ catchpointTracking int64
+ catchpointInterval uint64
+ archival bool
+ expected bool
+ }{
+ {
+ name: "-1 w/ no catchpoint interval expects false",
+ catchpointTracking: CatchpointTrackingModeUntracked,
+ catchpointInterval: 0,
+ expected: false,
+ },
+ {
+ name: "-1 expects false",
+ catchpointTracking: CatchpointTrackingModeUntracked,
+ catchpointInterval: GetDefaultLocal().CatchpointInterval,
+ archival: GetDefaultLocal().Archival,
+ expected: false,
+ },
+ {
+ name: "0 expects false",
+ catchpointTracking: CatchpointTrackingModeAutomatic,
+ catchpointInterval: GetDefaultLocal().CatchpointInterval,
+ archival: GetDefaultLocal().Archival,
+ expected: false,
+ },
+ {
+ name: "0 w/ archival expects true",
+ catchpointTracking: CatchpointTrackingModeAutomatic,
+ catchpointInterval: GetDefaultLocal().CatchpointInterval,
+ archival: true,
+ expected: true,
+ },
+ {
+ name: "0 w/ archival & catchpointInterval=0 expects false",
+ catchpointTracking: CatchpointTrackingModeAutomatic,
+ catchpointInterval: 0,
+ archival: true,
+ expected: false,
+ },
+ {
+ name: "1 expects false",
+ catchpointTracking: CatchpointTrackingModeTracked,
+ catchpointInterval: GetDefaultLocal().CatchpointInterval,
+ archival: GetDefaultLocal().Archival,
+ expected: false,
+ },
+ {
+ name: "1 w/ archival expects true",
+ catchpointTracking: CatchpointTrackingModeTracked,
+ catchpointInterval: GetDefaultLocal().CatchpointInterval,
+ archival: true,
+ expected: true,
+ },
+ {
+ name: "1 w/ archival & catchpointInterval=0 expects false",
+ catchpointTracking: CatchpointTrackingModeTracked,
+ catchpointInterval: 0,
+ archival: true,
+ expected: false,
+ },
+ {
+ name: "2 w/ catchpointInterval=0 expects false",
+ catchpointTracking: CatchpointTrackingModeStored,
+ catchpointInterval: 0,
+ archival: GetDefaultLocal().Archival,
+ expected: false,
+ },
+ {
+ name: "2 expects true",
+ catchpointTracking: CatchpointTrackingModeStored,
+ catchpointInterval: GetDefaultLocal().CatchpointInterval,
+ archival: GetDefaultLocal().Archival,
+ expected: true,
+ },
+ {
+ name: "99 expects false",
+ catchpointTracking: 99,
+ catchpointInterval: GetDefaultLocal().CatchpointInterval,
+ archival: GetDefaultLocal().Archival,
+ expected: false,
+ },
+ {
+ name: "99 w/ catchpointInterval=0 expects false",
+ catchpointTracking: 99,
+ catchpointInterval: 0,
+ archival: GetDefaultLocal().Archival,
+ expected: false,
+ },
+ {
+ name: "27 expects false",
+ catchpointTracking: 27,
+ catchpointInterval: GetDefaultLocal().CatchpointInterval,
+ archival: GetDefaultLocal().Archival,
+ expected: false,
+ },
+ }
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ cfg := GetDefaultLocal()
+ cfg.CatchpointTracking = test.catchpointTracking
+ cfg.CatchpointInterval = test.catchpointInterval
+ cfg.Archival = test.archival
+ require.Equal(t, test.expected, cfg.StoresCatchpoints())
+ if cfg.StoresCatchpoints() {
+ require.Equal(t, true, cfg.TracksCatchpoints())
+ }
+ })
+ }
+}
+
+func TestTracksCatchpointsWithoutStoring(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ cfg := GetDefaultLocal()
+ cfg.CatchpointTracking = CatchpointTrackingModeTracked
+ cfg.CatchpointInterval = 10000
+ cfg.Archival = false
+ require.Equal(t, true, cfg.TracksCatchpoints())
+ require.Equal(t, false, cfg.StoresCatchpoints())
+}
diff --git a/config/localTemplate.go b/config/localTemplate.go
index 4202c2648a..9036745565 100644
--- a/config/localTemplate.go
+++ b/config/localTemplate.go
@@ -388,7 +388,7 @@ type Local struct {
// A value of 1 means "track catchpoints as long as CatchpointInterval > 0".
// A value of 2 means "track catchpoints and always generate catchpoint files as long as CatchpointInterval > 0".
// A value of 0 means automatic, which is the default value. In this mode, a non archival node would not track the catchpoints, and an archival node would track the catchpoints as long as CatchpointInterval > 0.
- // Other values of CatchpointTracking would give a warning in the log file, and would behave as if the default value was provided.
+ // Other values of CatchpointTracking would behave as if the default value was provided.
CatchpointTracking int64 `version[11]:"0"`
// LedgerSynchronousMode defines the synchronous mode used by the ledger database. The supported options are:
@@ -440,7 +440,7 @@ type Local struct {
// an archiver or return StatusNotFound (404) when in does not have the requested round, and
// BlockServiceCustomFallbackEndpoints is empty.
// The archiver is randomly selected, if none is available, will return StatusNotFound (404).
- EnableBlockServiceFallbackToArchiver bool `version[16]:"true"`
+ EnableBlockServiceFallbackToArchiver bool `version[16]:"true" version[31]:"false"`
// CatchupBlockValidateMode is a development and testing configuration used by the catchup service.
// It can be used to omit certain validations to speed up the catchup process, or to apply extra validations which are redundant in normal operation.
@@ -581,6 +581,9 @@ type Local struct {
// DisableAPIAuth turns off authentication for public (non-admin) API endpoints.
DisableAPIAuth bool `version[30]:"false"`
+
+ // EnableDHT will turn on the hash table for use with capabilities advertisement
+ EnableDHTProviders bool `version[30]:"false"`
}
// DNSBootstrapArray returns an array of one or more DNS Bootstrap identifiers
@@ -862,3 +865,34 @@ func (cfg *Local) AdjustConnectionLimits(requiredFDs, maxFDs uint64) bool {
return true
}
+
+// StoresCatchpoints returns true if the node is configured to store catchpoints
+func (cfg *Local) StoresCatchpoints() bool {
+ if cfg.CatchpointInterval <= 0 {
+ return false
+ }
+ switch cfg.CatchpointTracking {
+ case CatchpointTrackingModeUntracked:
+ // No catchpoints.
+ default:
+ fallthrough
+ case CatchpointTrackingModeAutomatic, CatchpointTrackingModeTracked:
+ if cfg.Archival {
+ return true
+ }
+ case CatchpointTrackingModeStored:
+ return true
+ }
+ return false
+}
+
+// TracksCatchpoints returns true if the node is configured to track catchpoints
+func (cfg *Local) TracksCatchpoints() bool {
+ if cfg.StoresCatchpoints() {
+ return true
+ }
+ if cfg.CatchpointTracking == CatchpointTrackingModeTracked && cfg.CatchpointInterval > 0 {
+ return true
+ }
+ return false
+}
diff --git a/config/local_defaults.go b/config/local_defaults.go
index fd0aa20521..348e8eb704 100644
--- a/config/local_defaults.go
+++ b/config/local_defaults.go
@@ -64,8 +64,9 @@ var defaultLocal = Local{
EnableAgreementTimeMetrics: false,
EnableAssembleStats: false,
EnableBlockService: false,
- EnableBlockServiceFallbackToArchiver: true,
+ EnableBlockServiceFallbackToArchiver: false,
EnableCatchupFromArchiveServers: false,
+ EnableDHTProviders: false,
EnableDeveloperAPI: false,
EnableExperimentalAPI: false,
EnableFollowMode: false,
diff --git a/crypto/merklearray/proof.go b/crypto/merklearray/proof.go
index 0489312035..3455baa08f 100644
--- a/crypto/merklearray/proof.go
+++ b/crypto/merklearray/proof.go
@@ -149,7 +149,7 @@ func (p *SingleLeafProof) GetConcatenatedProof() []byte {
}
// ProofDataToSingleLeafProof receives serialized proof data and uses it to construct a proof object.
-func ProofDataToSingleLeafProof(hashTypeData string, treeDepth uint64, proofBytes []byte) (SingleLeafProof, error) {
+func ProofDataToSingleLeafProof(hashTypeData string, proofBytes []byte) (SingleLeafProof, error) {
hashType, err := crypto.UnmarshalHashType(hashTypeData)
if err != nil {
return SingleLeafProof{}, err
@@ -158,7 +158,7 @@ func ProofDataToSingleLeafProof(hashTypeData string, treeDepth uint64, proofByte
var proof SingleLeafProof
proof.HashFactory = crypto.HashFactory{HashType: hashType}
- proof.TreeDepth = uint8(treeDepth)
+ proof.TreeDepth = 0
digestSize := proof.HashFactory.NewHash().Size()
if len(proofBytes)%digestSize != 0 {
@@ -172,6 +172,7 @@ func ProofDataToSingleLeafProof(hashTypeData string, treeDepth uint64, proofByte
copy(d[:], proofBytes)
proofPath = append(proofPath, d[:])
proofBytes = proofBytes[len(d):]
+ proof.TreeDepth++
}
proof.Path = proofPath
diff --git a/crypto/merklearray/proof_test.go b/crypto/merklearray/proof_test.go
index 9591d6ee41..a160371550 100644
--- a/crypto/merklearray/proof_test.go
+++ b/crypto/merklearray/proof_test.go
@@ -157,8 +157,9 @@ func TestConcatenatedProofsMissingChild(t *testing.T) {
err = Verify(tree.Root(), map[uint64]crypto.Hashable{6: array[6]}, newP.ToProof())
a.NoError(err)
- recomputedProof, err := ProofDataToSingleLeafProof(p.HashFactory.HashType.String(), uint64(p.TreeDepth), concatenatedProof)
+ recomputedProof, err := ProofDataToSingleLeafProof(p.HashFactory.HashType.String(), concatenatedProof)
a.NoError(err)
+ a.Equal(recomputedProof.TreeDepth, p.TreeDepth)
// verify that we can reconstruct the original singleLeafProof from the concatenated proof
err = Verify(tree.Root(), map[uint64]crypto.Hashable{6: array[6]}, recomputedProof.ToProof())
@@ -189,8 +190,9 @@ func TestConcatenatedProofsFullTree(t *testing.T) {
err = Verify(tree.Root(), map[uint64]crypto.Hashable{6: array[6]}, newP.ToProof())
a.NoError(err)
- recomputedProof, err := ProofDataToSingleLeafProof(p.HashFactory.HashType.String(), uint64(p.TreeDepth), concatenatedProof)
+ recomputedProof, err := ProofDataToSingleLeafProof(p.HashFactory.HashType.String(), concatenatedProof)
a.NoError(err)
+ a.Equal(recomputedProof.TreeDepth, p.TreeDepth)
// verify that we can reconstruct the original singleLeafProof from the concatenated proof
err = Verify(tree.Root(), map[uint64]crypto.Hashable{6: array[6]}, recomputedProof.ToProof())
@@ -218,8 +220,9 @@ func TestConcatenatedProofsOneLeaf(t *testing.T) {
err = Verify(tree.Root(), map[uint64]crypto.Hashable{0: array[0]}, newP.ToProof())
a.NoError(err)
- recomputedProof, err := ProofDataToSingleLeafProof(p.HashFactory.HashType.String(), uint64(p.TreeDepth), concatenatedProof)
+ recomputedProof, err := ProofDataToSingleLeafProof(p.HashFactory.HashType.String(), concatenatedProof)
a.NoError(err)
+ a.Equal(recomputedProof.TreeDepth, p.TreeDepth)
// verify that we can reconstruct the original singleLeafProof from the concatenated proof
err = Verify(tree.Root(), map[uint64]crypto.Hashable{0: array[0]}, recomputedProof.ToProof())
@@ -230,7 +233,7 @@ func TestProofDeserializationError(t *testing.T) {
partitiontest.PartitionTest(t)
a := require.New(t)
- _, err := ProofDataToSingleLeafProof(crypto.Sha256.String(), 1, []byte{1})
+ _, err := ProofDataToSingleLeafProof(crypto.Sha256.String(), []byte{1})
a.ErrorIs(err, ErrProofLengthDigestSizeMismatch)
}
diff --git a/daemon/algod/api/algod.oas2.json b/daemon/algod/api/algod.oas2.json
index ed75263e03..f8b85e2c36 100644
--- a/daemon/algod/api/algod.oas2.json
+++ b/daemon/algod/api/algod.oas2.json
@@ -3289,6 +3289,23 @@
}
}
},
+ "AvmKeyValue": {
+ "description": "Represents an AVM key-value pair in an application store.",
+ "type": "object",
+ "required": [
+ "key",
+ "value"
+ ],
+ "properties": {
+ "key": {
+ "type": "string",
+ "format": "byte"
+ },
+ "value": {
+ "$ref": "#/definitions/AvmValue"
+ }
+ }
+ },
"StateDelta": {
"description": "Application state delta.",
"type": "array",
@@ -4131,6 +4148,52 @@
}
}
},
+ "ApplicationKVStorage": {
+ "description": "An application's global/local/box state.",
+ "required": [
+ "kvs"
+ ],
+ "properties": {
+ "kvs": {
+ "description": "Key-Value pairs representing application states.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/AvmKeyValue"
+ }
+ },
+ "account": {
+ "description": "The address of the account associated with the local state.",
+ "type": "string",
+ "x-algorand-format": "Address"
+ }
+ }
+ },
+ "ApplicationInitialStates": {
+ "description": "An application's initial global/local/box states that were accessed during simulation.",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "description": "Application index.",
+ "type": "integer",
+ "x-algorand-format": "uint64"
+ },
+ "app-locals": {
+ "description": "An application's initial local states tied to different accounts.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/ApplicationKVStorage"
+ }
+ },
+ "app-globals": {
+ "$ref": "#/definitions/ApplicationKVStorage"
+ },
+ "app-boxes": {
+ "$ref": "#/definitions/ApplicationKVStorage"
+ }
+ }
+ },
"SimulationOpcodeTraceUnit": {
"description": "The set of trace information and effect from evaluating a single opcode.",
"type": "object",
@@ -4279,6 +4342,19 @@
}
}
}
+ },
+ "SimulateInitialStates": {
+ "description": "Initial states of resources that were accessed during simulation.",
+ "type": "object",
+ "properties": {
+ "app-initial-states": {
+ "description": "The initial states of accessed application before simulation. The order of this array is arbitrary.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/ApplicationInitialStates"
+ }
+ }
+ }
}
},
"parameters": {
@@ -4929,6 +5005,9 @@
},
"exec-trace-config": {
"$ref": "#/definitions/SimulateTraceConfig"
+ },
+ "initial-states": {
+ "$ref": "#/definitions/SimulateInitialStates"
}
}
}
diff --git a/daemon/algod/api/algod.oas3.yml b/daemon/algod/api/algod.oas3.yml
index da57568a60..b690d06958 100644
--- a/daemon/algod/api/algod.oas3.yml
+++ b/daemon/algod/api/algod.oas3.yml
@@ -815,6 +815,9 @@
"exec-trace-config": {
"$ref": "#/components/schemas/SimulateTraceConfig"
},
+ "initial-states": {
+ "$ref": "#/components/schemas/SimulateInitialStates"
+ },
"last-round": {
"description": "The round immediately preceding this simulation. State changes through this round were used to run this simulation.",
"type": "integer"
@@ -1217,6 +1220,54 @@
],
"type": "object"
},
+ "ApplicationInitialStates": {
+ "description": "An application's initial global/local/box states that were accessed during simulation.",
+ "properties": {
+ "app-boxes": {
+ "$ref": "#/components/schemas/ApplicationKVStorage"
+ },
+ "app-globals": {
+ "$ref": "#/components/schemas/ApplicationKVStorage"
+ },
+ "app-locals": {
+ "description": "An application's initial local states tied to different accounts.",
+ "items": {
+ "$ref": "#/components/schemas/ApplicationKVStorage"
+ },
+ "type": "array"
+ },
+ "id": {
+ "description": "Application index.",
+ "type": "integer",
+ "x-algorand-format": "uint64"
+ }
+ },
+ "required": [
+ "id"
+ ],
+ "type": "object"
+ },
+ "ApplicationKVStorage": {
+ "description": "An application's global/local/box state.",
+ "properties": {
+ "account": {
+ "description": "The address of the account associated with the local state.",
+ "type": "string",
+ "x-algorand-format": "Address"
+ },
+ "kvs": {
+ "description": "Key-Value pairs representing application states.",
+ "items": {
+ "$ref": "#/components/schemas/AvmKeyValue"
+ },
+ "type": "array"
+ }
+ },
+ "required": [
+ "kvs"
+ ],
+ "type": "object"
+ },
"ApplicationLocalReference": {
"description": "References an account's local state for an application.",
"properties": {
@@ -1495,6 +1546,24 @@
],
"type": "object"
},
+ "AvmKeyValue": {
+ "description": "Represents an AVM key-value pair in an application store.",
+ "properties": {
+ "key": {
+ "format": "byte",
+ "pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$",
+ "type": "string"
+ },
+ "value": {
+ "$ref": "#/components/schemas/AvmValue"
+ }
+ },
+ "required": [
+ "key",
+ "value"
+ ],
+ "type": "object"
+ },
"AvmValue": {
"description": "Represents an AVM value.",
"properties": {
@@ -2066,6 +2135,19 @@
],
"type": "object"
},
+ "SimulateInitialStates": {
+ "description": "Initial states of resources that were accessed during simulation.",
+ "properties": {
+ "app-initial-states": {
+ "description": "The initial states of accessed application before simulation. The order of this array is arbitrary.",
+ "items": {
+ "$ref": "#/components/schemas/ApplicationInitialStates"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object"
+ },
"SimulateRequest": {
"description": "Request type for simulation endpoint.",
"properties": {
@@ -6820,6 +6902,9 @@
"exec-trace-config": {
"$ref": "#/components/schemas/SimulateTraceConfig"
},
+ "initial-states": {
+ "$ref": "#/components/schemas/SimulateInitialStates"
+ },
"last-round": {
"description": "The round immediately preceding this simulation. State changes through this round were used to run this simulation.",
"type": "integer"
@@ -6853,6 +6938,9 @@
"exec-trace-config": {
"$ref": "#/components/schemas/SimulateTraceConfig"
},
+ "initial-states": {
+ "$ref": "#/components/schemas/SimulateInitialStates"
+ },
"last-round": {
"description": "The round immediately preceding this simulation. State changes through this round were used to run this simulation.",
"type": "integer"
diff --git a/daemon/algod/api/server/v2/generated/data/routes.go b/daemon/algod/api/server/v2/generated/data/routes.go
index 4b1d09d4a9..a17b5f1ca8 100644
--- a/daemon/algod/api/server/v2/generated/data/routes.go
+++ b/daemon/algod/api/server/v2/generated/data/routes.go
@@ -114,206 +114,209 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
// Base64 encoded, gzipped, json marshaled Swagger object
var swaggerSpec = []string{
- "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",
+ "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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 2ca24cb9a1..77f2fccbea 100644
--- a/daemon/algod/api/server/v2/generated/experimental/routes.go
+++ b/daemon/algod/api/server/v2/generated/experimental/routes.go
@@ -90,206 +90,210 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
// Base64 encoded, gzipped, json marshaled Swagger object
var swaggerSpec = []string{
- "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",
+ "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",
+ "/fj5/wYAAP//423gG8XxAAA=",
}
// 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 dc48fed4e9..ea4246238c 100644
--- a/daemon/algod/api/server/v2/generated/model/types.go
+++ b/daemon/algod/api/server/v2/generated/model/types.go
@@ -280,6 +280,30 @@ type Application struct {
Params ApplicationParams `json:"params"`
}
+// ApplicationInitialStates An application's initial global/local/box states that were accessed during simulation.
+type ApplicationInitialStates struct {
+ // AppBoxes An application's global/local/box state.
+ AppBoxes *ApplicationKVStorage `json:"app-boxes,omitempty"`
+
+ // AppGlobals An application's global/local/box state.
+ AppGlobals *ApplicationKVStorage `json:"app-globals,omitempty"`
+
+ // AppLocals An application's initial local states tied to different accounts.
+ AppLocals *[]ApplicationKVStorage `json:"app-locals,omitempty"`
+
+ // Id Application index.
+ Id uint64 `json:"id"`
+}
+
+// ApplicationKVStorage An application's global/local/box state.
+type ApplicationKVStorage struct {
+ // Account The address of the account associated with the local state.
+ Account *string `json:"account,omitempty"`
+
+ // Kvs Key-Value pairs representing application states.
+ Kvs []AvmKeyValue `json:"kvs"`
+}
+
// ApplicationLocalReference References an account's local state for an application.
type ApplicationLocalReference struct {
// Account Address of the account with the local state.
@@ -443,6 +467,14 @@ type AssetParams struct {
UrlB64 *[]byte `json:"url-b64,omitempty"`
}
+// AvmKeyValue Represents an AVM key-value pair in an application store.
+type AvmKeyValue struct {
+ Key []byte `json:"key"`
+
+ // Value Represents an AVM value.
+ Value AvmValue `json:"value"`
+}
+
// AvmValue Represents an AVM value.
type AvmValue struct {
// Bytes bytes value.
@@ -696,6 +728,12 @@ type ScratchChange struct {
Slot uint64 `json:"slot"`
}
+// SimulateInitialStates Initial states of resources that were accessed during simulation.
+type SimulateInitialStates struct {
+ // AppInitialStates The initial states of accessed application before simulation. The order of this array is arbitrary.
+ AppInitialStates *[]ApplicationInitialStates `json:"app-initial-states,omitempty"`
+}
+
// SimulateRequest Request type for simulation endpoint.
type SimulateRequest struct {
// AllowEmptySignatures Allows transactions without signatures to be simulated as if they had correct signatures.
@@ -1243,6 +1281,9 @@ type SimulateResponse struct {
// ExecTraceConfig An object that configures simulation execution trace.
ExecTraceConfig *SimulateTraceConfig `json:"exec-trace-config,omitempty"`
+ // InitialStates Initial states of resources that were accessed during simulation.
+ InitialStates *SimulateInitialStates `json:"initial-states,omitempty"`
+
// LastRound The round immediately preceding this simulation. State changes through this round were used to run this simulation.
LastRound uint64 `json:"last-round"`
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 4c1e4862f8..34234f0aea 100644
--- a/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go
+++ b/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go
@@ -131,206 +131,209 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
var swaggerSpec = []string{
"H4sIAAAAAAAC/+x9/XMbN7Lgv4Livip/HEfyZ3btq613ip1kdXESl6Vk7z3Ll4AzTRKrITABMBIZn/73",
- "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",
+ "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",
}
// 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 80f5b62451..223956bf33 100644
--- a/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go
+++ b/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go
@@ -724,283 +724,286 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
// Base64 encoded, gzipped, json marshaled Swagger object
var swaggerSpec = []string{
- "H4sIAAAAAAAC/+y9+3fbtrIw+q9g6fvWyuMT5bzas+u7us51k7bbp0maFbvdZ58mt4HIkYRtCuAGQFtq",
- "bv73b2EAkCAJSpQt20nrnxKLJDAYDOaFeXwcpWJZCA5cq9Hhx1FBJV2CBol/0TQVJdcJy8xfGahUskIz",
- "wUeH/hlRWjI+H41HzPxaUL0YjUecLqF+x3w/Hkn4d8kkZKNDLUsYj1S6gCU1A+t1Yd6uRlolc5G4IY7s",
- "EMcvRp82PKBZJkGpLpQ/83xNGE/zMgOiJeWKpuaRIhdML4heMEXcx4RxIjgQMSN60XiZzBjkmZr4Rf67",
- "BLkOVukm71/SpxrERIocunA+F8sp4+ChggqoakOIFiSDGb60oJqYGQys/kUtiAIq0wWZCbkFVAtECC/w",
- "cjk6/G2kgGcgcbdSYOf435kE+AMSTeUc9Oj9OLa4mQaZaLaMLO3YYV+CKnOtCL6La5yzc+DEfDUhr0ql",
- "yRQI5eTtD8/J06dPvzELWVKtIXNE1ruqevZwTfbz0eEooxr84y6t0XwuJOVZUr3/9ofnOP+JW+DQt6hS",
- "ED8sR+YJOX7RtwD/YYSEGNcwx31oUL/5InIo6p+nMBMSBu6JfXmvmxLOf6u7klKdLgrBuI7sC8GnxD6O",
- "8rDg8008rAKg8X5hMCXNoL89Sr55//Hx+PGjT//rt6Pkf9yfXz39NHD5z6txt2Ag+mJaSgk8XSdzCRRP",
- "y4LyLj7eOnpQC1HmGVnQc9x8ukRW774l5lvLOs9pXho6YakUR/lcKEIdGWUwo2WuiZ+YlDw3bMqM5qid",
- "MEUKKc5ZBtnYcN+LBUsXJKXKDoHvkQuW54YGSwVZH63FV7fhMH0KUWLguhQ+cEGfLzLqdW3BBKyQGyRp",
- "LhQkWmwRT17iUJ6RUKDUskrtJqzI6QIITm4eWGGLuOOGpvN8TTTua0aoIpR40TQmbEbWoiQXuDk5O8Pv",
- "3WoM1pbEIA03pyFHzeHtQ18HGRHkTYXIgXJEnj93XZTxGZuXEhS5WIBeOJknQRWCKyBi+i9Itdn2/zr5",
- "+TURkrwCpegc3tD0jABPRQbZhBzPCBc6IA1HS4hD82XfOhxcMSH/LyUMTSzVvKDpWVyi52zJIqt6RVds",
- "WS4JL5dTkGZLvQjRgkjQpeR9ANkRt5Dikq66k57Kkqe4//W0DV3OUBtTRU7XiLAlXX37aOzAUYTmOSmA",
- "Z4zPiV7xXj3OzL0dvESKkmcD1Bxt9jQQrKqAlM0YZKQaZQMkbppt8DC+Gzy18hWA4wfpBaeaZQs4HFYR",
- "mjGn2zwhBZ1DQDIT8otjbvhUizPgFaGT6RofFRLOmShV9VEPjDj1Zg2cCw1JIWHGIjR24tBhGIx9x3Hg",
- "pdOBUsE1ZRwyw5wRaKHBMqtemIIJN9s7XSk+pQq+ftYn4+unA3d/Jtq7vnHHB+02vpTYIxkRneapO7Bx",
- "zarx/QD7MJxbsXlif+5sJJufGmkzYzlKon+Z/fNoKBUygQYivGxSbM6pLiUcvuMPzV8kISea8ozKzPyy",
- "tD+9KnPNTtjc/JTbn16KOUtP2LwHmRWsUYMLP1vaf8x4cXasV1G74qUQZ2URLihtGK7TNTl+0bfJdsxd",
- "CfOosnZDw+N05Y2RXb/Qq2oje4DsxV1BzYtnsJZgoKXpDP9ZzZCe6Ez+Yf4pitx8rYtZDLWGjp1IRveB",
- "cyscFUXOUmqQ+NY9Nk8NEwBrSND6jQMUqIcfAxALKQqQmtlBaVEkuUhpnihNNY70vyXMRoej/3VQ+18O",
- "7OfqIJj8pfnqBD8yKqtVgxJaFDuM8caoPmoDszAMGh8hm7BsD5Umxu0mGlJihgXncE65ntQmS4MfVAf4",
- "NzdTjW+r7Vh8t0ywXoQT++IUlNWA7Yv3FAlQTxCtBNGKCuk8F9Pqh/tHRVFjEJ8fFYXFB2qPwFAxgxVT",
- "Wj3A5dP6JIXzHL+YkB/DsVEVFzxfG+FgVQ0jG2ZOajkpVvmW3BrqEe8pgtsp5MRsjUeDUfP3QXFoVixE",
- "brSerbRiXv67ezckM/P7oI+/DBILcdtPXGhoOcxZGwd/CYyb+y3K6RKOc/dMyFH728uRjRklTjCXopWN",
- "+2nH3YDHCoUXkhYWQPfEylLG0UizL1lYr8hNBzK6KMzBGQ5oDaG69Fnbeh6ikCAptGD4Lhfp2d+pWuzh",
- "zE/9WN3jh9OQBdAMJFlQtZiMYlpGeLzq0YYcMfMiGvhkGkw1qZa4r+VtWVpGNQ2W5uCNqyUW9fgdMj2Q",
- "EdvlZ/wPzYl5bM62Yf122Ak5RQam7HF2lwyZsfatgWBnMi+gF0KQpTXwibG6d4LyeT15fJ8G7dH31qfg",
- "dsgtotqh0xXL1L62CQfr26tQQT1+YS06DUsVsdqqVVEp6Tq+djvXEAScioLkcA55GwTLsnA0ixCx2jtf",
- "+E6sYjB9J1YdniBWsJedMOOgXu2xuwW+Fw4yIbdjHscegnSzQKPLK2QPPFSBzCy1t/poKuTl2HGLz3JS",
- "++AJNaMG0mjcQhK+WhaJO5sRP559oTVQfe25mYu2h49hrIGFE02vAQvKjLoPLDQH2jcWxLJgOeyB9BdR",
- "KTilCp4+ISd/P/rq8ZPfn3z1tSHJQoq5pEsyXWtQ5L4zVonS6xwedFeG5mKZ6/joXz/zntvmuLFxlChl",
- "CktadIeyHmGrE9rXiHmvi7UmmnHVFYCDOCIY0WbRTuxlhwHtBVNG5VxO97IZfQjL6lky4iDJYCsx7bq8",
- "epp1uES5luU+bHuQUsio6Cqk0CIVeXIOUjERuV56494g7g2v7xft3y205IIqYuZGX3jJUcOKUJZe8eF8",
- "3w59uuI1bjZyfrveyOrcvEP2pYl871pVpACZ6BUnGUzLecM0nEmxJJRk+CHK6B9BW72FLeFE02Xx82y2",
- "H9tZ4EARG5YtQZmZiH3DaA0KUsFtaMgWc9WNOgQ9bcR4n6XuB8Bh5GTNU3S87uPY9lvyS8bxFkiteRqY",
- "9QbGHLJ5gyyvbr73ocNOdU9FwDHoeImP0fPzAnJNfxDytFb7fpSiLPau5LXnHLoc6hbjfEuZ+dY7FRif",
- "581wpLmBfRJb460s6Lk/vm4NCD1S5Es2X+jAznojhZjtH8bYLDFA8YG1UnPzTddWfS0yw0x0qfaggtWD",
- "1RzO0G3I1+hUlJpQwkUGuPmliitnPQEseHOOF/461Pf0whqeUzDUldLSrLYsCF5nd+RF/WFCU3tCE0SN",
- "6rnMq25h7Vt2OhsckUug2ZpMATgRU3dj5u7ycJEU7+K1V2+cahjhFw24CilSUAqyxHnqtoLm37OiQ2/A",
- "EwKOAFezECXIjMorA3t2vhXOM1gnGDmiyP2fflUPbgFeLTTNtyAW34mht/J7uGvRLtTDpt9EcO3JQ7Kj",
- "EoiXK0QL1GZz0NCHwp1w0rt/bYg6u3h1tJyDxAvKa6V4P8nVCKgC9Zrp/arQlkVPPKQzb42GZzaMUy68",
- "YhUbLKdKJ9vYsnmpYYObFQScMMaJceAexeslVdpeqjOeoS/QihOcxyphZop+gHvNEDPyr94C6Y6dGjnI",
- "Vakqc0SVRSGkhiy2Bg6rDXO9hlU1l5gFY1c2jxakVLBt5D4sBeM7ZNmVWARRXd09uaiT7uLwhsbI+XUU",
- "lQ0gakRsAuTEvxVgN4wJ6wGEqRrRlnCYalFOFYg2HiktisJwC52UvPquD00n9u0j/Uv9bpe4qK7ldiZA",
- "YSiae99BfmExa6MBF1QRBwdZ0jOje6AbxN7+d2E2hzFRjKeQbKJ8NPHMW+ER2HpIy2IuaQZJBjlddwf9",
- "xT4m9vGmAXDHa3NXaEhsWFd802tK9lE0G4YWOJ6KKY8En5DUHEFjCtQE4r7eMnIGOHaMOTk6ulcNhXNF",
- "t8iPh8u2Wx0ZEaXhudBmxx09IMiOow8BuAcP1dCXRwV+nNS2Z3uKf4JyE1R6xO6TrEH1LaEef6cF9PhQ",
- "XcR8cF5a7L3FgaNss5eNbeEjfUe2x6H7hkrNUlagrfMTrPdu+rUniN67kgw0ZTlkJHhgzcAi/J7YgKT2",
- "mJczBQf53rrgd5xvkeXkTKHK0wT+DNZoc7+xka6Bq2MftmxkVCOfKCcIqI+fMyp4+AqsaKrztVHU9ALW",
- "5AIkEFVOl0xrG8HeNHW1KJJwgOi9xoYZ3a1m9E5x4zXrCQ4VLK+7FeORtQk2w3faMgwa6HC2QCFEPsBD",
- "1kFGFIJBATCkEGbXmQum9+HUnpIaQDqmjVfalfi/pxpoxhWQf4qSpJSjyVVqqHQaIVFRQAXSzGBUsGpO",
- "F+pSYwhyWIK1JPHJw4fthT986PacKTKDC5+BYl5so+PhQ/TjvBFKNw7XHvyh5rgdR8QHXvgYweeskDZP",
- "2R5q4UYespNvWoNXt0TmTCnlCNcs/8oMoHUyV0PWHtLIsDATHHfQXU7jyr67btz3E7Ysc6r3cWsF5zRP",
- "xDlIyTLYysndxEzw789p/nP1GWbXQGpoNIUkxZyQgWPBqfnGppFssw3r8Dq2XELGqIZ8TQoJKdi0B6Py",
- "qQrGCbEBkemC8jlq+lKUcxeRZ8dBTl0q61ORJe8MEdWG9Ion6J2OcW4Xhe0zX4weBNTYYm3XtrU8Lmg1",
- "n0t2GiJSA+S1Xf3R263xqNdUNUg9r01Vi5xm+s4ALt5Q1AL81BMPvANB1BmlpYuvcFvMKTCbez2+9nro",
- "GJTdiYMYwfphX5igsZPz9R60FTsQkVBIUChbQv+Ssk/FLEzVc8JHrZWGZdcFbz/9vef4ve019ATPGYdk",
- "KTiso9npjMMrfBg9Tijfej5GTaPv27bx0IC/BVZzniHUeFX84m63T2j7qkn9IOS+7jLtgIP18gFXh1vv",
- "yd2Ul73gpHkeuRN0iTxtBqDGVeEAJglVSqQMla3jTI3tQXPXiC7rp4n+N1V48h7OXnvc1uVXmCOKzl3I",
- "C0JJmjN0/QqutCxT/Y5TdC4FS41ELXkrut/d+Ny/EvdvRtyPbqh3nGLEWuVyikZazCDiX/kBwHsdVTmf",
- "g9ItI2UG8I67txgnJWca51qa45LY81KAxNChiX1zSddkZmhCC/IHSEGmpW6q7ZinpjTLc3cTZ6YhYvaO",
- "U01yoEqTV4yfrnA4f1vvjywHfSHkWYWFuHSfAwfFVBKPrvrRPsVIYLf8hYsKxroC9rGPsqwTZ0dmmY1c",
- "+f/v/n8e/naU/A9N/niUfPN/Dt5/fPbpwcPOj08+ffvt/9/86emnbx/85/+O7ZSHPZZF5SA/fuFM2uMX",
- "aLfUlzcd2G/Mcb9kPIkSWRiG0aItch8zhh0BPWh6tfQC3nG94oaQzmnOMsNbLkMObQnTOYv2dLSoprER",
- "LS+WX+uO1sAVuAyJMJkWa7y0FtUNSIznK+JtoktBxPMyK7ndSq9923QcHxgmZuMqJ9WWqzkkmLC4oD6q",
- "0f355KuvR+M60bB6PhqP3NP3EUpm2SqWTprBKmbkuQOCB+OeIgVdK9Bx7oGwR2PgbFBGOOwSllOQasGK",
- "m+cUSrNpnMP5JAfnLFrxY24j2s35wbvJtbvyELObh1tLgAwKvYiVsWgoavhWvZsArXiRQopz4GPCJjBp",
- "O2syYy+6aLwc6AzLKaD1KYZYQ9U5sITmqSLAeriQQR6RGP204vmd8Fd7N4fcwDG42nNWF5H+by3IvR+/",
- "PyUHjmGqezaz2Q4d5KJGTGmXbtWIJDLczBbvsUreO/6Ov4AZ48w8P3zHM6rpwZQqlqqDUoH8juaUpzCZ",
- "C3LoM7heUE3f8Y6m1VtfK8idI0U5zVlKzkKDpCZPWzOlO8K7d7/RfC7evXvfCaromg9uqih/sRMkRhEW",
- "pU5cxYdEwgWVsUsrVWX848i2pMumWa2SLUrr2fQVJdz4cZ5Hi0K1M3+7yy+K3Cw/IEPl8lrNlhGlhfS6",
- "iFFQLDS4v6+FEwySXni/SqlAkQ9LWvzGuH5Pknflo0dPgTRSYT84kW9ocl3AYO9Kb2Zy26mCC7dmJay0",
- "pElB57G7sXfvftNAC9x91JeX6OPIc4KfNVJwfUQ9DlUvwOOjfwMsHDunE+LiTuxXvrpXfAn4CLcQ3zHq",
- "Rn1jf9n9CpJyL71drcTezi6VepGYsx1dlTIk7nemKvozN0qWD6NQbI7WqquPNAWSLiA9c4VrYFno9bjx",
- "uY/UcYqmZx1M2ZJGNqUOi2rgzcIUSFlk1KnilK/b1Q0UaO3jgd/CGaxPRV2TY5dyBs3setV3UJFSA+3S",
- "EGt4bN0Y7c134WBo2BeFT1LHbEVPFocVXfhv+g+yVXn3cIhjRNHI/u5DBJURRFji70HBJRZqxrsS6ceW",
- "Z6yMqZV8kfJGnvcT90ptPLnIrXA16HW3z5eA9dHEhSJTavR24Up72QzygIuVis6hR0MOL3cG5mk3LoRw",
- "kG1yLyrpxKwt0DryJgqyfTkxa45SCpgnhlTQmGnF6/mZ7P2hu5nAip0OYdMc1aQqsNEyHSobl2y2BGEf",
- "aHECBslrhcOD0cRIqNksqPJVx7A4mz/Lg3SAa6yIsKkOznEQahZUYKuq3Hie2z6nHevSVcPxJXB83ZvQ",
- "tBxQw8Zo+BjdHtsOwVEByiCHuV24fdkTSl2dod4gA8fPs1nOOJAkFrUWuEEDMePmAKMfPyTEeuDJ4BFi",
- "ZByAjffiODB5LcKzyee7AMlddQnqx8Yb9eBviOd92Thuo/KIwrBw1nOrlXoOQF2oYyW/WgG3OAxhfEwM",
- "mzunuWFzzuKrB+mUY0G1tVV8xUVmPOhTZzdcgFjBstOarCi6zGpCnckDHVfoNkA8FavEJn5GNd7pamro",
- "PRrajmmosYNpC9/cU2QqVhjtg6LFhlJvgaUfDg9GYOGvmEJ6xe/6pLkFZtO0m7WpGBUqJBnnzqvIpU+d",
- "GDJ1jwbTRy73g1o2lwKg5eyoC0M743erkdpUT7rCvJZq47pGm88aih3/viMU3aUe/HW9MFX1mTdtjSXq",
- "p2gGrTQL7wQqZIzoDZvoXtJ0r4IU5IBGQdJQopKz2M2psW0AJc6J/yxwXmB5H8rXD4JIKAlzpjTUTnQf",
- "J3Eb7kmKVQWFmPWvThdyZtb3VohKTNlrRPywscwbXwGGEs+YVDrBG4joEsxLPyg0qn8wr8Z1pWasla3B",
- "y7I4b8Bpz2CdZCwv4/Tq5v3phZn2dcUSVTlFfsu4DViZYs3oaATmhqltkO7GBb+0C35J97beYafBvGom",
- "loZcmnN8IeeixXk3sYMIAcaIo7trvSjdwCCDzNkudwz0puCOf7LJ+9o5TJkfe2vUjs/f7ZNRdqToWgKH",
- "wcZVMLwmMmoJ00HJ5W5Ka88ZoEXBslXLF2pH7bWY6U4OD1+oroUF3F032BYMoEr7FmYgIepCqB7Z6OhK",
- "XQoLFWJmd6MUTmTTe53/TVeaF5RV54hgoks4wVxpyf49rmMvG6UXm0uJ9C7ozloyrr9+1qXIysdvYBmy",
- "Gydx1/qJMTSaiA/MLVvKfMsmsB7DPSTPgD2HUzHlG3F0ybbKgdxGuadA859g/at5F5cz+jQeXc2RHaN8",
- "N+IWXL+pDlsUzxgoYR2bjXupHVFOi0KKc5onzt3fxyikOHeMAl/3twM3LHjilH36/dHLNw78T+NRmgOV",
- "SaW49a4K3yu+mFXZYpQ9B8QX+jcWuLegrGIfbH5VQS+8IrhYgKuYHtgGndKu9fVPcBTdlcEsHq+1lfe5",
- "myq7xA03VlBUF1a1M9XeVzXvqOg5Zbn3Ynpoe2KrcHHD6gNHuUI4wJXvuoIry2Sv7KZzuuOno6auLTwJ",
- "5/oZSyLFtRPuCiYhK3J3V00WdE85yjrAVR9MxaqWngNl8g9CNpi/C6yP3n15gd1mjHuR3Q6PPaFGvgtH",
- "W/GcEKQl8mH+wZzGhw/Do/bw4Zh8yN2DAED8fep+R2fRw4dRt2TU6jBMAo0KTpfwoAoS7N2ImzVROVwM",
- "E9BH50tEHcZ695NhRaH2Esuj+8Jh70Iyh8/M/ZJBDuan7Qk0rU236A6BGXKCTvoC6asYiaVt/KGI4O2Q",
- "IMzhMKSFzH5JsbSx9fJ2jxAvl+gZTVTO0vidEZ8qw165jQUwLxN8uce4NiOWrCe0hJcsGMu8NqRWVwvI",
- "YI4oMlW0XFiNu6lwx7vk7N8lEJYB1+aRRLnWEnXeOMBROwqpsYW6c7mB7Y1jPfxVbKawrHdbZ0QgNhtM",
- "YeRBB9wXlQvQL7TysNc2064BTOGMHca9IfjI0YejZhuMvWhGEAyzY4Y0gPOMztUX75kj2tCNqWQmxR8Q",
- "91uhuy+SgOkLmTOM2vsDQvMsbGPUYCmVt7ruS1fPvm27h9vGfRt/ZVvYL7qqnX4ZYRo/1btt5GWMXhUv",
- "E+iQ3GeEhVcXzci2HtaCxyuI5cCy1f5ak3J7nmz2YSNAOn4qw1SEAzt+fSodzJ30jZxeTGmsprexhQxM",
- "wfY2LmC1IP5jvwGqStGzs5MgAKl6l9kKJgXIOgG9Ww3tknaNnXawRVMbMEhRoekytkEjuRKRYUp+Qbnt",
- "hWa+s/zKfa3A3piYry6ExPpDKn5XnEHKljSPGzhZ2r0XzNic2TZfpYKgj5QbyLZQtFTkenFViacONccz",
- "8mgcNLNzu5Gxc6bYNAd847F9Y0oVisvq9qL6xCwPuF4ofP3JgNcXJc8kZHqhLGKVIJXtiUpeFfEwBX0B",
- "wMkjfO/xN+Q+xnoodg4PDBadEjQ6fPwN3tTZPx7FpKxr07aJZWfIs//heHacjjHYxY5hmKQbdRIt1WL7",
- "tPZLhw2nyX465Czhm06gbD9LS8rpHOLhhcstMNlvcTfx9qWFF57ZJoNKS7EmTMfnB00Nf+pJWTLsz4JB",
- "UrFcMr10EQFKLA091U2i7KR+ONux0NX393D5hxhYU/i4gpav64bNGLrsCTnG8KfXdAlNtI4JtUWnclaH",
- "vPmuI+TY17TDhgdVnwOLGzOXWTrqkhgBNyOFZFyj/6PUs+RvxiyWNDXsb9IHbjL9+lmkcUCztjbfDfAb",
- "x7sEBfI8jnrZQ/ZeZ3Hfkvtc8GRpOEr2oE4RDE5lbwRQPNajL+Bk89BDNV8zStJLbmWD3GjAqa9EeHzD",
- "gFckxWo9O9Hjziu7ccosZZw8aGl26Je3L52WsRQyVqi2Pu5O45CgJYNzDPiOb5IZ84p7IfNBu3AV6G/3",
- "utqrnIFa5s9y1BDwTqdNiV5Ghf/1lWtK3NG9e4LTbPRZ9c0NJ7BFnZZWQ2u4zR5/INJYkqiNPnyIQD98",
- "OHbK3IcnzceWST18GC/fFnUcmV9rLFzFrsNvY3v4nYi4cXyvlOoK3SWpRdxofazWPDBHeeqGGpNmX4qb",
- "l4X7CX+Oh7jET8G7d7/hE48H/KONiFs+8riBdRCfXUkPoQR9eaIkk1XPg+A6Sr4Tq6GE0+Kknng+AxT1",
- "oGSgkwlX0uk7FL103hr1ENCoGXUKuTCmUlhSPfRKfzl4Nosfb8B2yfLs17rARkuQSMrTRTQ0aWo+/L3u",
- "D1wt0bLKaJXmBeUc8uhw1kL73VtyEVvzX2LoPEvGB77b7ntll9taXA14E0wPlJ/QoJfp3EwQYrVZu6DK",
- "jcvnIiM4T10SuGaO3QZyQVebf5egdOxo4AMbn49XNob52qYqBHiGPpwJ+RGziA0sjXqP6DvxBbmaxWnK",
- "Ihc0G2OhsNPvj14SO6v9xna5tE1d5ug6aK4i6usdXqynalgZz0IdPs7mtDizaqWTqgdLrM6HeaPuEsNa",
- "AQDoVAixMyEvgmb+tiSIGYJgnTi5hCxo+WItCqQJ8x+tabpAR0lDkPWT/PBuRJ4qVdASvWptWpUAx3Nn",
- "4HYNiWw/ojERegHyginAvCM4h2ZpkarOjnPU+VIjzeXJknNLKZMddIqq4PeuaPfAWYXE33BGIWshfkcz",
- "2Tbz2rU50wl+Fa1I2u701OmFbgtVVC0rX/lu9pQLzlKsBxpTiLAMwrA7kwGlU+OXHWrkTmjkcEX7S1UZ",
- "Dw6LvR2nPCN0iOvePwZPzaZa6rB/ali5vgNz0MpxNsjGvk2a884zrsCVdDdEFPJJISMRFjGVI6luc3ck",
- "I8xw7nG3/GCevXbOOEz9O2MczW6HNqdmW/85drDXxlZnmswFKLeeZpkX9Zv5ZoIVTzJYvZ/4jvc4ho3p",
- "Mcu2AWzdoY58OJsLHzPvPjfvujqU1c+N2BQ76VFRuEn7m+jFO4eueC+CY0EU/lY7QG41fjjaBnLbGIeK",
- "8tQQGpxjCA0UKIc7hFE1lGt1bzUmgqUofIPYaPxoMSrGI2C8ZNzf58QFRBoVCbgxeF57vlOppNqqgIN4",
- "2inQvIqZaTM0pd2F4FWHalfhNCjBNfo5+rex7oXXwziqF2rFjfI18YfCUHegTDyneRXHGelsh1qVU6Iy",
- "TA5t9bqLMQ7DuH03zaYA2NJAd1x/jiVpd5VEffU+pmU2B53QLItV2P8OnxJ8SrISNQdYQVpWldiLgqRY",
- "3q5Z769LbW6iVHBVLjfM5V+44nRB88gINYQNLP0OYz7xdI3/7tLauIrg3Dmjw4drZrsVuexmqMS0XkPT",
- "iWLzZDgmUKZcHR311Jcj9Pr7vVJ6LuZNQG7DSdrD5cI9ivG3743gCItgdYJlrWipalRhYKrwPdDRbKyq",
- "qzS5EoqyTrF9vIKtWgpvdkP0Nwceo/DryaIKXd5Wvlo3cF8uVdqb+ke1K0KgKdnIgnoTu23gYsuJ3r3P",
- "6AtWtLGK+3M+u7VuRKiPI+8C9JNPUiEFZS5gpWYWXcy6MN9uuueQONp6g9uLcCl7vf7Rn8770ut8zVt8",
- "3m4eegauMlEh4ZyJ0oeC+IBMbxLaXxutOKsEx+j6o2HOt+187nWVn7omTnaZzib/6VcbvkuAa7n+DBzn",
- "nU3vtCXtarvWPVW/Qqr+H4P6gTSk4pB60LHSw043bDRG3dLWtUNWL4aoA902rePRcbaTwIyVrx7ZUWLH",
- "Lt50tb+6Z13RE49YIRSr2/DEurEOjHw+xYaqQXXS7lg+Iu4cUo29l+pIHwmwS61SM1nQ3/2uymePOV0F",
- "iLvinpsqenYbLm2R8Z2k+6BwhG1WMxlev/Koiue06SgXVGG1Z9tivZnAOTiNbDaDVLPzLUUO/rEAHiTQ",
- "j71fBmGZBTUPWJVUgTXydvc61gBtqkGwEZ6gVvWVwelLqj2D9T1FGtQQ7Z5TZRRdpjwaYgC5Q2JIRKhY",
- "vJR1JLsQFqYqykAs+PhE+znUhWZ7G28GJTsuOZcnSSM46jIeG6aMd/4bNJf5dKfiNpgf0FcHods4rN/+",
- "eIF92lTVFNuXVwutdHLcLUJ94cqzYUmK6u7EF2oD5X/z9WfsLDk7g7A1KN5UXVCZ+Teirhfv1Uk2yKNO",
- "8QLf9KoN9KyamdXR5N276khZU0zMSHNh1IikL7ulGcBdRT/dUzZMzXbZwdB0A9cMpGuhjPpvLhQkWvjo",
- "801wbEKFjcW7FBJUbylxC1xvgb+3dQVDbKlAsaAfdSF44QKJhCU10MmgzmD/nJuQ/dw+9xnBvqT+Vg9T",
- "Ra/bezv5PAKmOkgMqX5GnLTcnml8GWcT4xxk4m+e2kUHOcjmbUghRVamVkCHB6NyyA0u6bmBlUT9NGl3",
- "lS0bIcjYPYP1gTWCfFMsv4Mh0FZzsqAHxapam7xX95uKwT3fC3i36bkajwoh8qTnsuO4WymxTfFnLD2D",
- "jBhJ4eNtexoVkvvoY69usy8Wa18ZsCiAQ/ZgQsgRtxkO/mK72aqjNTm/pzfNv8JZs9IWL3VOtck7Hg8V",
- "x7Ki8orczA+zmYcpMKzuilPZQbbU4Vv1VGmU9CLStnMy1CrvXjW3WynWRGWhiOkkJ/bG6jke9JjjCPOx",
- "g8IBeJFJibvpIioXsZDMy+SMm6HimAonQ4A08CGpyxUUbvAoAqo2iVsChaoYobrDXB0n1FWP8lxcJHiM",
- "kqrObMzoMu+pppjwpfXr7wy9TSGIOKLKqRBrsqAZSYWUkIZfxNOiLFRLISHJBQYgxe5GZ9pohEvMheAk",
- "F3MiCmPo23rN/hYp2v+wM1fJOUWBDkG8RxQFNE3R+hTEfUOqb4ZOua/2krb4iV10Ym/ZekIiQbliJw5D",
- "9uUuvBs6PO5UKfl4hr4KhlEYzdxWqxeFfS5hxzaXLM+9KdvX6ZL8okoMlMHEBjPFM7IUxh5Gm8M3PPdD",
- "1cFH91PBtRR53nRPWGVt7nyur+jqKE31SyHOpjQ9e4AWDvbZ98lnY5/21w4Tq2eSrYo3A1tyni4iHkic",
- "xZ+6nftuOs6xc7u8AMwBHGu79/Uo1la0ua52g9u+dtNaLFkap+EvK+6qN1oqxhKipXRsxwqb/IyvIaMO",
- "hUN1zY4sqYtm4IZgY/vleJq7bkTmYf6Lulh7XDIDJyR6BFOXTzp5mqS9Ur8FAEJqM/J0KW2bi1AmV1xF",
- "zG0GL16WtgEdyMUxJuVqsJkR9g6UhisB1YmDqwC8b83QsS15ZGPqpmLlnz+oayJdCvhPm6k81ho4coor",
- "0nKdi339hB6OEA3V2RwZY9vFT4fGx1QtiQZK1ACA/oiZBgyD4mZ2BWNGWQ5ZQnWPcEdvxTiwuVyuRbvR",
- "HFOOk6fUCuwFEDN2KcHl89s+8a3GtAU1pCSq17s+RZ7BChQm29vumlRZD7j3xLsm9W2zUBRJDufQCCRy",
- "RQZKVO3YOYQN7u3HJAMo8F6q7S2JRciEsrxlQru1J0GMxRDsRm1qi1i7U2SLwRw171c8scdEDT1KBqJz",
- "lpW0gT91hVbf/V2+Ozp5YnVveyCGTPOLHeGtH+DIfx9TZTwm3g/jQzuzoDjqNjGgrRFzeKKip57HA+bC",
- "ChqVqx1ny6orOUviNd9QBb3g/a6pLsnX5s3wFvwBYr9fQYpaTTMi7Oo4ITgYUa3qOL0quKx2+PIuzluh",
- "4Y0k3DtezNRQgAy2tnDrCwi/joounMKOL2BrMW7UXqM1YzsPx/8d/xtjN2Q7kLGrbXeR0IJ7Af4uCQv2",
- "Vm50p9CySqD5yLexq9fWNspZEPO7pGsiJP5j7LV/lzRnszWeUAu+/4yoBTUk5C6v7K2qi6QzE29WTMYe",
- "MO8XEH4qu242dMxguLUZJQDaiEAipLsHWdIzCLcBL4wt50m1YTmqnC6ZUijsWtvZxYJbvM+5X9IstJGx",
- "8lezrZuvBWm+/n/qfKJwKl+wp8hpWrdpVnTZctXaflGeuPQClpsTzrrmsSeBqgdVTbTSJ5pmth6MxV9V",
- "/AE1EfzPlGlJ5XpD+OvWmIJYFDdqztvA7vTmQTV8b8vYpVlknbO7IVVv0FL2vQtDIxc6QOP1p6+atAV8",
- "W+3OV1i6CfxHi/L1LWMI+J8L3ntaGoXw2u5FN4DlRjJ6BFbrV52KVSJhprZd0lvHqjGEZZ3G7p2TjKcS",
- "qLJRC8c/O5OtrjnHuDEhbVxddS9UjZLBjPGaWTJelDpiAWDpOb4OEBa6pxGtPdcQfVqCUcPOaf7zOUjJ",
- "sr6NM6fDtlQJa357l7z7NmL8VzK1OwBTtfWDOW5Q51AFrxkBnrHZDKQNeVOa8ozKLHydcZKCNHKfXNC1",
- "uvzdh4FWlka/2HL7QQNtppl5HdyDIGlbQPK1u1i74s1EBSDd4xXFgKsFjK2MXCtYp4gWPTcJXRjiCf90",
- "leRijplPPQToivvh3Y81VgRHh63Vh3abR7E/YPM0WNfYHXwtcNYhU2w+Zz8j6tDg+YUzvfGkWW9aOxXN",
- "xgrag+Dpn8/rgGW7OV36j2UPnmJ4fSODsN0A2O+1DVyw80HPTUbTg9uzi3h161JPQ3etGn6T0bgdjuUo",
- "Whs2QdtWbQhJBlWH39LUhZR0nT4do9giZewyPHf0CVlPspcDPeDZroHubDWnra75zTjDdY3gTjsOUSGK",
- "JB0Sp2ZLn2fOoe0gbcLYQx+Bu7pn3dWVft3IulFyo9EVwGrKl1F3W10Jtt3LFOkmI7vPodHDQZvOcjFD",
- "XoZH2LpxMPugcl6M23kxTYdNxSQIJRLSUqJD84Kut/dt6Sm5efL3o68eP/n9yVdfE/MCydgcVF22tdX3",
- "pI5lYrztZ7nZ6KXO8nR8E3zGtEWcvynziSDVprizZrmt1dx4tOvLLp7QiACI9ffu9tu41F7hOHU48ue1",
- "XbFF7n3HYii4nj1zMZfxBRxxZ7+IGdnMM+qLEX/cI/zCKP8RIeW39hIL7PPH9mfsXoYea4fsZ0OFkRTk",
- "vdFetdzroLiolnm5VoaDQOumo0bIAwHoyTNrZAiFnU7rSorS+nbRC+wvzNpC7FV9kbY1IBoh8R9sAS9M",
- "HKvfq2J4HTi3XJLwVYWUYCnv+yihsfxtuWhugfXNY7BFztTVGmzfaVtYqbkvQaKhel7l7/Xotp00P2xr",
- "auybPI+kB1rrG89USDhGsZTnNL95roH9bo8QH5C97U8KCHPEQiRbVKrLVah6SQfNHeSD7W9q/gZTEv8B",
- "Zo+ics4N5S4dO9IMfSc0t+GbM5febYYkFzimDSp5/DWZuprXhYSUqfZlpr1xCqICz0GymQvgg5XekoO1",
- "bZ2/Cn0FMp75yAPyOriUEOj8qSGsj+gtM5Wekxul8hj1dcgigr8Yjwp75G0RF2eNQge1Lh5INCFhzwUP",
- "gtJFOxY86Hb/G7o8m9RvhE6poLvOwdK6gduIoK7XNrRax+AC1e/e/aanQ4psxItJm8+xysdeqkrvVFP6",
- "Gup7WBy5Mdy8MYr5ta/io61q2FNctLUfJcu3hhk0SsV+Go/mwEExhcVQf3cl3G9WlnoIbM5x96haWK9S",
- "KMEiJrLWxuTBVEER2AH1X91nkWqvmM+TlpLpNbbv824Y9nu0EsmPVVa7q4pQ3YA42afFGVQtVOsc+FJ5",
- "6fqjoDnKI3sxw40UEvmEfL+iyyJ3TkXy7b3pf8DTvz3LHj19/B/Tvz366lEKz7765tEj+s0z+vibp4/h",
- "yd++evYIHs++/mb6JHvy7Mn02ZNnX3/1Tfr02ePps6+/+Y97hg8ZkC2gvjbx4ei/k6N8LpKjN8fJqQG2",
- "xgkt2E9g9gZt5ZnA9lIGqSmeRFhSlo8O/U//rz9hk1Qs6+H9ryPXJmG00LpQhwcHFxcXk/CTgzkmvSZa",
- "lOniwM+DTX8a+sqb4yom2UZP4I7WPkjcVEcKR/js7fcnp+TozfGkJpjR4ejR5NHkseswyWnBRoejp/gT",
- "np4F7vuBI7bR4cdP49HBAmiONSLMH0vQkqX+kQSard3/1QWdz0FOMOzc/nT+5MCrFQcfXfLvJzND9NbG",
- "lgoO6sP6diZFOc1Z6svsMGXdiTYyWIXN2qyftVRjMrXt/HzwIc8wQMTm06qwpeVxZhBmPz+umZbvSGhb",
- "zh/+FinI4iPWfaO8MOQnCAb6r5OfXxMhiTNv3tD0rIrW9+kZdUpKmJ1hvpx4+v13CXJd05fjfGEDb+Dl",
- "0jARF/a/VPOiWZuw1qpiXp8Orv3MhiwCwq5S9WvGhXd8ASQ1Gzas9VHyzfuPX/3t02gAIFg3QgH2TfpA",
- "8/yDzYSBFUYEtuIexn0RKeM69Rs/qHdyjB6p6mnwef1Os6TvBy44fOjbBgdYdB9onpsXBYfYHrzHzj5I",
- "LHjmnjx65BmNU+MD6A7cmRrart1Xsba+5moUTxKXGKjLkOyjt1V1N0kLexbdE5vv57z99qWJ4TvP9rjQ",
- "Zg26Ky+3PVxn0d/RjEiX54hLefzFLuWY20g8I1isAPw0Hn31Be/NMTc8h+YE3wza5nUFzS/8jIsL7t80",
- "yk+5XFK5RtVGV7ywXSGfzhVesSGLtGc7KCDE56P3n3ql3kEYcnbwsVH9I7uSTLRRNo3+ElvE5D3Vxzm7",
- "vfHvHxUFRtydVM+PisJ24cRbZWAo/WDFlFYPJuTH8Gvk3pjqaDsklRKjhmp3ipF6VVNK3+qycXMatLeK",
- "Cu3AXXwnv29bfh81nR2N7tExYBqnYCNMndiVqwrQbnJDUOVj13DUqsKrUy0S1wRm4Bi+N/beOhwNSO63",
- "M72PmYJbGfUd7npw16cmBfBWGlPdXulmWLMvFllJkobIuEbG/YUrfa9obugkWG6rKYNtqX6nDP5llMGq",
- "qNzcamdFsQf1EGPiDz76Nvl7UAldd/kBymBoVgffBnHN91vs5MHEtmMP37kcz3BV5Laqeea9OwXvc1Dw",
- "bBm+baqdo+NbVerClJpdMlwa2oj5fdDHX7gW9xdGVq/aZiDdrrBdgn12lDHHrK+Nrf4plTCHtDv16y+t",
- "flW1Xa+kgIUBqgcuwzu4xrqS967tnWO60sSa9X0DzoZFEDDX2R7hcR3SbViMDRd2gcJq7C1DvE61RqPd",
- "rHHHbuyqWD9CaKB+tz5+sU27+oL8PIPbdEakQHxvrpuXRq8d3t7MtcMw3vTs0bObgyDchddCkx9Qil8z",
- "h7xWlhYnq11Z2CaOdDC1LeE3cSXeYktV2Szb6j3gUVV1xHHw3LxtozTuYzZls7HLgwnxDejrCgsuW3gu",
- "DKPyWUFUzu1HhtcZZJB7/s9DHP/ehPyAuW5ajTHYDCsp4YuM68PHT54+c69IemFjudrvTb9+dnj07bfu",
- "tUIyrjEewNo5ndeVlocLyHPhPnAyojuueXD43//8n8lkcm8rWxWr79avbSfIz4W3jmN12CoC6NutL3yT",
- "Yta676C/DXU3cn3/nVhFpYBY3UmhW5NCBvt/CukzbZKRM0QrT2ajV8QepZE9JrvIo7Fv9m74TiVMJuS1",
- "cG17ypxKW3sDC3sqMi+ppFwDZBNPqVjWSdk2JWnOME1cEgXyHGSiWFVAt5RQFYgoJJxjjHxderIBwXZG",
- "j5G0ny2Tf0VXQYr0tBLTWrglo9tzSVcE69BrokCPbXWqFfn2W/JoXFsveW4GSCrExJjrkq5GN+j1q4ht",
- "aMmVFw47Qm4P0MWxh3iQau2nqnpXmxp/dc79xWrultzdxu6Jc+588VNf7IR+BNccZ6MHwSp2Gmu0qrIo",
- "8nVdndNoeV6FirM4M8NQ58BnfEew1TUdNULb6L07xHdOgCuxkjZB7cg2MOtUHXxEuzzkGZ1zi1lzf63r",
- "0uDuSIqlvzwSZAY6XbiE3RbqI+xJuqTBft60ZJwtDZSPxteu1eAudmvLhr1JM2rT5Ie0vwlyKfECD2SE",
- "iH/23brNYzazBad9GwJfKQ6vplzN3qohoDW+bYtQF8/v83oL2mhwuB3K5/XkXYUM0bKP+887BO+G4A5z",
- "/N7VJLDHyy3izxDx703JhLwWddq4taD+lFeP1ynZr3tBrwUHe8duNF9Li3fXqZXaYRiHRYqvF2Ltl7rp",
- "z2VVkANfZ2ejHvJ389IWXWSI9MaaPV+iCP97tBpRQ8qYtU22FkOoRxvCnM2LttZ8szP6LVoxt8JPP0PT",
- "5jY41s2wGDykns84tYDvl+lgCR5LzAdVU+w+DvTSvBzoZW9cS/mB3EiLKgwNIrV/yBRywefq82RFm6gj",
- "jpcIldhKU7ZlRWf9k7/g2X3u+kn4ZtOu3pNiPAWixBLQZDA6OvY4sMGSzx797eYg1GzpO8vyMHf1lrnL",
- "V4+e3tz0JyDPWQrkFJaFkFSyfE1+4VXfiKtwO0Wo2/PQGxxhDozjbVOzLlgaFjG6PBNshK591CuWfdrO",
- "DINCijvyQcYDPhgW0aZFAVRengFuv7pqN5k8fhFGB4uq1IjflR5QDIp2DJD/P6OBfidMexczJ/xKbgH1",
- "1b8cm3Chu2I2roJjjBYgZofkHX9I1IL64pTuzydffd3jOTPzuKI9Xd9ZPZB5bIcZ4kD7ot2B+9XaK/we",
- "3vRu77aJ4xHLVtHu57AKSoc3m+A5teyeIgVd+zDaThGqIl6IstIGwmGXYNR4tWDFzRc7VJpN49VevflT",
- "NVM95t9VVrCtyGeU7+I2ityNR1oCZFDoxdbal/hWvZvgqmAy5are2wqFY8ImMLEF/OpuINkclLWoKcmB",
- "zqq2HkIMSZ4I+IwhNE8VAdbDhQyxSaP0gwVDkChv3jitkwysoPPIky2Zc6uKrr4tIzVBGxW4V2yaaLk9",
- "nRI79I+D6+5CCi1SkdvYlbIohNTV6VaTQeoe9F3bNbS9PsK9kjK3Ypna6kc7xbf24EhrUrb6Yvxopx5N",
- "MUdabFGXrMhXzzWEpZ2KgnSauBoQbpWv3TndYvys5XP70l1uupf09uyBS6lOF2Vx8BH/gxUJP9WJUlir",
- "XR3oFT/AnkoHHzeGNCFLzY1uIm2Z94YdHW0J3XXr4ed1SfkfhOz09N8WstRC2rgt9G1/KIx9irDH67Em",
- "/9JG2EZ/ZWvDr34FFxmxc16rPOCgy01Fu0GjAp/aa3tcRUj47sr481pQ7cSdMZ4RGmxjy9dU9aH1NsDf",
- "vthF34Zf+Obvyb/6gs/Za6HJ8bKwDf8hu1q0IWlzOC89Norb3RQDJ/q7IYldmR9KfB9IXekiWwX8DnZP",
- "UDoC/HRUYi0HI6uvx9y5k+SftyR/7kukN8jwTi5/OXJZ+vDvOxH8+Yvgp1/saq7x4nigSPaS6NJiuLbE",
- "dxTIHWXA+bBajoNN98poerdXqX4Q0rfjuZPiX+ilqN3JwUmWQzw02zyxbsp9hPp/VtAP8zPkecTT0HdQ",
- "x7Y3mV4AwyJZImXY7+A4U2N7iJ1zwp3iO8Xns1Z8gr2+03vuXA9fmOuhR8txVn+eD1E0dlWAzpciA3+x",
- "KmYzV5SyT/tp9soy5Kk0XRbEfhnVcuwlLFvCiXnzZzvFXkVsDXZLLWqBZ5ClIBU8UwOiONyol5VDeNHU",
- "D8CN32xWO+BhceUqJpcm2bdBzasOJZA28hX2OPPFOR0yMjgnhgAneyDbg4/2X3SnFUJFVnPiCbizMffd",
- "tthqo3bcBoDkDSqhrqO/+0rMyCNbdLTkmFlYNzOlPCNaro2i6mssSaA5SRsZRRUc3ZNz0ntytpoCndX1",
- "rCluC4j6hO4zgqGVzfnTjR+A55Q7ku8iSAtCCYc51ewc/JX/5K4CyKWlmau/sYEBjgnNMnsa602Ac5Br",
- "osqpMroObwaG31PN87IDw4BVAZIZEU3z+gLemgkHtrzHpjiiE/vGFYVWixfZoiKyGbXoJasrOSJm5BVL",
- "pTjK50L5OFS1VhqWnVah7tPfe4pEe0dCN2ZV8JxxSJaCxxpY/oxPX+HD2NdYIqXv41PzsO/blrxtwt8C",
- "qznPEJl8Vfx+Jqf/SoEurdVKKIQ01u3UNtW29L/jUfKHZs3T7kla8zS41HIPg4HCdpeNnw8+Nv50xX3c",
- "m2pR6kxcBN+iZW+DFIfU9Qga61/Ck9ZqUK+u15d2nXdIAR5iJ6Z6GmlVWD/s71b4F81nc1cuIZFgqHkq",
- "zkGqlnl2l9T2p0pqG7zvO/FY25p3G0cr1X41ktciAztuszN2rJ48Fxm4DsJdRaQKdownAnmpVL/XSs1I",
- "aTlfaFIWRItYEkj9YUJTy2QTa97EJwwqOFojCKdb0HMgNMe+zGQKwImYmkXX8hEXSRXW0PSZJC6kM6oK",
- "BXAVUqSgFGSJr5+/DbSqLzMGoOsNeELAEeBqFqIEmVF5ZWDPzrfCeQbrBE1cRe7/9KsxmG8cXqsKbkas",
- "rdwXQW9VHchpe12oh02/ieDak4dkRyUQrxpg4ptYFjm41LcICnfCSe/+tSHq7OLV0YK5YeyaKd5PcjUC",
- "qkC9Znq/KrRlkRj53QXxuX16ypaoiXHKhfcrxgbLqdLJNrZsXgrXoswKAk4Y48Q4cI/B+ZIq/dZlQWdY",
- "McuKE5zH6thmin6Aq078sZF/tQ9jY6dGHnJVKuJG8JlNkMXWwGG1Ya7XsKrmwjR0P3aVOmU9fNtG7sNS",
- "ML5DVtBEgFAd3Oab4SKLQ/8jdQ6KLiobQNSI2ATIiX8rwG54jd8DCFM1oi3hYFHkkHKmQuRAuc1AFUVh",
- "uIVOSl5914emE/v2kf6lfrdLXFTXcjsToMK0Ngf5hcWsQgftgiri4CBLeuYy3+auKVwXZnMYE6xYkWyi",
- "fHTZmrfCI7D1kJbFXNIMkgxyGnGl/GIfE/t40wC44548k3OhIZnCTEiIb3pNybLXRVQNLXA8FVMeCT4h",
- "qTmCxniuCcR9vWXkDHDsGHNydHSvGgrnim6RHw+Xbbe6xy1lxjA77ugBQXYcfQjAPXiohr48KvDjpHYf",
- "tKf4Jyg3QaVH7D7JGlTfEurxd1pA250XCrCGpGix9xYHjrLNXja2hY/0HdmYA/GLdPa3Y5euMXWu6UAN",
- "DMDJZYzbgwvKdDIT0irSCZ1pkFsD4v9Bmb8O90m5wtVSITiCk5tuHGTyYWsex0UsCMSJC0MiE3K6AAlG",
- "hlHymCwZL7V9Iko9tpVEJdB0YZT20LNqR8Lmiq7doIQ5lVmOjfdmldwUEoUR0y0Bj0BHsgybFr9Z9w9C",
- "DqpP3KzCRZkmJdcsD3o0VHb75+e9vPNI3Hkk7jwSdx6JO4/EnUfiziNx55G480jceSTuPBJ3Hom/rkfi",
- "toofJV7j8HUYueBJO0TyLkLyT1WgtxJV3kGC3okLyrTrOOxrD/T7LXZwBGmgOeKA5dAfs21DSU+/P3pJ",
- "lChlCiQ1EDJOipwa0wBWuup/2eys7Hu+2ya6tmkzVfD0CTn5+5GvI7pw9S6b794/sg3eiNLrHB64DjPA",
- "M6uJ+lYzwA3SXacZ6kWC75PpuoayHOPdFfke334B55CLAqQtUUi0LCON5k+B5s8dbrY4fP5hJncBtB/M",
- "aB/GDaeXQ9uSFl7N92ulilCbR0leBJmVH2Y0V/ChL7nSjrekRaxVZSX4rCsImcl3Ilu3TojZtQPcwObZ",
- "qKuJMk7lOlL7qZvY0CYNLQy7coTV9WV92nvN2y7RdslsG4XFtHUJKnqON1F5tNhrtWGdoWz67axFJ6NY",
- "5mi7wumoAnBQuT9MfrB7Qt7a7263uB9C5I5Yzcw/myjG5psV08B3jRHhWM+XmiHgER89vXj2x4awszIF",
- "wrQivmzudvEyHq0SM9IceOIYUDIV2TppsK9RQwplTFGlYDndLolC/umaszvhY55sllO3I0ZeBIvbxJND",
- "olkljgH3cOe1hsG8ucIWjujYc4Dx62bRfWw0BIE4/hRzKrV4365Mr55mfcf47hhfcBpbGgHjrsx4m4lM",
- "rpHxybUseT/P+34FaWmAC0/yffTO45UcrHTjkjWDaTmfY5P5zh2dWRrgeEzwW2KFdrlDueBuFGQHrxoP",
- "XzX1vD1cl7sE2eD3fb3FB7gdlK/xMmNZUL72V76QKLYsc4tD259zv4zWVgKPFY6ufX99Xu033uUX+G6d",
- "qG3+btFCLqgidn8hIyXPXB5Tp2L1ig+vXmKHPl3xmk1vrFRi1xtZnZt3iIjwu9xMIFekAJnoFbcHqnGY",
- "XF8Ce3Ind821/xpiw6afQw+D7dbYrxnCnqSHDPgaio+gk1KdmNfor0SbSYKNZ+jR6E9xCVsu2Tf3GljS",
- "Gb4ZX1K7W9z9KeQFoSTNGd6uCq60LFP9jlO8vwkWNunGnnhHdT/ve+5fiV8hRm743FDvOMUgo+pWJ8oD",
- "ZxC5wvgBwLNYVc7noAwfDQloBvCOu7cYJyU3VpiYkSVLpUhswqw5X0Z3mdg3l3RNZlinRJA/QAoyNVI/",
- "2HXrS1aa5bkLdjHTEDF7x6kmOVClyStmOLAZzhdJqELOQF8IeVZhId6BZw4cFFNJ3DHzo32KTW7c8r0D",
- "EJ2Z9nHdnOJmu9t42FnWC/nxC4xRwxrLOVO6jo/owH5jd+NLxpMokZ0ugLhwsTZtkftY2c0R0IPmxZFe",
- "wDtupJ8WBDk+1Zcjh/YNUOcs2tPRoprGRrQuivxaB5l/e+EyJMJk7q5d/kQppAEd+JtN3HhbNb+19zte",
- "sTRELvDMPO0RyPapa4rY85IzIBpOslbZGvfGaQPkjfcXX36xyP3bkh6Ne7MmuwN22VWz7R3izW/4mNBc",
- "8LmtlmisS4H7xHhRagwAv04HHpzTPBHnICXLQA1cKRP8+3Oa/1x99mk8ghWkiZY0hcR6FIZi7dR8Y+l0",
- "myANmn8ul5AxqiFfk0JCCpmtC8YUqQ3xia2sQNIF5XOUuVKU84V9zY5zARKqPonG9m0PEa/LsuKJrRHX",
- "hfGIWCdmWEYXaLqI9HFByWSMbU8JWaNF1EDkNSqA9lnX41GvhmyQel7HvFnkNPnDAPHfEOQBfuqJ91Ey",
- "9Y5a76j11qg1VpoQUTdr+QcsvsJtuWZH0nUX4rxBv9StVOm9K3X/Zy917zmQIpRI2tD64z3WqCJMkwss",
- "RDQFYgRPif5w17jOWciY2xYcdVexUrk2d+mCMu6q2FSZBAiHdl3XtW/zei2uRMvM0Ido0AFpKZleo51A",
- "C/b7GZj/vzeKtgJ57k2IUuajw9FC6+Lw4CAXKc0XQumD0adx+Ey1Hr6v4P/otf9CsnNj0Xx6/+n/BgAA",
- "//+Ly7CKlp8BAA==",
+ "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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 97d1f43bd6..49c6517c19 100644
--- a/daemon/algod/api/server/v2/generated/participating/private/routes.go
+++ b/daemon/algod/api/server/v2/generated/participating/private/routes.go
@@ -158,209 +158,213 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
// Base64 encoded, gzipped, json marshaled Swagger object
var swaggerSpec = []string{
- "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",
+ "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",
+ "16auAQEA",
}
// 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 eb278fd54e..3003f8b27d 100644
--- a/daemon/algod/api/server/v2/generated/participating/public/routes.go
+++ b/daemon/algod/api/server/v2/generated/participating/public/routes.go
@@ -232,163 +232,166 @@ var swaggerSpec = []string{
"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",
- "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",
- "ou8//v8AAAD//1ZZbzCCCQEA",
+ "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",
}
// 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 7b190acd52..1a013b8477 100644
--- a/daemon/algod/api/server/v2/handlers.go
+++ b/daemon/algod/api/server/v2/handlers.go
@@ -1003,6 +1003,7 @@ type PreEncodedSimulateResponse struct {
TxnGroups []PreEncodedSimulateTxnGroupResult `codec:"txn-groups"`
EvalOverrides *model.SimulationEvalOverrides `codec:"eval-overrides,omitempty"`
ExecTraceConfig simulation.ExecTraceConfig `codec:"exec-trace-config,omitempty"`
+ InitialStates *model.SimulateInitialStates `codec:"initial-states,omitempty"`
}
// PreEncodedSimulateRequestTransactionGroup mirrors model.SimulateRequestTransactionGroup
diff --git a/daemon/algod/api/server/v2/test/handlers_test.go b/daemon/algod/api/server/v2/test/handlers_test.go
index d59d9c971c..48f89538bb 100644
--- a/daemon/algod/api/server/v2/test/handlers_test.go
+++ b/daemon/algod/api/server/v2/test/handlers_test.go
@@ -1810,9 +1810,11 @@ func TestGetProofDefault(t *testing.T) {
blkHdr, err := l.BlockHdr(1)
a.NoError(err)
- singleLeafProof, err := merklearray.ProofDataToSingleLeafProof(string(resp.Hashtype), resp.Treedepth, resp.Proof)
+ singleLeafProof, err := merklearray.ProofDataToSingleLeafProof(string(resp.Hashtype), resp.Proof)
a.NoError(err)
+ a.Equal(uint64(singleLeafProof.TreeDepth), resp.Treedepth)
+
element := TxnMerkleElemRaw{Txn: crypto.Digest(txid)}
copy(element.Stib[:], resp.Stibhash[:])
elems := make(map[uint64]crypto.Hashable)
diff --git a/daemon/algod/api/server/v2/utils.go b/daemon/algod/api/server/v2/utils.go
index 8cdf37a1d9..bc7e71527c 100644
--- a/daemon/algod/api/server/v2/utils.go
+++ b/daemon/algod/api/server/v2/utils.go
@@ -79,6 +79,16 @@ func convertSlice[X any, Y any](input []X, fn func(X) Y) []Y {
return output
}
+func convertMap[X comparable, Y, Z any](input map[X]Y, fn func(X, Y) Z) []Z {
+ output := make([]Z, len(input))
+ counter := 0
+ for x, y := range input {
+ output[counter] = fn(x, y)
+ counter++
+ }
+ return output
+}
+
func uint64Slice[T ~uint64](s []T) []uint64 {
return convertSlice(s, func(t T) uint64 { return uint64(t) })
}
@@ -494,6 +504,51 @@ func convertUnnamedResourcesAccessed(resources *simulation.ResourceTracker) *mod
}
}
+func convertAppKVStorePtr(address basics.Address, appKVPairs simulation.AppKVPairs) *model.ApplicationKVStorage {
+ if len(appKVPairs) == 0 && address.IsZero() {
+ return nil
+ }
+ return &model.ApplicationKVStorage{
+ Account: addrOrNil(address),
+ Kvs: convertMap(appKVPairs, func(key string, value basics.TealValue) model.AvmKeyValue {
+ return model.AvmKeyValue{
+ Key: []byte(key),
+ Value: convertToAVMValue(value),
+ }
+ }),
+ }
+}
+
+func convertAppKVStoreInstance(address basics.Address, appKVPairs simulation.AppKVPairs) model.ApplicationKVStorage {
+ return model.ApplicationKVStorage{
+ Account: addrOrNil(address),
+ Kvs: convertMap(appKVPairs, func(key string, value basics.TealValue) model.AvmKeyValue {
+ return model.AvmKeyValue{
+ Key: []byte(key),
+ Value: convertToAVMValue(value),
+ }
+ }),
+ }
+}
+
+func convertApplicationInitialStates(appID basics.AppIndex, states simulation.SingleAppInitialStates) model.ApplicationInitialStates {
+ return model.ApplicationInitialStates{
+ Id: uint64(appID),
+ AppBoxes: convertAppKVStorePtr(basics.Address{}, states.AppBoxes),
+ AppGlobals: convertAppKVStorePtr(basics.Address{}, states.AppGlobals),
+ AppLocals: sliceOrNil(convertMap(states.AppLocals, convertAppKVStoreInstance)),
+ }
+}
+
+func convertSimulateInitialStates(initialStates *simulation.ResourcesInitialStates) *model.SimulateInitialStates {
+ if initialStates == nil {
+ return nil
+ }
+ return &model.SimulateInitialStates{
+ AppInitialStates: sliceOrNil(convertMap(initialStates.AllAppsInitialStates, convertApplicationInitialStates)),
+ }
+}
+
func convertTxnGroupResult(txnGroupResult simulation.TxnGroupResult) PreEncodedSimulateTxnGroupResult {
txnResults := make([]PreEncodedSimulateTxnResult, len(txnGroupResult.Txns))
for i, txnResult := range txnGroupResult.Txns {
@@ -528,19 +583,14 @@ func convertSimulationResult(result simulation.Result) PreEncodedSimulateRespons
}
}
- encodedSimulationResult := PreEncodedSimulateResponse{
+ return PreEncodedSimulateResponse{
Version: result.Version,
LastRound: uint64(result.LastRound),
- TxnGroups: make([]PreEncodedSimulateTxnGroupResult, len(result.TxnGroups)),
+ TxnGroups: convertSlice(result.TxnGroups, convertTxnGroupResult),
EvalOverrides: evalOverrides,
ExecTraceConfig: result.TraceConfig,
+ InitialStates: convertSimulateInitialStates(result.InitialStates),
}
-
- for i, txnGroup := range result.TxnGroups {
- encodedSimulationResult.TxnGroups[i] = convertTxnGroupResult(txnGroup)
- }
-
- return encodedSimulationResult
}
func convertSimulationRequest(request PreEncodedSimulateRequest) simulation.Request {
diff --git a/data/transactions/logic/assembler.go b/data/transactions/logic/assembler.go
index 77b8209d96..a5a4715579 100644
--- a/data/transactions/logic/assembler.go
+++ b/data/transactions/logic/assembler.go
@@ -1778,14 +1778,14 @@ func mergeProtos(specs map[int]OpSpec) (Proto, uint64, bool) {
}
}
if debugExplainFuncPtr == nil {
- debugExplainFuncPtr = spec.Explain
+ debugExplainFuncPtr = spec.StackExplain
}
i++
}
return Proto{
- Arg: typedList{args, ""},
- Return: typedList{returns, ""},
- Explain: debugExplainFuncPtr,
+ Arg: typedList{args, ""},
+ Return: typedList{returns, ""},
+ StackExplain: debugExplainFuncPtr,
}, minVersion, true
}
diff --git a/data/transactions/logic/opcodeExplain.go b/data/transactions/logic/opcodeExplain.go
index ec95d97d1b..4b4f965a65 100644
--- a/data/transactions/logic/opcodeExplain.go
+++ b/data/transactions/logic/opcodeExplain.go
@@ -32,6 +32,9 @@ const (
// AppStateDelete stands for deleting an app state.
AppStateDelete
+
+ // AppStateRead stands for reading from an app state.
+ AppStateRead
)
// AppStateEnum stands for the enum of app state type, should be one of global/local/box.
@@ -165,6 +168,20 @@ func opMatchStackChange(cx *EvalContext) (deletions, additions int) {
return
}
+func opBoxExtractStateChange(cx *EvalContext) (AppStateEnum, AppStateOpEnum, basics.AppIndex, basics.Address, string) {
+ last := len(cx.Stack) - 1 // length
+ prev := last - 1 // start
+ pprev := prev - 1 // name
+
+ return BoxState, AppStateRead, cx.appID, basics.Address{}, string(cx.Stack[pprev].Bytes)
+}
+
+func opBoxGetStateChange(cx *EvalContext) (AppStateEnum, AppStateOpEnum, basics.AppIndex, basics.Address, string) {
+ last := len(cx.Stack) - 1 // name
+
+ return BoxState, AppStateRead, cx.appID, basics.Address{}, string(cx.Stack[last].Bytes)
+}
+
func opBoxCreateStateChange(cx *EvalContext) (AppStateEnum, AppStateOpEnum, basics.AppIndex, basics.Address, string) {
last := len(cx.Stack) - 1 // size
prev := last - 1 // name
@@ -187,9 +204,51 @@ func opBoxDelStateChange(cx *EvalContext) (AppStateEnum, AppStateOpEnum, basics.
}
func opBoxPutStateChange(cx *EvalContext) (AppStateEnum, AppStateOpEnum, basics.AppIndex, basics.Address, string) {
- last := len(cx.Stack) - 1 // name
+ last := len(cx.Stack) - 1 // value
+ prev := last - 1 // name
+
+ return BoxState, AppStateWrite, cx.appID, basics.Address{}, string(cx.Stack[prev].Bytes)
+}
+
+func opAppLocalGetStateChange(cx *EvalContext) (AppStateEnum, AppStateOpEnum, basics.AppIndex, basics.Address, string) {
+ last := len(cx.Stack) - 1 // state key
+ prev := last - 1 // account
+
+ // NOTE: we swallow the error of finding account ref, for eventually it would error in execution time,
+ // and we don't have to complain here.
+ var addr basics.Address
+ addr, _, _, _ = cx.localsReference(cx.Stack[prev], 0)
+
+ return LocalState, AppStateRead, cx.appID, addr, string(cx.Stack[last].Bytes)
+}
+
+func opAppLocalGetExStateChange(cx *EvalContext) (AppStateEnum, AppStateOpEnum, basics.AppIndex, basics.Address, string) {
+ last := len(cx.Stack) - 1 // state key
+ prev := last - 1 // app id
+ pprev := prev - 1 // account
+
+ // NOTE: we swallow the error of finding account ref, for eventually it would error in execution time,
+ // and we don't have to complain here.
+ addr, appID, _, _ := cx.localsReference(cx.Stack[pprev], cx.Stack[prev].Uint)
+
+ return LocalState, AppStateRead, appID, addr, string(cx.Stack[last].Bytes)
+}
+
+func opAppGlobalGetStateChange(cx *EvalContext) (AppStateEnum, AppStateOpEnum, basics.AppIndex, basics.Address, string) {
+ last := len(cx.Stack) - 1 // state key
+
+ return GlobalState, AppStateRead, cx.appID, basics.Address{}, string(cx.Stack[last].Bytes)
+}
+
+func opAppGlobalGetExStateChange(cx *EvalContext) (AppStateEnum, AppStateOpEnum, basics.AppIndex, basics.Address, string) {
+ last := len(cx.Stack) - 1 // state key
+ prev := last - 1 // app id
- return BoxState, AppStateWrite, cx.appID, basics.Address{}, string(cx.Stack[last].Bytes)
+ // NOTE: we swallow the error of finding application ID, for eventually it would error in execution time,
+ // and we don't have to complain here.
+ appID, _ := cx.appReference(cx.Stack[prev].Uint, true)
+
+ return GlobalState, AppStateRead, appID, basics.Address{}, string(cx.Stack[last].Bytes)
}
func opAppLocalPutStateChange(cx *EvalContext) (AppStateEnum, AppStateOpEnum, basics.AppIndex, basics.Address, string) {
@@ -230,18 +289,15 @@ func opAppGlobalDelStateChange(cx *EvalContext) (AppStateEnum, AppStateOpEnum, b
return GlobalState, AppStateDelete, cx.appID, basics.Address{}, string(cx.Stack[last].Bytes)
}
-// AppNewStateQuerying is used only for simulation endpoint exec trace export:
+// AppStateQuerying is used for simulation endpoint exec trace export:
// it reads *new* app state after opcode that writes to app-state.
// Since it is collecting new/updated app state, we don't have to error again here,
// and thus we omit the error or non-existence case, just returning empty TealValue.
// Otherwise, we find the updated new state value, and wrap up with new TealValue.
-func AppNewStateQuerying(
+func AppStateQuerying(
cx *EvalContext,
appState AppStateEnum, stateOp AppStateOpEnum,
appID basics.AppIndex, account basics.Address, key string) basics.TealValue {
- if stateOp != AppStateWrite {
- return basics.TealValue{}
- }
switch appState {
case BoxState:
boxBytes, exists, err := cx.Ledger.GetBox(appID, key)
@@ -259,7 +315,17 @@ func AppNewStateQuerying(
}
return globalValue
case LocalState:
- addr, acctID, err := cx.mutableAccountReference(stackValue{Bytes: account[:]})
+ var (
+ addr basics.Address
+ acctID uint64
+ err error
+ )
+ switch stateOp {
+ case AppStateWrite, AppStateDelete:
+ addr, acctID, err = cx.mutableAccountReference(stackValue{Bytes: account[:]})
+ default:
+ addr, _, acctID, err = cx.localsReference(stackValue{Bytes: account[:]}, uint64(appID))
+ }
if err != nil {
return basics.TealValue{}
}
diff --git a/data/transactions/logic/opcodes.go b/data/transactions/logic/opcodes.go
index 4b6a9000eb..e005d57cf3 100644
--- a/data/transactions/logic/opcodes.go
+++ b/data/transactions/logic/opcodes.go
@@ -392,24 +392,24 @@ type Proto struct {
Arg typedList // what gets popped from the stack
Return typedList // what gets pushed to the stack
- // Explain is the pointer to the function used in debugging process during simulation:
- // - on default construction, Explain relies on Arg and Return count.
+ // StackExplain is the pointer to the function used in debugging process during simulation:
+ // - on default construction, StackExplain relies on Arg and Return count.
// - otherwise, we need to explicitly infer from EvalContext, by registering through explain function
- Explain debugStackExplain
+ StackExplain debugStackExplain
- // StateExplain is the pointer to the function used for debugging in simulation:
+ // AppStateExplain is the pointer to the function used for debugging in simulation:
// - for an opcode not touching app's local/global/box state, this pointer is nil.
// - otherwise, we call this method and check the operation of an opcode on app's state.
- StateExplain stateChangeExplain
+ AppStateExplain stateChangeExplain
}
func (p Proto) stackExplain(e debugStackExplain) Proto {
- p.Explain = e
+ p.StackExplain = e
return p
}
-func (p Proto) stateExplain(s stateChangeExplain) Proto {
- p.StateExplain = s
+func (p Proto) appStateExplain(s stateChangeExplain) Proto {
+ p.AppStateExplain = s
return p
}
@@ -442,9 +442,9 @@ func proto(signature string, effects ...string) Proto {
retTypes := parseStackTypes(parts[1])
debugExplainFunc := defaultDebugExplain(len(filterNoneTypes(argTypes)), len(filterNoneTypes(retTypes)))
return Proto{
- Arg: typedList{argTypes, argEffect},
- Return: typedList{retTypes, retEffect},
- Explain: debugExplainFunc,
+ Arg: typedList{argTypes, argEffect},
+ Return: typedList{retTypes, retEffect},
+ StackExplain: debugExplainFunc,
}
}
@@ -618,18 +618,18 @@ var OpSpecs = []OpSpec{
{0x60, "balance", opBalance, proto("a:i"), directRefEnabledVersion, only(ModeApp)},
{0x61, "app_opted_in", opAppOptedIn, proto("ii:T"), 2, only(ModeApp)},
{0x61, "app_opted_in", opAppOptedIn, proto("ai:T"), directRefEnabledVersion, only(ModeApp)},
- {0x62, "app_local_get", opAppLocalGet, proto("ib:a"), 2, only(ModeApp)},
- {0x62, "app_local_get", opAppLocalGet, proto("ab:a"), directRefEnabledVersion, only(ModeApp)},
- {0x63, "app_local_get_ex", opAppLocalGetEx, proto("iib:aT"), 2, only(ModeApp)},
- {0x63, "app_local_get_ex", opAppLocalGetEx, proto("aib:aT"), directRefEnabledVersion, only(ModeApp)},
- {0x64, "app_global_get", opAppGlobalGet, proto("b:a"), 2, only(ModeApp)},
- {0x65, "app_global_get_ex", opAppGlobalGetEx, proto("ib:aT"), 2, only(ModeApp)},
- {0x66, "app_local_put", opAppLocalPut, proto("iba:").stateExplain(opAppLocalPutStateChange), 2, only(ModeApp)},
- {0x66, "app_local_put", opAppLocalPut, proto("aba:").stateExplain(opAppLocalPutStateChange), directRefEnabledVersion, only(ModeApp)},
- {0x67, "app_global_put", opAppGlobalPut, proto("ba:").stateExplain(opAppGlobalPutStateChange), 2, only(ModeApp)},
- {0x68, "app_local_del", opAppLocalDel, proto("ib:").stateExplain(opAppLocalDelStateChange), 2, only(ModeApp)},
- {0x68, "app_local_del", opAppLocalDel, proto("ab:").stateExplain(opAppLocalDelStateChange), directRefEnabledVersion, only(ModeApp)},
- {0x69, "app_global_del", opAppGlobalDel, proto("b:").stateExplain(opAppGlobalDelStateChange), 2, only(ModeApp)},
+ {0x62, "app_local_get", opAppLocalGet, proto("ib:a").appStateExplain(opAppLocalGetStateChange), 2, only(ModeApp)},
+ {0x62, "app_local_get", opAppLocalGet, proto("ab:a").appStateExplain(opAppLocalGetStateChange), directRefEnabledVersion, only(ModeApp)},
+ {0x63, "app_local_get_ex", opAppLocalGetEx, proto("iib:aT").appStateExplain(opAppLocalGetExStateChange), 2, only(ModeApp)},
+ {0x63, "app_local_get_ex", opAppLocalGetEx, proto("aib:aT").appStateExplain(opAppLocalGetExStateChange), directRefEnabledVersion, only(ModeApp)},
+ {0x64, "app_global_get", opAppGlobalGet, proto("b:a").appStateExplain(opAppGlobalGetStateChange), 2, only(ModeApp)},
+ {0x65, "app_global_get_ex", opAppGlobalGetEx, proto("ib:aT").appStateExplain(opAppGlobalGetExStateChange), 2, only(ModeApp)},
+ {0x66, "app_local_put", opAppLocalPut, proto("iba:").appStateExplain(opAppLocalPutStateChange), 2, only(ModeApp)},
+ {0x66, "app_local_put", opAppLocalPut, proto("aba:").appStateExplain(opAppLocalPutStateChange), directRefEnabledVersion, only(ModeApp)},
+ {0x67, "app_global_put", opAppGlobalPut, proto("ba:").appStateExplain(opAppGlobalPutStateChange), 2, only(ModeApp)},
+ {0x68, "app_local_del", opAppLocalDel, proto("ib:").appStateExplain(opAppLocalDelStateChange), 2, only(ModeApp)},
+ {0x68, "app_local_del", opAppLocalDel, proto("ab:").appStateExplain(opAppLocalDelStateChange), directRefEnabledVersion, only(ModeApp)},
+ {0x69, "app_global_del", opAppGlobalDel, proto("b:").appStateExplain(opAppGlobalDelStateChange), 2, only(ModeApp)},
{0x70, "asset_holding_get", opAssetHoldingGet, proto("ii:aT"), 2, field("f", &AssetHoldingFields).only(ModeApp)},
{0x70, "asset_holding_get", opAssetHoldingGet, proto("ai:aT"), directRefEnabledVersion, field("f", &AssetHoldingFields).only(ModeApp)},
{0x71, "asset_params_get", opAssetParamsGet, proto("i:aT"), 2, field("f", &AssetParamsFields).only(ModeApp)},
@@ -701,13 +701,13 @@ var OpSpecs = []OpSpec{
{0xb8, "gitxna", opGitxna, proto(":a"), 6, immediates("t", "f", "i").field("f", &TxnArrayFields).only(ModeApp)},
// Unlimited Global Storage - Boxes
- {0xb9, "box_create", opBoxCreate, proto("Ni:T").stateExplain(opBoxCreateStateChange), boxVersion, only(ModeApp)},
- {0xba, "box_extract", opBoxExtract, proto("Nii:b"), boxVersion, only(ModeApp)},
- {0xbb, "box_replace", opBoxReplace, proto("Nib:").stateExplain(opBoxReplaceStateChange), boxVersion, only(ModeApp)},
- {0xbc, "box_del", opBoxDel, proto("N:T").stateExplain(opBoxDelStateChange), boxVersion, only(ModeApp)},
- {0xbd, "box_len", opBoxLen, proto("N:iT"), boxVersion, only(ModeApp)},
- {0xbe, "box_get", opBoxGet, proto("N:bT"), boxVersion, only(ModeApp)},
- {0xbf, "box_put", opBoxPut, proto("Nb:").stateExplain(opBoxPutStateChange), boxVersion, only(ModeApp)},
+ {0xb9, "box_create", opBoxCreate, proto("Ni:T").appStateExplain(opBoxCreateStateChange), boxVersion, only(ModeApp)},
+ {0xba, "box_extract", opBoxExtract, proto("Nii:b").appStateExplain(opBoxExtractStateChange), boxVersion, only(ModeApp)},
+ {0xbb, "box_replace", opBoxReplace, proto("Nib:").appStateExplain(opBoxReplaceStateChange), boxVersion, only(ModeApp)},
+ {0xbc, "box_del", opBoxDel, proto("N:T").appStateExplain(opBoxDelStateChange), boxVersion, only(ModeApp)},
+ {0xbd, "box_len", opBoxLen, proto("N:iT").appStateExplain(opBoxGetStateChange), boxVersion, only(ModeApp)},
+ {0xbe, "box_get", opBoxGet, proto("N:bT").appStateExplain(opBoxGetStateChange), boxVersion, only(ModeApp)},
+ {0xbf, "box_put", opBoxPut, proto("Nb:").appStateExplain(opBoxPutStateChange), boxVersion, only(ModeApp)},
// Dynamic indexing
{0xc0, "txnas", opTxnas, proto("i:a"), 5, field("f", &TxnArrayFields)},
diff --git a/docker/README.md b/docker/README.md
index d218b10139..68b43feee7 100644
--- a/docker/README.md
+++ b/docker/README.md
@@ -6,7 +6,7 @@ General purpose algod container image.
## Image Configuration
-Algorand maintains a Docker image with recent snapshot builds from our `master` branch on DockerHub to support users who prefer to run containerized processes. There are a couple of different images avaliable for running the latest stable or development versions of Algod.
+Algorand maintains a Docker image with recent snapshot builds from our `master` branch on DockerHub to support users who prefer to run containerized processes. There are a couple of different images available for running the latest stable or development versions of Algod.
- `algorand/algod:latest` is the latest stable release version of Algod (default)
- `algorand/algod:stable` is the latest stable version of Algod
diff --git a/go.mod b/go.mod
index d45f221f5a..3abece643d 100644
--- a/go.mod
+++ b/go.mod
@@ -26,10 +26,12 @@ require (
github.com/google/go-cmp v0.5.9
github.com/google/go-querystring v1.0.0
github.com/gorilla/mux v1.8.0
+ github.com/ipfs/go-log v1.0.5
github.com/jmoiron/sqlx v1.2.0
github.com/karalabe/usb v0.0.2
github.com/labstack/echo/v4 v4.9.1
github.com/libp2p/go-libp2p v0.29.1
+ github.com/libp2p/go-libp2p-kad-dht v0.24.3
github.com/libp2p/go-libp2p-pubsub v0.9.3
github.com/libp2p/go-yamux/v4 v4.0.1
github.com/mattn/go-sqlite3 v1.14.16
@@ -70,6 +72,8 @@ require (
github.com/flynn/noise v1.0.0 // indirect
github.com/fortytw2/leaktest v1.3.0 // indirect
github.com/francoispqt/gojay v1.2.13 // indirect
+ github.com/go-logr/logr v1.2.4 // indirect
+ github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/swag v0.19.5 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
@@ -82,14 +86,21 @@ require (
github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
+ github.com/hashicorp/errwrap v1.1.0 // indirect
+ github.com/hashicorp/go-multierror v1.1.1 // indirect
+ github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.2 // indirect
github.com/huin/goupnp v1.2.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/invopop/yaml v0.1.0 // indirect
+ github.com/ipfs/boxo v0.10.0 // indirect
github.com/ipfs/go-cid v0.4.1 // indirect
+ github.com/ipfs/go-datastore v0.6.0 // indirect
github.com/ipfs/go-log/v2 v2.5.1 // indirect
+ github.com/ipld/go-ipld-prime v0.20.0 // indirect
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
+ github.com/jbenet/goprocess v0.1.4 // indirect
github.com/jmespath/go-jmespath v0.3.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/klauspost/compress v1.16.7 // indirect
@@ -102,6 +113,8 @@ require (
github.com/libp2p/go-cidranger v1.1.0 // indirect
github.com/libp2p/go-flow-metrics v0.1.0 // indirect
github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect
+ github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect
+ github.com/libp2p/go-libp2p-record v0.2.0 // indirect
github.com/libp2p/go-msgio v0.3.0 // indirect
github.com/libp2p/go-nat v0.2.0 // indirect
github.com/libp2p/go-netroute v0.2.1 // indirect
@@ -127,14 +140,16 @@ require (
github.com/multiformats/go-varint v0.0.7 // indirect
github.com/onsi/ginkgo/v2 v2.11.0 // indirect
github.com/opencontainers/runtime-spec v1.0.2 // 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/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.14.0 // indirect
github.com/prometheus/client_model v0.4.0 // indirect
- github.com/prometheus/common v0.37.0 // indirect
- github.com/prometheus/procfs v0.8.0 // indirect
+ github.com/prometheus/common v0.42.0 // indirect
+ github.com/prometheus/procfs v0.9.0 // indirect
github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/qtls-go1-19 v0.3.3 // indirect
github.com/quic-go/qtls-go1-20 v0.2.3 // indirect
@@ -148,6 +163,11 @@ require (
github.com/stretchr/objx v0.5.0 // indirect
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
+ go.opencensus.io v0.24.0 // indirect
+ go.opentelemetry.io/otel v1.16.0 // indirect
+ go.opentelemetry.io/otel/metric v1.16.0 // indirect
+ go.opentelemetry.io/otel/trace v1.16.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/dig v1.17.0 // indirect
go.uber.org/fx v1.20.0 // indirect
@@ -159,6 +179,7 @@ require (
golang.org/x/term v0.10.0 // indirect
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 // indirect
golang.org/x/tools v0.11.0 // indirect
+ gonum.org/v1/gonum v0.13.0 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
diff --git a/go.sum b/go.sum
index cf7902eaa7..475b233299 100644
--- a/go.sum
+++ b/go.sum
@@ -2,45 +2,13 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo=
-cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
-cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
-cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
-cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
-cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
-cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
-cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
-cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
-cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
-cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
-cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
-cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
-cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
-cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
-cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
-cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
-cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
-cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
-cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
-cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
-cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
-cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
-cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
-cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
-cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
-cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
-cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
-cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
-cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
-cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
-dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw=
github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w=
github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8=
@@ -50,11 +18,6 @@ github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4K
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0=
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
-github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
-github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
-github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
-github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
-github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/algorand/avm-abi v0.2.0 h1:bkjsG+BOEcxUcnGSALLosmltE0JZdg+ZisXKx0UDX2k=
github.com/algorand/avm-abi v0.2.0/go.mod h1:+CgwM46dithy850bpTeHh9MC99zpn2Snirb3QTl2O/g=
github.com/algorand/falcon v0.1.0 h1:xl832kfZ7hHG6B4p90DQynjfKFGbIUgUOnsRiMZXfAo=
@@ -87,7 +50,6 @@ github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZx
github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o=
github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
-github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bits-and-blooms/bitset v1.7.0 h1:YjAGVd3XmtK9ktAbX8Zg2g2PwLIMjGREZJHlV4j7NEo=
@@ -96,14 +58,9 @@ github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvF
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
-github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chrismcguire/gobberish v0.0.0-20150821175641-1d8adb509a0e h1:CHPYEbz71w8DqJ7DRIq+MXyCQsdibK08vdcQTY4ufas=
-github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
-github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
-github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
@@ -181,6 +138,7 @@ github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
+github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
@@ -193,18 +151,11 @@ github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aev
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
-github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
-github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
-github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
-github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
-github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
-github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
-github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
-github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
-github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
-github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
-github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
+github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
+github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
@@ -213,9 +164,9 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
-github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
+github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
@@ -235,25 +186,17 @@ github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
-github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
-github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
-github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
-github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
-github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
-github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
-github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
-github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
@@ -263,52 +206,40 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
-github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
-github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
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/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
-github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
-github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+uqi7GyzaLa5MH7qlSLBZtRdiA=
github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA=
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=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
-github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
-github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
@@ -316,9 +247,14 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
+github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
+github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
+github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
-github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
-github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
+github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/golang-lru/v2 v2.0.2 h1:Dwmkdr5Nc/oBiXgJS3CDHNhJtIHkuZ3DZF5twqnfBdU=
github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
@@ -326,26 +262,38 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY=
github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8=
github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE=
-github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
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.10.0 h1:tdDAxq8jrsbRkYoF+5Rcqyeb91hgWe2hp7iLu7ORZLY=
+github.com/ipfs/boxo v0.10.0/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM=
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=
+github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8=
github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk=
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
+github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8=
+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/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g=
+github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M=
github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI=
github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0=
github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI=
github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw=
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
+github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA=
github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk=
github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk=
+github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o=
+github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4=
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
@@ -353,20 +301,14 @@ github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA=
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
-github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
-github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE=
github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
-github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
-github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
github.com/karalabe/usb v0.0.2 h1:M6QQBNxF+CQ8OFvxrT90BA0qBOXymndZnk5q235mFc4=
github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
@@ -384,11 +326,8 @@ github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQs
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
-github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0=
github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk=
-github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
@@ -417,8 +356,14 @@ github.com/libp2p/go-libp2p v0.29.1 h1:yNeg6XgP8gbdc4YSrwiIt5T1TGOrVjH8dzl8h0GIO
github.com/libp2p/go-libp2p v0.29.1/go.mod h1:20El+LLy3/YhdUYIvGbLnvVJN32nMdqY6KXBENRAfLY=
github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s=
github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w=
+github.com/libp2p/go-libp2p-kad-dht v0.24.3 h1:VjxtDVWaaf4UFjGBf+yl2JCiGaHx7+ctAUa9oJCR3QE=
+github.com/libp2p/go-libp2p-kad-dht v0.24.3/go.mod h1:BShPzRbK6+fN3hk8a0WGAYKpb8m4k+DtchkqouGTrSg=
+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-pubsub v0.9.3 h1:ihcz9oIBMaCK9kcx+yHWm3mLAFBMAUsM4ux42aikDxo=
github.com/libp2p/go-libp2p-pubsub v0.9.3/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc=
+github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0=
+github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk=
github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA=
github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0=
github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM=
@@ -480,11 +425,8 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh
github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY=
github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU=
github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU=
-github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
@@ -515,8 +457,6 @@ github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqd
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/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
-github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM=
github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
@@ -535,6 +475,8 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc=
github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0=
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
+github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
+github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0=
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y=
@@ -544,41 +486,26 @@ github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCr
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
-github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+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 v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
-github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
-github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
-github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
-github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
-github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
-github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
-github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
-github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
-github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
-github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE=
-github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
+github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
+github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
-github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
-github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
-github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
-github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
-github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
+github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
+github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
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/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9PeJVE=
@@ -625,14 +552,15 @@ github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4=
github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
-github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
-github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
-github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
+github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg=
+github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM=
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
@@ -649,7 +577,6 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@@ -661,12 +588,14 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
@@ -677,6 +606,10 @@ github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
+github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ=
+github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
+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/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=
@@ -685,18 +618,20 @@ github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmv
github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
-github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
-go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
-go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
-go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
-go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
-go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+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.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s=
+go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4=
+go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo=
+go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4=
+go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs=
+go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0=
+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/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
@@ -706,21 +641,22 @@ go.uber.org/fx v1.20.0 h1:ZMC/pnRvhsthOZh9MZjMq5U8Or3mA9zBSPaLnzs3ihQ=
go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0=
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
+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=
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.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
-golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
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-20190605123033-f99c8df09eb5/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=
@@ -731,36 +667,16 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
-golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
-golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
-golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
-golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
-golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
-golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
-golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
-golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
-golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
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-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/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-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
-golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
-golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
-golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/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=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@@ -772,7 +688,6 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -780,48 +695,24 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
-golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
-golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
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=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -829,84 +720,49 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
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-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/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-20210124154548-22da62e12c0c/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=
-golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
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.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
-golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
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=
@@ -917,8 +773,6 @@ golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
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.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 h1:Hir2P/De0WpUhtrKGGjvSb2YxUgyZ7EFOSLIcSSpiwE=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -929,45 +783,15 @@ golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
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-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+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-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
-golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
-golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
-golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
@@ -978,83 +802,33 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
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=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+gonum.org/v1/gonum v0.13.0 h1:a0T3bh+7fhRyqeNbiC3qVHYmkiQgit3wnNan/2c0HMM=
+gonum.org/v1/gonum v0.13.0/go.mod h1:/WPYRckkfWrhWefxyYTfrTtQR0KH4iyHNuzxqXAKyAU=
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
-google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
-google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
-google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
-google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
-google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
-google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
-google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
-google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
-google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
-google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
-google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
-google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
-google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
-google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
-google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
-google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
-google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
-google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
-google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
-google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
-google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
-google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -1063,13 +837,11 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
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.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
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=
@@ -1087,7 +859,6 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
@@ -1101,18 +872,12 @@ grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJd
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
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-20190418001031-e561f6794a2a/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=
-honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=
lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
pgregory.net/rapid v0.6.2 h1:ErW5sL+UKtfBfUTsWHDCoeB+eZKLKMxrSd1VJY6W4bw=
pgregory.net/rapid v0.6.2/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=
-rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
-rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
-rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU=
rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA=
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
diff --git a/installer/config.json.example b/installer/config.json.example
index 62cbe6427b..01192f4ecc 100644
--- a/installer/config.json.example
+++ b/installer/config.json.example
@@ -43,8 +43,9 @@
"EnableAgreementTimeMetrics": false,
"EnableAssembleStats": false,
"EnableBlockService": false,
- "EnableBlockServiceFallbackToArchiver": true,
+ "EnableBlockServiceFallbackToArchiver": false,
"EnableCatchupFromArchiveServers": false,
+ "EnableDHTProviders": false,
"EnableDeveloperAPI": false,
"EnableExperimentalAPI": false,
"EnableFollowMode": false,
diff --git a/ledger/acctupdates.go b/ledger/acctupdates.go
index 7e71a50f74..ca9cd55f72 100644
--- a/ledger/acctupdates.go
+++ b/ledger/acctupdates.go
@@ -93,7 +93,7 @@ const initializingAccountCachesMessageTimeout = 3 * time.Second
// where we end up batching up to 1000 rounds in a single update.
const accountsUpdatePerRoundHighWatermark = 1 * time.Second
-// forceCatchpointFileGeneration defines the CatchpointTracking mode that would be used to
+// forceCatchpointFileGenerationTrackingMode defines the CatchpointTracking mode that would be used to
// force a node to generate catchpoint files.
const forceCatchpointFileGenerationTrackingMode = 99
diff --git a/ledger/catchpointtracker.go b/ledger/catchpointtracker.go
index 5f8e48b005..d3bf1f87ea 100644
--- a/ledger/catchpointtracker.go
+++ b/ledger/catchpointtracker.go
@@ -163,34 +163,16 @@ func (ct *catchpointTracker) initialize(cfg config.Local, paths DirsAndPrefix) {
// the temp file uses the hot data directories
ct.tmpDir = paths.HotGenesisDir
- switch cfg.CatchpointTracking {
- case -1:
- // No catchpoints.
- default:
- // Give a warning, then fall through to case 0.
- logging.Base().Warnf("catchpointTracker: the CatchpointTracking field in the config.json file contains an invalid value (%d). The default value of 0 would be used instead.", cfg.CatchpointTracking)
- fallthrough
- case 0:
- if cfg.Archival && (cfg.CatchpointInterval > 0) {
- ct.catchpointInterval = cfg.CatchpointInterval
- ct.enableGeneratingCatchpointFiles = true
- }
- case 1:
- if cfg.CatchpointInterval > 0 {
- ct.catchpointInterval = cfg.CatchpointInterval
- ct.enableGeneratingCatchpointFiles = cfg.Archival
- }
- case 2:
- if cfg.CatchpointInterval > 0 {
- ct.catchpointInterval = cfg.CatchpointInterval
- ct.enableGeneratingCatchpointFiles = true
- }
- case forceCatchpointFileGenerationTrackingMode:
- if cfg.CatchpointInterval > 0 {
- ct.catchpointInterval = cfg.CatchpointInterval
- ct.enableGeneratingCatchpointFiles = true
- ct.forceCatchpointFileWriting = true
- }
+ if cfg.TracksCatchpoints() {
+ ct.catchpointInterval = cfg.CatchpointInterval
+ }
+ ct.enableGeneratingCatchpointFiles = cfg.StoresCatchpoints()
+
+ // Overwrite previous options if forceCatchpointFileGenerationTrackingMode
+ if cfg.CatchpointTracking == forceCatchpointFileGenerationTrackingMode && cfg.CatchpointInterval > 0 {
+ ct.catchpointInterval = cfg.CatchpointInterval
+ ct.forceCatchpointFileWriting = true
+ ct.enableGeneratingCatchpointFiles = true
}
ct.catchpointFileHistoryLength = cfg.CatchpointFileHistoryLength
diff --git a/ledger/simulation/initialStates.go b/ledger/simulation/initialStates.go
new file mode 100644
index 0000000000..e374719ccc
--- /dev/null
+++ b/ledger/simulation/initialStates.go
@@ -0,0 +1,179 @@
+// Copyright (C) 2019-2023 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 simulation
+
+import (
+ "github.com/algorand/go-algorand/data/basics"
+ "github.com/algorand/go-algorand/data/transactions/logic"
+ "github.com/algorand/go-algorand/util"
+)
+
+// AppKVPairs constructs a KV pair between state key and state value
+type AppKVPairs map[string]basics.TealValue
+
+// SingleAppInitialStates gathers all relevant application on-chain states, including
+// - Application Box states
+// - Application Global states
+// - Application Local states (which is tied to basics.Address)
+type SingleAppInitialStates struct {
+ AppBoxes AppKVPairs
+ CreatedBoxes util.Set[string]
+
+ AppGlobals AppKVPairs
+ CreatedGlobals util.Set[string]
+
+ AppLocals map[basics.Address]AppKVPairs
+ CreatedLocals map[basics.Address]util.Set[string]
+}
+
+// AppsInitialStates maintains a map from basics.AppIndex to SingleAppInitialStates
+type AppsInitialStates map[basics.AppIndex]SingleAppInitialStates
+
+// ResourcesInitialStates gathers all initial states of resources that were accessed during simulation
+type ResourcesInitialStates struct {
+ // AllAppsInitialStates gathers all initial states of apps that were touched (but not created) during simulation
+ AllAppsInitialStates AppsInitialStates
+ // CreatedApp gathers all created applications by appID, blocking initial app states in these apps being recorded
+ CreatedApp util.Set[basics.AppIndex]
+}
+
+func newResourcesInitialStates(request Request) *ResourcesInitialStates {
+ if !request.TraceConfig.State {
+ return nil
+ }
+ return &ResourcesInitialStates{
+ AllAppsInitialStates: make(AppsInitialStates),
+ CreatedApp: make(util.Set[basics.AppIndex]),
+ }
+}
+
+// hasBeenRecorded checks if an application state kv-pair has been recorded in SingleAppInitialStates.
+func (appIS SingleAppInitialStates) hasBeenRecorded(state logic.AppStateEnum, key string, addr basics.Address) (recorded bool) {
+ switch state {
+ case logic.BoxState:
+ _, recorded = appIS.AppBoxes[key]
+ case logic.GlobalState:
+ _, recorded = appIS.AppGlobals[key]
+ case logic.LocalState:
+ if kvs, addrLocalExists := appIS.AppLocals[addr]; addrLocalExists {
+ _, recorded = kvs[key]
+ }
+ }
+ return
+}
+
+// hasBeenCreated checks if an application state kv-pair has been created during simulation.
+func (appIS SingleAppInitialStates) hasBeenCreated(state logic.AppStateEnum, key string, addr basics.Address) (created bool) {
+ switch state {
+ case logic.BoxState:
+ created = appIS.CreatedBoxes.Contains(key)
+ case logic.GlobalState:
+ created = appIS.CreatedGlobals.Contains(key)
+ case logic.LocalState:
+ if kvs, addrLocalExists := appIS.CreatedLocals[addr]; addrLocalExists {
+ created = kvs.Contains(key)
+ }
+ }
+ return
+}
+
+// recordCreation records a newly created application state kv-pair in SingleAppInitialStates during simulation.
+func (appIS SingleAppInitialStates) recordCreation(state logic.AppStateEnum, key string, addr basics.Address) {
+ switch state {
+ case logic.BoxState:
+ appIS.CreatedBoxes.Add(key)
+ case logic.GlobalState:
+ appIS.CreatedGlobals.Add(key)
+ case logic.LocalState:
+ if _, addrLocalExists := appIS.CreatedLocals[addr]; !addrLocalExists {
+ appIS.CreatedLocals[addr] = make(util.Set[string])
+ }
+ appIS.CreatedLocals[addr].Add(key)
+ }
+}
+
+func (appsIS AppsInitialStates) increment(cx *logic.EvalContext) {
+ appState, stateOp, appID, acctAddr, stateKey := cx.GetOpSpec().AppStateExplain(cx)
+ // No matter read or write, once this code-path is triggered, something must be recorded into initial state
+ if _, ok := appsIS[appID]; !ok {
+ appsIS[appID] = SingleAppInitialStates{
+ AppGlobals: make(AppKVPairs),
+ CreatedGlobals: make(util.Set[string]),
+
+ AppBoxes: make(AppKVPairs),
+ CreatedBoxes: make(util.Set[string]),
+
+ AppLocals: make(map[basics.Address]AppKVPairs),
+ CreatedLocals: make(map[basics.Address]util.Set[string]),
+ }
+ }
+
+ // if the state has been recorded, pass
+ if appsIS[appID].hasBeenRecorded(appState, stateKey, acctAddr) {
+ return
+ }
+
+ // if this state is created during simulation, pass
+ if appsIS[appID].hasBeenCreated(appState, stateKey, acctAddr) {
+ return
+ }
+
+ tv := logic.AppStateQuerying(cx, appState, stateOp, appID, acctAddr, stateKey)
+ switch stateOp {
+ case logic.AppStateWrite:
+ // if the unrecorded value to write to is nil, pass
+ // this case means it is creating a state
+ if tv == (basics.TealValue{}) {
+ appsIS[appID].recordCreation(appState, stateKey, acctAddr)
+ return
+ }
+ fallthrough
+ case logic.AppStateDelete:
+ fallthrough
+ case logic.AppStateRead:
+ switch appState {
+ case logic.BoxState:
+ appsIS[appID].AppBoxes[stateKey] = tv
+ case logic.GlobalState:
+ appsIS[appID].AppGlobals[stateKey] = tv
+ case logic.LocalState:
+ if appsIS[appID].AppLocals[acctAddr] == nil {
+ appsIS[appID].AppLocals[acctAddr] = make(AppKVPairs)
+ }
+ appsIS[appID].AppLocals[acctAddr][stateKey] = tv
+ }
+ }
+}
+
+// increment is the entry point of (potentially) adding new initial states to ResourcesInitialStates during simulation.
+// This method is the top entry point of simulate-initial-state, for ResourcesInitialStates captures all initial states.
+// By checking if current opcode has related `Explain` function, this method dispatch incrementing initial states by:
+// +- AppStateExplain exists, then dispatch to AppsInitialStates.increment.
+func (is *ResourcesInitialStates) increment(cx *logic.EvalContext) {
+ // This method only applies on logic.ModeApp
+ if cx.RunMode() == logic.ModeSig {
+ return
+ }
+ // If this method triggers application state changes
+ if cx.GetOpSpec().AppStateExplain != nil {
+ if is.CreatedApp.Contains(cx.AppID()) {
+ return
+ }
+ is.AllAppsInitialStates.increment(cx)
+ }
+ // TODO asset?
+}
diff --git a/ledger/simulation/simulation_eval_test.go b/ledger/simulation/simulation_eval_test.go
index ab668295dc..3fbe61512c 100644
--- a/ledger/simulation/simulation_eval_test.go
+++ b/ledger/simulation/simulation_eval_test.go
@@ -38,6 +38,7 @@ import (
ledgertesting "github.com/algorand/go-algorand/ledger/testing"
"github.com/algorand/go-algorand/protocol"
"github.com/algorand/go-algorand/test/partitiontest"
+ "github.com/algorand/go-algorand/util"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -2306,6 +2307,7 @@ byte "hello"; log; int 1`,
TraceConfig: simulation.ExecTraceConfig{
Enable: true,
Stack: true,
+ State: true,
},
},
developerAPI: true,
@@ -2315,6 +2317,7 @@ byte "hello"; log; int 1`,
TraceConfig: simulation.ExecTraceConfig{
Enable: true,
Stack: true,
+ State: true,
},
TxnGroups: []simulation.TxnGroupResult{
{
@@ -2390,6 +2393,10 @@ byte "hello"; log; int 1`,
AppBudgetConsumed: 3,
},
},
+ InitialStates: &simulation.ResourcesInitialStates{
+ AllAppsInitialStates: simulation.AppsInitialStates{},
+ CreatedApp: util.MakeSet(basics.AppIndex(1002)),
+ },
},
}
})
@@ -3394,6 +3401,10 @@ int 1`,
AppBudgetConsumed: 44,
},
},
+ InitialStates: &simulation.ResourcesInitialStates{
+ AllAppsInitialStates: make(simulation.AppsInitialStates),
+ CreatedApp: util.MakeSet(futureAppID),
+ },
},
}
})
@@ -3404,17 +3415,7 @@ func TestAppLocalGlobalStateChange(t *testing.T) {
t.Parallel()
simulationTest(t, func(env simulationtesting.Environment) simulationTestCase {
- sender := env.Accounts[0]
-
- futureAppID := basics.AppIndex(1001)
-
- createTxn := env.TxnInfo.NewTxn(txntest.Txn{
- Type: protocol.ApplicationCallTx,
- Sender: sender.Addr,
- ApplicationID: 0,
- GlobalStateSchema: basics.StateSchema{NumUint: 1, NumByteSlice: 1},
- LocalStateSchema: basics.StateSchema{NumUint: 1, NumByteSlice: 1},
- ApprovalProgram: `#pragma version 8
+ approvalProgramSrc := `#pragma version 8
txn ApplicationID
bz end // Do nothing during create
@@ -3451,12 +3452,19 @@ global:
end:
int 1
-`,
+`
+
+ sender := env.Accounts[0]
+
+ createdAppID := env.CreateApp(sender.Addr, simulationtesting.AppParams{
+ GlobalStateSchema: basics.StateSchema{NumUint: 1, NumByteSlice: 1},
+ LocalStateSchema: basics.StateSchema{NumUint: 1, NumByteSlice: 1},
+ ApprovalProgram: approvalProgramSrc,
ClearStateProgram: `#pragma version 8
int 1`,
})
- op, err := logic.AssembleString(createTxn.ApprovalProgram.(string))
+ op, err := logic.AssembleString(approvalProgramSrc)
require.NoError(t, err)
progHash := crypto.Hash(op.Program)
@@ -3464,26 +3472,25 @@ int 1`,
Type: protocol.ApplicationCallTx,
OnCompletion: transactions.OptInOC,
Sender: sender.Addr,
- ApplicationID: futureAppID,
+ ApplicationID: createdAppID,
})
globalStateCall := env.TxnInfo.NewTxn(txntest.Txn{
Type: protocol.ApplicationCallTx,
Sender: sender.Addr,
- ApplicationID: futureAppID,
+ ApplicationID: createdAppID,
ApplicationArgs: [][]byte{[]byte("global")},
})
localStateCall := env.TxnInfo.NewTxn(txntest.Txn{
Type: protocol.ApplicationCallTx,
Sender: sender.Addr,
- ApplicationID: futureAppID,
+ ApplicationID: createdAppID,
ApplicationArgs: [][]byte{[]byte("local")},
})
- txntest.Group(&createTxn, &optIn, &globalStateCall, &localStateCall)
+ txntest.Group(&optIn, &globalStateCall, &localStateCall)
- signedCreate := createTxn.Txn().Sign(sender.Sk)
signedOptin := optIn.Txn().Sign(sender.Sk)
signedGlobalStateCall := globalStateCall.Txn().Sign(sender.Sk)
signedLocalStateCall := localStateCall.Txn().Sign(sender.Sk)
@@ -3491,7 +3498,7 @@ int 1`,
return simulationTestCase{
input: simulation.Request{
TxnGroups: [][]transactions.SignedTxn{
- {signedCreate, signedOptin, signedGlobalStateCall, signedLocalStateCall},
+ {signedOptin, signedGlobalStateCall, signedLocalStateCall},
},
TraceConfig: simulation.ExecTraceConfig{
Enable: true,
@@ -3513,44 +3520,6 @@ int 1`,
TxnGroups: []simulation.TxnGroupResult{
{
Txns: []simulation.TxnResult{
- // App creation
- {
- Txn: transactions.SignedTxnWithAD{
- ApplyData: transactions.ApplyData{
- ApplicationID: futureAppID,
- },
- },
- AppBudgetConsumed: 4,
- Trace: &simulation.TransactionTrace{
- ApprovalProgramTrace: []simulation.OpcodeTraceUnit{
- {
- PC: 1,
- },
- {
- PC: 4,
- StackAdded: []basics.TealValue{
- {
- Type: basics.TealUintType,
- },
- },
- },
- {
- PC: 6,
- StackPopCount: 1,
- },
- {
- PC: 154,
- StackAdded: []basics.TealValue{
- {
- Type: basics.TealUintType,
- Uint: 1,
- },
- },
- },
- },
- ApprovalProgramHash: progHash,
- },
- },
// Optin
{
AppBudgetConsumed: 8,
@@ -3564,7 +3533,7 @@ int 1`,
StackAdded: []basics.TealValue{
{
Type: basics.TealUintType,
- Uint: uint64(futureAppID),
+ Uint: uint64(createdAppID),
},
},
},
@@ -3646,7 +3615,7 @@ int 1`,
StackAdded: []basics.TealValue{
{
Type: basics.TealUintType,
- Uint: uint64(futureAppID),
+ Uint: uint64(createdAppID),
},
},
},
@@ -3739,7 +3708,7 @@ int 1`,
{
AppStateOp: logic.AppStateWrite,
AppState: logic.GlobalState,
- AppID: futureAppID,
+ AppID: createdAppID,
Key: "global-int-key",
NewValue: basics.TealValue{
Type: basics.TealUintType,
@@ -3774,7 +3743,7 @@ int 1`,
{
AppStateOp: logic.AppStateWrite,
AppState: logic.GlobalState,
- AppID: futureAppID,
+ AppID: createdAppID,
Key: "global-bytes-key",
NewValue: basics.TealValue{
Type: basics.TealBytesType,
@@ -3828,7 +3797,7 @@ int 1`,
StackAdded: []basics.TealValue{
{
Type: basics.TealUintType,
- Uint: uint64(futureAppID),
+ Uint: uint64(createdAppID),
},
},
},
@@ -3930,7 +3899,7 @@ int 1`,
{
AppStateOp: logic.AppStateWrite,
AppState: logic.LocalState,
- AppID: futureAppID,
+ AppID: createdAppID,
Key: "local-int-key",
NewValue: basics.TealValue{
Type: basics.TealUintType,
@@ -3974,7 +3943,7 @@ int 1`,
{
AppStateOp: logic.AppStateWrite,
AppState: logic.LocalState,
- AppID: futureAppID,
+ AppID: createdAppID,
Key: "local-bytes-key",
NewValue: basics.TealValue{
Type: basics.TealBytesType,
@@ -3999,10 +3968,25 @@ int 1`,
},
},
},
- AppBudgetAdded: 2800,
- AppBudgetConsumed: 52,
+ AppBudgetAdded: 2100,
+ AppBudgetConsumed: 48,
},
},
+ InitialStates: &simulation.ResourcesInitialStates{
+ AllAppsInitialStates: simulation.AppsInitialStates{
+ createdAppID: simulation.SingleAppInitialStates{
+ AppLocals: map[basics.Address]simulation.AppKVPairs{},
+ AppGlobals: simulation.AppKVPairs{},
+ AppBoxes: simulation.AppKVPairs{},
+ CreatedGlobals: util.MakeSet("global-bytes-key", "global-int-key"),
+ CreatedBoxes: make(util.Set[string]),
+ CreatedLocals: map[basics.Address]util.Set[string]{
+ sender.Addr: util.MakeSet("local-bytes-key", "local-int-key"),
+ },
+ },
+ },
+ CreatedApp: util.Set[basics.AppIndex]{},
+ },
},
}
})
@@ -4237,6 +4221,10 @@ int 1`,
AppBudgetConsumed: 14,
},
},
+ InitialStates: &simulation.ResourcesInitialStates{
+ AllAppsInitialStates: make(simulation.AppsInitialStates),
+ CreatedApp: util.MakeSet(futureAppID),
+ },
},
}
})
@@ -4417,130 +4405,1713 @@ int 1`,
AppBudgetConsumed: 8,
},
},
+ InitialStates: &simulation.ResourcesInitialStates{
+ AllAppsInitialStates: make(simulation.AppsInitialStates),
+ CreatedApp: util.MakeSet(futureAppID),
+ },
},
}
})
}
-// TestBalanceChangesWithApp sends a payment transaction to a new account and confirms its balance
-// within a subsequent app call
-func TestBalanceChangesWithApp(t *testing.T) {
- partitiontest.PartitionTest(t)
- t.Parallel()
+type BoxInitialStatesTestCase struct {
+ boxOpsForPrepare []boxOperation
+ boxOpsForSimulate []boxOperation
+ initialBoxStates simulation.AppKVPairs
+}
+
+func testBoxInitialStatesHelper(t *testing.T, testcase BoxInitialStatesTestCase) {
+ t.Helper()
+
simulationTest(t, func(env simulationtesting.Environment) simulationTestCase {
- sender := env.Accounts[0]
- senderBalance := sender.AcctData.MicroAlgos.Raw
- sendAmount := senderBalance - 500_000 // Leave 0.5 Algos in the sender account
- receiver := env.Accounts[1]
- receiverBalance := receiver.AcctData.MicroAlgos.Raw
+ proto := env.TxnInfo.CurrentProtocolParams()
+ appCreator := env.Accounts[0]
- futureAppID := basics.AppIndex(1001)
- createTxn := env.TxnInfo.NewTxn(txntest.Txn{
- Type: protocol.ApplicationCallTx,
- Sender: sender.Addr,
- ApprovalProgram: `#pragma version 6
-txn ApplicationID // [appId]
-bz end // []
-int 1 // [1]
-balance // [bal[1]]
-itob // [itob(bal[1])]
-txn ApplicationArgs 0 // [itob(bal[1]), args[0]]
-== // [itob(bal[1])=?=args[0]]
-assert
-end:
-int 1 // [1]
-`,
- ClearStateProgram: `#pragma version 6
+ boxApprovalProgram := fmt.Sprintf(boxTestProgram, 8)
+ boxAppID := env.CreateApp(appCreator.Addr, simulationtesting.AppParams{
+ ApprovalProgram: boxApprovalProgram,
+ ClearStateProgram: `#pragma version 8
int 1`,
})
- checkStartingBalanceTxn := env.TxnInfo.NewTxn(txntest.Txn{
- Type: protocol.ApplicationCallTx,
- Sender: sender.Addr,
- ApplicationID: futureAppID,
- Accounts: []basics.Address{receiver.Addr},
- ApplicationArgs: [][]byte{uint64ToBytes(receiverBalance)},
- })
- paymentTxn := env.TxnInfo.NewTxn(txntest.Txn{
- Type: protocol.PaymentTx,
- Sender: sender.Addr,
- Receiver: receiver.Addr,
- Amount: sendAmount,
- })
- checkEndingBalanceTxn := env.TxnInfo.NewTxn(txntest.Txn{
- Type: protocol.ApplicationCallTx,
- Sender: sender.Addr,
- ApplicationID: futureAppID,
- Accounts: []basics.Address{receiver.Addr},
- // Receiver's balance should have increased by sendAmount
- ApplicationArgs: [][]byte{uint64ToBytes(receiverBalance + sendAmount)},
- })
- txntest.Group(&createTxn, &checkStartingBalanceTxn, &paymentTxn, &checkEndingBalanceTxn)
+ op, err := logic.AssembleString(boxApprovalProgram)
+ require.NoError(t, err)
+ progHash := crypto.Hash(op.Program)
- signedCreateTxn := createTxn.Txn().Sign(sender.Sk)
- signedCheckStartingBalanceTxn := checkStartingBalanceTxn.Txn().Sign(sender.Sk)
- signedPaymentTxn := paymentTxn.Txn().Sign(sender.Sk)
- signedCheckEndingBalanceTxn := checkEndingBalanceTxn.Txn().Sign(sender.Sk)
+ transferable := env.Accounts[1].AcctData.MicroAlgos.Raw - proto.MinBalance - proto.MinTxnFee
+ env.TransferAlgos(env.Accounts[1].Addr, boxAppID.Address(), transferable)
+
+ for _, boxOp := range testcase.boxOpsForPrepare {
+ env.Txn(env.TxnInfo.NewTxn(txntest.Txn{
+ Type: protocol.ApplicationCallTx,
+ Sender: appCreator.Addr,
+ ApplicationID: boxAppID,
+ ApplicationArgs: boxOp.appArgs(),
+ Boxes: boxOp.boxRefs(),
+ }).SignedTxn())
+ }
+
+ boxOpToSimResult := func(boxOp boxOperation) simulation.TxnResult {
+ var res simulation.TxnResult
+ switch boxOp.op {
+ case logic.BoxReadOperation:
+ res = simulation.TxnResult{
+ AppBudgetConsumed: 14,
+ Trace: &simulation.TransactionTrace{
+ ApprovalProgramTrace: []simulation.OpcodeTraceUnit{
+ {PC: 1},
+ {PC: 3},
+ {PC: 6},
+ {PC: 14},
+ {PC: 22},
+ {PC: 28},
+ {PC: 35},
+ {PC: 38},
+ {PC: 69},
+ {PC: 72},
+ {PC: 73},
+ {PC: 74},
+ {PC: 75},
+ {PC: 87},
+ },
+ ApprovalProgramHash: progHash,
+ },
+ }
+ case logic.BoxWriteOperation:
+ res = simulation.TxnResult{
+ AppBudgetConsumed: 13,
+ Trace: &simulation.TransactionTrace{
+ ApprovalProgramTrace: []simulation.OpcodeTraceUnit{
+ {PC: 1},
+ {PC: 3},
+ {PC: 6},
+ {PC: 14},
+ {PC: 22},
+ {PC: 28},
+ {PC: 35},
+ {PC: 38},
+ {PC: 78},
+ {PC: 81},
+ {PC: 83},
+ {
+ PC: 86,
+ StateChanges: []simulation.StateOperation{
+ {
+ AppStateOp: logic.AppStateWrite,
+ AppState: logic.BoxState,
+ AppID: boxAppID,
+ Key: boxOp.name,
+ NewValue: basics.TealValue{
+ Type: basics.TealBytesType,
+ Bytes: string(boxOp.contents),
+ },
+ },
+ },
+ },
+ {PC: 87},
+ },
+ ApprovalProgramHash: progHash,
+ },
+ }
+ case logic.BoxCreateOperation:
+ res = simulation.TxnResult{
+ AppBudgetConsumed: 15,
+ Trace: &simulation.TransactionTrace{
+ ApprovalProgramTrace: []simulation.OpcodeTraceUnit{
+ {PC: 1},
+ {PC: 3},
+ {PC: 6},
+ {PC: 14},
+ {PC: 22},
+ {PC: 28},
+ {PC: 35},
+ {PC: 38},
+ {PC: 49},
+ {PC: 52},
+ {PC: 55},
+ {
+ PC: 56,
+ StateChanges: []simulation.StateOperation{
+ {
+ AppStateOp: logic.AppStateWrite,
+ AppState: logic.BoxState,
+ AppID: boxAppID,
+ Key: boxOp.name,
+ NewValue: basics.TealValue{
+ Type: basics.TealBytesType,
+ Bytes: string(make([]byte, boxOp.createSize)),
+ },
+ },
+ },
+ },
+ {PC: 57},
+ {PC: 58},
+ {PC: 87},
+ },
+ ApprovalProgramHash: progHash,
+ },
+ }
+ case logic.BoxDeleteOperation:
+ res = simulation.TxnResult{
+ AppBudgetConsumed: 13,
+ Trace: &simulation.TransactionTrace{
+ ApprovalProgramTrace: []simulation.OpcodeTraceUnit{
+ {PC: 1},
+ {PC: 3},
+ {PC: 6},
+ {PC: 14},
+ {PC: 22},
+ {PC: 28},
+ {PC: 35},
+ {PC: 38},
+ {PC: 61},
+ {
+ PC: 64,
+ StateChanges: []simulation.StateOperation{
+ {
+ AppStateOp: logic.AppStateDelete,
+ AppState: logic.BoxState,
+ AppID: boxAppID,
+ Key: boxOp.name,
+ },
+ },
+ },
+ {PC: 65},
+ {PC: 66},
+ {PC: 87},
+ },
+ ApprovalProgramHash: progHash,
+ },
+ }
+ }
+ return res
+ }
+
+ txnPtrs := make([]*txntest.Txn, len(testcase.boxOpsForSimulate))
+ for i, boxOp := range testcase.boxOpsForSimulate {
+ tempTxn := env.TxnInfo.NewTxn(txntest.Txn{
+ Type: protocol.ApplicationCallTx,
+ Sender: appCreator.Addr,
+ ApplicationID: boxAppID,
+ ApplicationArgs: boxOp.appArgs(),
+ Boxes: boxOp.boxRefs(),
+ })
+ txnPtrs[i] = &tempTxn
+ }
+
+ txntest.Group(txnPtrs...)
+ signedTxns := make([]transactions.SignedTxn, len(testcase.boxOpsForSimulate))
+ for i, txn := range txnPtrs {
+ signedTxns[i] = txn.Txn().Sign(appCreator.Sk)
+ }
+
+ txnResults := make([]simulation.TxnResult, len(testcase.boxOpsForSimulate))
+ for i, boxOp := range testcase.boxOpsForSimulate {
+ txnResults[i] = boxOpToSimResult(boxOp)
+ }
+ totalConsumed := uint64(0)
+ for _, txnResult := range txnResults {
+ totalConsumed += txnResult.AppBudgetConsumed
+ }
+
+ prepareKeys := make(util.Set[string])
+ for _, instruction := range testcase.boxOpsForPrepare {
+ if instruction.op != logic.BoxWriteOperation {
+ continue
+ }
+ prepareKeys.Add(instruction.name)
+ }
+ newlyCreatedGlobalKeySet := make(util.Set[string])
+ for _, instruction := range testcase.boxOpsForSimulate {
+ if instruction.op != logic.BoxWriteOperation {
+ continue
+ }
+ if prepareKeys.Contains(instruction.name) {
+ continue
+ }
+ newlyCreatedGlobalKeySet.Add(instruction.name)
+ }
return simulationTestCase{
input: simulation.Request{
TxnGroups: [][]transactions.SignedTxn{
- {
- signedCreateTxn,
- signedCheckStartingBalanceTxn,
- signedPaymentTxn,
- signedCheckEndingBalanceTxn,
- },
+ signedTxns,
+ },
+ TraceConfig: simulation.ExecTraceConfig{
+ Enable: true,
+ State: true,
},
},
+ developerAPI: true,
expected: simulation.Result{
Version: simulation.ResultLatestVersion,
LastRound: env.TxnInfo.LatestRound(),
+ TraceConfig: simulation.ExecTraceConfig{
+ Enable: true,
+ State: true,
+ },
TxnGroups: []simulation.TxnGroupResult{
{
- Txns: []simulation.TxnResult{
- {
- Txn: transactions.SignedTxnWithAD{
- ApplyData: transactions.ApplyData{
- ApplicationID: futureAppID,
- },
- },
- AppBudgetConsumed: 4,
- },
- {
- AppBudgetConsumed: 10,
- },
- {},
- {
- AppBudgetConsumed: 10,
- },
+ Txns: txnResults,
+ AppBudgetAdded: 700 * uint64(len(txnResults)),
+ AppBudgetConsumed: totalConsumed,
+ },
+ },
+ InitialStates: &simulation.ResourcesInitialStates{
+ AllAppsInitialStates: simulation.AppsInitialStates{
+ boxAppID: simulation.SingleAppInitialStates{
+ AppGlobals: make(simulation.AppKVPairs),
+ AppLocals: map[basics.Address]simulation.AppKVPairs{},
+ AppBoxes: testcase.initialBoxStates,
+ CreatedGlobals: make(util.Set[string]),
+ CreatedBoxes: newlyCreatedGlobalKeySet,
+ CreatedLocals: map[basics.Address]util.Set[string]{},
},
- AppBudgetAdded: 2100,
- AppBudgetConsumed: 24,
},
+ CreatedApp: util.Set[basics.AppIndex]{},
},
},
}
})
}
-// TestOptionalSignatures tests that transactions with signatures and without signatures are both
-// properly handled when AllowEmptySignatures is enabled.
-func TestOptionalSignatures(t *testing.T) {
+func TestAppInitialBoxStates(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]
- txn := env.TxnInfo.NewTxn(txntest.Txn{
- Type: protocol.PaymentTx,
- Sender: sender.Addr,
- Receiver: sender.Addr,
- Amount: 1,
- })
+ testBoxInitialStatesHelper(t, BoxInitialStatesTestCase{
+ boxOpsForPrepare: []boxOperation{
+ {
+ op: logic.BoxCreateOperation,
+ name: "A",
+ createSize: 21,
+ },
+ {
+ op: logic.BoxWriteOperation,
+ name: "A",
+ contents: []byte("initial box A content"),
+ },
+ },
+ boxOpsForSimulate: []boxOperation{
+ {
+ op: logic.BoxReadOperation,
+ name: "A",
+ },
+ {
+ op: logic.BoxWriteOperation,
+ name: "A",
+ contents: []byte("box A get overwritten"),
+ },
+ },
+ initialBoxStates: simulation.AppKVPairs{
+ "A": {
+ Type: basics.TealBytesType,
+ Bytes: "initial box A content",
+ },
+ },
+ })
+
+ testBoxInitialStatesHelper(t, BoxInitialStatesTestCase{
+ boxOpsForPrepare: []boxOperation{
+ {
+ op: logic.BoxCreateOperation,
+ name: "A",
+ createSize: 21,
+ },
+ {
+ op: logic.BoxWriteOperation,
+ name: "A",
+ contents: []byte("initial box A content"),
+ },
+ {
+ op: logic.BoxCreateOperation,
+ name: "B",
+ createSize: 21,
+ },
+ {
+ op: logic.BoxWriteOperation,
+ name: "B",
+ contents: []byte("initial box B content"),
+ },
+ {
+ op: logic.BoxCreateOperation,
+ name: "C",
+ createSize: 21,
+ },
+ {
+ op: logic.BoxWriteOperation,
+ name: "C",
+ contents: []byte("initial box C content"),
+ },
+ },
+ boxOpsForSimulate: []boxOperation{
+ {
+ op: logic.BoxDeleteOperation,
+ name: "C",
+ },
+ {
+ op: logic.BoxReadOperation,
+ name: "A",
+ },
+ },
+ initialBoxStates: simulation.AppKVPairs{
+ "A": {
+ Type: basics.TealBytesType,
+ Bytes: "initial box A content",
+ },
+ "C": {
+ Type: basics.TealBytesType,
+ Bytes: "initial box C content",
+ },
+ },
+ })
+
+ testBoxInitialStatesHelper(t, BoxInitialStatesTestCase{
+ boxOpsForPrepare: []boxOperation{
+ {
+ op: logic.BoxCreateOperation,
+ name: "A",
+ createSize: 21,
+ },
+ {
+ op: logic.BoxWriteOperation,
+ name: "A",
+ contents: []byte("initial box A content"),
+ },
+ {
+ op: logic.BoxCreateOperation,
+ name: "C",
+ createSize: 21,
+ },
+ {
+ op: logic.BoxWriteOperation,
+ name: "C",
+ contents: []byte("initial box C content"),
+ },
+ },
+ boxOpsForSimulate: []boxOperation{
+ {
+ op: logic.BoxCreateOperation,
+ name: "B",
+ createSize: 21,
+ },
+ {
+ op: logic.BoxWriteOperation,
+ name: "B",
+ contents: []byte("initial box B content"),
+ },
+ },
+ initialBoxStates: simulation.AppKVPairs{},
+ })
+}
+
+func testBoxPutInitialStatesHelper(t *testing.T, testcase BoxInitialStatesTestCase) {
+ t.Helper()
+
+ simulationTest(t, func(env simulationtesting.Environment) simulationTestCase {
+ proto := env.TxnInfo.CurrentProtocolParams()
+ appCreator := env.Accounts[0]
+
+ boxApprovalProgram := `#pragma version 8
+txn ApplicationID
+bz end // Do nothing during create
+
+byte "write"
+byte "delete"
+txn ApplicationArgs 0
+match put del
+err // Unknown command
+
+put:
+txn ApplicationArgs 1
+txn ApplicationArgs 2
+box_put
+b end
+
+del:
+txn ApplicationArgs 1
+box_del
+assert
+b end
+
+end:
+int 1
+`
+ boxAppID := env.CreateApp(appCreator.Addr, simulationtesting.AppParams{
+ ApprovalProgram: boxApprovalProgram,
+ ClearStateProgram: `#pragma version 8
+ int 1`,
+ })
+
+ op, err := logic.AssembleString(boxApprovalProgram)
+ require.NoError(t, err)
+ progHash := crypto.Hash(op.Program)
+
+ transferable := env.Accounts[1].AcctData.MicroAlgos.Raw - proto.MinBalance - proto.MinTxnFee
+ env.TransferAlgos(env.Accounts[1].Addr, boxAppID.Address(), transferable)
+
+ for _, boxOp := range testcase.boxOpsForPrepare {
+ env.Txn(env.TxnInfo.NewTxn(txntest.Txn{
+ Type: protocol.ApplicationCallTx,
+ Sender: appCreator.Addr,
+ ApplicationID: boxAppID,
+ ApplicationArgs: boxOp.appArgs(),
+ Boxes: boxOp.boxRefs(),
+ }).SignedTxn())
+ }
+
+ boxOpToSimResult := func(boxOp boxOperation) simulation.TxnResult {
+ var res simulation.TxnResult
+ switch boxOp.op {
+ case logic.BoxWriteOperation:
+ res = simulation.TxnResult{
+ AppBudgetConsumed: 11,
+ Trace: &simulation.TransactionTrace{
+ ApprovalProgramTrace: []simulation.OpcodeTraceUnit{
+ {PC: 1},
+ {PC: 3},
+ {PC: 6},
+ {PC: 13},
+ {PC: 21},
+ {PC: 24},
+ {PC: 31},
+ {PC: 34},
+ {
+ PC: 37,
+ StateChanges: []simulation.StateOperation{
+ {
+ AppStateOp: logic.AppStateWrite,
+ AppState: logic.BoxState,
+ AppID: boxAppID,
+ Key: boxOp.name,
+ NewValue: basics.TealValue{
+ Type: basics.TealBytesType,
+ Bytes: string(boxOp.contents),
+ },
+ },
+ },
+ },
+ {PC: 38},
+ {PC: 49},
+ },
+ ApprovalProgramHash: progHash,
+ },
+ }
+ case logic.BoxDeleteOperation:
+ res = simulation.TxnResult{
+ AppBudgetConsumed: 11,
+ Trace: &simulation.TransactionTrace{
+ ApprovalProgramTrace: []simulation.OpcodeTraceUnit{
+ {PC: 1},
+ {PC: 3},
+ {PC: 6},
+ {PC: 13},
+ {PC: 21},
+ {PC: 24},
+ {PC: 31},
+ {PC: 34},
+ {PC: 37},
+ {PC: 61},
+ {
+ PC: 64,
+ StateChanges: []simulation.StateOperation{
+ {
+ AppStateOp: logic.AppStateDelete,
+ AppState: logic.BoxState,
+ AppID: boxAppID,
+ Key: boxOp.name,
+ },
+ },
+ },
+ {PC: 65},
+ {PC: 66},
+ {PC: 87},
+ },
+ ApprovalProgramHash: progHash,
+ },
+ }
+ }
+ return res
+ }
+
+ txnPtrs := make([]*txntest.Txn, len(testcase.boxOpsForSimulate))
+ for i, boxOp := range testcase.boxOpsForSimulate {
+ tempTxn := env.TxnInfo.NewTxn(txntest.Txn{
+ Type: protocol.ApplicationCallTx,
+ Sender: appCreator.Addr,
+ ApplicationID: boxAppID,
+ ApplicationArgs: boxOp.appArgs(),
+ Boxes: boxOp.boxRefs(),
+ })
+ txnPtrs[i] = &tempTxn
+ }
+
+ txntest.Group(txnPtrs...)
+ signedTxns := make([]transactions.SignedTxn, len(testcase.boxOpsForSimulate))
+ for i, txn := range txnPtrs {
+ signedTxns[i] = txn.Txn().Sign(appCreator.Sk)
+ }
+
+ txnResults := make([]simulation.TxnResult, len(testcase.boxOpsForSimulate))
+ for i, boxOp := range testcase.boxOpsForSimulate {
+ txnResults[i] = boxOpToSimResult(boxOp)
+ }
+ totalConsumed := uint64(0)
+ for _, txnResult := range txnResults {
+ totalConsumed += txnResult.AppBudgetConsumed
+ }
+
+ prepareKeys := make(util.Set[string])
+ for _, instruction := range testcase.boxOpsForPrepare {
+ if instruction.op != logic.BoxWriteOperation {
+ continue
+ }
+ prepareKeys.Add(instruction.name)
+ }
+ newlyCreatedGlobalKeySet := make(util.Set[string])
+ for _, instruction := range testcase.boxOpsForSimulate {
+ if instruction.op != logic.BoxWriteOperation {
+ continue
+ }
+ if prepareKeys.Contains(instruction.name) {
+ continue
+ }
+ newlyCreatedGlobalKeySet.Add(instruction.name)
+ }
+
+ return simulationTestCase{
+ input: simulation.Request{
+ TxnGroups: [][]transactions.SignedTxn{
+ signedTxns,
+ },
+ TraceConfig: simulation.ExecTraceConfig{
+ Enable: true,
+ State: true,
+ },
+ },
+ developerAPI: true,
+ expected: simulation.Result{
+ Version: simulation.ResultLatestVersion,
+ LastRound: env.TxnInfo.LatestRound(),
+ TraceConfig: simulation.ExecTraceConfig{
+ Enable: true,
+ State: true,
+ },
+ TxnGroups: []simulation.TxnGroupResult{
+ {
+ Txns: txnResults,
+ AppBudgetAdded: 700 * uint64(len(txnResults)),
+ AppBudgetConsumed: totalConsumed,
+ },
+ },
+ InitialStates: &simulation.ResourcesInitialStates{
+ AllAppsInitialStates: simulation.AppsInitialStates{
+ boxAppID: simulation.SingleAppInitialStates{
+ AppGlobals: make(simulation.AppKVPairs),
+ AppLocals: map[basics.Address]simulation.AppKVPairs{},
+ AppBoxes: testcase.initialBoxStates,
+ CreatedGlobals: make(util.Set[string]),
+ CreatedBoxes: newlyCreatedGlobalKeySet,
+ CreatedLocals: map[basics.Address]util.Set[string]{},
+ },
+ },
+ CreatedApp: util.Set[basics.AppIndex]{},
+ },
+ },
+ }
+ })
+}
+
+func TestAppInitialBoxStatesAboutBoxPut(t *testing.T) {
+ partitiontest.PartitionTest(t)
+ t.Parallel()
+
+ testBoxPutInitialStatesHelper(t, BoxInitialStatesTestCase{
+ boxOpsForPrepare: []boxOperation{
+ {
+ op: logic.BoxWriteOperation,
+ name: "A",
+ contents: []byte("initial box A content"),
+ },
+ },
+ boxOpsForSimulate: []boxOperation{
+ {
+ op: logic.BoxWriteOperation,
+ name: "A",
+ contents: []byte("box A get overwritten"),
+ },
+ },
+ initialBoxStates: simulation.AppKVPairs{
+ "A": {
+ Type: basics.TealBytesType,
+ Bytes: "initial box A content",
+ },
+ },
+ })
+
+ testBoxPutInitialStatesHelper(t, BoxInitialStatesTestCase{
+ boxOpsForSimulate: []boxOperation{
+ {
+ op: logic.BoxWriteOperation,
+ name: "A",
+ contents: []byte("box A get overwritten"),
+ },
+ },
+ initialBoxStates: simulation.AppKVPairs{},
+ })
+}
+
+type GlobalInitialStatesTestCase struct {
+ prepareInstruction [][][]byte
+ txnsArgs [][][]byte
+ initialGlobalStates simulation.AppKVPairs
+}
+
+func (l GlobalInitialStatesTestCase) toSignedTxns(env simulationtesting.Environment, addr simulationtesting.Account, appID basics.AppIndex) []transactions.SignedTxn {
+ txns := make([]*txntest.Txn, len(l.txnsArgs))
+ for i, txnArgs := range l.txnsArgs {
+ tempTxn := env.TxnInfo.NewTxn(txntest.Txn{
+ Type: protocol.ApplicationCallTx,
+ Sender: addr.Addr,
+ ApplicationID: appID,
+ ApplicationArgs: txnArgs,
+ })
+ txns[i] = &tempTxn
+ }
+ txntest.Group(txns...)
+ signedTxns := make([]transactions.SignedTxn, len(l.txnsArgs))
+ for i, txn := range txns {
+ signedTxns[i] = txn.Txn().Sign(addr.Sk)
+ }
+ return signedTxns
+}
+
+func testGlobalInitialStatesHelper(t *testing.T, testcase GlobalInitialStatesTestCase) {
+ t.Helper()
+
+ simulationTest(t, func(env simulationtesting.Environment) simulationTestCase {
+ appCreator := env.Accounts[0]
+
+ approvalProgramSrc := `#pragma version 8
+txn ApplicationID
+bz end // Do nothing during create
+
+byte "put"
+byte "del"
+txn ApplicationArgs 0
+match put del
+err // Unknown command
+
+put:
+ txn ApplicationArgs 1
+ txn ApplicationArgs 2
+ app_global_put
+ b end
+
+del:
+ txn ApplicationArgs 1
+ app_global_del
+ b end
+
+end:
+ int 1
+`
+
+ appID := env.CreateApp(appCreator.Addr, simulationtesting.AppParams{
+ GlobalStateSchema: basics.StateSchema{NumByteSlice: 8},
+ ApprovalProgram: approvalProgramSrc,
+ ClearStateProgram: `#pragma version 8
+int 1`,
+ })
+
+ op, err := logic.AssembleString(approvalProgramSrc)
+ require.NoError(t, err)
+ progHash := crypto.Hash(op.Program)
+
+ for _, instruction := range testcase.prepareInstruction {
+ txnArgs := [][]byte{[]byte("put")}
+ txnArgs = append(txnArgs, instruction...)
+ env.Txn(env.TxnInfo.NewTxn(txntest.Txn{
+ Sender: appCreator.Addr,
+ Type: protocol.ApplicationCallTx,
+ ApplicationID: appID,
+ ApplicationArgs: txnArgs,
+ }).SignedTxn())
+ }
+
+ signedTxns := testcase.toSignedTxns(env, appCreator, appID)
+
+ txnArgsToResult := func(txnAppArgs [][]byte) simulation.TxnResult {
+ var res simulation.TxnResult
+ switch string(txnAppArgs[0]) {
+ case "put":
+ res = simulation.TxnResult{
+ Txn: transactions.SignedTxnWithAD{
+ ApplyData: transactions.ApplyData{
+ EvalDelta: transactions.EvalDelta{
+ GlobalDelta: basics.StateDelta{
+ string(txnAppArgs[1]): basics.ValueDelta{
+ Bytes: string(txnAppArgs[2]),
+ Action: basics.SetBytesAction,
+ },
+ },
+ },
+ },
+ },
+ AppBudgetConsumed: 11,
+ Trace: &simulation.TransactionTrace{
+ ApprovalProgramTrace: []simulation.OpcodeTraceUnit{
+ {PC: 1},
+ {PC: 3},
+ {PC: 6},
+ {PC: 11},
+ {PC: 16},
+ {PC: 19},
+ {PC: 26},
+ {PC: 29},
+ {
+ PC: 32,
+ StateChanges: []simulation.StateOperation{
+ {
+ AppStateOp: logic.AppStateWrite,
+ AppState: logic.GlobalState,
+ AppID: appID,
+ Key: string(txnAppArgs[1]),
+ NewValue: basics.TealValue{
+ Type: basics.TealBytesType,
+ Bytes: string(txnAppArgs[2]),
+ },
+ },
+ },
+ },
+ {PC: 33},
+ {PC: 43},
+ },
+ ApprovalProgramHash: progHash,
+ },
+ }
+ case "del":
+ res = simulation.TxnResult{
+ Txn: transactions.SignedTxnWithAD{
+ ApplyData: transactions.ApplyData{
+ EvalDelta: transactions.EvalDelta{
+ GlobalDelta: basics.StateDelta{
+ string(txnAppArgs[1]): basics.ValueDelta{
+ Action: basics.DeleteAction,
+ },
+ },
+ },
+ },
+ },
+ AppBudgetConsumed: 10,
+ Trace: &simulation.TransactionTrace{
+ ApprovalProgramTrace: []simulation.OpcodeTraceUnit{
+ {PC: 1},
+ {PC: 3},
+ {PC: 6},
+ {PC: 11},
+ {PC: 16},
+ {PC: 19},
+ {PC: 36},
+ {
+ PC: 39,
+ StateChanges: []simulation.StateOperation{
+ {
+ AppStateOp: logic.AppStateDelete,
+ AppState: logic.GlobalState,
+ AppID: appID,
+ Key: string(txnAppArgs[1]),
+ },
+ },
+ },
+ {PC: 40},
+ {PC: 43},
+ },
+ ApprovalProgramHash: progHash,
+ },
+ }
+ default:
+ }
+ return res
+ }
+ txnResults := make([]simulation.TxnResult, len(testcase.txnsArgs))
+ for i, txnArgs := range testcase.txnsArgs {
+ txnResults[i] = txnArgsToResult(txnArgs)
+ }
+
+ prepareKeys := make(util.Set[string])
+ for _, instruction := range testcase.prepareInstruction {
+ prepareKeys.Add(string(instruction[0]))
+ }
+ newlyCreatedGlobalKeySet := make(util.Set[string])
+ for _, txnArgs := range testcase.txnsArgs {
+ if string(txnArgs[0]) != "put" {
+ continue
+ }
+ if prepareKeys.Contains(string(txnArgs[1])) {
+ continue
+ }
+ newlyCreatedGlobalKeySet.Add(string(txnArgs[1]))
+ }
+
+ totalConsumed := uint64(0)
+ for _, txnResult := range txnResults {
+ totalConsumed += txnResult.AppBudgetConsumed
+ }
+
+ return simulationTestCase{
+ input: simulation.Request{
+ TxnGroups: [][]transactions.SignedTxn{
+ signedTxns,
+ },
+ TraceConfig: simulation.ExecTraceConfig{
+ Enable: true,
+ State: true,
+ },
+ },
+ developerAPI: true,
+ expected: simulation.Result{
+ Version: simulation.ResultLatestVersion,
+ LastRound: env.TxnInfo.LatestRound(),
+ TraceConfig: simulation.ExecTraceConfig{
+ Enable: true,
+ State: true,
+ },
+ TxnGroups: []simulation.TxnGroupResult{
+ {
+ Txns: txnResults,
+ AppBudgetAdded: 700 * uint64(len(txnResults)),
+ AppBudgetConsumed: totalConsumed,
+ },
+ },
+ InitialStates: &simulation.ResourcesInitialStates{
+ AllAppsInitialStates: simulation.AppsInitialStates{
+ appID: simulation.SingleAppInitialStates{
+ AppGlobals: testcase.initialGlobalStates,
+ AppLocals: map[basics.Address]simulation.AppKVPairs{},
+ AppBoxes: make(simulation.AppKVPairs),
+ CreatedGlobals: newlyCreatedGlobalKeySet,
+ CreatedBoxes: make(util.Set[string]),
+ CreatedLocals: map[basics.Address]util.Set[string]{},
+ },
+ },
+ CreatedApp: make(util.Set[basics.AppIndex]),
+ },
+ },
+ }
+ })
+}
+
+func TestAppInitialGlobalStates(t *testing.T) {
+ partitiontest.PartitionTest(t)
+ t.Parallel()
+
+ testGlobalInitialStatesHelper(t,
+ GlobalInitialStatesTestCase{
+ txnsArgs: [][][]byte{
+ {
+ []byte("put"), []byte("A"), []byte("content A"),
+ },
+ {
+ []byte("del"), []byte("A"),
+ },
+ },
+ initialGlobalStates: simulation.AppKVPairs{},
+ },
+ )
+
+ testGlobalInitialStatesHelper(t,
+ GlobalInitialStatesTestCase{
+ prepareInstruction: [][][]byte{
+ {
+ []byte("A"), []byte("initial content A"),
+ },
+ },
+ txnsArgs: [][][]byte{
+ {
+ []byte("put"), []byte("A"), []byte("content A"),
+ },
+ {
+ []byte("del"), []byte("A"),
+ },
+ },
+ initialGlobalStates: simulation.AppKVPairs{
+ "A": basics.TealValue{
+ Type: basics.TealBytesType,
+ Bytes: "initial content A",
+ },
+ },
+ },
+ )
+}
+
+type LocalStateOperation struct {
+ addressIndex uint64
+ appArgs [][]byte
+}
+
+type LocalInitialStatesTestCase struct {
+ prepareInstructions []LocalStateOperation
+ simulateInstructions []LocalStateOperation
+ initialLocalStates map[uint64]simulation.AppKVPairs
+}
+
+func (testcase LocalInitialStatesTestCase) toSignedTxns(env simulationtesting.Environment, appID basics.AppIndex) []transactions.SignedTxn {
+ txns := make([]*txntest.Txn, len(testcase.simulateInstructions))
+ for i, instruction := range testcase.simulateInstructions {
+ tempTxn := env.TxnInfo.NewTxn(txntest.Txn{
+ Type: protocol.ApplicationCallTx,
+ Sender: env.Accounts[instruction.addressIndex].Addr,
+ ApplicationID: appID,
+ ApplicationArgs: instruction.appArgs,
+ })
+ txns[i] = &tempTxn
+ }
+ txntest.Group(txns...)
+ signedTxns := make([]transactions.SignedTxn, len(testcase.simulateInstructions))
+ for i, txn := range txns {
+ signedTxns[i] = txn.Txn().Sign(env.Accounts[testcase.simulateInstructions[i].addressIndex].Sk)
+ }
+ return signedTxns
+}
+
+func testLocalInitialStatesHelper(t *testing.T, testcase LocalInitialStatesTestCase) {
+ t.Helper()
+
+ simulationTest(t, func(env simulationtesting.Environment) simulationTestCase {
+ appCreator := env.Accounts[0]
+
+ approvalProgramSrc := `#pragma version 8
+txn ApplicationID
+bz end // Do nothing during create
+
+txn OnCompletion
+int OptIn
+==
+bnz end // Always allow optin
+
+byte "put"
+byte "get"
+byte "del"
+
+txn ApplicationArgs 0
+match put get del
+err // Unknown command
+
+put:
+ txn Sender // account
+ txn ApplicationArgs 1 // key
+ txn ApplicationArgs 2 // local state content
+ app_local_put
+ b end
+
+get:
+ txn Sender // account
+ txn ApplicationArgs 1 // key
+ app_local_get
+ pop
+ b end
+
+del:
+ txn Sender // account
+ txn ApplicationArgs 1 // key
+ app_local_del
+ b end
+
+end:
+ int 1
+`
+
+ appID := env.CreateApp(appCreator.Addr, simulationtesting.AppParams{
+ LocalStateSchema: basics.StateSchema{NumByteSlice: 8},
+ ApprovalProgram: approvalProgramSrc,
+ ClearStateProgram: `#pragma version 8
+int 1`,
+ })
+
+ op, err := logic.AssembleString(approvalProgramSrc)
+ require.NoError(t, err)
+ progHash := crypto.Hash(op.Program)
+
+ for _, acct := range env.Accounts[2:] {
+ env.Txn(env.TxnInfo.NewTxn(txntest.Txn{
+ Sender: acct.Addr,
+ Type: protocol.ApplicationCallTx,
+ ApplicationID: appID,
+ OnCompletion: transactions.OptInOC,
+ }).SignedTxn())
+ }
+
+ for _, instruction := range testcase.prepareInstructions {
+ env.Txn(env.TxnInfo.NewTxn(txntest.Txn{
+ Sender: env.Accounts[instruction.addressIndex].Addr,
+ Type: protocol.ApplicationCallTx,
+ ApplicationID: appID,
+ ApplicationArgs: instruction.appArgs,
+ }).SignedTxn())
+ }
+
+ signedTxns := testcase.toSignedTxns(env, appID)
+
+ txnArgsToResult := func(instruction LocalStateOperation) simulation.TxnResult {
+ var res simulation.TxnResult
+ switch string(instruction.appArgs[0]) {
+ case "put":
+ res = simulation.TxnResult{
+ Txn: transactions.SignedTxnWithAD{
+ ApplyData: transactions.ApplyData{
+ EvalDelta: transactions.EvalDelta{
+ LocalDeltas: map[uint64]basics.StateDelta{
+ 0: {
+ string(instruction.appArgs[1]): basics.ValueDelta{
+ Bytes: string(instruction.appArgs[2]),
+ Action: basics.SetBytesAction,
+ },
+ },
+ },
+ },
+ },
+ },
+ AppBudgetConsumed: 18,
+ Trace: &simulation.TransactionTrace{
+ ApprovalProgramTrace: []simulation.OpcodeTraceUnit{
+ {PC: 1},
+ {PC: 4},
+ {PC: 6},
+ {PC: 9},
+ {PC: 11},
+ {PC: 12},
+ {PC: 13},
+ {PC: 16},
+ {PC: 21},
+ {PC: 26},
+ {PC: 31},
+ {PC: 34},
+ {PC: 43},
+ {PC: 45},
+ {PC: 48},
+ {
+ PC: 51,
+ StateChanges: []simulation.StateOperation{
+ {
+ AppStateOp: logic.AppStateWrite,
+ AppState: logic.LocalState,
+ AppID: appID,
+ Key: string(instruction.appArgs[1]),
+ NewValue: basics.TealValue{
+ Type: basics.TealBytesType,
+ Bytes: string(instruction.appArgs[2]),
+ },
+ Account: env.Accounts[instruction.addressIndex].Addr,
+ },
+ },
+ },
+ {PC: 52},
+ {PC: 74},
+ },
+ ApprovalProgramHash: progHash,
+ },
+ }
+ case "del":
+ res = simulation.TxnResult{
+ Txn: transactions.SignedTxnWithAD{
+ ApplyData: transactions.ApplyData{
+ EvalDelta: transactions.EvalDelta{
+ LocalDeltas: map[uint64]basics.StateDelta{
+ 0: {
+ string(instruction.appArgs[1]): basics.ValueDelta{
+ Action: basics.DeleteAction,
+ },
+ },
+ },
+ },
+ },
+ },
+ AppBudgetConsumed: 17,
+ Trace: &simulation.TransactionTrace{
+ ApprovalProgramTrace: []simulation.OpcodeTraceUnit{
+ {PC: 1},
+ {PC: 4},
+ {PC: 6},
+ {PC: 9},
+ {PC: 11},
+ {PC: 12},
+ {PC: 13},
+ {PC: 16},
+ {PC: 21},
+ {PC: 26},
+ {PC: 31},
+ {PC: 34},
+ {PC: 65},
+ {PC: 67},
+ {
+ PC: 70,
+ StateChanges: []simulation.StateOperation{
+ {
+ AppStateOp: logic.AppStateDelete,
+ AppState: logic.LocalState,
+ AppID: appID,
+ Key: string(instruction.appArgs[1]),
+ Account: env.Accounts[instruction.addressIndex].Addr,
+ },
+ },
+ },
+ {PC: 71},
+ {PC: 74},
+ },
+ ApprovalProgramHash: progHash,
+ },
+ }
+ case "get":
+ res = simulation.TxnResult{
+ AppBudgetConsumed: 18,
+ Trace: &simulation.TransactionTrace{
+ ApprovalProgramTrace: []simulation.OpcodeTraceUnit{
+ {PC: 1},
+ {PC: 4},
+ {PC: 6},
+ {PC: 9},
+ {PC: 11},
+ {PC: 12},
+ {PC: 13},
+ {PC: 16},
+ {PC: 21},
+ {PC: 26},
+ {PC: 31},
+ {PC: 34},
+ {PC: 55},
+ {PC: 57},
+ {PC: 60},
+ {PC: 61},
+ {PC: 62},
+ {PC: 74},
+ },
+ ApprovalProgramHash: progHash,
+ },
+ }
+ default:
+ }
+ return res
+ }
+ txnResults := make([]simulation.TxnResult, len(testcase.simulateInstructions))
+ for i, txnArgs := range testcase.simulateInstructions {
+ txnResults[i] = txnArgsToResult(txnArgs)
+ }
+
+ prepareInitialStates := make(map[basics.Address]util.Set[string])
+ for _, instruction := range testcase.prepareInstructions {
+ if prepareInitialStates[env.Accounts[instruction.addressIndex].Addr] == nil {
+ prepareInitialStates[env.Accounts[instruction.addressIndex].Addr] = make(util.Set[string])
+ }
+ prepareInitialStates[env.Accounts[instruction.addressIndex].Addr].Add(string(instruction.appArgs[1]))
+ }
+
+ newlyCreatedLocalStates := make(map[basics.Address]util.Set[string])
+ for _, instruction := range testcase.simulateInstructions {
+ if string(instruction.appArgs[0]) != "put" {
+ continue
+ }
+ acctAddress := env.Accounts[instruction.addressIndex].Addr
+ if prepareInitialStates[acctAddress] != nil && prepareInitialStates[acctAddress].Contains(string(instruction.appArgs[1])) {
+ continue
+ }
+ if newlyCreatedLocalStates[acctAddress] == nil {
+ newlyCreatedLocalStates[acctAddress] = make(util.Set[string])
+ }
+ newlyCreatedLocalStates[acctAddress].Add(string(instruction.appArgs[1]))
+ }
+
+ totalConsumed := uint64(0)
+ for _, txnResult := range txnResults {
+ totalConsumed += txnResult.AppBudgetConsumed
+ }
+
+ expectedInitialLocalStates := make(map[basics.Address]simulation.AppKVPairs)
+ for addrID, kvPair := range testcase.initialLocalStates {
+ expectedInitialLocalStates[env.Accounts[addrID].Addr] = kvPair
+ }
+
+ return simulationTestCase{
+ input: simulation.Request{
+ TxnGroups: [][]transactions.SignedTxn{
+ signedTxns,
+ },
+ TraceConfig: simulation.ExecTraceConfig{
+ Enable: true,
+ State: true,
+ },
+ },
+ developerAPI: true,
+ expected: simulation.Result{
+ Version: simulation.ResultLatestVersion,
+ LastRound: env.TxnInfo.LatestRound(),
+ TraceConfig: simulation.ExecTraceConfig{
+ Enable: true,
+ State: true,
+ },
+ TxnGroups: []simulation.TxnGroupResult{
+ {
+ Txns: txnResults,
+ AppBudgetAdded: 700 * uint64(len(txnResults)),
+ AppBudgetConsumed: totalConsumed,
+ },
+ },
+ InitialStates: &simulation.ResourcesInitialStates{
+ AllAppsInitialStates: simulation.AppsInitialStates{
+ appID: simulation.SingleAppInitialStates{
+ AppGlobals: make(simulation.AppKVPairs),
+ AppLocals: expectedInitialLocalStates,
+ AppBoxes: make(simulation.AppKVPairs),
+ CreatedGlobals: make(util.Set[string]),
+ CreatedLocals: newlyCreatedLocalStates,
+ CreatedBoxes: make(util.Set[string]),
+ },
+ },
+ CreatedApp: make(util.Set[basics.AppIndex]),
+ },
+ },
+ }
+ })
+}
+
+func TestLocalInitialStates(t *testing.T) {
+ partitiontest.PartitionTest(t)
+ t.Parallel()
+
+ testLocalInitialStatesHelper(t, LocalInitialStatesTestCase{
+ prepareInstructions: []LocalStateOperation{},
+ simulateInstructions: []LocalStateOperation{
+ {
+ addressIndex: 2,
+ appArgs: [][]byte{
+ []byte("put"), []byte("key"), []byte("value"),
+ },
+ },
+ },
+ initialLocalStates: map[uint64]simulation.AppKVPairs{},
+ })
+
+ testLocalInitialStatesHelper(t, LocalInitialStatesTestCase{
+ prepareInstructions: []LocalStateOperation{
+ {
+ addressIndex: 2,
+ appArgs: [][]byte{
+ []byte("put"), []byte("key"), []byte("value"),
+ },
+ },
+ },
+ simulateInstructions: []LocalStateOperation{
+ {
+ addressIndex: 2,
+ appArgs: [][]byte{
+ []byte("put"), []byte("key"), []byte("new-value"),
+ },
+ },
+ {
+ addressIndex: 2,
+ appArgs: [][]byte{
+ []byte("get"), []byte("key"),
+ },
+ },
+ {
+ addressIndex: 2,
+ appArgs: [][]byte{
+ []byte("del"), []byte("key"),
+ },
+ },
+ },
+ initialLocalStates: map[uint64]simulation.AppKVPairs{
+ 2: {
+ "key": basics.TealValue{
+ Type: basics.TealBytesType,
+ Bytes: "value",
+ },
+ },
+ },
+ })
+}
+
+func TestInitialStatesGetEx(t *testing.T) {
+ partitiontest.PartitionTest(t)
+ t.Parallel()
+
+ simulationTest(t, func(env simulationtesting.Environment) simulationTestCase {
+ appCreator := env.Accounts[0]
+
+ approvalProgramSrc := `#pragma version 8
+txn ApplicationID
+bz end // Do nothing during create
+
+txn OnCompletion
+int OptIn
+==
+bnz end // Always allow optin
+
+byte "put"
+byte "local_put"
+byte "del"
+txn ApplicationArgs 0
+match put local_put del
+err // Unknown command
+
+put:
+ txn ApplicationArgs 1
+ txn ApplicationArgs 2
+ app_global_put
+ b end
+
+local_put:
+ txn Sender
+ txn ApplicationArgs 1
+ txn ApplicationArgs 2
+ app_local_put
+ b end
+
+del:
+ txn ApplicationArgs 1
+ app_global_del
+ b end
+
+end:
+ int 1
+`
+
+ appIDWithStates := env.CreateApp(appCreator.Addr, simulationtesting.AppParams{
+ GlobalStateSchema: basics.StateSchema{NumByteSlice: 8},
+ LocalStateSchema: basics.StateSchema{NumByteSlice: 8},
+ ApprovalProgram: approvalProgramSrc,
+ ClearStateProgram: `#pragma version 8
+int 1`,
+ })
+
+ env.Txn(env.TxnInfo.NewTxn(txntest.Txn{
+ Sender: appCreator.Addr,
+ Type: protocol.ApplicationCallTx,
+ ApplicationID: appIDWithStates,
+ OnCompletion: transactions.OptInOC,
+ }).SignedTxn())
+
+ prepareSteps := [][][]byte{
+ {
+ []byte("put"), []byte("A"), []byte("initial content A"),
+ },
+ {
+ []byte("local_put"), []byte("B"), []byte("initial content B"),
+ },
+ }
+
+ for _, txnArgs := range prepareSteps {
+ env.Txn(env.TxnInfo.NewTxn(txntest.Txn{
+ Sender: appCreator.Addr,
+ Type: protocol.ApplicationCallTx,
+ ApplicationID: appIDWithStates,
+ ApplicationArgs: txnArgs,
+ }).SignedTxn())
+ }
+
+ // The application to read another app
+ approvalProgramSrc = `#pragma version 8
+txn ApplicationID
+bz end // Do nothing during create
+
+byte "read_global"
+byte "read_local"
+txn ApplicationArgs 0
+match read_global read_local
+err // Unknown command
+
+read_global:
+ txn ApplicationArgs 1 // AppID
+ btoi
+ txn ApplicationArgs 2 // GlobalKey
+ app_global_get_ex
+ assert
+ pop
+ b end
+
+read_local:
+ txn Sender
+ txn ApplicationArgs 1 // AppID
+ btoi
+ txn ApplicationArgs 2 // LocalKey
+ app_local_get_ex
+ assert
+ pop
+ b end
+
+end:
+int 1
+`
+ appIDReadingStates := env.CreateApp(appCreator.Addr, simulationtesting.AppParams{
+ ApprovalProgram: approvalProgramSrc,
+ ClearStateProgram: `#pragma version 8
+int 1`,
+ })
+
+ op, err := logic.AssembleString(approvalProgramSrc)
+ require.NoError(t, err)
+ progHash := crypto.Hash(op.Program)
+
+ txns := make([]*txntest.Txn, 2)
+ tmpTxn0 := env.TxnInfo.NewTxn(txntest.Txn{
+ Type: protocol.ApplicationCallTx,
+ Sender: appCreator.Addr,
+ ApplicationID: appIDReadingStates,
+ ApplicationArgs: [][]byte{
+ []byte("read_global"),
+ uint64ToBytes(uint64(appIDWithStates)),
+ []byte("A"),
+ },
+ ForeignApps: []basics.AppIndex{appIDWithStates},
+ })
+ txns[0] = &tmpTxn0
+ tmpTxn1 := env.TxnInfo.NewTxn(txntest.Txn{
+ Type: protocol.ApplicationCallTx,
+ Sender: appCreator.Addr,
+ ApplicationID: appIDReadingStates,
+ ApplicationArgs: [][]byte{
+ []byte("read_local"),
+ uint64ToBytes(uint64(appIDWithStates)),
+ []byte("B"),
+ },
+ ForeignApps: []basics.AppIndex{appIDWithStates},
+ Note: []byte("bla"),
+ })
+ txns[1] = &tmpTxn1
+ txntest.Group(txns...)
+ signedTxns := make([]transactions.SignedTxn, len(txns))
+ for i, txn := range txns {
+ signedTxns[i] = txn.Txn().Sign(appCreator.Sk)
+ }
+
+ // now construct app calls for global local get ex
+ txnResults := []simulation.TxnResult{
+ {
+ AppBudgetConsumed: 14,
+ Trace: &simulation.TransactionTrace{
+ ApprovalProgramTrace: []simulation.OpcodeTraceUnit{
+ {PC: 1},
+ {PC: 3},
+ {PC: 6},
+ {PC: 19},
+ {PC: 31},
+ {PC: 34},
+ {PC: 41},
+ {PC: 44},
+ {PC: 45},
+ {PC: 48},
+ {PC: 49},
+ {PC: 50},
+ {PC: 51},
+ {PC: 69},
+ },
+ ApprovalProgramHash: progHash,
+ },
+ },
+ {
+ AppBudgetConsumed: 15,
+ Trace: &simulation.TransactionTrace{
+ ApprovalProgramTrace: []simulation.OpcodeTraceUnit{
+ {PC: 1},
+ {PC: 3},
+ {PC: 6},
+ {PC: 19},
+ {PC: 31},
+ {PC: 34},
+ {PC: 54},
+ {PC: 56},
+ {PC: 59},
+ {PC: 60},
+ {PC: 63},
+ {PC: 64},
+ {PC: 65},
+ {PC: 66},
+ {PC: 69},
+ },
+ ApprovalProgramHash: progHash,
+ },
+ },
+ }
+
+ totalConsumed := uint64(0)
+ for _, txnResult := range txnResults {
+ totalConsumed += txnResult.AppBudgetConsumed
+ }
+
+ return simulationTestCase{
+ input: simulation.Request{
+ TxnGroups: [][]transactions.SignedTxn{
+ signedTxns,
+ },
+ TraceConfig: simulation.ExecTraceConfig{
+ Enable: true,
+ State: true,
+ },
+ },
+ developerAPI: true,
+ expected: simulation.Result{
+ Version: simulation.ResultLatestVersion,
+ LastRound: env.TxnInfo.LatestRound(),
+ TraceConfig: simulation.ExecTraceConfig{
+ Enable: true,
+ State: true,
+ },
+ TxnGroups: []simulation.TxnGroupResult{
+ {
+ Txns: txnResults,
+ AppBudgetAdded: 700 * uint64(len(txnResults)),
+ AppBudgetConsumed: totalConsumed,
+ },
+ },
+ InitialStates: &simulation.ResourcesInitialStates{
+ AllAppsInitialStates: simulation.AppsInitialStates{
+ appIDWithStates: simulation.SingleAppInitialStates{
+ AppGlobals: simulation.AppKVPairs{
+ "A": basics.TealValue{
+ Type: basics.TealBytesType,
+ Bytes: "initial content A",
+ },
+ },
+ AppLocals: map[basics.Address]simulation.AppKVPairs{
+ appCreator.Addr: {
+ "B": basics.TealValue{
+ Type: basics.TealBytesType,
+ Bytes: "initial content B",
+ },
+ },
+ },
+ AppBoxes: make(simulation.AppKVPairs),
+ CreatedGlobals: make(util.Set[string]),
+ CreatedBoxes: make(util.Set[string]),
+ CreatedLocals: map[basics.Address]util.Set[string]{},
+ },
+ },
+ CreatedApp: make(util.Set[basics.AppIndex]),
+ },
+ },
+ }
+ })
+}
+
+// TestBalanceChangesWithApp sends a payment transaction to a new account and confirms its balance
+// within a subsequent app call
+func TestBalanceChangesWithApp(t *testing.T) {
+ partitiontest.PartitionTest(t)
+ t.Parallel()
+ simulationTest(t, func(env simulationtesting.Environment) simulationTestCase {
+ sender := env.Accounts[0]
+ senderBalance := sender.AcctData.MicroAlgos.Raw
+ sendAmount := senderBalance - 500_000 // Leave 0.5 Algos in the sender account
+ receiver := env.Accounts[1]
+ receiverBalance := receiver.AcctData.MicroAlgos.Raw
+
+ futureAppID := basics.AppIndex(1001)
+ createTxn := env.TxnInfo.NewTxn(txntest.Txn{
+ Type: protocol.ApplicationCallTx,
+ Sender: sender.Addr,
+ ApprovalProgram: `#pragma version 6
+txn ApplicationID // [appId]
+bz end // []
+int 1 // [1]
+balance // [bal[1]]
+itob // [itob(bal[1])]
+txn ApplicationArgs 0 // [itob(bal[1]), args[0]]
+== // [itob(bal[1])=?=args[0]]
+assert
+end:
+int 1 // [1]
+`,
+ ClearStateProgram: `#pragma version 6
+int 1`,
+ })
+ checkStartingBalanceTxn := env.TxnInfo.NewTxn(txntest.Txn{
+ Type: protocol.ApplicationCallTx,
+ Sender: sender.Addr,
+ ApplicationID: futureAppID,
+ Accounts: []basics.Address{receiver.Addr},
+ ApplicationArgs: [][]byte{uint64ToBytes(receiverBalance)},
+ })
+ paymentTxn := env.TxnInfo.NewTxn(txntest.Txn{
+ Type: protocol.PaymentTx,
+ Sender: sender.Addr,
+ Receiver: receiver.Addr,
+ Amount: sendAmount,
+ })
+ checkEndingBalanceTxn := env.TxnInfo.NewTxn(txntest.Txn{
+ Type: protocol.ApplicationCallTx,
+ Sender: sender.Addr,
+ ApplicationID: futureAppID,
+ Accounts: []basics.Address{receiver.Addr},
+ // Receiver's balance should have increased by sendAmount
+ ApplicationArgs: [][]byte{uint64ToBytes(receiverBalance + sendAmount)},
+ })
+
+ txntest.Group(&createTxn, &checkStartingBalanceTxn, &paymentTxn, &checkEndingBalanceTxn)
+
+ signedCreateTxn := createTxn.Txn().Sign(sender.Sk)
+ signedCheckStartingBalanceTxn := checkStartingBalanceTxn.Txn().Sign(sender.Sk)
+ signedPaymentTxn := paymentTxn.Txn().Sign(sender.Sk)
+ signedCheckEndingBalanceTxn := checkEndingBalanceTxn.Txn().Sign(sender.Sk)
+
+ return simulationTestCase{
+ input: simulation.Request{
+ TxnGroups: [][]transactions.SignedTxn{
+ {
+ signedCreateTxn,
+ signedCheckStartingBalanceTxn,
+ signedPaymentTxn,
+ signedCheckEndingBalanceTxn,
+ },
+ },
+ },
+ expected: simulation.Result{
+ Version: simulation.ResultLatestVersion,
+ LastRound: env.TxnInfo.LatestRound(),
+ TxnGroups: []simulation.TxnGroupResult{
+ {
+ Txns: []simulation.TxnResult{
+ {
+ Txn: transactions.SignedTxnWithAD{
+ ApplyData: transactions.ApplyData{
+ ApplicationID: futureAppID,
+ },
+ },
+ AppBudgetConsumed: 4,
+ },
+ {
+ AppBudgetConsumed: 10,
+ },
+ {},
+ {
+ AppBudgetConsumed: 10,
+ },
+ },
+ AppBudgetAdded: 2100,
+ AppBudgetConsumed: 24,
+ },
+ },
+ },
+ }
+ })
+}
+
+// TestOptionalSignatures tests that transactions with signatures and without signatures are both
+// properly handled when AllowEmptySignatures is enabled.
+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]
+
+ txn := env.TxnInfo.NewTxn(txntest.Txn{
+ Type: protocol.PaymentTx,
+ Sender: sender.Addr,
+ Receiver: sender.Addr,
+ Amount: 1,
+ })
var stxn transactions.SignedTxn
if signed {
@@ -5802,6 +7373,10 @@ func (o boxOperation) appArgs() [][]byte {
}
}
+func (o boxOperation) boxRefs() []transactions.BoxRef {
+ return []transactions.BoxRef{{Name: []byte(o.name)}}
+}
+
type boxTestResult struct {
Boxes map[logic.BoxRef]uint64
NumEmptyBoxRefs int
diff --git a/ledger/simulation/trace.go b/ledger/simulation/trace.go
index 7861292830..afc6a2124e 100644
--- a/ledger/simulation/trace.go
+++ b/ledger/simulation/trace.go
@@ -141,6 +141,7 @@ type Result struct {
EvalOverrides ResultEvalOverrides
Block *ledgercore.ValidatedBlock
TraceConfig ExecTraceConfig
+ InitialStates *ResourcesInitialStates
}
// ReturnTrace reads from Result object and decides if simulation returns PC.
@@ -217,6 +218,7 @@ func makeSimulationResult(lastRound basics.Round, request Request, developerAPI
TxnGroups: groups,
EvalOverrides: resultEvalConstants,
TraceConfig: request.TraceConfig,
+ InitialStates: newResourcesInitialStates(request),
}, nil
}
diff --git a/ledger/simulation/tracer.go b/ledger/simulation/tracer.go
index 0d5f2eb5c1..2bc600ee38 100644
--- a/ledger/simulation/tracer.go
+++ b/ledger/simulation/tracer.go
@@ -270,7 +270,7 @@ func (tracer *evalTracer) makeOpcodeTraceUnit(cx *logic.EvalContext) OpcodeTrace
}
func (o *OpcodeTraceUnit) computeStackValueDeletions(cx *logic.EvalContext, tracer *evalTracer) {
- tracer.popCount, tracer.addCount = cx.GetOpSpec().Explain(cx)
+ tracer.popCount, tracer.addCount = cx.GetOpSpec().StackExplain(cx)
o.StackPopCount = uint64(tracer.popCount)
stackHeight := len(cx.Stack)
@@ -309,6 +309,7 @@ func (tracer *evalTracer) BeforeOpcode(cx *logic.EvalContext) {
}
if tracer.result.ReturnStateChange() {
latestOpcodeTraceUnit.appendStateOperations(cx)
+ tracer.result.InitialStates.increment(cx)
}
}
}
@@ -325,10 +326,14 @@ func (o *OpcodeTraceUnit) appendAddedStackValue(cx *logic.EvalContext, tracer *e
}
func (o *OpcodeTraceUnit) appendStateOperations(cx *logic.EvalContext) {
- if cx.GetOpSpec().StateExplain == nil {
+ if cx.GetOpSpec().AppStateExplain == nil {
+ return
+ }
+ appState, stateOp, appID, acctAddr, stateKey := cx.GetOpSpec().AppStateExplain(cx)
+ // If the operation is not write or delete, return without
+ if stateOp == logic.AppStateRead {
return
}
- appState, stateOp, appID, acctAddr, stateKey := cx.GetOpSpec().StateExplain(cx)
o.StateChanges = append(o.StateChanges, StateOperation{
AppStateOp: stateOp,
AppState: appState,
@@ -376,7 +381,7 @@ func (tracer *evalTracer) recordUpdatedScratchVars(cx *logic.EvalContext) []Scra
func (o *OpcodeTraceUnit) updateNewStateValues(cx *logic.EvalContext) {
for i, sc := range o.StateChanges {
- o.StateChanges[i].NewValue = logic.AppNewStateQuerying(
+ o.StateChanges[i].NewValue = logic.AppStateQuerying(
cx, sc.AppState, sc.AppStateOp, sc.AppID, sc.Account, sc.Key)
}
}
@@ -447,6 +452,13 @@ func (tracer *evalTracer) BeforeProgram(cx *logic.EvalContext) {
txnTraceStackElem.ApprovalProgramHash = programHash
}
}
+ if tracer.result.ReturnStateChange() {
+ // If we are recording state changes, including initial states,
+ // then we should exclude initial states of created app during simulation.
+ if cx.TxnGroup[groupIndex].SignedTxn.Txn.ApplicationID == 0 {
+ tracer.result.InitialStates.CreatedApp.Add(cx.AppID())
+ }
+ }
if tracer.unnamedResourcePolicy != nil {
globalSharing := false
diff --git a/ledger/store/trackerdb/sqlitedriver/merkle_commiter.go b/ledger/store/trackerdb/sqlitedriver/merkle_committer.go
similarity index 100%
rename from ledger/store/trackerdb/sqlitedriver/merkle_commiter.go
rename to ledger/store/trackerdb/sqlitedriver/merkle_committer.go
diff --git a/netdeploy/network.go b/netdeploy/network.go
index 02202d5559..4e86bd831f 100644
--- a/netdeploy/network.go
+++ b/netdeploy/network.go
@@ -70,7 +70,7 @@ func CreateNetworkFromTemplate(name, rootDir string, templateReader io.Reader, b
var err error
template := defaultNetworkTemplate
- err = loadTemplateFromReader(templateReader, &template)
+ err = LoadTemplateFromReader(templateReader, &template)
if err == nil {
if overrideDevMode {
@@ -100,7 +100,7 @@ func CreateNetworkFromTemplate(name, rootDir string, templateReader io.Reader, b
return n, err
}
template.Consensus = consensus
- err = template.generateGenesisAndWallets(rootDir, n.cfg.Name, binDir)
+ err = template.generateGenesisAndWallets(rootDir, n.cfg.Name)
if err != nil {
return n, err
}
diff --git a/netdeploy/networkTemplate.go b/netdeploy/networkTemplate.go
index 40ea5d4985..43bb9d816f 100644
--- a/netdeploy/networkTemplate.go
+++ b/netdeploy/networkTemplate.go
@@ -48,7 +48,7 @@ var defaultNetworkTemplate = NetworkTemplate{
Genesis: gen.DefaultGenesis,
}
-func (t NetworkTemplate) generateGenesisAndWallets(targetFolder, networkName, binDir string) error {
+func (t NetworkTemplate) generateGenesisAndWallets(targetFolder, networkName string) error {
genesisData := t.Genesis
genesisData.NetworkName = networkName
mergedConsensus := config.Consensus.Merge(t.Consensus)
@@ -180,11 +180,12 @@ func loadTemplate(templateFile string) (NetworkTemplate, error) {
}
defer f.Close()
- err = loadTemplateFromReader(f, &template)
+ err = LoadTemplateFromReader(f, &template)
return template, err
}
-func loadTemplateFromReader(reader io.Reader, template *NetworkTemplate) error {
+// LoadTemplateFromReader loads and decodes a network template
+func LoadTemplateFromReader(reader io.Reader, template *NetworkTemplate) error {
if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" {
// for arm machines, use smaller key dilution
diff --git a/netdeploy/networkTemplates_test.go b/netdeploy/networkTemplates_test.go
index f21c37ace9..80f2c2a43c 100644
--- a/netdeploy/networkTemplates_test.go
+++ b/netdeploy/networkTemplates_test.go
@@ -69,9 +69,8 @@ func TestGenerateGenesis(t *testing.T) {
targetFolder := t.TempDir()
networkName := "testGenGen"
- binDir := os.ExpandEnv("${GOPATH}/bin")
- err := template.generateGenesisAndWallets(targetFolder, networkName, binDir)
+ err := template.generateGenesisAndWallets(targetFolder, networkName)
a.NoError(err)
_, err = os.Stat(filepath.Join(targetFolder, config.GenesisJSONFile))
fileExists := err == nil
diff --git a/network/p2p/capabilities.go b/network/p2p/capabilities.go
new file mode 100644
index 0000000000..149d643da1
--- /dev/null
+++ b/network/p2p/capabilities.go
@@ -0,0 +1,172 @@
+// Copyright (C) 2019-2023 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 p2p
+
+import (
+ "context"
+ "sync"
+ "time"
+
+ dht "github.com/libp2p/go-libp2p-kad-dht"
+ "github.com/libp2p/go-libp2p/core/discovery"
+ "github.com/libp2p/go-libp2p/core/host"
+ "github.com/libp2p/go-libp2p/core/peer"
+ libpeerstore "github.com/libp2p/go-libp2p/core/peerstore"
+
+ "github.com/algorand/go-algorand/config"
+ "github.com/algorand/go-algorand/logging"
+ algoDht "github.com/algorand/go-algorand/network/p2p/dht"
+ "github.com/algorand/go-algorand/network/p2p/peerstore"
+)
+
+// Capability represents functions that some nodes may provide and other nodes would want to know about
+type Capability string
+
+const (
+ // Archival nodes
+ Archival Capability = "archival"
+ // Catchpoints storing nodes
+ Catchpoints = "catchpointStoring"
+)
+
+const operationTimeout = time.Second * 5
+const maxAdvertisementInterval = time.Hour * 22
+
+// CapabilitiesDiscovery exposes Discovery interfaces and wraps underlying DHT methods to provide capabilities advertisement for the node
+type CapabilitiesDiscovery struct {
+ disc discovery.Discovery
+ dht *dht.IpfsDHT
+ log logging.Logger
+ wg sync.WaitGroup
+}
+
+// Advertise implements the discovery.Discovery/discovery.Advertiser interface
+func (c *CapabilitiesDiscovery) Advertise(ctx context.Context, ns string, opts ...discovery.Option) (time.Duration, error) {
+ return c.disc.Advertise(ctx, ns, opts...)
+}
+
+// FindPeers implements the discovery.Discovery/discovery.Discoverer interface
+func (c *CapabilitiesDiscovery) FindPeers(ctx context.Context, ns string, opts ...discovery.Option) (<-chan peer.AddrInfo, error) {
+ return c.disc.FindPeers(ctx, ns, opts...)
+}
+
+// Close should be called when fully shutting down the node
+func (c *CapabilitiesDiscovery) Close() {
+ _ = c.dht.Close()
+ c.wg.Wait()
+}
+
+// Host exposes the underlying libp2p host.Host object
+func (c *CapabilitiesDiscovery) Host() host.Host {
+ return c.dht.Host()
+}
+
+// AddPeer adds a given peer.AddrInfo to the Host's Peerstore, and the DHT's routing table
+func (c *CapabilitiesDiscovery) AddPeer(p peer.AddrInfo) (bool, error) {
+ c.Host().Peerstore().AddAddrs(p.ID, p.Addrs, libpeerstore.AddressTTL)
+ return c.dht.RoutingTable().TryAddPeer(p.ID, true, true)
+}
+
+// PeersForCapability returns a slice of peer.AddrInfo for a Capability
+// Since CapabilitiesDiscovery uses a backoffcache, it will attempt to hit cache, then disk, then network
+// in order to fetch n peers which are advertising the required capability.
+func (c *CapabilitiesDiscovery) PeersForCapability(capability Capability, n int) ([]peer.AddrInfo, error) {
+ ctx, cancel := context.WithTimeout(context.Background(), operationTimeout)
+ defer cancel()
+ var peers []peer.AddrInfo
+ peersChan, err := c.FindPeers(ctx, string(capability), discovery.Limit(n))
+ if err != nil {
+ return nil, err
+ }
+ for p := range peersChan {
+ if p.ID.Size() > 0 && p.ID != c.Host().ID() {
+ peers = append(peers, p)
+ }
+ if len(peers) >= n {
+ break
+ }
+ }
+ return peers, nil
+}
+
+// AdvertiseCapabilities periodically runs the Advertiser interface on the DHT
+// If a capability fails to advertise we will retry every 10 seconds until full success
+// This gets rerun every at the minimum ttl or the maxAdvertisementInterval.
+func (c *CapabilitiesDiscovery) AdvertiseCapabilities(capabilities ...Capability) {
+ c.wg.Add(1)
+ go func() {
+ // Run the initial Advertisement immediately
+ nextExecution := time.After(time.Second / 10000)
+ defer func() {
+ c.wg.Done()
+ }()
+
+ for {
+ select {
+ case <-c.dht.Context().Done():
+ return
+ case <-nextExecution:
+ var err error
+ advertisementInterval := maxAdvertisementInterval
+ for _, capa := range capabilities {
+ ttl, err0 := c.Advertise(c.dht.Context(), string(capa))
+ if err0 != nil {
+ err = err0
+ c.log.Errorf("failed to advertise for capability %s: %v", capa, err0)
+ break
+ }
+ if ttl < advertisementInterval {
+ advertisementInterval = ttl
+ }
+ c.log.Infof("advertised capability %s", capa)
+ }
+ // If we failed to advertise, retry every 10 seconds until successful
+ if err != nil {
+ nextExecution = time.After(time.Second * 10)
+ } else {
+ // Otherwise, ensure we're at the correct interval
+ nextExecution = time.After(advertisementInterval)
+ }
+ }
+ }
+ }()
+}
+
+// MakeCapabilitiesDiscovery creates a new CapabilitiesDiscovery object which exposes peer discovery and capabilities advertisement
+func MakeCapabilitiesDiscovery(ctx context.Context, cfg config.Local, datadir string, network string, log logging.Logger, bootstrapPeers []*peer.AddrInfo) (*CapabilitiesDiscovery, error) {
+ pstore, err := peerstore.NewPeerStore(bootstrapPeers)
+ if err != nil {
+ return nil, err
+ }
+ h, err := makeHost(cfg, datadir, pstore)
+ if err != nil {
+ return nil, err
+ }
+ discDht, err := algoDht.MakeDHT(ctx, h, network, cfg, bootstrapPeers)
+ if err != nil {
+ return nil, err
+ }
+ discImpl, err := algoDht.MakeDiscovery(discDht)
+ if err != nil {
+ return nil, err
+ }
+ return &CapabilitiesDiscovery{
+ disc: discImpl,
+ dht: discDht,
+ log: log,
+ }, nil
+}
diff --git a/network/p2p/capabilities_test.go b/network/p2p/capabilities_test.go
new file mode 100644
index 0000000000..170916dd65
--- /dev/null
+++ b/network/p2p/capabilities_test.go
@@ -0,0 +1,289 @@
+// Copyright (C) 2019-2023 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 p2p
+
+import (
+ "context"
+ "testing"
+ "time"
+
+ golog "github.com/ipfs/go-log"
+ "github.com/libp2p/go-libp2p"
+ dht "github.com/libp2p/go-libp2p-kad-dht"
+ "github.com/libp2p/go-libp2p/core/discovery"
+ "github.com/libp2p/go-libp2p/core/host"
+ "github.com/libp2p/go-libp2p/core/peer"
+ "github.com/stretchr/testify/require"
+
+ "github.com/algorand/go-algorand/config"
+ "github.com/algorand/go-algorand/logging"
+ algodht "github.com/algorand/go-algorand/network/p2p/dht"
+ "github.com/algorand/go-algorand/network/p2p/peerstore"
+ "github.com/algorand/go-algorand/test/partitiontest"
+)
+
+func TestCapabilitiesDiscovery(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ golog.SetDebugLogging()
+ var caps []*CapabilitiesDiscovery
+ var addrs []peer.AddrInfo
+ testSize := 3
+ for i := 0; i < testSize; i++ {
+ tempdir := t.TempDir()
+ capD, err := MakeCapabilitiesDiscovery(context.Background(), config.GetDefaultLocal(), tempdir, "devtestnet", logging.Base(), []*peer.AddrInfo{})
+ require.NoError(t, err)
+ caps = append(caps, capD)
+ addrs = append(addrs, peer.AddrInfo{
+ ID: capD.Host().ID(),
+ Addrs: capD.Host().Addrs(),
+ })
+ }
+ for _, capD := range caps {
+ peersAdded := 0
+ for _, addr := range addrs {
+ added, err := capD.AddPeer(addr)
+ require.NoError(t, err)
+ require.True(t, added)
+ peersAdded++
+ }
+ err := capD.dht.Bootstrap(context.Background())
+ require.NoError(t, err)
+ capD.dht.ForceRefresh()
+ require.Equal(t, peersAdded, capD.dht.RoutingTable().Size())
+ }
+}
+
+func setupDHTHosts(t *testing.T, numHosts int) []*dht.IpfsDHT {
+ var hosts []host.Host
+ var bootstrapPeers []*peer.AddrInfo
+ var dhts []*dht.IpfsDHT
+ cfg := config.GetDefaultLocal()
+ for i := 0; i < numHosts; i++ {
+ tmpdir := t.TempDir()
+ pk, err := GetPrivKey(cfg, tmpdir)
+ require.NoError(t, err)
+ ps, err := peerstore.NewPeerStore([]*peer.AddrInfo{})
+ require.NoError(t, err)
+ h, err := libp2p.New(
+ libp2p.ListenAddrStrings("/dns4/localhost/tcp/0"),
+ libp2p.Identity(pk),
+ libp2p.Peerstore(ps))
+ require.NoError(t, err)
+ hosts = append(hosts, h)
+ bootstrapPeers = append(bootstrapPeers, &peer.AddrInfo{ID: h.ID(), Addrs: h.Addrs()})
+ }
+ for _, h := range hosts {
+ ht, err := algodht.MakeDHT(context.Background(), h, "devtestnet", cfg, bootstrapPeers)
+ require.NoError(t, err)
+ err = ht.Bootstrap(context.Background())
+ require.NoError(t, err)
+ dhts = append(dhts, ht)
+ }
+ return dhts
+}
+
+func waitForRouting(t *testing.T, disc *CapabilitiesDiscovery) {
+ refreshCtx, refCancel := context.WithTimeout(context.Background(), time.Second*5)
+ for {
+ select {
+ case <-refreshCtx.Done():
+ refCancel()
+ require.Fail(t, "failed to populate routing table before timeout")
+ default:
+ if disc.dht.RoutingTable().Size() > 0 {
+ refCancel()
+ return
+ }
+ }
+ }
+}
+
+func setupCapDiscovery(t *testing.T, numHosts int) []*CapabilitiesDiscovery {
+ var hosts []host.Host
+ var bootstrapPeers []*peer.AddrInfo
+ var capsDisc []*CapabilitiesDiscovery
+ cfg := config.GetDefaultLocal()
+ for i := 0; i < numHosts; i++ {
+ tmpdir := t.TempDir()
+ pk, err := GetPrivKey(cfg, tmpdir)
+ require.NoError(t, err)
+ ps, err := peerstore.NewPeerStore([]*peer.AddrInfo{})
+ require.NoError(t, err)
+ h, err := libp2p.New(
+ libp2p.ListenAddrStrings("/dns4/localhost/tcp/0"),
+ libp2p.Identity(pk),
+ libp2p.Peerstore(ps))
+ require.NoError(t, err)
+ hosts = append(hosts, h)
+ bootstrapPeers = append(bootstrapPeers, &peer.AddrInfo{ID: h.ID(), Addrs: h.Addrs()})
+ }
+ for _, h := range hosts {
+ ht, err := algodht.MakeDHT(context.Background(), h, "devtestnet", cfg, bootstrapPeers)
+ require.NoError(t, err)
+ disc, err := algodht.MakeDiscovery(ht)
+ require.NoError(t, err)
+ cd := &CapabilitiesDiscovery{
+ disc: disc,
+ dht: ht,
+ log: logging.Base(),
+ }
+ capsDisc = append(capsDisc, cd)
+ }
+ return capsDisc
+}
+
+func TestDHTTwoPeers(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ numAdvertisers := 2
+ dhts := setupDHTHosts(t, numAdvertisers)
+ topic := "foobar"
+ for i, ht := range dhts {
+ disc, err := algodht.MakeDiscovery(ht)
+ require.NoError(t, err)
+ refreshCtx, refCancel := context.WithTimeout(context.Background(), time.Second*5)
+ peersPopulated:
+ for {
+ select {
+ case <-refreshCtx.Done():
+ refCancel()
+ require.Fail(t, "failed to populate routing table before timeout")
+ default:
+ if ht.RoutingTable().Size() > 0 {
+ refCancel()
+ break peersPopulated
+ }
+ }
+ }
+ _, err = disc.Advertise(context.Background(), topic)
+ require.NoError(t, err)
+
+ ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
+ var advertisers []peer.AddrInfo
+ peersChan, err := disc.FindPeers(ctx, topic, discovery.Limit(numAdvertisers))
+ pollingForPeers:
+ for {
+ select {
+ case p, open := <-peersChan:
+ if p.ID.Size() > 0 {
+ advertisers = append(advertisers, p)
+ }
+ if !open {
+ break pollingForPeers
+ }
+ }
+ }
+ cancel()
+ // Returned peers will include the querying node's ID since it advertises for the topic as well
+ require.Equal(t, i+1, len(advertisers))
+ }
+}
+
+func TestVaryingCapabilities(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ numAdvertisers := 10
+ capsDisc := setupCapDiscovery(t, numAdvertisers)
+ noCap := capsDisc[:3]
+ archOnly := capsDisc[3:5]
+ catchOnly := capsDisc[5:7]
+ archCatch := capsDisc[7:]
+
+ for _, disc := range archOnly {
+ waitForRouting(t, disc)
+ disc.AdvertiseCapabilities(Archival)
+ }
+ for _, disc := range catchOnly {
+ waitForRouting(t, disc)
+ disc.AdvertiseCapabilities(Catchpoints)
+ }
+ for _, disc := range archCatch {
+ waitForRouting(t, disc)
+ disc.AdvertiseCapabilities(Archival, Catchpoints)
+ }
+
+ for _, disc := range noCap {
+ require.Eventuallyf(t,
+ func() bool {
+ numArchPeers := len(archOnly) + len(archCatch)
+ peers, err := disc.PeersForCapability(Archival, numArchPeers)
+ if err == nil && len(peers) == numArchPeers {
+ return true
+ }
+ return false
+ },
+ time.Minute,
+ time.Second,
+ "Not all expected archival peers were found",
+ )
+
+ require.Eventuallyf(t,
+ func() bool {
+ numCatchPeers := len(catchOnly) + len(archCatch)
+ peers, err := disc.PeersForCapability(Catchpoints, numCatchPeers)
+ if err == nil && len(peers) == numCatchPeers {
+ return true
+ }
+ return false
+ },
+ time.Minute,
+ time.Second,
+ "Not all expected catchpoint peers were found",
+ )
+ }
+
+ for _, disc := range capsDisc[3:] {
+ disc.Close()
+ // Make sure it actually closes
+ disc.wg.Wait()
+ }
+}
+
+func TestCapabilitiesExcludesSelf(t *testing.T) {
+ partitiontest.PartitionTest(t)
+ disc := setupCapDiscovery(t, 2)
+
+ testPeersFound := func(disc *CapabilitiesDiscovery, n int, cap Capability) bool {
+ peers, err := disc.PeersForCapability(cap, n+1)
+ if err == nil && len(peers) == n {
+ return true
+ }
+ return false
+ }
+
+ waitForRouting(t, disc[0])
+ disc[0].AdvertiseCapabilities(Archival)
+ // disc[1] finds Archival
+ require.Eventuallyf(t,
+ func() bool { return testPeersFound(disc[1], 1, Archival) },
+ time.Minute,
+ time.Second,
+ "Could not find archival peer",
+ )
+
+ // disc[0] doesn't find itself
+ require.Neverf(t,
+ func() bool { return testPeersFound(disc[0], 1, Archival) },
+ time.Second*5,
+ time.Second,
+ "Found self when searching for capability",
+ )
+
+ disc[0].Close()
+ disc[0].wg.Wait()
+}
diff --git a/network/p2p/dht/dht.go b/network/p2p/dht/dht.go
new file mode 100644
index 0000000000..e612f6062d
--- /dev/null
+++ b/network/p2p/dht/dht.go
@@ -0,0 +1,100 @@
+// Copyright (C) 2019-2023 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 dht
+
+import (
+ "context"
+ "fmt"
+ "math/rand"
+ "time"
+
+ dht "github.com/libp2p/go-libp2p-kad-dht"
+ "github.com/libp2p/go-libp2p/core/discovery"
+ "github.com/libp2p/go-libp2p/core/host"
+ "github.com/libp2p/go-libp2p/core/peer"
+ "github.com/libp2p/go-libp2p/core/protocol"
+ crouting "github.com/libp2p/go-libp2p/core/routing"
+ "github.com/libp2p/go-libp2p/p2p/discovery/backoff"
+ "github.com/libp2p/go-libp2p/p2p/discovery/routing"
+
+ "github.com/algorand/go-algorand/config"
+ "github.com/algorand/go-algorand/network/p2p/dnsaddr"
+ algoproto "github.com/algorand/go-algorand/protocol"
+)
+
+const minBackoff = time.Second * 5
+const maxBackoff = time.Second * 20
+const baseBackoff = float64(1)
+
+// getBootstrapPeersFunc looks up a list of Multiaddrs strings from the dnsaddr records at the primary
+// SRV record domain.
+func getBootstrapPeersFunc(cfg config.Local, network string) func() []peer.AddrInfo {
+ return func() []peer.AddrInfo {
+ var addrs []peer.AddrInfo
+ bootstraps := cfg.DNSBootstrapArray(algoproto.NetworkID(network))
+ for _, dnsBootstrap := range bootstraps {
+ controller := dnsaddr.NewMultiaddrDNSResolveController(cfg.DNSSecuritySRVEnforced(), "")
+ resolvedAddrs, err := dnsaddr.MultiaddrsFromResolver(dnsBootstrap.PrimarySRVBootstrap, controller)
+ if err != nil {
+ continue
+ }
+ for _, resolvedAddr := range resolvedAddrs {
+ info, err0 := peer.AddrInfoFromP2pAddr(resolvedAddr)
+ if err0 != nil {
+ continue
+ }
+ addrs = append(addrs, *info)
+ }
+ }
+ return addrs
+ }
+}
+
+func dhtProtocolPrefix(network string) protocol.ID {
+ return protocol.ID(fmt.Sprintf("/algorand/kad/%s", network))
+}
+
+// MakeDHT creates the dht.IpfsDHT object
+func MakeDHT(ctx context.Context, h host.Host, network string, cfg config.Local, bootstrapPeers []*peer.AddrInfo) (*dht.IpfsDHT, error) {
+ var peers []peer.AddrInfo
+ for _, bPeer := range bootstrapPeers {
+ if bPeer != nil {
+ peers = append(peers, *bPeer)
+ }
+ }
+ dhtCfg := []dht.Option{
+ // Automatically determine server or client mode
+ dht.Mode(dht.ModeAutoServer),
+ // We don't need the value store right now
+ dht.DisableValues(),
+ dht.ProtocolPrefix(dhtProtocolPrefix(network)),
+ dht.BootstrapPeers(peers...),
+ }
+ if len(bootstrapPeers) == 0 {
+ dhtCfg = append(dhtCfg, dht.BootstrapPeersFunc(getBootstrapPeersFunc(cfg, network)))
+ }
+ return dht.New(ctx, h, dhtCfg...)
+}
+
+func backoffFactory() backoff.BackoffFactory {
+ return backoff.NewExponentialDecorrelatedJitter(minBackoff, maxBackoff, baseBackoff, rand.New(rand.NewSource(rand.Int63())))
+}
+
+// MakeDiscovery creates a discovery.Discovery object using backoff and cacching
+func MakeDiscovery(r crouting.ContentRouting) (discovery.Discovery, error) {
+ return backoff.NewBackoffDiscovery(routing.NewRoutingDiscovery(r), backoffFactory(), backoff.WithBackoffDiscoveryReturnedChannelSize(0), backoff.WithBackoffDiscoverySimultaneousQueryBufferSize(0))
+}
diff --git a/network/p2p/dht/dht_test.go b/network/p2p/dht/dht_test.go
new file mode 100644
index 0000000000..3d4eabb3bc
--- /dev/null
+++ b/network/p2p/dht/dht_test.go
@@ -0,0 +1,106 @@
+// Copyright (C) 2019-2023 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 dht
+
+import (
+ "context"
+ "testing"
+
+ logging "github.com/ipfs/go-log"
+ "github.com/libp2p/go-libp2p"
+ "github.com/libp2p/go-libp2p/core/peer"
+ "github.com/stretchr/testify/require"
+
+ "github.com/algorand/go-algorand/config"
+ "github.com/algorand/go-algorand/test/partitiontest"
+)
+
+func TestDHTBasic(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ h, err := libp2p.New()
+ require.NoError(t, err)
+ dht, err := MakeDHT(
+ context.Background(),
+ h,
+ "devtestnet",
+ config.GetDefaultLocal(),
+ []*peer.AddrInfo{{}})
+ require.NoError(t, err)
+ _, err = MakeDiscovery(dht)
+ require.NoError(t, err)
+ err = dht.Bootstrap(context.Background())
+ require.NoError(t, err)
+}
+
+func TestDHTBasicAlgodev(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ logging.SetDebugLogging()
+ h, err := libp2p.New()
+ require.NoError(t, err)
+ cfg := config.GetDefaultLocal()
+ cfg.DNSBootstrapID = ".algodev.network"
+ dht, err := MakeDHT(context.Background(), h, "betanet", cfg, []*peer.AddrInfo{})
+ require.NoError(t, err)
+ _, err = MakeDiscovery(dht)
+ require.NoError(t, err)
+ err = dht.Bootstrap(context.Background())
+ require.NoError(t, err)
+}
+
+func TestGetBootstrapPeers(t *testing.T) {
+ t.Parallel()
+ partitiontest.PartitionTest(t)
+
+ cfg := config.GetDefaultLocal()
+ cfg.DNSBootstrapID = ".algodev.network"
+ cfg.DNSSecurityFlags = 0
+
+ addrs := getBootstrapPeersFunc(cfg, "test")()
+
+ require.GreaterOrEqual(t, len(addrs), 1)
+ addr := addrs[0]
+ require.Equal(t, len(addr.Addrs), 1)
+ require.GreaterOrEqual(t, len(addr.Addrs), 1)
+}
+
+func TestGetBootstrapPeersFailure(t *testing.T) {
+ t.Parallel()
+ partitiontest.PartitionTest(t)
+
+ cfg := config.GetDefaultLocal()
+ cfg.DNSSecurityFlags = 0
+ cfg.DNSBootstrapID = "non-existent.algodev.network"
+
+ addrs := getBootstrapPeersFunc(cfg, "test")()
+
+ require.Equal(t, 0, len(addrs))
+}
+
+func TestGetBootstrapPeersInvalidAddr(t *testing.T) {
+ t.Parallel()
+ partitiontest.PartitionTest(t)
+
+ cfg := config.GetDefaultLocal()
+ cfg.DNSSecurityFlags = 0
+ cfg.DNSBootstrapID = ".algodev.network"
+
+ addrs := getBootstrapPeersFunc(cfg, "testInvalidAddr")()
+
+ require.Equal(t, 0, len(addrs))
+}
diff --git a/network/p2p/p2p.go b/network/p2p/p2p.go
index 70c9267731..42db4694c4 100644
--- a/network/p2p/p2p.go
+++ b/network/p2p/p2p.go
@@ -20,6 +20,7 @@ import (
"context"
"fmt"
"runtime"
+ "strings"
"time"
"github.com/algorand/go-algorand/config"
@@ -69,8 +70,7 @@ const AlgorandWsProtocol = "/algorand-ws/1.0.0"
const dialTimeout = 30 * time.Second
-// MakeService creates a P2P service instance
-func MakeService(ctx context.Context, log logging.Logger, cfg config.Local, datadir string, pstore peerstore.Peerstore, wsStreamHandler StreamHandler) (*serviceImpl, error) {
+func makeHost(cfg config.Local, datadir string, pstore peerstore.Peerstore) (host.Host, error) {
// load stored peer ID, or make ephemeral peer ID
privKey, err := GetPrivKey(cfg, datadir)
if err != nil {
@@ -83,14 +83,28 @@ func MakeService(ctx context.Context, log logging.Logger, cfg config.Local, data
version := config.GetCurrentVersion()
ua := fmt.Sprintf("algod/%d.%d (%s; commit=%s; %d) %s(%s)", version.Major, version.Minor, version.Channel, version.CommitHash, version.BuildNumber, runtime.GOOS, runtime.GOARCH)
- h, err := libp2p.New(
+ var listenAddr string
+ if cfg.NetAddress != "" {
+ if parsedListenAddr, perr := netAddressToListenAddress(cfg.NetAddress); perr == nil {
+ listenAddr = parsedListenAddr
+ }
+ } else {
+ listenAddr = "/ip4/0.0.0.0/tcp/0"
+ }
+
+ return libp2p.New(
libp2p.Identity(privKey),
libp2p.UserAgent(ua),
libp2p.Transport(tcp.NewTCPTransport),
libp2p.Muxer("/yamux/1.0.0", &ymx),
libp2p.Peerstore(pstore),
- libp2p.ListenAddrStrings("/ip4/0.0.0.0/tcp/0"),
+ libp2p.ListenAddrStrings(listenAddr),
)
+}
+
+// MakeService creates a P2P service instance
+func MakeService(ctx context.Context, log logging.Logger, cfg config.Local, datadir string, pstore peerstore.Peerstore, wsStreamHandler StreamHandler) (*serviceImpl, error) {
+ h, err := makeHost(cfg, datadir, pstore)
if err != nil {
return nil, err
}
@@ -173,3 +187,23 @@ func (s *serviceImpl) Conns() []network.Conn {
func (s *serviceImpl) ClosePeer(peer peer.ID) error {
return s.host.Network().ClosePeer(peer)
}
+
+// netAddressToListenAddress converts a netAddress in "ip:port" format to a listen address
+// that can be passed in to libp2p.ListenAddrStrings
+func netAddressToListenAddress(netAddress string) (string, error) {
+ // split the string on ":"
+ // if there are more than 2 parts, return an error
+ parts := strings.Split(netAddress, ":")
+ if len(parts) != 2 {
+ return "", fmt.Errorf("invalid netAddress %s; required format is \"ip:port\"", netAddress)
+ }
+ ip := "0.0.0.0"
+ if parts[0] != "" {
+ ip = parts[0]
+ }
+ if parts[1] == "" {
+ return "", fmt.Errorf("invalid netAddress %s, port is required", netAddress)
+ }
+
+ return fmt.Sprintf("/ip4/%s/tcp/%s", ip, parts[1]), nil
+}
diff --git a/network/p2p/p2p_test.go b/network/p2p/p2p_test.go
new file mode 100644
index 0000000000..5095e0d4b5
--- /dev/null
+++ b/network/p2p/p2p_test.go
@@ -0,0 +1,76 @@
+// Copyright (C) 2019-2023 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 p2p
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/algorand/go-algorand/test/partitiontest"
+ "github.com/stretchr/testify/require"
+)
+
+// Tests the helper function netAddressToListenAddress which converts
+// a config value netAddress to a multiaddress usable by libp2p.
+func TestNetAddressToListenAddress(t *testing.T) {
+ partitiontest.PartitionTest(t)
+ t.Parallel()
+
+ tests := []struct {
+ input string
+ output string
+ err bool
+ }{
+ {
+ input: "192.168.1.1:8080",
+ output: "/ip4/192.168.1.1/tcp/8080",
+ err: false,
+ },
+ {
+ input: ":8080",
+ output: "/ip4/0.0.0.0/tcp/8080",
+ err: false,
+ },
+ {
+ input: "192.168.1.1:",
+ output: "",
+ err: true,
+ },
+ {
+ input: "192.168.1.1",
+ output: "",
+ err: true,
+ },
+ {
+ input: "192.168.1.1:8080:9090",
+ output: "",
+ err: true,
+ },
+ }
+
+ for _, test := range tests { //nolint:paralleltest
+ t.Run(fmt.Sprintf("input: %s", test.input), func(t *testing.T) {
+ res, err := netAddressToListenAddress(test.input)
+ if test.err {
+ require.Error(t, err)
+ } else {
+ require.NoError(t, err)
+ require.Equal(t, test.output, res)
+ }
+ })
+ }
+}
diff --git a/network/p2p/peerstore/peerstore.go b/network/p2p/peerstore/peerstore.go
index ee6bf90a65..63a88966ff 100644
--- a/network/p2p/peerstore/peerstore.go
+++ b/network/p2p/peerstore/peerstore.go
@@ -18,15 +18,52 @@ package peerstore
import (
"fmt"
+ "math"
+ "math/rand"
+ "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"
)
+// when using GetAddresses with getAllAddresses, all the addresses will be retrieved, regardless
+// of how many addresses the phonebook actually has. ( with the retry-after logic applied )
+const getAllAddresses = math.MaxInt32
+
+// PhoneBookEntryRoles defines the roles that a single entry on the phonebook can take.
+// currently, we have two roles : relay role and archiver role, which are mutually exclusive.
+//
+//msgp:ignore PhoneBookEntryRoles
+type PhoneBookEntryRoles int
+
+const addressDataKey string = "addressData"
+
// PeerStore implements Peerstore and CertifiedAddrBook.
type PeerStore struct {
peerStoreCAB
+ connectionsRateLimitingCount uint
+ connectionsRateLimitingWindow time.Duration
+}
+
+// addressData: holds the information associated with each phonebook address.
+type addressData struct {
+ // retryAfter is the time to wait before retrying to connect to the address.
+ retryAfter time.Time
+
+ // recentConnectionTimes is the log of connection times used to observe the maximum
+ // connections to the address in a given time window.
+ recentConnectionTimes []time.Time
+
+ // networkNames: lists the networks to which the given address belongs.
+ networkNames map[string]bool
+
+ // role is the role that this address serves.
+ role PhoneBookEntryRoles
+
+ // persistent is set true for peers whose record should not be removed for the peer list
+ persistent bool
}
// peerStoreCAB combines the libp2p Peerstore and CertifiedAddrBook interfaces.
@@ -47,6 +84,294 @@ func NewPeerStore(addrInfo []*peer.AddrInfo) (*PeerStore, error) {
info := addrInfo[i]
ps.AddAddrs(info.ID, info.Addrs, libp2p.AddressTTL)
}
- pstore := &PeerStore{ps}
+ pstore := &PeerStore{peerStoreCAB: ps}
+ return pstore, nil
+}
+
+// MakePhonebook creates a phonebook with the passed configuration values
+func MakePhonebook(connectionsRateLimitingCount uint,
+ connectionsRateLimitingWindow time.Duration) (*PeerStore, error) {
+ ps, err := mempstore.NewPeerstore()
+ if err != nil {
+ return &PeerStore{}, fmt.Errorf("cannot initialize a peerstore: %w", err)
+ }
+ pstore := &PeerStore{peerStoreCAB: ps,
+ connectionsRateLimitingCount: connectionsRateLimitingCount,
+ connectionsRateLimitingWindow: connectionsRateLimitingWindow,
+ }
return pstore, nil
}
+
+// GetAddresses returns up to N addresses, but may return fewer
+func (ps *PeerStore) GetAddresses(n int, role PhoneBookEntryRoles) []string {
+ return shuffleSelect(ps.filterRetryTime(time.Now(), role), n)
+}
+
+// UpdateRetryAfter updates the retryAfter time for the given address.
+func (ps *PeerStore) UpdateRetryAfter(addr string, retryAfter time.Time) {
+ info, err := PeerInfoFromDomainPort(addr)
+ if err != nil {
+ return
+ }
+ metadata, _ := ps.Get(info.ID, addressDataKey)
+ if metadata != nil {
+ ad, ok := metadata.(addressData)
+ if !ok {
+ return
+ }
+ ad.retryAfter = retryAfter
+ _ = ps.Put(info.ID, addressDataKey, ad)
+ }
+
+}
+
+// GetConnectionWaitTime will calculate and return the wait
+// time to prevent exceeding connectionsRateLimitingCount.
+// The connection should be established when the waitTime is 0.
+// It will register a provisional next connection time when the waitTime is 0.
+// The provisional time should be updated after the connection with UpdateConnectionTime
+func (ps *PeerStore) GetConnectionWaitTime(addr string) (bool, time.Duration, time.Time) {
+ curTime := time.Now()
+ info, err := PeerInfoFromDomainPort(addr)
+ if err != nil {
+ return false, 0 /* not used */, curTime /* not used */
+ }
+ var timeSince time.Duration
+ var numElmtsToRemove int
+ metadata, err := ps.Get(info.ID, addressDataKey)
+ if err != nil {
+ return false, 0 /* not used */, curTime /* not used */
+ }
+ ad, ok := metadata.(addressData)
+ if !ok {
+ return false, 0 /* not used */, curTime /* not used */
+ }
+ // Remove from recentConnectionTimes the times later than ConnectionsRateLimitingWindowSeconds
+ for numElmtsToRemove < len(ad.recentConnectionTimes) {
+ timeSince = curTime.Sub(ad.recentConnectionTimes[numElmtsToRemove])
+ if timeSince >= ps.connectionsRateLimitingWindow {
+ numElmtsToRemove++
+ } else {
+ break // break the loop. The rest are earlier than 1 second
+ }
+ }
+
+ // Remove the expired elements from e.data[addr].recentConnectionTimes
+ ps.popNElements(numElmtsToRemove, peer.ID(addr))
+ // If there are max number of connections within the time window, wait
+ metadata, _ = ps.Get(info.ID, addressDataKey)
+ ad, ok = metadata.(addressData)
+ if !ok {
+ return false, 0 /* not used */, curTime /* not used */
+ }
+ numElts := len(ad.recentConnectionTimes)
+ if uint(numElts) >= ps.connectionsRateLimitingCount {
+ return true, /* true */
+ ps.connectionsRateLimitingWindow - timeSince, curTime /* not used */
+ }
+
+ // Else, there is space in connectionsRateLimitingCount. The
+ // connection request of the caller will proceed
+ // Update curTime, since it may have significantly changed if waited
+ provisionalTime := time.Now()
+ // Append the provisional time for the next connection request
+ ps.appendTime(info.ID, provisionalTime)
+ return true, 0 /* no wait. proceed */, provisionalTime
+}
+
+// UpdateConnectionTime updates the connection time for the given address.
+func (ps *PeerStore) UpdateConnectionTime(addr string, provisionalTime time.Time) bool {
+ info, err := PeerInfoFromDomainPort(addr)
+ if err != nil {
+ return false
+ }
+ metadata, err := ps.Get(info.ID, addressDataKey)
+ if err != nil {
+ return false
+ }
+ ad, ok := metadata.(addressData)
+ if !ok {
+ return false
+ }
+ defer func() {
+ _ = ps.Put(info.ID, addressDataKey, ad)
+
+ }()
+
+ // Find the provisionalTime and update it
+ entry := ad.recentConnectionTimes
+ for indx, val := range entry {
+ if provisionalTime == val {
+ entry[indx] = time.Now()
+ return true
+ }
+ }
+
+ // Case where the time is not found: it was removed from the list.
+ // This may happen when the time expires before the connection was established with the server.
+ // The time should be added again.
+ entry = append(entry, time.Now())
+ ad.recentConnectionTimes = entry
+
+ return true
+}
+
+// ReplacePeerList replaces the peer list for the given networkName and role.
+func (ps *PeerStore) ReplacePeerList(addressesThey []string, networkName string, role PhoneBookEntryRoles) {
+ // prepare a map of items we'd like to remove.
+ removeItems := make(map[peer.ID]bool, 0)
+ peerIDs := ps.Peers()
+ for _, pid := range peerIDs {
+ data, _ := ps.Get(pid, addressDataKey)
+ if data != nil {
+ ad := data.(addressData)
+ if ad.networkNames[networkName] && ad.role == role && !ad.persistent {
+ removeItems[pid] = true
+ }
+ }
+
+ }
+ for _, addr := range addressesThey {
+ info, err := PeerInfoFromDomainPort(addr)
+ if err != nil {
+ return
+ }
+ data, _ := ps.Get(info.ID, addressDataKey)
+ if data != nil {
+ // we already have this.
+ // Update the networkName
+ ad := data.(addressData)
+ ad.networkNames[networkName] = true
+
+ // do not remove this entry
+ delete(removeItems, info.ID)
+ } else {
+ // we don't have this item. add it.
+ ps.AddAddrs(info.ID, info.Addrs, libp2p.AddressTTL)
+ entry := makePhonebookEntryData(networkName, role, false)
+ _ = ps.Put(info.ID, addressDataKey, entry)
+ }
+ }
+
+ // remove items that were missing in addressesThey
+ for k := range removeItems {
+ ps.deletePhonebookEntry(k, networkName)
+ }
+}
+
+// AddPersistentPeers stores addresses of peers which are persistent.
+// i.e. they won't be replaced by ReplacePeerList calls
+func (ps *PeerStore) AddPersistentPeers(dnsAddresses []string, networkName string, role PhoneBookEntryRoles) {
+
+ for _, addr := range dnsAddresses {
+ info, err := PeerInfoFromDomainPort(addr)
+ if err != nil {
+ return
+ }
+ data, _ := ps.Get(info.ID, addressDataKey)
+ if data != nil {
+ // we already have this.
+ // Make sure the persistence field is set to true
+ ad := data.(addressData)
+ ad.persistent = true
+ _ = ps.Put(info.ID, addressDataKey, data)
+
+ } else {
+ // we don't have this item. add it.
+ ps.AddAddrs(info.ID, info.Addrs, libp2p.PermanentAddrTTL)
+ entry := makePhonebookEntryData(networkName, role, true)
+ _ = ps.Put(info.ID, addressDataKey, entry)
+ }
+ }
+}
+
+// Length returns the number of addrs in peerstore
+func (ps *PeerStore) Length() int {
+ return len(ps.Peers())
+}
+
+// makePhonebookEntryData creates a new address entry for provided network name and role.
+func makePhonebookEntryData(networkName string, role PhoneBookEntryRoles, persistent bool) addressData {
+ pbData := addressData{
+ networkNames: make(map[string]bool),
+ recentConnectionTimes: make([]time.Time, 0),
+ role: role,
+ persistent: persistent,
+ }
+ pbData.networkNames[networkName] = true
+ return pbData
+}
+
+func (ps *PeerStore) deletePhonebookEntry(peerID peer.ID, networkName string) {
+ data, err := ps.Get(peerID, addressDataKey)
+ if err != nil {
+ return
+ }
+ ad := data.(addressData)
+ delete(ad.networkNames, networkName)
+ if 0 == len(ad.networkNames) {
+ ps.ClearAddrs(peerID)
+ _ = ps.Put(peerID, addressDataKey, nil)
+ }
+}
+
+// AppendTime adds the current time to recentConnectionTimes in
+// addressData of addr
+func (ps *PeerStore) appendTime(peerID peer.ID, t time.Time) {
+ data, _ := ps.Get(peerID, addressDataKey)
+ ad := data.(addressData)
+ ad.recentConnectionTimes = append(ad.recentConnectionTimes, t)
+ _ = ps.Put(peerID, addressDataKey, ad)
+}
+
+// PopEarliestTime removes the earliest time from recentConnectionTimes in
+// addressData for addr
+// It is expected to be later than ConnectionsRateLimitingWindow
+func (ps *PeerStore) popNElements(n int, peerID peer.ID) {
+ data, _ := ps.Get(peerID, addressDataKey)
+ ad := data.(addressData)
+ ad.recentConnectionTimes = ad.recentConnectionTimes[n:]
+ _ = ps.Put(peerID, addressDataKey, ad)
+}
+
+func (ps *PeerStore) filterRetryTime(t time.Time, role PhoneBookEntryRoles) []string {
+ o := make([]string, 0, len(ps.Peers()))
+ for _, peerID := range ps.Peers() {
+ data, _ := ps.Get(peerID, addressDataKey)
+ if data != nil {
+ ad := data.(addressData)
+ if t.After(ad.retryAfter) && role == ad.role {
+ o = append(o, string(peerID))
+ }
+ }
+ }
+ return o
+}
+
+func shuffleSelect(set []string, n int) []string {
+ if n >= len(set) || n == getAllAddresses {
+ // return shuffled copy of everything
+ out := slices.Clone(set)
+ shuffleStrings(out)
+ return out
+ }
+ // Pick random indexes from the set
+ indexSample := make([]int, n)
+ for i := range indexSample {
+ indexSample[i] = rand.Intn(len(set)-i) + i
+ for oi, ois := range indexSample[:i] {
+ if ois == indexSample[i] {
+ indexSample[i] = oi
+ }
+ }
+ }
+ out := make([]string, n)
+ for i, index := range indexSample {
+ out[i] = set[index]
+ }
+ return out
+}
+
+func shuffleStrings(set []string) {
+ rand.Shuffle(len(set), func(i, j int) { set[i], set[j] = set[j], set[i] })
+}
diff --git a/network/p2p/peerstore/peerstore_test.go b/network/p2p/peerstore/peerstore_test.go
index 2debcae255..47b43c9820 100644
--- a/network/p2p/peerstore/peerstore_test.go
+++ b/network/p2p/peerstore/peerstore_test.go
@@ -19,15 +19,25 @@ package peerstore
import (
"crypto/rand"
"fmt"
+ "math"
"testing"
+ "time"
- "github.com/algorand/go-algorand/test/partitiontest"
libp2p_crypto "github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/peer"
libp2p "github.com/libp2p/go-libp2p/core/peerstore"
"github.com/stretchr/testify/require"
+
+ "github.com/algorand/go-algorand/test/partitiontest"
)
+// PhoneBookEntryRelayRole used for all the relays that are provided either via the algobootstrap SRV record
+// or via a configuration file.
+const PhoneBookEntryRelayRole = 1
+
+// PhoneBookEntryArchiverRole used for all the archivers that are provided via the archive SRV record.
+const PhoneBookEntryArchiverRole = 2
+
func TestPeerstore(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()
@@ -77,3 +87,342 @@ func TestPeerstore(t *testing.T) {
require.Equal(t, 7, len(peers))
}
+
+func testPhonebookAll(t *testing.T, set []string, ph *PeerStore) {
+ actual := ph.GetAddresses(len(set), PhoneBookEntryRelayRole)
+ for _, got := range actual {
+ ok := false
+ for _, known := range set {
+ if got == known {
+ ok = true
+ break
+ }
+ }
+ if !ok {
+ t.Errorf("get returned junk %#v", got)
+ }
+ }
+ for _, known := range set {
+ ok := false
+ for _, got := range actual {
+ if got == known {
+ ok = true
+ break
+ }
+ }
+ if !ok {
+ t.Errorf("get missed %#v; actual=%#v; set=%#v", known, actual, set)
+ }
+ }
+}
+
+func testPhonebookUniform(t *testing.T, set []string, ph *PeerStore, getsize int) {
+ uniformityTestLength := 250000 / len(set)
+ expected := (uniformityTestLength * getsize) / len(set)
+ counts := make(map[string]int)
+ for i := 0; i < len(set); i++ {
+ counts[set[i]] = 0
+ }
+ for i := 0; i < uniformityTestLength; i++ {
+ actual := ph.GetAddresses(getsize, PhoneBookEntryRelayRole)
+ for _, xa := range actual {
+ if _, ok := counts[xa]; ok {
+ counts[xa]++
+ }
+ }
+ }
+ min, max := math.MaxInt, 0
+ for _, count := range counts {
+ if count > max {
+ max = count
+ }
+ if count < min {
+ min = count
+ }
+ }
+ // TODO: what's a good probability-theoretic threshold for good enough?
+ if max-min > (expected / 5) {
+ t.Errorf("counts %#v", counts)
+ }
+}
+
+func TestArrayPhonebookAll(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ set := []string{"a:4041", "b:4042", "c:4043", "d:4044", "e:4045", "f:4046", "g:4047", "h:4048", "i:4049", "j:4010"}
+ ph, err := MakePhonebook(1, 1*time.Millisecond)
+ require.NoError(t, err)
+ for _, addr := range set {
+ entry := makePhonebookEntryData("", PhoneBookEntryRelayRole, false)
+ info, _ := PeerInfoFromDomainPort(addr)
+ ph.AddAddrs(info.ID, info.Addrs, libp2p.AddressTTL)
+ ph.Put(info.ID, addressDataKey, entry)
+ }
+ testPhonebookAll(t, set, ph)
+}
+
+func TestArrayPhonebookUniform1(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ set := []string{"a:4041", "b:4042", "c:4043", "d:4044", "e:4045", "f:4046", "g:4047", "h:4048", "i:4049", "j:4010"}
+ ph, err := MakePhonebook(1, 1*time.Millisecond)
+ require.NoError(t, err)
+ for _, addr := range set {
+ entry := makePhonebookEntryData("", PhoneBookEntryRelayRole, false)
+ info, _ := PeerInfoFromDomainPort(addr)
+ ph.AddAddrs(info.ID, info.Addrs, libp2p.AddressTTL)
+ ph.Put(info.ID, addressDataKey, entry)
+ }
+ testPhonebookUniform(t, set, ph, 1)
+}
+
+func TestArrayPhonebookUniform3(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ set := []string{"a:4041", "b:4042", "c:4043", "d:4044", "e:4045", "f:4046", "g:4047", "h:4048", "i:4049", "j:4010"}
+ ph, err := MakePhonebook(1, 1*time.Millisecond)
+ require.NoError(t, err)
+ for _, addr := range set {
+ entry := makePhonebookEntryData("", PhoneBookEntryRelayRole, false)
+ info, _ := PeerInfoFromDomainPort(addr)
+ ph.AddAddrs(info.ID, info.Addrs, libp2p.AddressTTL)
+ ph.Put(info.ID, addressDataKey, entry)
+ }
+ testPhonebookUniform(t, set, ph, 3)
+}
+
+func TestMultiPhonebook(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ set := []string{"a:4041", "b:4042", "c:4043", "d:4044", "e:4045", "f:4046", "g:4047", "h:4048", "i:4049", "j:4010"}
+ pha := make([]string, 0)
+ for _, e := range set[:5] {
+ pha = append(pha, e)
+ }
+ phb := make([]string, 0)
+ for _, e := range set[5:] {
+ phb = append(phb, e)
+ }
+
+ ph, err := MakePhonebook(1, 1*time.Millisecond)
+ require.NoError(t, err)
+ ph.ReplacePeerList(pha, "pha", PhoneBookEntryRelayRole)
+ ph.ReplacePeerList(phb, "phb", PhoneBookEntryRelayRole)
+
+ testPhonebookAll(t, set, ph)
+ testPhonebookUniform(t, set, ph, 1)
+ testPhonebookUniform(t, set, ph, 3)
+}
+
+// TestMultiPhonebookPersistentPeers validates that the peers added via Phonebook.AddPersistentPeers
+// are not replaced when Phonebook.ReplacePeerList is called
+func TestMultiPhonebookPersistentPeers(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ persistentPeers := []string{"a:4041"}
+ set := []string{"b:4042", "c:4043", "d:4044", "e:4045", "f:4046", "g:4047", "h:4048", "i:4049", "j:4010"}
+ pha := make([]string, 0)
+ for _, e := range set[:5] {
+ pha = append(pha, e)
+ }
+ phb := make([]string, 0)
+ for _, e := range set[5:] {
+ phb = append(phb, e)
+ }
+ ph, err := MakePhonebook(1, 1*time.Millisecond)
+ require.NoError(t, err)
+ ph.AddPersistentPeers(persistentPeers, "pha", PhoneBookEntryRelayRole)
+ ph.AddPersistentPeers(persistentPeers, "phb", PhoneBookEntryRelayRole)
+ ph.ReplacePeerList(pha, "pha", PhoneBookEntryRelayRole)
+ ph.ReplacePeerList(phb, "phb", PhoneBookEntryRelayRole)
+
+ testPhonebookAll(t, append(set, persistentPeers...), ph)
+ allAddresses := ph.GetAddresses(len(set)+len(persistentPeers), PhoneBookEntryRelayRole)
+ for _, pp := range persistentPeers {
+ require.Contains(t, allAddresses, pp)
+ }
+}
+
+func TestMultiPhonebookDuplicateFiltering(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ set := []string{"b:4042", "c:4043", "d:4044", "e:4045", "f:4046", "g:4047", "h:4048", "i:4049", "j:4010"}
+ pha := make([]string, 0)
+ for _, e := range set[:7] {
+ pha = append(pha, e)
+ }
+ phb := make([]string, 0)
+ for _, e := range set[3:] {
+ phb = append(phb, e)
+ }
+ ph, err := MakePhonebook(1, 1*time.Millisecond)
+ require.NoError(t, err)
+ ph.ReplacePeerList(pha, "pha", PhoneBookEntryRelayRole)
+ ph.ReplacePeerList(phb, "phb", PhoneBookEntryRelayRole)
+
+ testPhonebookAll(t, set, ph)
+ testPhonebookUniform(t, set, ph, 1)
+ testPhonebookUniform(t, set, ph, 3)
+}
+
+func TestWaitAndAddConnectionTimeLongtWindow(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ // make the connectionsRateLimitingWindow long enough to avoid triggering it when the
+ // test is running in a slow environment
+ // The test will artificially simulate time passing
+ timeUnit := 2000 * time.Second
+ connectionsRateLimitingWindow := 2 * timeUnit
+ entries, err := MakePhonebook(3, connectionsRateLimitingWindow)
+ require.NoError(t, err)
+ addr1 := "addrABC:4040"
+ addr2 := "addrXYZ:4041"
+ info1, _ := PeerInfoFromDomainPort(addr1)
+ info2, _ := PeerInfoFromDomainPort(addr2)
+
+ // Address not in. Should return false
+ addrInPhonebook, _, provisionalTime := entries.GetConnectionWaitTime(addr1)
+ require.Equal(t, false, addrInPhonebook)
+ require.Equal(t, false, entries.UpdateConnectionTime(addr1, provisionalTime))
+
+ // Test the addresses are populated in the phonebook and a
+ // time can be added to one of them
+ entries.ReplacePeerList([]string{addr1, addr2}, "default", PhoneBookEntryRelayRole)
+ addrInPhonebook, waitTime, provisionalTime := entries.GetConnectionWaitTime(addr1)
+ require.Equal(t, true, addrInPhonebook)
+ require.Equal(t, time.Duration(0), waitTime)
+ require.Equal(t, true, entries.UpdateConnectionTime(addr1, provisionalTime))
+ data, _ := entries.Get(info1.ID, addressDataKey)
+ require.NotNil(t, data)
+ ad := data.(addressData)
+ phBookData := ad.recentConnectionTimes
+ require.Equal(t, 1, len(phBookData))
+
+ // simulate passing a unit of time
+ for rct := range phBookData {
+ phBookData[rct] = phBookData[rct].Add(-1 * timeUnit)
+ }
+
+ // add another value to addr
+ addrInPhonebook, waitTime, provisionalTime = entries.GetConnectionWaitTime(addr1)
+ require.Equal(t, time.Duration(0), waitTime)
+ require.Equal(t, true, entries.UpdateConnectionTime(addr1, provisionalTime))
+ data, _ = entries.Get(info1.ID, addressDataKey)
+ ad = data.(addressData)
+ phBookData = ad.recentConnectionTimes
+ require.Equal(t, 2, len(phBookData))
+
+ // simulate passing a unit of time
+ for rct := range phBookData {
+ phBookData[rct] = phBookData[rct].Add(-1 * timeUnit)
+ }
+
+ // the first time should be removed and a new one added
+ // there should not be any wait
+ addrInPhonebook, waitTime, provisionalTime = entries.GetConnectionWaitTime(addr1)
+ require.Equal(t, time.Duration(0), waitTime)
+ require.Equal(t, true, entries.UpdateConnectionTime(addr1, provisionalTime))
+ data, _ = entries.Get(info1.ID, addressDataKey)
+ ad = data.(addressData)
+ phBookData2 := ad.recentConnectionTimes
+ require.Equal(t, 2, len(phBookData2))
+
+ // make sure the right time was removed
+ require.Equal(t, phBookData[1], phBookData2[0])
+ require.Equal(t, true, phBookData2[0].Before(phBookData2[1]))
+
+ // try requesting from another address, make sure
+ // a separate array is used for these new requests
+
+ // add 3 values to another address. should not wait
+ // value 1
+ _, waitTime, provisionalTime = entries.GetConnectionWaitTime(addr2)
+ require.Equal(t, time.Duration(0), waitTime)
+ require.Equal(t, true, entries.UpdateConnectionTime(addr2, provisionalTime))
+
+ // introduce a gap between the two requests so that only the first will be removed later when waited
+ // simulate passing a unit of time
+ data2, _ := entries.Get(info2.ID, addressDataKey)
+ require.NotNil(t, data2)
+ ad2 := data2.(addressData)
+ for rct := range ad2.recentConnectionTimes {
+ ad2.recentConnectionTimes[rct] = ad2.recentConnectionTimes[rct].Add(-1 * timeUnit)
+ }
+
+ // value 2
+ _, waitTime, provisionalTime = entries.GetConnectionWaitTime(addr2)
+ require.Equal(t, time.Duration(0), waitTime)
+ require.Equal(t, true, entries.UpdateConnectionTime(addr2, provisionalTime))
+ // value 3
+ _, waitTime, provisionalTime = entries.GetConnectionWaitTime(addr2)
+ require.Equal(t, time.Duration(0), waitTime)
+ require.Equal(t, true, entries.UpdateConnectionTime(addr2, provisionalTime))
+
+ data2, _ = entries.Get(info2.ID, addressDataKey)
+ ad2 = data2.(addressData)
+ phBookData = ad2.recentConnectionTimes
+ // all three times should be queued
+ require.Equal(t, 3, len(phBookData))
+
+ // add another element to trigger wait
+ _, waitTime, provisionalTime = entries.GetConnectionWaitTime(addr2)
+ require.Greater(t, int64(waitTime), int64(0))
+ // no element should be removed
+ data2, _ = entries.Get(info2.ID, addressDataKey)
+ ad2 = data2.(addressData)
+ phBookData2 = ad2.recentConnectionTimes
+ require.Equal(t, phBookData[0], phBookData2[0])
+ require.Equal(t, phBookData[1], phBookData2[1])
+ require.Equal(t, phBookData[2], phBookData2[2])
+ // simulate passing of the waitTime duration
+ for rct := range ad2.recentConnectionTimes {
+ ad2.recentConnectionTimes[rct] = ad2.recentConnectionTimes[rct].Add(-1 * waitTime)
+ }
+
+ // The wait should be sufficient
+ _, waitTime, provisionalTime = entries.GetConnectionWaitTime(addr2)
+ require.Equal(t, time.Duration(0), waitTime)
+ require.Equal(t, true, entries.UpdateConnectionTime(addr2, provisionalTime))
+ // only one element should be removed, and one added
+ data2, _ = entries.Get(info2.ID, addressDataKey)
+ ad2 = data2.(addressData)
+ phBookData2 = ad2.recentConnectionTimes
+ require.Equal(t, 3, len(phBookData2))
+
+ // make sure the right time was removed
+ require.Equal(t, phBookData[1], phBookData2[0])
+ require.Equal(t, phBookData[2], phBookData2[1])
+}
+
+// TestPhonebookRoles tests that the filtering by roles for different
+// phonebooks entries works as expected.
+func TestPhonebookRoles(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ relaysSet := []string{"relay1:4040", "relay2:4041", "relay3:4042"}
+ archiverSet := []string{"archiver1:1111", "archiver2:1112", "archiver3:1113"}
+
+ ph, err := MakePhonebook(1, 1)
+ require.NoError(t, err)
+ ph.ReplacePeerList(relaysSet, "default", PhoneBookEntryRelayRole)
+ ph.ReplacePeerList(archiverSet, "default", PhoneBookEntryArchiverRole)
+ require.Equal(t, len(relaysSet)+len(archiverSet), len(ph.Peers()))
+ require.Equal(t, len(relaysSet)+len(archiverSet), ph.Length())
+
+ for _, role := range []PhoneBookEntryRoles{PhoneBookEntryRelayRole, PhoneBookEntryArchiverRole} {
+ for k := 0; k < 100; k++ {
+ for l := 0; l < 3; l++ {
+ entries := ph.GetAddresses(l, role)
+ if role == PhoneBookEntryRelayRole {
+ for _, entry := range entries {
+ require.Contains(t, entry, "relay")
+ }
+ } else if role == PhoneBookEntryArchiverRole {
+ for _, entry := range entries {
+ require.Contains(t, entry, "archiver")
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/network/p2p/peerstore/utils.go b/network/p2p/peerstore/utils.go
index eabcccbdae..b96fc1c8e0 100644
--- a/network/p2p/peerstore/utils.go
+++ b/network/p2p/peerstore/utils.go
@@ -17,6 +17,9 @@
package peerstore
import (
+ "fmt"
+ "strings"
+
"github.com/libp2p/go-libp2p/core/peer"
"github.com/multiformats/go-multiaddr"
)
@@ -49,3 +52,18 @@ func PeerInfoFromAddr(addr string) (*peer.AddrInfo, error) {
}
return info, nil
}
+
+// PeerInfoFromDomainPort converts a string of the form domain:port to AddrInfo
+func PeerInfoFromDomainPort(domainPort string) (*peer.AddrInfo, error) {
+ parts := strings.Split(domainPort, ":")
+ if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
+ return nil, fmt.Errorf("invalid domain port string %s, found %d colon-separated parts", domainPort, len(parts))
+ }
+ maddr, err := multiaddr.NewMultiaddr(fmt.Sprintf("/dns4/%s/tcp/%s", parts[0], parts[1]))
+ if err != nil {
+ return nil, err
+ }
+ // These will never have peer IDs
+ transport, _ := peer.SplitAddr(maddr)
+ return &peer.AddrInfo{ID: peer.ID(domainPort), Addrs: []multiaddr.Multiaddr{transport}}, nil
+}
diff --git a/network/p2p/peerstore/utils_test.go b/network/p2p/peerstore/utils_test.go
index c8927d27ee..39124a75e4 100644
--- a/network/p2p/peerstore/utils_test.go
+++ b/network/p2p/peerstore/utils_test.go
@@ -20,8 +20,9 @@ import (
"fmt"
"testing"
- "github.com/algorand/go-algorand/test/partitiontest"
"github.com/stretchr/testify/require"
+
+ "github.com/algorand/go-algorand/test/partitiontest"
)
func TestPeerInfoFromAddr(t *testing.T) {
diff --git a/network/p2pNetwork.go b/network/p2pNetwork.go
index b689b1d4f0..f36b0d3280 100644
--- a/network/p2pNetwork.go
+++ b/network/p2pNetwork.go
@@ -35,6 +35,7 @@ import (
pubsub "github.com/libp2p/go-libp2p-pubsub"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer"
+ manet "github.com/multiformats/go-multiaddr/net"
)
// P2PNetwork implements the GossipNode interface
@@ -202,19 +203,29 @@ func (n *P2PNetwork) GetGenesisID() string {
// Address returns a string and whether that is a 'final' address or guessed.
func (n *P2PNetwork) Address() (string, bool) {
addrInfo := n.service.AddrInfo()
+ if len(addrInfo.Addrs) == 0 {
+ return "", false
+ }
addrs, err := peer.AddrInfoToP2pAddrs(&addrInfo)
if err != nil {
n.log.Warnf("Failed to generate valid multiaddr: %v", err)
return "", false
}
- if len(addrs) == 0 {
- return "", false
+ // loop through and see if we have a non loopback address available
+ for _, addr := range addrs {
+ if !manet.IsIPLoopback(addr) && !manet.IsIPUnspecified(addr) {
+ return addr.String(), true
+
+ }
}
- if len(addrs) > 1 {
- n.log.Infof("Multiple addresses found, using first one from %v", addrs)
+ // We don't have a non loopback address, so just return the first one if it contains an ip4 address or port
+ addr := addrs[0].String()
+ if strings.Contains(addr, "/ip4/") && strings.Contains(addr, "/tcp/") {
+ return addr, true
+
}
+ return "", false
- return addrs[0].String(), true
}
// Broadcast sends a message.
diff --git a/network/p2pNetwork_test.go b/network/p2pNetwork_test.go
index 86c6de1c40..585d9aaa17 100644
--- a/network/p2pNetwork_test.go
+++ b/network/p2pNetwork_test.go
@@ -28,7 +28,12 @@ import (
"github.com/algorand/go-algorand/network/p2p"
"github.com/algorand/go-algorand/protocol"
"github.com/algorand/go-algorand/test/partitiontest"
+
+ pubsub "github.com/libp2p/go-libp2p-pubsub"
+ "github.com/libp2p/go-libp2p/core/network"
+ "github.com/libp2p/go-libp2p/core/peer"
peerstore "github.com/libp2p/go-libp2p/core/peer"
+ ma "github.com/multiformats/go-multiaddr"
"github.com/stretchr/testify/require"
)
@@ -177,3 +182,125 @@ func TestP2PSubmitWS(t *testing.T) {
50*time.Millisecond,
)
}
+
+type mockService struct {
+ id peer.ID
+ addrs []ma.Multiaddr
+ peers map[peer.ID]peer.AddrInfo
+}
+
+func (s *mockService) Close() error {
+ return nil
+}
+
+func (s *mockService) ID() peer.ID {
+ return s.id
+}
+
+func (s *mockService) AddrInfo() peer.AddrInfo {
+ return peer.AddrInfo{
+ ID: s.id,
+ Addrs: s.addrs,
+ }
+}
+
+func (s *mockService) DialNode(ctx context.Context, peer *peer.AddrInfo) error {
+ s.peers[peer.ID] = *peer
+ return nil
+}
+
+func (s *mockService) DialPeersUntilTargetCount(targetConnCount int) {
+}
+
+func (s *mockService) ClosePeer(peer peer.ID) error {
+ if _, ok := s.peers[peer]; ok {
+ delete(s.peers, peer)
+ }
+ return nil
+}
+
+func (s *mockService) Conns() []network.Conn {
+ return nil
+}
+
+func (s *mockService) ListPeersForTopic(topic string) []peer.ID {
+ return nil
+}
+
+func (s *mockService) Subscribe(topic string, val pubsub.ValidatorEx) (*pubsub.Subscription, error) {
+ return nil, nil
+}
+func (s *mockService) Publish(ctx context.Context, topic string, data []byte) error {
+ return nil
+}
+
+func (s *mockService) setAddrs(addrs []ma.Multiaddr) {
+ s.addrs = addrs
+}
+
+func makeMockService(id peer.ID, addrs []ma.Multiaddr) *mockService {
+ return &mockService{
+ id: id,
+ addrs: addrs,
+ }
+}
+
+func TestP2PNetworkAddress(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ cfg := config.GetDefaultLocal()
+ log := logging.TestingLog(t)
+ netA, err := NewP2PNetwork(log, cfg, "", nil, genesisID, config.Devtestnet)
+ defer netA.Stop()
+ require.NoError(t, err)
+ addrInfo := netA.service.AddrInfo()
+ // close the real service since we will substitute a mock one
+ netA.service.Close()
+
+ // define some multiaddrs we will use in the test
+ loopbackAddr, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/1234")
+ require.NoError(t, err)
+ unspecifiedAddr, err := ma.NewMultiaddr("/ip4/0.0.0.0/tcp/0")
+ require.NoError(t, err)
+ publicAddr, err := ma.NewMultiaddr("/ip4/12.86.192.5/tcp/5678")
+ require.NoError(t, err)
+ publicAddr2, err := ma.NewMultiaddr("/ip4/23.97.191.6/tcp/1564")
+ require.NoError(t, err)
+
+ // first two are invalid so third one should be returned as the first public address
+ addrsA := []ma.Multiaddr{
+ loopbackAddr,
+ unspecifiedAddr,
+ publicAddr,
+ publicAddr2,
+ }
+ mockService := makeMockService(addrInfo.ID, addrsA)
+ netA.service = mockService
+
+ retAddr, ok := netA.Address()
+ require.True(t, ok)
+ // using Contains since the return of Address also includes the public peerID
+ require.Contains(t, retAddr, publicAddr.String())
+
+ // don't have a public address so return the first one
+ addrsB := []ma.Multiaddr{
+ loopbackAddr,
+ unspecifiedAddr,
+ }
+ mockService.addrs = addrsB
+ retAddr, ok = netA.Address()
+ require.True(t, ok)
+ require.Contains(t, retAddr, loopbackAddr.String())
+
+ // confirm that we don't return an address if none is supplied
+ mockService.addrs = nil
+ retAddr, ok = netA.Address()
+ require.False(t, ok)
+ require.Empty(t, retAddr)
+
+ mockService.addrs = addrsA // these are still valid addresses
+ mockService.id = "invalid peer ID" // this won't parse and encode properly
+ retAddr, ok = netA.Address()
+ require.False(t, ok)
+ require.Empty(t, retAddr)
+}
diff --git a/network/phonebook.go b/network/phonebook.go
index 0ad7be1a0c..cf189eb6a4 100644
--- a/network/phonebook.go
+++ b/network/phonebook.go
@@ -25,7 +25,7 @@ import (
"golang.org/x/exp/slices"
)
-// when using GetAddresses with getAllAddresses, all the addresses will be retrieved, regardless
+// getAllAddresses when using GetAddresses with getAllAddresses, all the addresses will be retrieved, regardless
// of how many addresses the phonebook actually has. ( with the retry-after logic applied )
const getAllAddresses = math.MaxInt32
diff --git a/network/wsNetwork_test.go b/network/wsNetwork_test.go
index ba8c870ef1..31a4144dc0 100644
--- a/network/wsNetwork_test.go
+++ b/network/wsNetwork_test.go
@@ -4075,82 +4075,95 @@ func TestRefreshRelayArchivePhonebookAddresses(t *testing.T) {
var netA *WebsocketNetwork
var refreshRelayDNSBootstrapID = ".algorand.network?backup=.algorand.net&dedup=.algorand-.(network|net)"
- rapid.Check(t, func(t1 *rapid.T) {
- refreshTestConf := defaultConfig
- refreshTestConf.DNSBootstrapID = refreshRelayDNSBootstrapID
- netA = makeTestWebsocketNodeWithConfig(t, refreshTestConf)
- netA.NetworkID = nonHardcodedNetworkIDGen().Draw(t1, "network")
-
- primarySRVBootstrap := strings.Replace(".algorand.network", "", string(netA.NetworkID), -1)
- backupSRVBootstrap := strings.Replace(".algorand.net", "", string(netA.NetworkID), -1)
- var primaryRelayResolvedRecords []string
- var secondaryRelayResolvedRecords []string
- var primaryArchiveResolvedRecords []string
- var secondaryArchiveResolvedRecords []string
-
- for _, record := range []string{"r1.algorand-.network",
- "r2.algorand-.network", "r3.algorand-.network"} {
- var recordSub = strings.Replace(record, "", string(netA.NetworkID), -1)
- primaryRelayResolvedRecords = append(primaryRelayResolvedRecords, recordSub)
- secondaryRelayResolvedRecords = append(secondaryRelayResolvedRecords, strings.Replace(recordSub, "network", "net", -1))
- }
-
- for _, record := range []string{"r1archive.algorand-.network",
- "r2archive.algorand-.network", "r3archive.algorand-.network"} {
- var recordSub = strings.Replace(record, "", string(netA.NetworkID), -1)
- primaryArchiveResolvedRecords = append(primaryArchiveResolvedRecords, recordSub)
- secondaryArchiveResolvedRecords = append(secondaryArchiveResolvedRecords, strings.Replace(recordSub, "network", "net", -1))
- }
+ testRefreshWithConfig := func(refreshTestConf config.Local) {
+ rapid.Check(t, func(t1 *rapid.T) {
+ refreshTestConf.DNSBootstrapID = refreshRelayDNSBootstrapID
+ netA = makeTestWebsocketNodeWithConfig(t, refreshTestConf)
+ netA.NetworkID = nonHardcodedNetworkIDGen().Draw(t1, "network")
+
+ primarySRVBootstrap := strings.Replace(".algorand.network", "", string(netA.NetworkID), -1)
+ backupSRVBootstrap := strings.Replace(".algorand.net", "", string(netA.NetworkID), -1)
+ var primaryRelayResolvedRecords []string
+ var secondaryRelayResolvedRecords []string
+ var primaryArchiveResolvedRecords []string
+ var secondaryArchiveResolvedRecords []string
+
+ for _, record := range []string{"r1.algorand-.network",
+ "r2.algorand-.network", "r3.algorand-.network"} {
+ var recordSub = strings.Replace(record, "", string(netA.NetworkID), -1)
+ primaryRelayResolvedRecords = append(primaryRelayResolvedRecords, recordSub)
+ secondaryRelayResolvedRecords = append(secondaryRelayResolvedRecords, strings.Replace(recordSub, "network", "net", -1))
+ }
- // Mock the SRV record lookup
- netA.resolveSRVRecords = func(service string, protocol string, name string, fallbackDNSResolverAddress string,
- secure bool) (addrs []string, err error) {
- if service == "algobootstrap" && protocol == "tcp" && name == primarySRVBootstrap {
- return primaryRelayResolvedRecords, nil
- } else if service == "algobootstrap" && protocol == "tcp" && name == backupSRVBootstrap {
- return secondaryRelayResolvedRecords, nil
+ for _, record := range []string{"r1archive.algorand-.network",
+ "r2archive.algorand-.network", "r3archive.algorand-.network"} {
+ var recordSub = strings.Replace(record, "", string(netA.NetworkID), -1)
+ primaryArchiveResolvedRecords = append(primaryArchiveResolvedRecords, recordSub)
+ secondaryArchiveResolvedRecords = append(secondaryArchiveResolvedRecords, strings.Replace(recordSub, "network", "net", -1))
}
- if service == "archive" && protocol == "tcp" && name == primarySRVBootstrap {
- return primaryArchiveResolvedRecords, nil
- } else if service == "archive" && protocol == "tcp" && name == backupSRVBootstrap {
- return secondaryArchiveResolvedRecords, nil
+ // Mock the SRV record lookup
+ netA.resolveSRVRecords = func(service string, protocol string, name string, fallbackDNSResolverAddress string,
+ secure bool) (addrs []string, err error) {
+ if service == "algobootstrap" && protocol == "tcp" && name == primarySRVBootstrap {
+ return primaryRelayResolvedRecords, nil
+ } else if service == "algobootstrap" && protocol == "tcp" && name == backupSRVBootstrap {
+ return secondaryRelayResolvedRecords, nil
+ }
+
+ if service == "archive" && protocol == "tcp" && name == primarySRVBootstrap {
+ return primaryArchiveResolvedRecords, nil
+ } else if service == "archive" && protocol == "tcp" && name == backupSRVBootstrap {
+ return secondaryArchiveResolvedRecords, nil
+ }
+
+ return
}
- return
- }
+ relayPeers := netA.GetPeers(PeersPhonebookRelays)
+ assert.Equal(t, 0, len(relayPeers))
- relayPeers := netA.GetPeers(PeersPhonebookRelays)
- assert.Equal(t, 0, len(relayPeers))
+ archivePeers := netA.GetPeers(PeersPhonebookArchivers)
+ assert.Equal(t, 0, len(archivePeers))
- archivePeers := netA.GetPeers(PeersPhonebookArchivers)
- assert.Equal(t, 0, len(archivePeers))
+ netA.refreshRelayArchivePhonebookAddresses()
- netA.refreshRelayArchivePhonebookAddresses()
+ relayPeers = netA.GetPeers(PeersPhonebookRelays)
- relayPeers = netA.GetPeers(PeersPhonebookRelays)
+ assert.Equal(t, 3, len(relayPeers))
+ relayAddrs := make([]string, 0, len(relayPeers))
+ for _, peer := range relayPeers {
+ relayAddrs = append(relayAddrs, peer.(HTTPPeer).GetAddress())
+ }
- assert.Equal(t, 3, len(relayPeers))
- relayAddrs := make([]string, 0, len(relayPeers))
- for _, peer := range relayPeers {
- relayAddrs = append(relayAddrs, peer.(HTTPPeer).GetAddress())
- }
+ assert.ElementsMatch(t, primaryRelayResolvedRecords, relayAddrs)
- assert.ElementsMatch(t, primaryRelayResolvedRecords, relayAddrs)
+ archivePeers = netA.GetPeers(PeersPhonebookArchivers)
- archivePeers = netA.GetPeers(PeersPhonebookArchivers)
+ if refreshTestConf.EnableBlockServiceFallbackToArchiver {
+ // For the time being, we do not dedup resolved archive nodes
+ assert.Equal(t, len(primaryArchiveResolvedRecords)+len(secondaryArchiveResolvedRecords), len(archivePeers))
- // For the time being, we do not dedup resolved archive nodes
- assert.Equal(t, 6, len(archivePeers))
+ archiveAddrs := make([]string, 0, len(archivePeers))
+ for _, peer := range archivePeers {
+ archiveAddrs = append(archiveAddrs, peer.(HTTPPeer).GetAddress())
+ }
- archiveAddrs := make([]string, 0, len(archivePeers))
- for _, peer := range archivePeers {
- archiveAddrs = append(archiveAddrs, peer.(HTTPPeer).GetAddress())
- }
+ assert.ElementsMatch(t, append(primaryArchiveResolvedRecords, secondaryArchiveResolvedRecords...), archiveAddrs)
- assert.ElementsMatch(t, append(primaryArchiveResolvedRecords, secondaryArchiveResolvedRecords...), archiveAddrs)
+ } else {
+ assert.Equal(t, 0, len(archivePeers))
+ }
- })
+ })
+ }
+
+ testRefreshWithConfig(defaultConfig)
+
+ configWithBlockServiceFallbackToArchiverEnabled := config.GetDefaultLocal()
+ configWithBlockServiceFallbackToArchiverEnabled.EnableBlockServiceFallbackToArchiver = true
+
+ testRefreshWithConfig(configWithBlockServiceFallbackToArchiverEnabled)
}
/*
diff --git a/node/node.go b/node/node.go
index 4c18ad1d51..b637eda32e 100644
--- a/node/node.go
+++ b/node/node.go
@@ -28,6 +28,10 @@ import (
"sync"
"time"
+ "github.com/libp2p/go-libp2p/core/peer"
+
+ "github.com/algorand/go-deadlock"
+
"github.com/algorand/go-algorand/agreement"
"github.com/algorand/go-algorand/agreement/gossip"
"github.com/algorand/go-algorand/catchup"
@@ -47,6 +51,7 @@ import (
"github.com/algorand/go-algorand/logging"
"github.com/algorand/go-algorand/network"
"github.com/algorand/go-algorand/network/messagetracer"
+ "github.com/algorand/go-algorand/network/p2p"
"github.com/algorand/go-algorand/protocol"
"github.com/algorand/go-algorand/rpcs"
"github.com/algorand/go-algorand/stateproof"
@@ -54,7 +59,6 @@ import (
"github.com/algorand/go-algorand/util/execpool"
"github.com/algorand/go-algorand/util/metrics"
"github.com/algorand/go-algorand/util/timers"
- "github.com/algorand/go-deadlock"
)
const (
@@ -152,6 +156,8 @@ type AlgorandFullNode struct {
tracer messagetracer.MessageTracer
stateProofWorker *stateproof.Worker
+
+ capabilitiesDiscovery *p2p.CapabilitiesDiscovery
}
// TxnWithStatus represents information about a single transaction,
@@ -194,6 +200,15 @@ func MakeFull(log logging.Logger, rootDir string, cfg config.Local, phonebookAdd
return nil, err
}
+ if cfg.EnableDHTProviders {
+ caps, err0 := p2p.MakeCapabilitiesDiscovery(node.ctx, node.config, node.genesisDirs.RootGenesisDir, string(genesis.Network), node.log, []*peer.AddrInfo{})
+ if err0 != nil {
+ log.Errorf("Failed to create dht node capabilities discovery: %v", err)
+ return nil, err
+ }
+ node.capabilitiesDiscovery = caps
+ }
+
// tie network, block fetcher, and agreement services together
var p2pNode network.GossipNode
if cfg.EnableP2P {
@@ -372,9 +387,23 @@ func (node *AlgorandFullNode) Start() {
node.startMonitoringRoutines()
}
+ if node.capabilitiesDiscovery != nil {
+ node.capabilitiesDiscovery.AdvertiseCapabilities(node.capabilities()...)
+ }
}
+func (node *AlgorandFullNode) capabilities() []p2p.Capability {
+ var caps []p2p.Capability
+ if node.IsArchival() {
+ caps = append(caps, p2p.Archival)
+ }
+ if node.config.StoresCatchpoints() {
+ caps = append(caps, p2p.Catchpoints)
+ }
+ return caps
+}
+
// startMonitoringRoutines starts the internal monitoring routines used by the node.
func (node *AlgorandFullNode) startMonitoringRoutines() {
node.monitoringRoutinesWaitGroup.Add(2)
@@ -430,6 +459,9 @@ func (node *AlgorandFullNode) Stop() {
node.lowPriorityCryptoVerificationPool.Shutdown()
node.cryptoPool.Shutdown()
node.cancelCtx()
+ if node.capabilitiesDiscovery != nil {
+ node.capabilitiesDiscovery.Close()
+ }
}
// note: unlike the other two functions, this accepts a whole filename
diff --git a/rpcs/blockService_test.go b/rpcs/blockService_test.go
index 98d86ae36d..a0ba919c98 100644
--- a/rpcs/blockService_test.go
+++ b/rpcs/blockService_test.go
@@ -143,6 +143,9 @@ func TestRedirectFallbackArchiver(t *testing.T) {
net2 := &httpTestPeerSource{}
config := config.GetDefaultLocal()
+ // Need to enable block service fallbacks
+ config.EnableBlockServiceFallbackToArchiver = true
+
bs1 := MakeBlockService(log, config, ledger1, net1, "test-genesis-ID")
bs2 := MakeBlockService(log, config, ledger2, net2, "test-genesis-ID")
@@ -311,6 +314,8 @@ func TestRedirectOnFullCapacity(t *testing.T) {
net2 := &httpTestPeerSource{}
config := config.GetDefaultLocal()
+ // Need to enable block service fallbacks
+ config.EnableBlockServiceFallbackToArchiver = true
bs1 := MakeBlockService(log1, config, ledger1, net1, "test-genesis-ID")
bs2 := MakeBlockService(log2, config, ledger2, net2, "test-genesis-ID")
// set the memory cap so that it can serve only 1 block at a time
@@ -487,6 +492,9 @@ func TestRedirectExceptions(t *testing.T) {
net1 := &httpTestPeerSource{}
config := config.GetDefaultLocal()
+ // Need to enable block service fallbacks
+ config.EnableBlockServiceFallbackToArchiver = true
+
bs1 := MakeBlockService(log, config, ledger1, net1, "{genesisID}")
nodeA := &basicRPCNode{}
diff --git a/scripts/configure_dev.sh b/scripts/configure_dev.sh
index d40b551474..c7bd93a250 100755
--- a/scripts/configure_dev.sh
+++ b/scripts/configure_dev.sh
@@ -13,24 +13,30 @@ Options:
FORCE=false
while getopts ":sfh" opt; do
- case ${opt} in
- f ) FORCE=true
- ;;
- h ) echo "${HELP}"
+ case ${opt} in
+ f)
+ FORCE=true
+ ;;
+ h)
+ echo "${HELP}"
exit 0
- ;;
- \? ) echo "${HELP}"
+ ;;
+ \?)
+ echo "${HELP}"
exit 2
- ;;
- esac
+ ;;
+ esac
done
-SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
+SCRIPTPATH="$(
+ cd "$(dirname "$0")"
+ pwd -P
+)"
OS=$("$SCRIPTPATH"/ostype.sh)
function install_or_upgrade {
- if ${FORCE} ; then
+ if ${FORCE}; then
BREW_FORCE="-f"
fi
if brew ls --versions "$1" >/dev/null; then
@@ -43,30 +49,30 @@ function install_or_upgrade {
function install_windows_shellcheck() {
version="v0.7.1"
if ! wget https://github.com/koalaman/shellcheck/releases/download/$version/shellcheck-$version.zip -O /tmp/shellcheck-$version.zip; then
- rm /tmp/shellcheck-$version.zip &> /dev/null
+ rm /tmp/shellcheck-$version.zip &>/dev/null
echo "Error downloading shellcheck $version"
return 1
fi
if ! unzip -o /tmp/shellcheck-$version.zip shellcheck-$version.exe -d /tmp; then
- rm /tmp/shellcheck-$version.zip &> /dev/null
+ rm /tmp/shellcheck-$version.zip &>/dev/null
echo "Unable to decompress shellcheck $version"
return 1
fi
if ! mv -f /tmp/shellcheck-$version.exe /usr/bin/shellcheck.exe; then
- rm /tmp/shellcheck-$version.zip &> /dev/null
+ rm /tmp/shellcheck-$version.zip &>/dev/null
echo "Unable to move shellcheck to /usr/bin"
return 1
fi
- rm /tmp/shellcheck-$version.zip &> /dev/null
+ rm /tmp/shellcheck-$version.zip &>/dev/null
return 0
}
if [ "${OS}" = "linux" ]; then
- if ! which sudo > /dev/null; then
+ if ! which sudo >/dev/null; then
"$SCRIPTPATH/install_linux_deps.sh"
else
sudo "$SCRIPTPATH/install_linux_deps.sh"
@@ -74,7 +80,13 @@ if [ "${OS}" = "linux" ]; then
elif [ "${OS}" = "darwin" ]; then
if [ "${CIRCLECI}" != "true" ]; then
brew update
- brew tap homebrew/cask
+ brew_version=$(brew --version | head -1 | cut -d' ' -f2)
+ major_version=$(echo $brew_version | cut -d. -f1)
+ minor_version=$(echo $brew_version | cut -d. -f2)
+ version_decimal="$major_version.$minor_version"
+ if (($(echo "$version_decimal < 2.5" | bc -l))); then
+ brew tap homebrew/cask
+ fi
fi
install_or_upgrade pkg-config
install_or_upgrade libtool
diff --git a/test/e2e-go/features/privatenet/privatenet_test.go b/test/e2e-go/features/privatenet/privatenet_test.go
new file mode 100644
index 0000000000..312abed618
--- /dev/null
+++ b/test/e2e-go/features/privatenet/privatenet_test.go
@@ -0,0 +1,62 @@
+// Copyright (C) 2019-2023 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 .
+
+// Check that private networks are started as designed.
+package privatenet
+
+import (
+ "testing"
+
+ "github.com/algorand/go-algorand/test/framework/fixtures"
+ "github.com/algorand/go-algorand/test/partitiontest"
+ "github.com/stretchr/testify/require"
+)
+
+// TestPrivateNetworkImportKeys tests that part keys can be exported and
+// imported when starting a private network.
+func TestPrivateNetworkImportKeys(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ // This test takes 5~10 seconds.
+ if testing.Short() {
+ t.Skip()
+ }
+
+ // First test that keys can be exported by using `goal network pregen ...`
+ // Don't start up network, just create genesis files.
+ var goalFixture fixtures.GoalFixture
+ tmpGenDir := t.TempDir()
+ tmpNetDir := t.TempDir()
+ defaultTemplate := "" // Use the default template by omitting the filepath.
+
+ _, err := goalFixture.NetworkPregen(defaultTemplate, tmpGenDir)
+ require.NoError(t, err)
+
+ // Check that if there is an existing directory with same name, test fails.
+ errStr, err := goalFixture.NetworkPregen(defaultTemplate, tmpGenDir)
+ require.Error(t, err)
+ require.Contains(t, errStr, "already exists and is not empty")
+
+ // Then try importing files from same template.
+ err = goalFixture.NetworkCreate(tmpNetDir, "", defaultTemplate, tmpGenDir)
+ require.NoError(t, err)
+
+ err = goalFixture.NetworkStart(tmpNetDir)
+ require.NoError(t, err)
+
+ err = goalFixture.NetworkStop(tmpNetDir)
+ require.NoError(t, err)
+}
diff --git a/test/e2e-go/restAPI/helpers.go b/test/e2e-go/restAPI/helpers.go
index b1067ecc93..3e85020e94 100644
--- a/test/e2e-go/restAPI/helpers.go
+++ b/test/e2e-go/restAPI/helpers.go
@@ -117,7 +117,7 @@ func WaitForRoundOne(t *testing.T, testClient libgoal.Client) {
var errWaitForTransactionTimeout = errors.New("wait for transaction timed out")
// WaitForTransaction waits for a transaction to be confirmed
-func WaitForTransaction(t *testing.T, testClient libgoal.Client, fromAddress, txID string, timeout time.Duration) (tx v2.PreEncodedTxInfo, err error) {
+func WaitForTransaction(t *testing.T, testClient libgoal.Client, txID string, timeout time.Duration) (tx v2.PreEncodedTxInfo, err error) {
a := require.New(fixtures.SynchronizedTest(t))
rnd, err := testClient.Status()
a.NoError(err)
diff --git a/test/e2e-go/restAPI/other/appsRestAPI_test.go b/test/e2e-go/restAPI/other/appsRestAPI_test.go
index 0fe44e3b28..8abe6a4dbc 100644
--- a/test/e2e-go/restAPI/other/appsRestAPI_test.go
+++ b/test/e2e-go/restAPI/other/appsRestAPI_test.go
@@ -101,7 +101,7 @@ return
a.NoError(err)
appCreateTxID, err := testClient.SignAndBroadcastTransaction(wh, nil, appCreateTxn)
a.NoError(err)
- _, err = helper.WaitForTransaction(t, testClient, someAddress, appCreateTxID, 30*time.Second)
+ _, err = helper.WaitForTransaction(t, testClient, appCreateTxID, 30*time.Second)
a.NoError(err)
// get app ID
@@ -115,7 +115,7 @@ return
appFundTxn, err := testClient.SendPaymentFromWallet(wh, nil, someAddress, createdAppID.Address().String(), 0, 1_000_000, nil, "", 0, 0)
a.NoError(err)
appFundTxID := appFundTxn.ID()
- _, err = helper.WaitForTransaction(t, testClient, someAddress, appFundTxID.String(), 30*time.Second)
+ _, err = helper.WaitForTransaction(t, testClient, appFundTxID.String(), 30*time.Second)
a.NoError(err)
// call app, which will issue an ASA create inner txn
@@ -125,7 +125,7 @@ return
a.NoError(err)
appCallTxnTxID, err := testClient.SignAndBroadcastTransaction(wh, nil, appCallTxn)
a.NoError(err)
- _, err = helper.WaitForTransaction(t, testClient, someAddress, appCallTxnTxID, 30*time.Second)
+ _, err = helper.WaitForTransaction(t, testClient, appCallTxnTxID, 30*time.Second)
a.NoError(err)
// verify pending txn info of outer txn
@@ -240,7 +240,7 @@ end:
a.NoError(err)
appCreateTxID, err := testClient.SignAndBroadcastTransaction(wh, nil, appCreateTxn)
a.NoError(err)
- _, err = helper.WaitForTransaction(t, testClient, someAddress, appCreateTxID, 30*time.Second)
+ _, err = helper.WaitForTransaction(t, testClient, appCreateTxID, 30*time.Second)
a.NoError(err)
// get app ID
@@ -257,7 +257,7 @@ end:
)
a.NoError(err)
appFundTxID := appFundTxn.ID()
- _, err = helper.WaitForTransaction(t, testClient, someAddress, appFundTxID.String(), 30*time.Second)
+ _, err = helper.WaitForTransaction(t, testClient, appFundTxID.String(), 30*time.Second)
a.NoError(err)
createdBoxName := map[string]bool{}
@@ -306,7 +306,7 @@ end:
err = testClient.BroadcastTransactionGroup(stxns)
if len(errPrefix) == 0 {
a.NoError(err)
- _, err = helper.WaitForTransaction(t, testClient, someAddress, txns[0].ID().String(), 30*time.Second)
+ _, err = helper.WaitForTransaction(t, testClient, txns[0].ID().String(), 30*time.Second)
a.NoError(err)
} else {
a.ErrorContains(err, errPrefix[0])
@@ -545,7 +545,7 @@ end:
a.NoError(err)
appDeleteTxID, err := testClient.SignAndBroadcastTransaction(wh, nil, appDeleteTxn)
a.NoError(err)
- _, err = helper.WaitForTransaction(t, testClient, someAddress, appDeleteTxID, 30*time.Second)
+ _, err = helper.WaitForTransaction(t, testClient, appDeleteTxID, 30*time.Second)
a.NoError(err)
_, err = testClient.ApplicationInformation(uint64(createdAppID))
diff --git a/test/e2e-go/restAPI/restClient_test.go b/test/e2e-go/restAPI/restClient_test.go
index 3929939c8b..65292563da 100644
--- a/test/e2e-go/restAPI/restClient_test.go
+++ b/test/e2e-go/restAPI/restClient_test.go
@@ -285,7 +285,7 @@ func TestClientCanSendAndGetNote(t *testing.T) {
note := make([]byte, maxTxnNoteBytes)
tx, err := testClient.SendPaymentFromWallet(wh, nil, someAddress, toAddress, 10000, 100000, note, "", 0, 0)
a.NoError(err)
- txStatus, err := WaitForTransaction(t, testClient, someAddress, tx.ID().String(), 30*time.Second)
+ txStatus, err := WaitForTransaction(t, testClient, tx.ID().String(), 30*time.Second)
a.NoError(err)
a.Equal(note, txStatus.Txn.Txn.Note)
}
@@ -311,7 +311,7 @@ func TestClientCanGetTransactionStatus(t *testing.T) {
t.Log(string(protocol.EncodeJSON(tx)))
a.NoError(err)
t.Log(tx.ID().String())
- _, err = WaitForTransaction(t, testClient, someAddress, tx.ID().String(), 30*time.Second)
+ _, err = WaitForTransaction(t, testClient, tx.ID().String(), 30*time.Second)
a.NoError(err)
}
@@ -336,7 +336,7 @@ func TestAccountBalance(t *testing.T) {
a.NoError(err)
tx, err := testClient.SendPaymentFromWallet(wh, nil, someAddress, toAddress, 10000, 100000, nil, "", 0, 0)
a.NoError(err)
- _, err = WaitForTransaction(t, testClient, someAddress, tx.ID().String(), 30*time.Second)
+ _, err = WaitForTransaction(t, testClient, tx.ID().String(), 30*time.Second)
a.NoError(err)
account, err := testClient.AccountInformation(toAddress, false)
@@ -403,7 +403,7 @@ func TestAccountParticipationInfo(t *testing.T) {
}
txID, err := testClient.SignAndBroadcastTransaction(wh, nil, tx)
a.NoError(err)
- _, err = WaitForTransaction(t, testClient, someAddress, txID, 30*time.Second)
+ _, err = WaitForTransaction(t, testClient, txID, 30*time.Second)
a.NoError(err)
account, err := testClient.AccountInformation(someAddress, false)
diff --git a/test/e2e-go/restAPI/simulate/simulateRestAPI_test.go b/test/e2e-go/restAPI/simulate/simulateRestAPI_test.go
index 63c062e30c..c70767713d 100644
--- a/test/e2e-go/restAPI/simulate/simulateRestAPI_test.go
+++ b/test/e2e-go/restAPI/simulate/simulateRestAPI_test.go
@@ -468,7 +468,7 @@ int 1`
// sign and broadcast
appCreateTxID, err := testClient.SignAndBroadcastTransaction(wh, nil, appCreateTxn)
a.NoError(err)
- submittedAppCreateTxn, err := helper.WaitForTransaction(t, testClient, senderAddress, appCreateTxID, 30*time.Second)
+ submittedAppCreateTxn, err := helper.WaitForTransaction(t, testClient, appCreateTxID, 30*time.Second)
a.NoError(err)
// get app ID
@@ -483,7 +483,7 @@ int 1`
)
a.NoError(err)
appFundTxID := appFundTxn.ID()
- _, err = helper.WaitForTransaction(t, testClient, senderAddress, appFundTxID.String(), 30*time.Second)
+ _, err = helper.WaitForTransaction(t, testClient, appFundTxID.String(), 30*time.Second)
a.NoError(err)
// construct app call
@@ -596,7 +596,7 @@ int 1`
// sign and broadcast
appCreateTxID, err := testClient.SignAndBroadcastTransaction(wh, nil, appCreateTxn)
a.NoError(err)
- submittedAppCreateTxn, err := helper.WaitForTransaction(t, testClient, senderAddress, appCreateTxID, 30*time.Second)
+ submittedAppCreateTxn, err := helper.WaitForTransaction(t, testClient, appCreateTxID, 30*time.Second)
a.NoError(err)
// get app ID
@@ -611,7 +611,7 @@ int 1`
)
a.NoError(err)
appFundTxID := appFundTxn.ID()
- _, err = helper.WaitForTransaction(t, testClient, senderAddress, appFundTxID.String(), 30*time.Second)
+ _, err = helper.WaitForTransaction(t, testClient, appFundTxID.String(), 30*time.Second)
a.NoError(err)
// construct app call
@@ -862,7 +862,7 @@ func TestMaxDepthAppWithPCandStackTrace(t *testing.T) {
appCreateTxID, err := testClient.SignAndBroadcastTransaction(wh, nil, appCreateTxn)
a.NoError(err)
- submittedAppCreateTxn, err := helper.WaitForTransaction(t, testClient, senderAddress, appCreateTxID, 30*time.Second)
+ submittedAppCreateTxn, err := helper.WaitForTransaction(t, testClient, appCreateTxID, 30*time.Second)
a.NoError(err)
futureAppID := basics.AppIndex(*submittedAppCreateTxn.ApplicationIndex)
@@ -1710,7 +1710,7 @@ func TestSimulateScratchSlotChange(t *testing.T) {
appCreateTxID, err := testClient.SignAndBroadcastTransaction(wh, nil, appCreateTxn)
a.NoError(err)
- submittedAppCreateTxn, err := helper.WaitForTransaction(t, testClient, senderAddress, appCreateTxID, 30*time.Second)
+ submittedAppCreateTxn, err := helper.WaitForTransaction(t, testClient, appCreateTxID, 30*time.Second)
a.NoError(err)
futureAppID := basics.AppIndex(*submittedAppCreateTxn.ApplicationIndex)
@@ -1904,7 +1904,7 @@ end:
appCreateTxID, err := testClient.SignAndBroadcastTransaction(wh, nil, appCreateTxn)
a.NoError(err)
- submittedAppCreateTxn, err := helper.WaitForTransaction(t, testClient, senderAddress, appCreateTxID, 30*time.Second)
+ submittedAppCreateTxn, err := helper.WaitForTransaction(t, testClient, appCreateTxID, 30*time.Second)
a.NoError(err)
futureAppID := basics.AppIndex(*submittedAppCreateTxn.ApplicationIndex)
@@ -2094,6 +2094,340 @@ end:
}, *resp.TxnGroups[0].Txns[2].TransactionTrace.ApprovalProgramTrace)
}
+func TestSimulateExecTraceAppInitialState(t *testing.T) {
+ partitiontest.PartitionTest(t)
+ t.Parallel()
+
+ a := require.New(fixtures.SynchronizedTest(t))
+ var localFixture fixtures.RestClientFixture
+ localFixture.SetupNoStart(t, filepath.Join("nettemplates", "OneNodeFuture.json"))
+
+ // Get primary node
+ primaryNode, err := localFixture.GetNodeController("Primary")
+ a.NoError(err)
+
+ localFixture.Start()
+ defer primaryNode.FullStop()
+
+ // get lib goal client
+ testClient := localFixture.LibGoalFixture.GetLibGoalClientFromNodeController(primaryNode)
+
+ _, err = testClient.WaitForRound(1)
+ a.NoError(err)
+
+ wh, err := testClient.GetUnencryptedWalletHandle()
+ a.NoError(err)
+ addresses, err := testClient.ListAddresses(wh)
+ a.NoError(err)
+ _, senderAddress := helper.GetMaxBalAddr(t, testClient, addresses)
+ a.NotEmpty(senderAddress, "no addr with funds")
+
+ addressDigest, err := basics.UnmarshalChecksumAddress(senderAddress)
+ a.NoError(err)
+
+ ops, err := logic.AssembleString(
+ `#pragma version 8
+txn ApplicationID
+bz end // Do nothing during create
+
+txn OnCompletion
+int OptIn
+==
+bnz end // Always allow optin
+
+byte "local"
+byte "global"
+txn ApplicationArgs 0
+match local global
+err // Unknown command
+
+local:
+ txn Sender
+ byte "local-int-key"
+ int 0xcafeb0ba
+ app_local_put
+ int 0
+ byte "local-bytes-key"
+ byte "xqcL"
+ app_local_put
+ b end
+
+global:
+ byte "global-int-key"
+ int 0xdeadbeef
+ app_global_put
+ byte "global-bytes-key"
+ byte "welt am draht"
+ app_global_put
+ b end
+
+end:
+ int 1`)
+ a.NoError(err)
+ approval := ops.Program
+
+ ops, err = logic.AssembleString("#pragma version 8\nint 1")
+ a.NoError(err)
+ clearState := ops.Program
+
+ gl := basics.StateSchema{NumByteSlice: 1, NumUint: 1}
+ lc := basics.StateSchema{NumByteSlice: 1, NumUint: 1}
+
+ MinFee := config.Consensus[protocol.ConsensusFuture].MinTxnFee
+ MinBalance := config.Consensus[protocol.ConsensusFuture].MinBalance
+
+ // create app and get the application ID
+ appCreateTxn, err := testClient.MakeUnsignedAppCreateTx(
+ transactions.NoOpOC, approval, clearState, gl,
+ lc, nil, nil, nil, nil, nil, 0)
+ a.NoError(err)
+ appCreateTxn, err = testClient.FillUnsignedTxTemplate(senderAddress, 0, 0, 0, appCreateTxn)
+ a.NoError(err)
+
+ appCreateTxID, err := testClient.SignAndBroadcastTransaction(wh, nil, appCreateTxn)
+ a.NoError(err)
+ submittedAppCreateTxn, err := helper.WaitForTransaction(t, testClient, appCreateTxID, 30*time.Second)
+ a.NoError(err)
+ futureAppID := basics.AppIndex(*submittedAppCreateTxn.ApplicationIndex)
+
+ // fund app account
+ _, err = testClient.ConstructPayment(
+ senderAddress, futureAppID.Address().String(),
+ 0, MinBalance*2, nil, "", [32]byte{}, 0, 0,
+ )
+ a.NoError(err)
+
+ // construct app call "global"
+ appCallGlobalTxn, err := testClient.MakeUnsignedAppNoOpTx(
+ uint64(futureAppID), [][]byte{[]byte("global")}, nil, nil, nil, nil,
+ )
+ a.NoError(err)
+ appCallGlobalTxn, err = testClient.FillUnsignedTxTemplate(senderAddress, 0, 0, MinFee, appCallGlobalTxn)
+ a.NoError(err)
+ // construct app optin
+ appOptInTxn, err := testClient.MakeUnsignedAppOptInTx(uint64(futureAppID), nil, nil, nil, nil, nil)
+ a.NoError(err)
+ appOptInTxn, err = testClient.FillUnsignedTxTemplate(senderAddress, 0, 0, MinFee, appOptInTxn)
+ // construct app call "local"
+ appCallLocalTxn, err := testClient.MakeUnsignedAppNoOpTx(
+ uint64(futureAppID), [][]byte{[]byte("local")}, nil, nil, nil, nil,
+ )
+ a.NoError(err)
+ appCallLocalTxn, err = testClient.FillUnsignedTxTemplate(senderAddress, 0, 0, MinFee, appCallLocalTxn)
+ a.NoError(err)
+
+ gid, err := testClient.GroupID([]transactions.Transaction{appCallGlobalTxn, appOptInTxn, appCallLocalTxn})
+ a.NoError(err)
+ appCallGlobalTxn.Group = gid
+ appOptInTxn.Group = gid
+ appCallLocalTxn.Group = gid
+
+ appCallTxnGlobalSigned, err := testClient.SignTransactionWithWallet(wh, nil, appCallGlobalTxn)
+ a.NoError(err)
+ appOptInSigned, err := testClient.SignTransactionWithWallet(wh, nil, appOptInTxn)
+ a.NoError(err)
+ appCallTxnLocalSigned, err := testClient.SignTransactionWithWallet(wh, nil, appCallLocalTxn)
+ a.NoError(err)
+
+ a.NoError(testClient.BroadcastTransactionGroup([]transactions.SignedTxn{
+ appCallTxnGlobalSigned,
+ appOptInSigned,
+ appCallTxnLocalSigned,
+ }))
+ _, err = helper.WaitForTransaction(t, testClient, appCallTxnGlobalSigned.Txn.ID().String(), 30*time.Second)
+ a.NoError(err)
+
+ // construct simulation request, with state change enabled
+ execTraceConfig := simulation.ExecTraceConfig{
+ Enable: true,
+ State: true,
+ }
+
+ appCallGlobalTxn.Note = []byte("note for global")
+ appCallGlobalTxn.Group = crypto.Digest{}
+ appCallLocalTxn.Note = []byte("note for local")
+ appCallLocalTxn.Group = crypto.Digest{}
+
+ gid, err = testClient.GroupID([]transactions.Transaction{appCallGlobalTxn, appCallLocalTxn})
+ a.NoError(err)
+ appCallGlobalTxn.Group = gid
+ appCallLocalTxn.Group = gid
+
+ appCallTxnGlobalSigned, err = testClient.SignTransactionWithWallet(wh, nil, appCallGlobalTxn)
+ a.NoError(err)
+ appCallTxnLocalSigned, err = testClient.SignTransactionWithWallet(wh, nil, appCallLocalTxn)
+ a.NoError(err)
+
+ simulateRequest := v2.PreEncodedSimulateRequest{
+ TxnGroups: []v2.PreEncodedSimulateRequestTransactionGroup{
+ {Txns: []transactions.SignedTxn{appCallTxnGlobalSigned, appCallTxnLocalSigned}},
+ },
+ ExecTraceConfig: execTraceConfig,
+ }
+
+ // update the configuration file to enable EnableDeveloperAPI
+ err = primaryNode.FullStop()
+ a.NoError(err)
+ cfg, err := config.LoadConfigFromDisk(primaryNode.GetDataDir())
+ a.NoError(err)
+ cfg.EnableDeveloperAPI = true
+ err = cfg.SaveToDisk(primaryNode.GetDataDir())
+ require.NoError(t, err)
+ localFixture.Start()
+
+ // start real simulating
+ resp, err := testClient.SimulateTransactions(simulateRequest)
+ a.NoError(err)
+
+ // assertions
+ a.Len(resp.TxnGroups, 1)
+ a.Nil(resp.TxnGroups[0].FailureMessage)
+ a.Len(resp.TxnGroups[0].Txns, 2)
+
+ a.Equal([]model.SimulationOpcodeTraceUnit{
+ {Pc: 1},
+ {Pc: 4},
+ {Pc: 6},
+ {Pc: 9},
+ {Pc: 11},
+ {Pc: 12},
+ {Pc: 13},
+ {Pc: 16},
+ {Pc: 23},
+ {Pc: 31},
+ {Pc: 34},
+ {Pc: 94},
+ {Pc: 110},
+ {
+ Pc: 116,
+ StateChanges: &[]model.ApplicationStateOperation{
+ {
+ Operation: "w",
+ AppStateType: "g",
+ Key: []byte("global-int-key"),
+ NewValue: &model.AvmValue{
+ Type: uint64(basics.TealUintType),
+ Uint: toPtr[uint64](0xdeadbeef),
+ },
+ },
+ },
+ },
+ {Pc: 117},
+ {Pc: 135},
+ {
+ Pc: 150,
+ StateChanges: &[]model.ApplicationStateOperation{
+ {
+ Operation: "w",
+ AppStateType: "g",
+ Key: []byte("global-bytes-key"),
+ NewValue: &model.AvmValue{
+ Type: uint64(basics.TealBytesType),
+ Bytes: toPtr([]byte("welt am draht")),
+ },
+ },
+ },
+ },
+ {Pc: 151},
+ {Pc: 154},
+ }, *resp.TxnGroups[0].Txns[0].TransactionTrace.ApprovalProgramTrace)
+ a.Equal([]model.SimulationOpcodeTraceUnit{
+ {Pc: 1},
+ {Pc: 4},
+ {Pc: 6},
+ {Pc: 9},
+ {Pc: 11},
+ {Pc: 12},
+ {Pc: 13},
+ {Pc: 16},
+ {Pc: 23},
+ {Pc: 31},
+ {Pc: 34},
+ {Pc: 41},
+ {Pc: 43},
+ {Pc: 58},
+ {
+ Pc: 64,
+ StateChanges: &[]model.ApplicationStateOperation{
+ {
+ Operation: "w",
+ AppStateType: "l",
+ Key: []byte("local-int-key"),
+ NewValue: &model.AvmValue{
+ Type: uint64(basics.TealUintType),
+ Uint: toPtr[uint64](0xcafeb0ba),
+ },
+ Account: toPtr(addressDigest.String()),
+ },
+ },
+ },
+ {Pc: 65},
+ {Pc: 67},
+ {Pc: 84},
+ {
+ Pc: 90,
+ StateChanges: &[]model.ApplicationStateOperation{
+ {
+ Operation: "w",
+ AppStateType: "l",
+ Key: []byte("local-bytes-key"),
+ NewValue: &model.AvmValue{
+ Type: uint64(basics.TealBytesType),
+ Bytes: toPtr([]byte("xqcL")),
+ },
+ Account: toPtr(addressDigest.String()),
+ },
+ },
+ },
+ {Pc: 91},
+ {Pc: 154},
+ }, *resp.TxnGroups[0].Txns[1].TransactionTrace.ApprovalProgramTrace)
+
+ a.NotNil(resp.InitialStates)
+ a.Len(*resp.InitialStates.AppInitialStates, 1)
+
+ a.Len((*resp.InitialStates.AppInitialStates)[0].AppGlobals.Kvs, 2)
+
+ globalKVs := (*resp.InitialStates.AppInitialStates)[0].AppGlobals.Kvs
+ globalKVMap := make(map[string]model.AvmValue)
+ for _, kv := range globalKVs {
+ globalKVMap[string(kv.Key)] = kv.Value
+ }
+ expectedGlobalKVMap := map[string]model.AvmValue{
+ "global-int-key": {
+ Type: 2,
+ Uint: toPtr[uint64](0xdeadbeef),
+ },
+ "global-bytes-key": {
+ Type: 1,
+ Bytes: toPtr([]byte("welt am draht")),
+ },
+ }
+ a.Equal(expectedGlobalKVMap, globalKVMap)
+
+ a.Len(*(*resp.InitialStates.AppInitialStates)[0].AppLocals, 1)
+
+ localKVs := (*(*resp.InitialStates.AppInitialStates)[0].AppLocals)[0]
+ a.NotNil(localKVs.Account)
+ a.Equal(senderAddress, *localKVs.Account)
+
+ localKVMap := make(map[string]model.AvmValue)
+ for _, kv := range localKVs.Kvs {
+ localKVMap[string(kv.Key)] = kv.Value
+ }
+ expectedLocalKVMap := map[string]model.AvmValue{
+ "local-int-key": {
+ Type: 2,
+ Uint: toPtr[uint64](0xcafeb0ba),
+ },
+ "local-bytes-key": {
+ Type: 1,
+ Bytes: toPtr([]byte("xqcL")),
+ },
+ }
+ a.Equal(expectedLocalKVMap, localKVMap)
+}
+
func TestSimulateWithUnnamedResources(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()
@@ -2125,7 +2459,7 @@ func TestSimulateWithUnnamedResources(t *testing.T) {
)
a.NoError(err)
txID := txn.ID().String()
- _, err = helper.WaitForTransaction(t, testClient, senderAddress, txID, 30*time.Second)
+ _, err = helper.WaitForTransaction(t, testClient, txID, 30*time.Second)
a.NoError(err)
// create asset
@@ -2136,7 +2470,7 @@ func TestSimulateWithUnnamedResources(t *testing.T) {
// sign and broadcast
txID, err = testClient.SignAndBroadcastTransaction(wh, nil, txn)
a.NoError(err)
- confirmedTxn, err := helper.WaitForTransaction(t, testClient, senderAddress, txID, 30*time.Second)
+ confirmedTxn, err := helper.WaitForTransaction(t, testClient, txID, 30*time.Second)
a.NoError(err)
// get asset ID
a.NotNil(confirmedTxn.AssetIndex)
@@ -2151,7 +2485,7 @@ func TestSimulateWithUnnamedResources(t *testing.T) {
// sign and broadcast
txID, err = testClient.SignAndBroadcastTransaction(wh, nil, txn)
a.NoError(err)
- _, err = helper.WaitForTransaction(t, testClient, otherAddress, txID, 30*time.Second)
+ _, err = helper.WaitForTransaction(t, testClient, txID, 30*time.Second)
a.NoError(err)
// transfer asset
@@ -2162,7 +2496,7 @@ func TestSimulateWithUnnamedResources(t *testing.T) {
// sign and broadcast
txID, err = testClient.SignAndBroadcastTransaction(wh, nil, txn)
a.NoError(err)
- _, err = helper.WaitForTransaction(t, testClient, senderAddress, txID, 30*time.Second)
+ _, err = helper.WaitForTransaction(t, testClient, txID, 30*time.Second)
a.NoError(err)
ops, err := logic.AssembleString("#pragma version 9\n int 1")
@@ -2180,7 +2514,7 @@ func TestSimulateWithUnnamedResources(t *testing.T) {
// sign and broadcast
txID, err = testClient.SignAndBroadcastTransaction(wh, nil, txn)
a.NoError(err)
- confirmedTxn, err = helper.WaitForTransaction(t, testClient, otherAddress, txID, 30*time.Second)
+ confirmedTxn, err = helper.WaitForTransaction(t, testClient, txID, 30*time.Second)
a.NoError(err)
// get app ID
a.NotNil(confirmedTxn.ApplicationIndex)
@@ -2258,7 +2592,7 @@ int 1
// sign and broadcast
txID, err = testClient.SignAndBroadcastTransaction(wh, nil, txn)
a.NoError(err)
- confirmedTxn, err = helper.WaitForTransaction(t, testClient, senderAddress, txID, 30*time.Second)
+ confirmedTxn, err = helper.WaitForTransaction(t, testClient, txID, 30*time.Second)
a.NoError(err)
// get app ID
a.NotNil(confirmedTxn.ApplicationIndex)
@@ -2272,7 +2606,7 @@ int 1
)
a.NoError(err)
txID = txn.ID().String()
- _, err = helper.WaitForTransaction(t, testClient, senderAddress, txID, 30*time.Second)
+ _, err = helper.WaitForTransaction(t, testClient, txID, 30*time.Second)
a.NoError(err)
// construct app call
diff --git a/test/e2e-go/restAPI/stateproof/stateproofRestAPI_test.go b/test/e2e-go/restAPI/stateproof/stateproofRestAPI_test.go
index 17427ff4f6..497d128643 100644
--- a/test/e2e-go/restAPI/stateproof/stateproofRestAPI_test.go
+++ b/test/e2e-go/restAPI/stateproof/stateproofRestAPI_test.go
@@ -100,7 +100,7 @@ func TestStateProofInParticipationInfo(t *testing.T) {
}
txID, err := testClient.SignAndBroadcastTransaction(wh, nil, tx)
a.NoError(err)
- _, err = helper.WaitForTransaction(t, testClient, someAddress, txID, 120*time.Second)
+ _, err = helper.WaitForTransaction(t, testClient, txID, 120*time.Second)
a.NoError(err)
account, err := testClient.AccountInformation(someAddress, false)
@@ -197,7 +197,7 @@ func TestNilStateProofInParticipationInfo(t *testing.T) {
}
txID, err := testClient.SignAndBroadcastTransaction(wh, nil, tx)
a.NoError(err)
- _, err = helper.WaitForTransaction(t, testClient, someAddress, txID, 30*time.Second)
+ _, err = helper.WaitForTransaction(t, testClient, txID, 30*time.Second)
a.NoError(err)
account, err := testClient.AccountInformation(someAddress, false)
diff --git a/test/framework/fixtures/goalFixture.go b/test/framework/fixtures/goalFixture.go
index ef52b51b63..69e43e784a 100644
--- a/test/framework/fixtures/goalFixture.go
+++ b/test/framework/fixtures/goalFixture.go
@@ -58,19 +58,27 @@ const (
nodeCmd = "node"
startCmd = "start"
stopCmd = "stop"
+
+ networkCmd = "network"
+ pregenCmd = "pregen"
+ createCmd = "create"
)
-func (f *GoalFixture) executeCommand(args ...string) (retStdout string, retStderr string, err error) {
+func (f *GoalFixture) executeRawCommand(args ...string) (retStdout string, retStderr string, err error) {
+ // Executes a command without a specified data directory
cmd := filepath.Join(f.binDir, goalCmd)
- // We always execute goal against the PrimaryDataDir() instance
- args = append(args, "-d", f.PrimaryDataDir())
retStdout, retStderr, err = util.ExecAndCaptureOutput(cmd, args...)
retStdout = strings.TrimRight(retStdout, "\n")
retStderr = strings.TrimRight(retStderr, "\n")
- //fmt.Printf("command: %v %v\nret: %v\n", cmd, args, ret)
return
}
+func (f *GoalFixture) executeCommand(args ...string) (retStdout string, retStderr string, err error) {
+ // We always execute goal against the PrimaryDataDir() instance
+ args = append(args, "-d", f.PrimaryDataDir())
+ return f.executeRawCommand(args...)
+}
+
// combine the error and the output so that we could return it as a single error object.
func combineExecuteError(retStdout string, retStderr string, err error) error {
if err == nil {
@@ -227,3 +235,63 @@ func (f *GoalFixture) AccountImportRootKey(wallet string, createDefaultUnencrypt
_, _, err = f.executeCommand(args...)
return
}
+
+// NetworkPregen exposes the `goal network pregen` command
+func (f *GoalFixture) NetworkPregen(template, pregendir string) (stdErr string, err error) {
+ args := []string{
+ networkCmd,
+ pregenCmd,
+ "-p",
+ pregendir,
+ }
+ if template != "" {
+ args = append(args, "-t", template)
+ }
+ _, stdErr, err = f.executeRawCommand(args...)
+ return
+}
+
+// NetworkCreate exposes the `goal network create` command
+func (f *GoalFixture) NetworkCreate(networkdir, networkName, template, pregendir string) (err error) {
+ args := []string{
+ networkCmd,
+ createCmd,
+ "-r",
+ networkdir,
+ }
+ if networkName != "" {
+ args = append(args, "-n", networkName)
+ }
+ if template != "" {
+ args = append(args, "-t", template)
+ }
+ if pregendir != "" {
+ args = append(args, "-p", pregendir)
+ }
+ _, _, err = f.executeRawCommand(args...)
+ return
+}
+
+// NetworkStart exposes the `goal network start` command
+func (f *GoalFixture) NetworkStart(networkdir string) (err error) {
+ args := []string{
+ networkCmd,
+ startCmd,
+ "-r",
+ networkdir,
+ }
+ _, _, err = f.executeRawCommand(args...)
+ return
+}
+
+// NetworkStop exposes the `goal network stop` command
+func (f *GoalFixture) NetworkStop(networkdir string) (err error) {
+ args := []string{
+ networkCmd,
+ stopCmd,
+ "-r",
+ networkdir,
+ }
+ _, _, err = f.executeRawCommand(args...)
+ return
+}
diff --git a/test/framework/fixtures/libgoalFixture.go b/test/framework/fixtures/libgoalFixture.go
index c0527fdd62..1cc0b24fb8 100644
--- a/test/framework/fixtures/libgoalFixture.go
+++ b/test/framework/fixtures/libgoalFixture.go
@@ -534,7 +534,7 @@ func (f *LibGoalFixture) TransactionProof(txid string, round uint64, hashType cr
return model.TransactionProofResponse{}, merklearray.SingleLeafProof{}, err
}
- proof, err := merklearray.ProofDataToSingleLeafProof(string(proofResp.Hashtype), proofResp.Treedepth, proofResp.Proof)
+ proof, err := merklearray.ProofDataToSingleLeafProof(string(proofResp.Hashtype), proofResp.Proof)
if err != nil {
return model.TransactionProofResponse{}, merklearray.SingleLeafProof{}, err
}
@@ -550,7 +550,7 @@ func (f *LibGoalFixture) LightBlockHeaderProof(round uint64) (model.LightBlockHe
return model.LightBlockHeaderProofResponse{}, merklearray.SingleLeafProof{}, err
}
- proof, err := merklearray.ProofDataToSingleLeafProof(crypto.Sha256.String(), proofResp.Treedepth, proofResp.Proof)
+ proof, err := merklearray.ProofDataToSingleLeafProof(crypto.Sha256.String(), proofResp.Proof)
if err != nil {
return model.LightBlockHeaderProofResponse{}, merklearray.SingleLeafProof{}, err
}
diff --git a/test/scripts/test_private_network.sh b/test/scripts/test_private_network.sh
index f1adc7f62b..72f0bd9160 100755
--- a/test/scripts/test_private_network.sh
+++ b/test/scripts/test_private_network.sh
@@ -1,8 +1,10 @@
#!/usr/bin/env bash
+
+set -euf -o pipefail
+
echo "######################################################################"
echo " test_private_network"
echo "######################################################################"
-set -e
# Suppress telemetry reporting for tests
export ALGOTEST=1
diff --git a/test/testdata/configs/config-v30.json b/test/testdata/configs/config-v30.json
index 5021c8fd40..1c71a55563 100644
--- a/test/testdata/configs/config-v30.json
+++ b/test/testdata/configs/config-v30.json
@@ -41,6 +41,7 @@
"EnableBlockService": false,
"EnableBlockServiceFallbackToArchiver": true,
"EnableCatchupFromArchiveServers": false,
+ "EnableDHTProviders": false,
"EnableDeveloperAPI": false,
"EnableExperimentalAPI": false,
"EnableFollowMode": false,
diff --git a/test/testdata/configs/config-v31.json b/test/testdata/configs/config-v31.json
index 62cbe6427b..01192f4ecc 100644
--- a/test/testdata/configs/config-v31.json
+++ b/test/testdata/configs/config-v31.json
@@ -43,8 +43,9 @@
"EnableAgreementTimeMetrics": false,
"EnableAssembleStats": false,
"EnableBlockService": false,
- "EnableBlockServiceFallbackToArchiver": true,
+ "EnableBlockServiceFallbackToArchiver": false,
"EnableCatchupFromArchiveServers": false,
+ "EnableDHTProviders": false,
"EnableDeveloperAPI": false,
"EnableExperimentalAPI": false,
"EnableFollowMode": false,
diff --git a/tools/block-generator/go.mod b/tools/block-generator/go.mod
index 040210731a..3c7c21d8c2 100644
--- a/tools/block-generator/go.mod
+++ b/tools/block-generator/go.mod
@@ -46,6 +46,8 @@ require (
github.com/elastic/gosigar v0.14.2 // indirect
github.com/flynn/noise v1.0.0 // indirect
github.com/francoispqt/gojay v1.2.13 // indirect
+ github.com/go-logr/logr v1.2.4 // indirect
+ github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
@@ -57,13 +59,21 @@ require (
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
+ github.com/hashicorp/errwrap v1.1.0 // indirect
+ github.com/hashicorp/go-multierror v1.1.1 // indirect
+ github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.2 // indirect
github.com/huin/goupnp v1.2.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
+ github.com/ipfs/boxo v0.10.0 // 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.20.0 // indirect
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
+ github.com/jbenet/goprocess v0.1.4 // indirect
github.com/jmespath/go-jmespath v0.3.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/klauspost/compress v1.16.7 // indirect
@@ -76,7 +86,10 @@ require (
github.com/libp2p/go-flow-metrics v0.1.0 // indirect
github.com/libp2p/go-libp2p v0.29.1 // indirect
github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect
+ github.com/libp2p/go-libp2p-kad-dht v0.24.3 // indirect
+ github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect
github.com/libp2p/go-libp2p-pubsub v0.9.3 // indirect
+ github.com/libp2p/go-libp2p-record v0.2.0 // indirect
github.com/libp2p/go-msgio v0.3.0 // indirect
github.com/libp2p/go-nat v0.2.0 // indirect
github.com/libp2p/go-netroute v0.2.1 // indirect
@@ -106,14 +119,16 @@ require (
github.com/olivere/elastic v6.2.14+incompatible // indirect
github.com/onsi/ginkgo/v2 v2.11.0 // indirect
github.com/opencontainers/runtime-spec v1.0.2 // 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/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.14.0 // indirect
github.com/prometheus/client_model v0.4.0 // indirect
- github.com/prometheus/common v0.37.0 // indirect
- github.com/prometheus/procfs v0.8.0 // indirect
+ github.com/prometheus/common v0.42.0 // indirect
+ github.com/prometheus/procfs v0.9.0 // indirect
github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/qtls-go1-19 v0.3.3 // indirect
github.com/quic-go/qtls-go1-20 v0.2.3 // indirect
@@ -124,6 +139,11 @@ require (
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
+ go.opencensus.io v0.24.0 // indirect
+ go.opentelemetry.io/otel v1.16.0 // indirect
+ go.opentelemetry.io/otel/metric v1.16.0 // indirect
+ go.opentelemetry.io/otel/trace v1.16.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/dig v1.17.0 // indirect
go.uber.org/fx v1.20.0 // indirect
@@ -137,6 +157,7 @@ require (
golang.org/x/sys v0.10.0 // indirect
golang.org/x/text v0.11.0 // indirect
golang.org/x/tools v0.11.0 // indirect
+ gonum.org/v1/gonum v0.13.0 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/sohlich/elogrus.v3 v3.0.0-20180410122755-1fa29e2f2009 // indirect
lukechampine.com/blake3 v1.2.1 // indirect
diff --git a/tools/block-generator/go.sum b/tools/block-generator/go.sum
index d680289e61..1f67ab139d 100644
--- a/tools/block-generator/go.sum
+++ b/tools/block-generator/go.sum
@@ -2,45 +2,13 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo=
-cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
-cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
-cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
-cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
-cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
-cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
-cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
-cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
-cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
-cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
-cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
-cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
-cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
-cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
-cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
-cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
-cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
-cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
-cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
-cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
-cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
-cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
-cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
-cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
-cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
-cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
-cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
-cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
-cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
-cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
-dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw=
github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w=
github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8=
@@ -49,11 +17,6 @@ github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKz
github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM=
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0=
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
-github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
-github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
-github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
-github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
-github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/algorand/avm-abi v0.2.0 h1:bkjsG+BOEcxUcnGSALLosmltE0JZdg+ZisXKx0UDX2k=
github.com/algorand/avm-abi v0.2.0/go.mod h1:+CgwM46dithy850bpTeHh9MC99zpn2Snirb3QTl2O/g=
github.com/algorand/falcon v0.1.0 h1:xl832kfZ7hHG6B4p90DQynjfKFGbIUgUOnsRiMZXfAo=
@@ -82,7 +45,6 @@ github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZx
github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o=
github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
-github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bits-and-blooms/bitset v1.7.0 h1:YjAGVd3XmtK9ktAbX8Zg2g2PwLIMjGREZJHlV4j7NEo=
@@ -90,14 +52,9 @@ github.com/bits-and-blooms/bitset v1.7.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edY
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
-github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chrismcguire/gobberish v0.0.0-20150821175641-1d8adb509a0e h1:CHPYEbz71w8DqJ7DRIq+MXyCQsdibK08vdcQTY4ufas=
-github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
-github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
-github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
@@ -171,6 +128,7 @@ github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwU
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
+github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
@@ -181,23 +139,16 @@ github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aev
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
-github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
-github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
-github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
-github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
-github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
-github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
-github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
-github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
-github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
-github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
-github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
+github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
+github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
-github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
+github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
@@ -213,25 +164,17 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
-github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
-github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
-github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
-github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
-github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
-github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
-github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
-github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
@@ -241,50 +184,38 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
-github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
-github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
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/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
-github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
-github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+uqi7GyzaLa5MH7qlSLBZtRdiA=
github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA=
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=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
-github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
-github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
@@ -292,9 +223,14 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
+github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
+github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
+github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
-github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
-github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
+github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/golang-lru/v2 v2.0.2 h1:Dwmkdr5Nc/oBiXgJS3CDHNhJtIHkuZ3DZF5twqnfBdU=
github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
@@ -302,43 +238,49 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY=
github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8=
github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE=
-github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
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.10.0 h1:tdDAxq8jrsbRkYoF+5Rcqyeb91hgWe2hp7iLu7ORZLY=
+github.com/ipfs/boxo v0.10.0/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM=
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=
+github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8=
github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk=
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
+github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8=
+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/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g=
+github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M=
github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI=
github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0=
github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI=
github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw=
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
+github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA=
github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk=
github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk=
+github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o=
+github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4=
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
-github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
-github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
-github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
-github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk=
github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U=
@@ -354,11 +296,8 @@ github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQs
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
-github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0=
github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk=
-github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
@@ -383,8 +322,14 @@ github.com/libp2p/go-libp2p v0.29.1 h1:yNeg6XgP8gbdc4YSrwiIt5T1TGOrVjH8dzl8h0GIO
github.com/libp2p/go-libp2p v0.29.1/go.mod h1:20El+LLy3/YhdUYIvGbLnvVJN32nMdqY6KXBENRAfLY=
github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s=
github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w=
+github.com/libp2p/go-libp2p-kad-dht v0.24.3 h1:VjxtDVWaaf4UFjGBf+yl2JCiGaHx7+ctAUa9oJCR3QE=
+github.com/libp2p/go-libp2p-kad-dht v0.24.3/go.mod h1:BShPzRbK6+fN3hk8a0WGAYKpb8m4k+DtchkqouGTrSg=
+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-pubsub v0.9.3 h1:ihcz9oIBMaCK9kcx+yHWm3mLAFBMAUsM4ux42aikDxo=
github.com/libp2p/go-libp2p-pubsub v0.9.3/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc=
+github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0=
+github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk=
github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA=
github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0=
github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM=
@@ -438,11 +383,8 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh
github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY=
github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU=
github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU=
-github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
@@ -471,8 +413,6 @@ github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqd
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/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
-github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM=
github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
@@ -491,6 +431,8 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc=
github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0=
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
+github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
+github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0=
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y=
@@ -500,41 +442,26 @@ github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCr
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
-github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+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 v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
-github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
-github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
-github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
-github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
-github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
-github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
-github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
-github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
-github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
-github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE=
-github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
+github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
+github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
-github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
-github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
-github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
-github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
-github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
+github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
+github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
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/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9PeJVE=
@@ -580,14 +507,15 @@ github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4=
github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
-github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
-github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
-github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
+github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg=
+github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM=
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
@@ -603,20 +531,25 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
@@ -624,6 +557,10 @@ github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPU
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
+github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ=
+github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
+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/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=
@@ -632,18 +569,20 @@ github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmv
github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
-github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
-go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
-go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
-go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
-go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
-go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+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.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s=
+go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4=
+go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo=
+go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4=
+go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs=
+go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0=
+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/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
@@ -653,21 +592,22 @@ go.uber.org/fx v1.20.0 h1:ZMC/pnRvhsthOZh9MZjMq5U8Or3mA9zBSPaLnzs3ihQ=
go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0=
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
+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=
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.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
-golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
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-20190605123033-f99c8df09eb5/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=
@@ -678,36 +618,16 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
-golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
-golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
-golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
-golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
-golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
-golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
-golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
-golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
-golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
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-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/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-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
-golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
-golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
-golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/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=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@@ -719,7 +639,6 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -727,48 +646,24 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
-golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
-golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
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=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -776,79 +671,43 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
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-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/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-20210124154548-22da62e12c0c/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=
-golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
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/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
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=
@@ -859,8 +718,6 @@ golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
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.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -869,45 +726,15 @@ golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
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-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+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-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
-golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
-golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
-golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
@@ -918,83 +745,33 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
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=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+gonum.org/v1/gonum v0.13.0 h1:a0T3bh+7fhRyqeNbiC3qVHYmkiQgit3wnNan/2c0HMM=
+gonum.org/v1/gonum v0.13.0/go.mod h1:/WPYRckkfWrhWefxyYTfrTtQR0KH4iyHNuzxqXAKyAU=
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
-google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
-google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
-google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
-google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
-google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
-google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
-google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
-google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
-google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
-google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
-google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
-google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
-google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
-google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
-google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
-google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
-google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
-google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
-google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
-google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
-google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
-google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -1003,13 +780,11 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
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.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
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=
@@ -1027,11 +802,9 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
-gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
@@ -1040,17 +813,11 @@ grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJd
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
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-20190418001031-e561f6794a2a/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=
-honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=
lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
pgregory.net/rapid v0.6.2 h1:ErW5sL+UKtfBfUTsWHDCoeB+eZKLKMxrSd1VJY6W4bw=
-rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
-rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
-rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU=
rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA=
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
diff --git a/util/set.go b/util/set.go
new file mode 100644
index 0000000000..a23f543dd6
--- /dev/null
+++ b/util/set.go
@@ -0,0 +1,42 @@
+// Copyright (C) 2019-2023 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 util
+
+// Set is a type alias for map with empty struct{}, where keys are comparable
+// We don't attempt to move even forward for the generics,
+// for keys being comparable should be sufficient for most cases.
+// (Though we actually want compare byte slices, but seems not achievable at this moment)
+type Set[T comparable] map[T]struct{}
+
+// Add adds variate number of elements to the set.
+func (s Set[T]) Add(elems ...T) Set[T] {
+ for _, elem := range elems {
+ s[elem] = struct{}{}
+ }
+ return s
+}
+
+// MakeSet constructs a set instance directly from elements.
+func MakeSet[T comparable](elems ...T) Set[T] {
+ return make(Set[T]).Add(elems...)
+}
+
+// Contains checks the membership of an element in the set.
+func (s Set[T]) Contains(elem T) (exists bool) {
+ _, exists = s[elem]
+ return
+}