diff --git a/.github/workflows/pr-type-category.yml b/.github/workflows/pr-type-category.yml new file mode 100644 index 0000000000..678499ed3b --- /dev/null +++ b/.github/workflows/pr-type-category.yml @@ -0,0 +1,37 @@ +name: Check PR category and type +on: + pull_request: + branches: + - master + types: [opened, synchronize, reopened, labeled, unlabeled, edited] +jobs: + check_label: + runs-on: ubuntu-latest + name: Check PR Category and Type + steps: + - name: "Failed to find proper PR Type label. Please add one of the following: 'New Feature', 'Enhancement', or 'Bug-Fix'" + run: exit 1 + if: | + !contains(github.event.pull_request.labels.*.name, 'New Feature') && + !contains(github.event.pull_request.labels.*.name, 'Enhancement') && + !contains(github.event.pull_request.labels.*.name, 'Bug-Fix') + - name: "Found more than one PR Type label. Please add only one of the following: 'New Feature', 'Enhancement', or 'Bug-Fix'" + run: exit 1 + if: | + ( + contains(github.event.pull_request.labels.*.name, 'New Feature') && + contains(github.event.pull_request.labels.*.name, 'Enhancement') + ) || ( + contains(github.event.pull_request.labels.*.name, 'New Feature') && + contains(github.event.pull_request.labels.*.name, 'Bug-Fix') + ) || ( + contains(github.event.pull_request.labels.*.name, 'Enhancement') && + contains(github.event.pull_request.labels.*.name, 'Bug-Fix') + ) + - name: "PR Category is missing from PR title. Please add it like ': '" + run: | + if [[ ! "${{ github.event.pull_request.title }}" =~ ^.{2,}\:.{2,} ]]; then + exit 1 + fi + - name: "Found at least one PR Type label and Category in the title. Good job!" + run: exit 0 diff --git a/Makefile b/Makefile index 8b3d36e056..4acfb982a5 100644 --- a/Makefile +++ b/Makefile @@ -307,6 +307,9 @@ gen/mainnet/genesis.dump: gen/mainnet/genesis.json mainnetgen: gen/mainnet/genesis.dump +# The mainnet genesis.json file generated by this target does not have timestamp value so the hash is different from the deployed mainnet, +# use a real genesis.json file from installer/genesis/mainnet/genesis.json if needed. +# This target is preserved as part of the history on how mainnet genesis.json was generated from the CSV file. gen/mainnet/genesis.json: gen/pregen/mainnet/genesis.csv buildsrc mkdir -p gen/mainnet cat gen/pregen/mainnet/genesis.csv | $(GOPATH1)/bin/incorporate -m gen/pregen/mainnet/metadata.json > gen/mainnet/genesis.json diff --git a/agreement/asyncVoteVerifier_test.go b/agreement/asyncVoteVerifier_test.go index 40ad59d5e4..8a4e819595 100644 --- a/agreement/asyncVoteVerifier_test.go +++ b/agreement/asyncVoteVerifier_test.go @@ -44,7 +44,7 @@ func TestVerificationAgainstFullExecutionPool(t *testing.T) { voteVerifier := MakeAsyncVoteVerifier(&expiredExecPool{mainPool}) defer voteVerifier.Quit() verifyErr := voteVerifier.verifyVote(context.Background(), nil, unauthenticatedVote{}, 0, message{}, make(chan<- asyncVerifyVoteResponse, 1)) - require.Error(t, context.Canceled, verifyErr) + require.Equal(t, context.Canceled, verifyErr) verifyEqVoteErr := voteVerifier.verifyEqVote(context.Background(), nil, unauthenticatedEquivocationVote{}, 0, message{}, make(chan<- asyncVerifyVoteResponse, 1)) - require.Error(t, context.Canceled, verifyEqVoteErr) + require.Equal(t, context.Canceled, verifyEqVoteErr) } diff --git a/agreement/pseudonode_test.go b/agreement/pseudonode_test.go index b4209ffdee..dfb9f2ce1f 100644 --- a/agreement/pseudonode_test.go +++ b/agreement/pseudonode_test.go @@ -520,11 +520,12 @@ func TestPseudonodeFailedEnqueuedTasks(t *testing.T) { for i := 0; i < pseudonodeVerificationBacklog*2; i++ { ch, err = pb.MakeProposals(context.Background(), startRound, period(i)) if err != nil { - require.Subset(t, []int{pseudonodeVerificationBacklog, pseudonodeVerificationBacklog + 1}, []int{i}) + require.ErrorAs(t, errPseudonodeBacklogFull, &err) break } channels = append(channels, ch) } + enqueuedProposals := len(channels) require.Error(t, err, "MakeProposals did not returned an error when being overflowed with requests") require.True(t, errors.Is(err, errPseudonodeBacklogFull)) @@ -533,17 +534,17 @@ func TestPseudonodeFailedEnqueuedTasks(t *testing.T) { for i := 0; i < pseudonodeVerificationBacklog*2; i++ { ch, err = pb.MakeVotes(context.Background(), startRound, period(i), step(i%5), makeProposalValue(period(i), accounts[0].Address()), persist) if err != nil { - require.Subset(t, []int{pseudonodeVerificationBacklog, pseudonodeVerificationBacklog + 1}, []int{i}) + require.ErrorAs(t, errPseudonodeBacklogFull, &err) break } channels = append(channels, ch) } require.Error(t, err, "MakeVotes did not returned an error when being overflowed with requests") - + enqueuedVotes := len(channels) - enqueuedProposals // drain output channels. for _, ch := range channels { drainChannel(ch) } - require.Equal(t, 330, subStrLogger.instancesFound[0]) - require.Equal(t, 330, subStrLogger.instancesFound[1]) + require.Equal(t, enqueuedVotes*len(accounts), subStrLogger.instancesFound[0]) + require.Equal(t, enqueuedProposals*len(accounts), subStrLogger.instancesFound[1]) } diff --git a/buildnumber.dat b/buildnumber.dat index d00491fd7e..0cfbf08886 100644 --- a/buildnumber.dat +++ b/buildnumber.dat @@ -1 +1 @@ -1 +2 diff --git a/cmd/algokey/keyreg.go b/cmd/algokey/keyreg.go new file mode 100644 index 0000000000..445a07827e --- /dev/null +++ b/cmd/algokey/keyreg.go @@ -0,0 +1,258 @@ +// Copyright (C) 2019-2022 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 main + +import ( + "encoding/base64" + "errors" + "fmt" + "io/ioutil" + "os" + "strings" + + "github.com/spf13/cobra" + + "github.com/algorand/go-algorand/crypto" + "github.com/algorand/go-algorand/data/account" + "github.com/algorand/go-algorand/data/basics" + "github.com/algorand/go-algorand/data/transactions" + "github.com/algorand/go-algorand/protocol" + "github.com/algorand/go-algorand/util" + "github.com/algorand/go-algorand/util/db" +) + +var keyregCmd *cobra.Command + +type keyregCmdParams struct { + fee uint64 + firstValid uint64 + lastValid uint64 + network string + offline bool + txFile string + partkeyFile string + addr string +} + +// There is no node to query, so we do our best here. +const ( + txnLife uint64 = 1000 + minFee uint64 = 1000 +) + +var validNetworks map[string]crypto.Digest +var validNetworkList []string + +func init() { + var params keyregCmdParams + + keyregCmd = &cobra.Command{ + Use: "keyreg", + Short: "Make key registration transaction", + Args: cobra.NoArgs, + Run: func(cmd *cobra.Command, _ []string) { + err := run(params) + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n\n", err.Error()) + os.Exit(1) + } + }, + } + + keyregCmd.Flags().Uint64Var(¶ms.fee, "fee", minFee, "transaction fee") + keyregCmd.Flags().Uint64Var(¶ms.firstValid, "firstvalid", 0, "first round where the transaction may be committed to the ledger") + keyregCmd.MarkFlagRequired("firstvalid") // nolint:errcheck + keyregCmd.Flags().Uint64Var(¶ms.lastValid, "lastvalid", 0, fmt.Sprintf("last round where the generated transaction may be committed to the ledger, defaults to firstvalid + %d", txnLife)) + keyregCmd.Flags().StringVar(¶ms.network, "network", "mainnet", "the network where the provided keys will be registered, one of mainnet/testnet/betanet") + keyregCmd.MarkFlagRequired("network") // nolint:errcheck + keyregCmd.Flags().BoolVar(¶ms.offline, "offline", false, "set to bring an account offline") + keyregCmd.Flags().StringVarP(¶ms.txFile, "outputFile", "o", "", fmt.Sprintf("write signed transaction to this file, or '%s' to write to stdout", stdoutFilenameValue)) + keyregCmd.Flags().StringVar(¶ms.partkeyFile, "keyfile", "", "participation keys to register, file is opened to fetch metadata for the transaction; only specify when bringing an account online to vote in Algorand consensus") + keyregCmd.Flags().StringVar(¶ms.addr, "account", "", "account address to bring offline; only specify when taking an account offline from voting in Algorand consensus") + + // TODO: move 'bundleGenesisInject' into something that can be imported here instead of using constants. + validNetworks = map[string]crypto.Digest{ + "mainnet": mustConvertB64ToDigest("wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8="), + "testnet": mustConvertB64ToDigest("SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI="), + "betanet": mustConvertB64ToDigest("mFgazF+2uRS1tMiL9dsj01hJGySEmPN28B/TjjvpVW0="), + "devnet": mustConvertB64ToDigest("sC3P7e2SdbqKJK0tbiCdK9tdSpbe6XeCGKdoNzmlj0E="), + } + validNetworkList = make([]string, 0, len(validNetworks)) + for k := range validNetworks { + validNetworkList = append(validNetworkList, k) + } +} + +func mustConvertB64ToDigest(b64 string) (digest crypto.Digest) { + data, err := base64.StdEncoding.DecodeString(b64) + if err != nil { + fmt.Fprintf(os.Stderr, "Unable to decode digest '%s': %s\n\n", b64, err) + os.Exit(1) + } + if len(data) != len(digest[:]) { + fmt.Fprintf(os.Stderr, "Unexpected decoded digest length decoding '%s'.\n\n", b64) + os.Exit(1) + } + copy(digest[:], data) + return +} + +func getGenesisInformation(network string) (crypto.Digest, error) { + // For testing purposes, there is a secret option to override the genesis information. + hashOverride := os.Getenv("ALGOKEY_GENESIS_HASH") + if hashOverride != "" { + return mustConvertB64ToDigest(hashOverride), nil + } + + // Otherwise check that network matches one of the known networks. + gen, ok := validNetworks[strings.ToLower(network)] + if !ok { + return crypto.Digest{}, fmt.Errorf("unknown network '%s' provided. Supported networks: %s", + network, + strings.Join(validNetworkList, ", ")) + } + + return gen, nil +} + +func run(params keyregCmdParams) error { + // Implicit last valid + if params.lastValid == 0 { + params.lastValid = params.firstValid + txnLife + } + + if params.fee < minFee { + return fmt.Errorf("the provided transaction fee (%d) is too low, the minimum fee is %d", params.fee, minFee) + } + + if !params.offline { + if params.partkeyFile == "" { + return errors.New("must provide --keyfile when registering participation keys") + } + if params.addr != "" { + return errors.New("do not provide --address when registering participation keys") + } + } else { + if params.addr == "" { + return errors.New("must provide --address when bringing an account offline") + } + if params.partkeyFile != "" { + return errors.New("do not provide --keyfile when bringing an account offline") + } + } + + var accountAddress basics.Address + if params.addr != "" { + var err error + accountAddress, err = basics.UnmarshalChecksumAddress(params.addr) + if err != nil { + return fmt.Errorf("unable to parse --address: %w", err) + } + } + + if params.partkeyFile != "" && !util.FileExists(params.partkeyFile) { + return fmt.Errorf("cannot access keyfile '%s'", params.partkeyFile) + } + + if params.txFile == "" { + params.txFile = fmt.Sprintf("%s.tx", params.partkeyFile) + } + + if util.FileExists(params.txFile) || params.txFile == stdoutFilenameValue { + return fmt.Errorf("outputFile '%s' already exists", params.partkeyFile) + } + + // Lookup information from partkey file + var part *account.Participation + if params.partkeyFile != "" { + partDB, err := db.MakeErasableAccessor(params.partkeyFile) + if err != nil { + return fmt.Errorf("cannot open keyfile %s: %v", params.partkeyFile, err) + } + + partkey, err := account.RestoreParticipation(partDB) + if err != nil { + return fmt.Errorf("cannot load keyfile %s: %v", params.partkeyFile, err) + } + defer partkey.Close() + + part = &partkey.Participation + + if params.firstValid < uint64(part.FirstValid) { + return fmt.Errorf("the transaction's firstvalid round (%d) field should be set greater than or equal to the participation key's first valid round (%d). The network will reject key registration transactions that are set to take effect before the participation key's first valid round", params.firstValid, part.FirstValid) + } + } + + validRange := params.lastValid - params.firstValid + if validRange > txnLife { + return fmt.Errorf("the transaction's specified validity range must be less than or equal to 1000 rounds due to security constraints. Please enter a first valid round (%d) and last valid round (%d) whose difference is no more than 1000 rounds", params.firstValid, params.lastValid) + } + + var txn transactions.Transaction + if !params.offline { + // Generate go-online transaction + txn = part.GenerateRegistrationTransaction( + basics.MicroAlgos{Raw: params.fee}, + basics.Round(params.firstValid), + basics.Round(params.lastValid), + [32]byte{}, + part.StateProofSecrets != nil) + } else { + // Generate go-offline transaction + txn = transactions.Transaction{ + Type: protocol.KeyRegistrationTx, + Header: transactions.Header{ + Sender: accountAddress, + Fee: basics.MicroAlgos{Raw: params.fee}, + FirstValid: basics.Round(params.firstValid), + LastValid: basics.Round(params.lastValid), + }, + } + } + + var err error + txn.GenesisHash, err = getGenesisInformation(params.network) + if err != nil { + return err + } + + // Wrap in a transactions.SignedTxn with an empty sig. + // This way protocol.Encode will encode the transaction type + stxn, err := transactions.AssembleSignedTxn(txn, crypto.Signature{}, crypto.MultisigSig{}) + if err != nil { + return fmt.Errorf("failed to assemble transaction: %w", err) + } + + data := protocol.Encode(&stxn) + if params.txFile == stdoutFilenameValue { + // Write to Stdout + if _, err = os.Stdout.Write(data); err != nil { + return fmt.Errorf("failed to write transaction to stdout: %w", err) + } + } else { + if err = ioutil.WriteFile(params.txFile, data, 0600); err != nil { + return fmt.Errorf("failed to write transaction to '%s': %w", params.txFile, err) + } + } + + if params.offline { + fmt.Printf("Account key go offline transaction written to '%s'.\n", params.txFile) + } else { + fmt.Printf("Key registration transaction written to '%s'.\n", params.txFile) + } + return nil +} diff --git a/cmd/algokey/part.go b/cmd/algokey/part.go index 5a29f9d719..57a4ddedce 100644 --- a/cmd/algokey/part.go +++ b/cmd/algokey/part.go @@ -175,6 +175,7 @@ func init() { partCmd.AddCommand(partGenerateCmd) partCmd.AddCommand(partInfoCmd) partCmd.AddCommand(partReparentCmd) + partCmd.AddCommand(keyregCmd) partGenerateCmd.Flags().StringVar(&partKeyfile, "keyfile", "", "Participation key filename") partGenerateCmd.Flags().Uint64Var(&partFirstRound, "first", 0, "First round for participation key") diff --git a/cmd/goal/bundle_genesis_json.sh b/cmd/goal/bundle_genesis_json.sh new file mode 100755 index 0000000000..2c7f2e6107 --- /dev/null +++ b/cmd/goal/bundle_genesis_json.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +THISDIR=$(dirname $0) + +cat < $THISDIR/bundledGenesisInject.go +// Code generated by bundle_genesis_json.sh. DO NOT EDIT. +package main +var genesisMainnet []byte +var genesisTestnet []byte +var genesisBetanet []byte +var genesisDevnet []byte +func init() { + genesisMainnet = []byte(\`$(cat $THISDIR/../../installer/genesis/mainnet/genesis.json)\`) + genesisTestnet = []byte(\`$(cat $THISDIR/../../installer/genesis/testnet/genesis.json)\`) + genesisBetanet = []byte(\`$(cat $THISDIR/../../installer/genesis/betanet/genesis.json)\`) + genesisDevnet = []byte(\`$(cat $THISDIR/../../installer/genesis/devnet/genesis.json)\`) +} +EOM \ No newline at end of file diff --git a/cmd/goal/bundledGenesisInject.go b/cmd/goal/bundledGenesisInject.go new file mode 100644 index 0000000000..86bd491893 --- /dev/null +++ b/cmd/goal/bundledGenesisInject.go @@ -0,0 +1,2793 @@ +// Code generated by bundle_genesis_json.sh, along with langspec.json. DO NOT EDIT. +package main + +var genesisMainnet []byte +var genesisTestnet []byte +var genesisBetanet []byte +var genesisDevnet []byte + +func init() { + genesisMainnet = []byte(`{ + "alloc": [ + { + "addr": "737777777777777777777777777777777777777777777777777UFEJ2CI", + "comment": "RewardsPool", + "state": { + "algo": 10000000000000, + "onl": 2 + } + }, + { + "addr": "Y76M3MSY6DKBRHBL7C3NNDXGS5IIMQVQVUAB6MP4XEMMGVF2QWNPL226CA", + "comment": "FeeSink", + "state": { + "algo": 1000000, + "onl": 2 + } + }, + { + "addr": "ALGORANDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIN5DNAU", + "comment": "A BIT DOES E NOT BUT E STARTS EVERYTHING LIFE A MANY FORTUNE R BUILD SIMPLER BE THE STARTS PERSEVERES FAVORS A ENOUGH RIPROVANDO POSSIBLE JOURNEY VICTORIA HE BOLD U WITHOUT MEN A K OF BORDERS WHO HE E RACES TOMORROW BUT WHO SINGLE PURPOSE GEOGRAPHICAL PROVANDO A KNOW SUFFOCATES NOT SCIENCE STEP MATHEMATICS OF OR A BRIDGES WALLS TECHNOLOGY TODAY AND WITH AS ET MILES OF THOUSAND VITA SIMPLE TOO MUST AS NOT MADE NOT", + "state": { + "algo": 1000000, + "onl": 2 + } + }, + { + "addr": "XQJEJECPWUOXSKMIC5TCSARPVGHQJIIOKHO7WTKEPPLJMKG3D7VWWID66E", + "comment": "AlgorandCommunityAnnouncement", + "state": { + "algo": 10000000, + "onl": 2 + } + }, + { + "addr": "VCINCVUX2DBKQ6WP63NOGPEAQAYGHGSGQX7TSH4M5LI5NBPVAGIHJPMIPM", + "comment": "AuctionsMaster", + "state": { + "algo": 1000000000, + "onl": 2 + } + }, + { + "addr": "OGP6KK5KCMHT4GOEQXJ4LLNJ7D6P6IH7MV5WZ5EX4ZWACHP75ID5PPEE5E", + "comment": "", + "state": { + "algo": 300000000000000, + "onl": 2 + } + }, + { + "addr": "AYBHAG2DAIOG26QEV35HKUBGWPMPOCCQ44MQEY32UOW3EXEMSZEIS37M2U", + "comment": "", + "state": { + "algo": 300000000000000, + "onl": 2 + } + }, + { + "addr": "2XKK2L6HOBCYHGIGBS3N365FJKHS733QOX42HIYLSBARUIJHMGQZYAQDRY", + "comment": "", + "state": { + "algo": 300000000000000, + "onl": 2 + } + }, + { + "addr": "ZBSPQQG7O5TR5MHPG3D5RS2TIFFD5NMOPR77VUKURMN6HV2BSN224ZHKGU", + "comment": "", + "state": { + "algo": 300000000000000, + "onl": 2 + } + }, + { + "addr": "7NQED6NJ4NZU7B5HGGFU2ZEC2UZQYU2SA5S4QOE2EXBVAR4CNAHIXV2XYY", + "comment": "", + "state": { + "algo": 300000000000000, + "onl": 2 + } + }, + { + "addr": "RX2ZKVJ43GNYDJNIOB6TIX26U7UEQFUQY46OMHX6CXLMMBHENJIH4YVLUQ", + "comment": "", + "state": { + "algo": 300000000000000, + "onl": 2 + } + }, + { + "addr": "RHSKYCCZYYQ2BL6Z63626YUETJMLFGVVV47ED5D55EKIK4YFJ5DQT5CV4A", + "comment": "", + "state": { + "algo": 300000000000000, + "onl": 2 + } + }, + { + "addr": "RJS6FDZ46ZZJIONLMMCKDJHYSJNHHAXNABMAVSGH23ULJSEAHZC6AQ6ALE", + "comment": "", + "state": { + "algo": 300000000000000, + "onl": 2 + } + }, + { + "addr": "AZ2KKAHF2PJMEEUVN4E2ILMNJCSZLJJYVLBIA7HOY3BQ7AENOVVTXMGN3I", + "comment": "", + "state": { + "algo": 300000000000000, + "onl": 2 + } + }, + { + "addr": "CGUKRKXNMEEOK7SJKOGXLRWEZESF24ELG3TAW6LUF43XRT2LX4OVQLU4BQ", + "comment": "", + "state": { + "algo": 300000000000000, + "onl": 2 + } + }, + { + "addr": "VVW6BVYHBG7MZQXKAR3OSPUZVAZ66JMQHOBMIBJG6YSPR7SLMNAPA7UWGY", + "comment": "", + "state": { + "algo": 250000000000000, + "onl": 2 + } + }, + { + "addr": "N5BGWISAJSYT7MVW2BDTTEHOXFQF4QQH4VKSMKJEOA4PHPYND43D6WWTIU", + "comment": "", + "state": { + "algo": 1740000000000000, + "onl": 2 + } + }, + { + "addr": "MKT3JAP2CEI5C4IX73U7QKRUF6JR7KPKE2YD6BLURFVPW6N7CYXVBSJPEQ", + "comment": "", + "state": { + "algo": 158000000000000, + "onl": 2 + } + }, + { + "addr": "GVCPSWDNSL54426YL76DZFVIZI5OIDC7WEYSJLBFFEQYPXM7LTGSDGC4SA", + "comment": "", + "state": { + "algo": 49998988000000, + "onl": 1, + "sel": "lZ9z6g0oSlis/8ZlEyOMiGfX0XDUcObfpJEg5KjU0OA=", + "vote": "Kk+5CcpHWIXSMO9GiAvnfe+eNSeRtpDb2telHb6I1EE=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "M7XKTBQXVQARLS7IVS6NVDHNLJFIAXR2CGGZTUDEKRIHRVLWL5TJFJOL5U", + "comment": "", + "state": { + "algo": 50000000000000, + "onl": 1, + "sel": "Z5gE/m2E/WSuaS5E8aYzO2DugTdSWQdc5W5BroCJdms=", + "vote": "QHHw03LnZQhKvjjIxVj3+qwgohOij2j3TBDMy7V9JMk=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "QFYWTHPNZBKKZ4XG2OWVNEX6ETBISD2VJZTCMODIZKT3QHQ4TIRJVEDVV4", + "comment": "", + "state": { + "algo": 50000000000000, + "onl": 1, + "sel": "NthIIUyiiRVnU/W13ajFFV4EhTvT5EZR/9N6ZRD/Z7U=", + "vote": "3KtiTLYvHJqa+qkGFj2RcZC77bz9yUYKxBZt8B24Z+c=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "DPOZQ6HRYLNNWVQL3I4XV4LMK5UZVROKGJBRIYIRNZUBMVHCU4DZWDBHYE", + "comment": "", + "state": { + "algo": 50000000000000, + "onl": 1, + "sel": "PBZ/agWgmwMdmWgt/W0NvdTN/XSTrVhPvRSMjmP5j90=", + "vote": "FDONnMcq1acmIBjJr3vz4kx4Q8ZRZ8oIH8xXRV5c4L8=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "42GALMKS3HMDB24ZPOR237WQ5QDHL5NIRC3KIA4PCKENJZAD5RP5QPBFO4", + "comment": "", + "state": { + "algo": 50000000000000, + "onl": 1, + "sel": "p7axjoy3Wn/clD7IKoTK2Zahc5ZU+Qkt2POVHKugQU4=", + "vote": "PItHHw+b01XplxRBFmZniqmdm+RyJFYd0fDz+OP4D6o=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "OXWIMTRZA5TVPABJF534EBBERJG367OLAB6VFN4RAW5P6CQEMXEX7VVDV4", + "comment": "", + "state": { + "algo": 50000000000000, + "onl": 1, + "sel": "RSOWYRM6/LD7MYxlZGvvF+WFGmBZg7UUutdkaWql0Xo=", + "vote": "sYSYFRL7AMJ61egushOYD5ABh9p06C4ZRV/OUSx7o3g=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "AICDUO6E46YBJRLM4DFJPVRVZGOFTRNPF7UPQXWEPPYRPVGIMQMLY5HLFM", + "comment": "", + "state": { + "algo": 50000000000000, + "onl": 1, + "sel": "0vxjPZqEreAhUt9PHJU2Eerb7gBhMU+PgyEXYLmbifg=", + "vote": "fuc0z/tpiZXBWARCJa4jPdmDvSmun4ShQLFiAxQkOFI=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "DYATVHCICZA7VVOWZN6OLFFSKUAZ64TZ7WZWCJQBFWL3JL4VBBV6R7Z6IE", + "comment": "", + "state": { + "algo": 50000000000000, + "onl": 1, + "sel": "KO2035CRpp1XmVPOTOF6ICWCw/0I6FgelKxdwPq+gMY=", + "vote": "rlcoayAuud0suR3bvvI0+psi/NzxvAJUFlp+I4ntzkM=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "6XJH2PJMAXWS4RGE6NBYIS3OZFOPU3LOHYC6MADBFUAALSWNFHMPJUWVSE", + "comment": "", + "state": { + "algo": 50000000000000, + "onl": 1, + "sel": "PgW1dncjs9chAVM89SB0FD4lIrygxrf+uqsAeZw8Qts=", + "vote": "pA4NJqjTAtHGGvZWET9kliq24Go5kEW8w7f1BGAWmKY=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "EYOZMULFFZZ5QDDMWQ64HKIMUPPNEL3WJMNGAFD43L52ZXTPESBEVJPEZU", + "comment": "", + "state": { + "algo": 50000000000000, + "onl": 1, + "sel": "sfebD2noAbrn1vblMmeCIeGB3BxLGKQDTG4sKSNibFs=", + "vote": "Cuz3REj26J+JhOpf91u6PO6MV5ov5b1K/ii1U1uPD/g=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "I3345FUQQ2GRBHFZQPLYQQX5HJMMRZMABCHRLWV6RCJYC6OO4MOLEUBEGU", + "comment": "", + "state": { + "algo": 24000000000000, + "onl": 1, + "sel": "MkH9KsdwiFgYtFFWFu48CeejEop1vsyGFG4/kqPIOFg=", + "vote": "RcntidhQqXQIvYjLFtc6HuL335rMnNX92roa2LcC+qQ=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "6LQH42A4QJ3Y27FGKJWERY3MD65SXM4QQCJJR2HRJYNB427IQ73YBI3YFY", + "comment": "", + "state": { + "algo": 24000000000000, + "onl": 1, + "sel": "nF3mu9Bu0Ad5MIrT31NgTxxrsZOXc4u1+WCvaPQTYEQ=", + "vote": "NaqWR/7FzOq/MiHb3adO6+J+kvnQKat8NSqEmoEkVfE=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "3V2MC7WJGAFU2EHWBHEETIMJVFJNAT4KKWVPOMJFJIM6ZPWEJRJ4POTXGI", + "comment": "", + "state": { + "algo": 24000000000000, + "onl": 1, + "sel": "3i4K8zdmnf1kxwgcNmI3x50iIwAxDmLMvoQEhjzhado=", + "vote": "wfJWa0kby76rqX2yvCD/aCfJdNt+qItylDPQiuAWFkQ=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "FTXSKED23VEXNW442T2JKNPPNUC2WKFNRWBVQTFMT7HYX365IVLZXYILAI", + "comment": "", + "state": { + "algo": 24000000000000, + "onl": 1, + "sel": "icuL7ehcGonAcJ02Zy4MIHqcT+Sp1R1UURNCYJQHmo4=", + "vote": "tmFcj3v7X5DDxKI1IDbGdhXh3a5f0Ab1ftltM7TgIDE=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "IAOW7PXLCDGLKMIQF26IXFF4THSQMU662MUU6W5KPOXHIVKHYFLYRWOUT4", + "comment": "", + "state": { + "algo": 24000000000000, + "onl": 1, + "sel": "zTn9rl/8Y2gokMdFyFP/pKg4eP02arkxlrBZIS94vPI=", + "vote": "a0pX68GgY7u8bd2Z3311+Mtc6yDnESZmi9k8zJ0oHzY=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "4NRNE5RIGC2UGOMGMDR6L5YMQUV3Q76TPOR7TDU3WEMJLMC6BSBEKPJ2SY", + "comment": "", + "state": { + "algo": 24000000000000, + "onl": 1, + "sel": "orSV2VHPY8m5ckEHGwK0r+SM9jq4BujAICXegAUAecI=", + "vote": "NJ9tisH+7+S29m/uMymFTD8X02/PKU0JUX1ghnLCzkw=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "E2EIMPLDISONNZLXONGMC33VBYOIBC2R7LVOS4SYIEZYJQK6PYSAPQL7LQ", + "comment": "", + "state": { + "algo": 24000000000000, + "onl": 1, + "sel": "XM2iW9wg9G5TyOfVu9kTS80LDIqcEPkJsgxaZll3SWA=", + "vote": "p/opFfDOsIomj5j7pAYU+G/CNUIwvD2XdEer6dhGquQ=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "APDO5T76FB57LNURPHTLAGLQOHUQZXYHH2ZKR4DPQRKK76FB4IAOBVBXHQ", + "comment": "", + "state": { + "algo": 24000000000000, + "onl": 1, + "sel": "5k2vclbUQBE6zBl45F3kGSv1PYhE2k9wZjxyxoPlnwA=", + "vote": "3dcLRSckm3wd9KB0FBRxub3meIgT6lMZnv5F08GJgEo=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "3KJTYHNHK37G2JDZJPV55IHBADU22TX2FPJZJH43MY64IFWKVNMP2F4JZE", + "comment": "", + "state": { + "algo": 24000000000000, + "onl": 1, + "sel": "o5e9VLqMdmJas5wRovfYFHgQ+Z6sQoATf3a6j0HeIXU=", + "vote": "rG7J8pPAW+Xtu5pqMIJOG9Hxdlyewtf9zPHEKR2Q6OE=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "IVKDCE6MS44YVGMQQFVXCDABW2HKULKIXMLDS2AEOIA6P2OGMVHVJ64MZI", + "comment": "", + "state": { + "algo": 24000000000000, + "onl": 1, + "sel": "XgUrwumD7oin/rG3NKwywBSsTETg/aWg9MjCDG61Ybg=", + "vote": "sBPEGGrEqcQMdT+iq2ududNxCa/1HcluvsosO1SkE/k=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "2WDM5XFF7ONWFANPE5PBMPJLVWOEN2BBRLSKJ37PQYW5WWIHEFT3FV6N5Y", + "comment": "", + "state": { + "algo": 24000000000000, + "onl": 1, + "sel": "Lze5dARJdb1+Gg6ui8ySIi+LAOM3P9dKiHKB9HpMM6A=", + "vote": "ys4FsqUNQiv+N0RFtr0Hh9OnzVcxXS6cRVD/XrLgW84=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "EOZWAIPQEI23ATBWQ5J57FUMRMXADS764XLMBTSOLVKPMK5MK5DBIS3PCY", + "comment": "", + "state": { + "algo": 24000000000000, + "onl": 1, + "sel": "jtmLcJhaAknJtA1cS5JPZil4SQ5SKh8P0w1fUw3X0CE=", + "vote": "pyEtTxJAas/j+zi/N13b/3LB4UoCar1gfcTESl0SI2I=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "REMF542E5ZFKS7SGSNHTYB255AUITEKHLAATWVPK3CY7TAFPT6GNNCHH6M", + "comment": "", + "state": { + "algo": 24000000000000, + "onl": 1, + "sel": "8ggWPvRpSkyrjxoh1SVS9PiSjff2azWtH0HFadwI9Ck=", + "vote": "Ej/dSkWbzRf09RAuWZfC4luRPNuqkLFCSGYXDcOtwic=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "T4UBSEAKK7JHT7RNLXVHDRW72KKFJITITR54J464CAGE5FGAZFI3SQH3TI", + "comment": "", + "state": { + "algo": 24000000000000, + "onl": 1, + "sel": "eIB8MKaG2lyJyM9spk+b/Ap/bkbo9bHfvF9f8T51OQk=", + "vote": "7xuBsE5mJaaRAdm5wnINVwm4SgPqKwJTAS1QBQV3sEc=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "YUDNQMOHAXC4B3BAMRMMQNFDFZ7GYO2HUTBIMNIP7YQ4BL57HZ5VM3AFYU", + "comment": "", + "state": { + "algo": 24000000000000, + "onl": 1, + "sel": "CSTCDvvtsJB0VYUcl3oRXyiJfhm3CtqvRIuFYZ69Z68=", + "vote": "uBK1TH4xKdWfv5nnnHkvYssI0tyhWRFZRLHgVt9TE1k=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "4SZTEUQIURTRT37FCI3TRMHSYT5IKLUPXUI7GWC5DZFXN2DGTATFJY5ABY", + "comment": "", + "state": { + "algo": 24000000000000, + "onl": 1, + "sel": "THGOlrqElX13xMqeLUPy6kooTbXjiyrUoZfVccnHrfI=", + "vote": "k4hde2Q3Zl++sQobo01U8heZd/X0GIX1nyqM8aI/hCY=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "UEDD34QFEMWRGYCBLKZIEHPKSTNBFSRMFBHRJPY3O2JPGKHQCXH4IY6XRI", + "comment": "", + "state": { + "algo": 24000000000000, + "onl": 1, + "sel": "jE+AUFvtp2NJsfNeUZeXdWt0X6I58YOgY+z/HB17GDs=", + "vote": "lmnYTjg1FhRNAR9TwVmOahVr5Z+7H1GO6McmvOZZRTQ=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "HHZQOGQKMQDLBEL3HXMDX7AGTNORYVZ4JFDWVSL5QLWMD3EXOIAHDI5L7M", + "comment": "", + "state": { + "algo": 24000000000000, + "onl": 1, + "sel": "Hajdvzem2rR2GjLmCG+98clHZFY5Etlp0n+x/gQTGj0=", + "vote": "2+Ie4MDWC6o/SfFSqev1A7UAkzvKRESI42b4NKS6Iw8=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "XRTBXPKH3DXDJ5OLQSYXOGX3DJ3U5NR6Y3LIVIWMK7TY33YW4I2NJZOTVE", + "comment": "", + "state": { + "algo": 24000000000000, + "onl": 1, + "sel": "5qe7rVoQfGdIUuDbhP2ABWivCoCstKbUsjdmYY76akA=", + "vote": "3J3O9DyJMWKvACubUK9QvmCiArtZR7yFHWG7k7+apdQ=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "JJFGCPCZPYRLOUYBZVC4F7GRPZ5CLB6BMTVRGNDP7GRGXL6GG4JEN7DL54", + "comment": "", + "state": { + "algo": 24000000000000, + "onl": 1, + "sel": "YoRFAcTiOgJcLudNScYstbaKJ8anrrHwQMZAffWMqYE=", + "vote": "VQFKlDdxRqqqPUQ/mVoF8xZS9BGxUtTnPUjYyKnOVRA=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "4VNSA2GZVUD5ZNO62OVVNP4NEL2LIEE5N3MZEK4BKH62KGKRLVINFZYTZM", + "comment": "", + "state": { + "algo": 100000000000000, + "onl": 2 + } + }, + { + "addr": "IVCEEIH2Q32DZNRTS5XFVEFFAQGERNZHHQT6S4UPY7ORJMHIQDSTX7YM4E", + "comment": "", + "state": { + "algo": 408400000000000, + "onl": 2 + } + }, + { + "addr": "PLFHBIRGM3ZWGAMCXTREX2N537TWOMFIQXHFO2ZGQOEPZU473SYBVGVA5M", + "comment": "", + "state": { + "algo": 1011600000000000, + "onl": 2 + } + }, + { + "addr": "KF7X4ZABZUQU7IFMHSKLDKWCS4F3GZLOLJRDAK5KMEMDAGU32CX36CJQ5M", + "comment": "", + "state": { + "algo": 10000000000000, + "onl": 2 + } + }, + { + "addr": "BTEESEYQMFLWZKULSKLNDELYJTOOQK6ZT4FBCW3TOZQ55NZYLOO6BRQ5K4", + "comment": "", + "state": { + "algo": 36199095000000, + "onl": 2 + } + }, + { + "addr": "E36JOZVSZZDXKSERASLAWQE4NU67HC7Q6YDOCG7P7IRRWCPSWXOI245DPA", + "comment": "", + "state": { + "algo": 20000000000000, + "onl": 2 + } + }, + { + "addr": "I5Q6RRN44OZWYMX6YLWHBGEVPL7S3GBUCMHZCOOLJ245TONH7PERHJXE4A", + "comment": "", + "state": { + "algo": 20000000000000, + "onl": 2 + } + }, + { + "addr": "2GYS272T3W2AP4N2VX5BFBASVNLWN44CNVZVKLWMMVPZPHVJ52SJPPFQ2I", + "comment": "", + "state": { + "algo": 40000000000000, + "onl": 2 + } + }, + { + "addr": "D5LSV2UGT4JJNSLJ5XNIF52WP4IHRZN46ZGWH6F4QEF4L2FLDYS6I6R35Y", + "comment": "", + "state": { + "algo": 20000000000000, + "onl": 2 + } + }, + { + "addr": "UWMSBIP2CGCGR3GYVUIOW3YOMWEN5A2WRTTBH6Y23KE3MOVFRHNXBP6IOE", + "comment": "", + "state": { + "algo": 20000000000000, + "onl": 2 + } + }, + { + "addr": "OF3MKZZ3L5ZN7AZ46K7AXJUI4UWJI3WBRRVNTDKYVZUHZAOBXPVR3DHINE", + "comment": "", + "state": { + "algo": 40000000000000, + "onl": 2 + } + }, + { + "addr": "2PPWE36YUMWUVIFTV2A6U4MLZLGROW4GHYIRVHMUCHDH6HCNVPUKPQ53NY", + "comment": "", + "state": { + "algo": 440343426000000, + "onl": 2 + } + }, + { + "addr": "JRGRGRW4HYBNAAHR7KQLLBAGRSPOYY6TRSINKYB3LI5S4AN247TANH5IQY", + "comment": "", + "state": { + "algo": 362684706000000, + "onl": 2 + } + }, + { + "addr": "D7YVVQJXJEFOZYUHJLIJBW3ATCAW46ML62VYRJ3SMGLOHMWYH4OS3KNHTU", + "comment": "", + "state": { + "algo": 10000000000000, + "onl": 2 + } + }, + { + "addr": "PZJKH2ILW2YDZNUIYQVJZ2MANRSMK6LCHAFSAPYT6R3L3ZCWKYRDZXRVY4", + "comment": "", + "state": { + "algo": 10000000000000, + "onl": 2 + } + }, + { + "addr": "3MODEFJVPGUZH3HDIQ6L2MO3WLJV3FK3XSWKFBHUGZDCHXQMUKD4B7XLMI", + "comment": "", + "state": { + "algo": 130000000000000, + "onl": 2 + } + }, + { + "addr": "WNSA5P6C5IIH2UJPQWJX6FRNPHXY7XZZHOWLSW5ZWHOEHBUW4AD2H6TZGM", + "comment": "", + "state": { + "algo": 130000000000000, + "onl": 2 + } + }, + { + "addr": "OO65J5AIFDS6255WL3AESTUGJD5SUV47RTUDOUGYHEIME327GX7K2BGC6U", + "comment": "", + "state": { + "algo": 40000000000000, + "onl": 2 + } + }, + { + "addr": "DM6A24ZWHRZRM2HWXUHAUDSAACO7VKEZAOC2THWDXH4DX5L7LSO3VF2OPU", + "comment": "", + "state": { + "algo": 20000000000000, + "onl": 2 + } + }, + { + "addr": "NTJJSFM75RADUOUGOBHZB7IJGO7NLVBWA66EYOOPU67H7LYIXVSPSI7BTA", + "comment": "", + "state": { + "algo": 18099548000000, + "onl": 2 + } + }, + { + "addr": "DAV2AWBBW4HBGIL2Z6AAAWDWRJPTOQD6BSKU2CFXZQCOBFEVFEJ632I2LY", + "comment": "", + "state": { + "algo": 1000000000000, + "onl": 2 + } + }, + { + "addr": "M5VIY6QPSMALVVPVG5LVH35NBMH6XJMXNWKWTARGGTEEQNQ3BHPQGYP5XU", + "comment": "", + "state": { + "algo": 20000000000000, + "onl": 2 + } + }, + { + "addr": "WZZLVKMCXJG3ICVZSVOVAGCCN755VHJKZWVSVQ6JPSRQ2H2OSPOOZKW6DQ", + "comment": "", + "state": { + "algo": 45248869000000, + "onl": 2 + } + }, + { + "addr": "XEJLJUZRQOLBHHSOJJUE4IWI3EZOM44P646UDKHS4AV2JW7ZWBWNFGY6BU", + "comment": "", + "state": { + "algo": 20000000000000, + "onl": 2 + } + }, + { + "addr": "OGIPDCRJJPNVZ6X6NBQHMTEVKJVF74QHZIXVLABMGUKZWNMEH7MNXZIJ7Q", + "comment": "", + "state": { + "algo": 40000000000000, + "onl": 2 + } + }, + { + "addr": "G47R73USFN6FJJQTI3JMYQXO7F6H4LRPBCTTAD5EZWPWY2WCG64AVPCYG4", + "comment": "", + "state": { + "algo": 10000000000000, + "onl": 2 + } + }, + { + "addr": "PQ5T65QB564NMIY6HXNYZXTFRSTESUEFIF2C26ZZKIZE6Q4R4XFP5UYYWI", + "comment": "", + "state": { + "algo": 5000000000000, + "onl": 2 + } + }, + { + "addr": "R6S7TRMZCHNQPKP2PGEEJ6WYUKMTURNMM527ZQXABTHFT5GBVMF6AZAL54", + "comment": "", + "state": { + "algo": 1000000000000, + "onl": 2 + } + }, + { + "addr": "36LZKCBDUR5EHJ74Q6UWWNADLVJOHGCPBBQ5UTUM3ILRTQLA6RYYU4PUWQ", + "comment": "", + "state": { + "algo": 5000000000000, + "onl": 2 + } + }, + { + "addr": "JRHPFMSJLU42V75NTGFRQIALCK6RHTEK26QKLWCH2AEEAFNAVEXWDTA5AM", + "comment": "", + "state": { + "algo": 40000000000000, + "onl": 2 + } + }, + { + "addr": "64VZVS2LFZXWA5W3S657W36LWGP34B7XLMDIF4ROXBTPADD7SR5WNUUYJE", + "comment": "", + "state": { + "algo": 171945701000000, + "onl": 2 + } + }, + { + "addr": "TXDBSEZPFP2UB6BDNFCHCZBTPONIIQVZGABM4UBRHVAAPR5NE24QBL6H2A", + "comment": "", + "state": { + "algo": 60000000000000, + "onl": 2 + } + }, + { + "addr": "XI5TYT4XPWUHE4AMDDZCCU6M4AP4CAI4VTCMXXUNS46I36O7IYBQ7SL3D4", + "comment": "", + "state": { + "algo": 40000000000000, + "onl": 2 + } + }, + { + "addr": "Y6ZPKPXF2QHF6ULYQXVHM7NPI3L76SP6QHJHK7XTNPHNXDEUTJPRKUZBNE", + "comment": "", + "state": { + "algo": 40000000000000, + "onl": 2 + } + }, + { + "addr": "6LY2PGUJLCK4Q75JU4IX5VWVJVU22VGJBWPZOFP3752UEBIUBQRNGJWIEA", + "comment": "", + "state": { + "algo": 40000000000000, + "onl": 2 + } + }, + { + "addr": "L7AGFNAFJ6Z2FYCX3LXE4ZSERM2VOJF4KPF7OUCMGK6GWFXXDNHZJBEC2E", + "comment": "", + "state": { + "algo": 10000000000000, + "onl": 2 + } + }, + { + "addr": "RYXX5U2HMWGTPBG2UDLDT6OXDDRCK2YGL7LFAKYNBLRGZGYEJLRMGYLSVU", + "comment": "", + "state": { + "algo": 40000000000000, + "onl": 2 + } + }, + { + "addr": "S263NYHFQWZYLINTBELLMIRMAJX6J5CUMHTECTGGVZUKUN2XY6ND2QBZVY", + "comment": "", + "state": { + "algo": 21647524000000, + "onl": 2 + } + }, + { + "addr": "AERTZIYYGK3Q364M6DXPKSRRNSQITWYEDGAHXC6QXFCF4GPSCCSISAGCBY", + "comment": "", + "state": { + "algo": 19306244000000, + "onl": 2 + } + }, + { + "addr": "34UYPXOJA6WRTWRNH5722LFDLWT23OM2ZZTCFQ62EHQI6MM3AJIAKOWDVQ", + "comment": "", + "state": { + "algo": 10000000000000, + "onl": 2 + } + }, + { + "addr": "EDVGNQL6APUFTIGFZHASIEWGJRZNWGIKJE64B72V36IQM2SJPOAG2MJNQE", + "comment": "", + "state": { + "algo": 20000000000000, + "onl": 2 + } + }, + { + "addr": "RKKLUIIGR75DFWGQOMJB5ZESPT7URDPC7QHGYKM4MAJ4OEL2J5WAQF6Z2Q", + "comment": "", + "state": { + "algo": 40000000000000, + "onl": 2 + } + }, + { + "addr": "M4TNVJLDZZFAOH2M24BE7IU72KUX3P6M2D4JN4WZXW7WXH3C5QSHULJOU4", + "comment": "", + "state": { + "algo": 10000000000000, + "onl": 2 + } + }, + { + "addr": "WQL6MQS5SPK3CR3XUPYMGOUSCUC5PNW5YQPLGEXGKVRK3KFKSAZ6JK4HXQ", + "comment": "", + "state": { + "algo": 10000000000000, + "onl": 2 + } + }, + { + "addr": "36JTK4PKUBJGVCWKXZTAG6VLJRXWZXQVPQQSYODSN6WEGVHOWSVK6O54YU", + "comment": "", + "state": { + "algo": 10000000000000, + "onl": 2 + } + }, + { + "addr": "YFOAYI4SNXJR2DBEZ3O6FJOFSEQHWD7TYROCNDWF6VLBGLNJMRRHDXXZUI", + "comment": "", + "state": { + "algo": 30000000000000, + "onl": 2 + } + }, + { + "addr": "XASOPHD3KK3NNI5IF2I7S7U55RGF22SG6OEICVRMCTMMGHT3IBOJG7QWBU", + "comment": "", + "state": { + "algo": 40000000000000, + "onl": 2 + } + }, + { + "addr": "H2AUGBLVQFHHFLFEPJ6GGJ7PBQITEN2GE6T7JZCALBKNU7Q52AVJM5HOYU", + "comment": "", + "state": { + "algo": 10000000000000, + "onl": 2 + } + }, + { + "addr": "GX3XLHSRMFTADVKJBBQBTZ6BKINW6ZO5JHXWGCWB4CPDNPDQ2PIYN4AVHQ", + "comment": "", + "state": { + "algo": 40000000000000, + "onl": 2 + } + }, + { + "addr": "VBJBJ4VC3IHUTLVLWMBON36Y5MPAMPV4DNGW5FQ47GRLPT7JR5PQOUST2E", + "comment": "", + "state": { + "algo": 4524887000000, + "onl": 2 + } + }, + { + "addr": "7AQVTOMB5DJRSUM4LPLVF6PY3Y5EBDF4RZNDIWNW4Z63JYTAQCPQ62IZFE", + "comment": "", + "state": { + "algo": 50000000000000, + "onl": 2 + } + }, + { + "addr": "B4ZIHKD4VYLA4BAFEP7KUHZD7PNWXW4QLCHCNKWRENJ2LYVEOIYA3ZX6IA", + "comment": "", + "state": { + "algo": 40000000000000, + "onl": 2 + } + }, + { + "addr": "G5RGT3EENES7UVIQUHXMJ5APMOGSW6W6RBC534JC6U2TZA4JWC7U27RADE", + "comment": "", + "state": { + "algo": 10000000000000, + "onl": 2 + } + }, + { + "addr": "5AHJFDLAXVINK34IGSI3JA5OVRVMPCWLFEZ6TA4I7XUZ7I6M34Q56DUYIM", + "comment": "", + "state": { + "algo": 20000000000000, + "onl": 2 + } + } + ], + "fees": "Y76M3MSY6DKBRHBL7C3NNDXGS5IIMQVQVUAB6MP4XEMMGVF2QWNPL226CA", + "id": "v1.0", + "network": "mainnet", + "proto": "https://github.com/algorandfoundation/specs/tree/5615adc36bad610c7f165fa2967f4ecfa75125f0", + "rwd": "737777777777777777777777777777777777777777777777777UFEJ2CI", + "timestamp": 1560211200 +}`) + genesisTestnet = []byte(`{ + "alloc": [ + { + "addr": "7777777777777777777777777777777777777777777777777774MSJUVU", + "comment": "RewardsPool", + "state": { + "algo": 125000000000000, + "onl": 2 + } + }, + { + "addr": "A7NMWS3NT3IUDMLVO26ULGXGIIOUQ3ND2TXSER6EBGRZNOBOUIQXHIBGDE", + "comment": "FeeSink", + "state": { + "algo": 100000, + "onl": 2 + } + }, + { + "addr": "LHHQJ6UMXRGEPXBVFKT7SY26BQOIK64VVPCLVRL3RNQLX5ZMBYG6ZHZMBE", + "comment": "Wallet1", + "state": { + "algo": 320000000000000, + "onl": 1, + "sel": "h7Ml/mY/PDCPSj33u72quxaMX99n+/VE+wD94/hMdzY=", + "vote": "R9kxsHbji4DlxPOAyLehy8vaiWyLjWdLGWBLnQ5jjY8=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "CQW2QBBUW5AGFDXMURQBRJN2AM3OHHQWXXI4PEJXRCVTEJ3E5VBTNRTEAE", + "comment": "Wallet10", + "state": { + "algo": 320000000000000, + "onl": 1, + "sel": "p2tiuQ2kqJGG049hHOKNIjid4/u1MqlvgXfbxK4tuEY=", + "vote": "E73cc+KB/LGdDHO1o84440WKCmqvbM4EgROMRyHfjDc=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "HXPCXKQZF4LDL3CE5ERWC5V2BQZTKXUUT3JE6AXXNKLF3OJL4XUAW5WYXM", + "comment": "Wallet11", + "state": { + "algo": 320000000000000, + "onl": 1, + "sel": "ex32mzy8E94GkHGy+cmkRP5JNqFBKGfHtgyUGNxTiW8=", + "vote": "BtYvtmeEBY2JovHUfePTjo3OtOMrhKp3QMeOYl3JFYM=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "Y3FSHQ43JWDSJG7LL5FBRTXHEGTPSWEQBO4CO2RO7KS2Z4ZGBUI7LSEDHQ", + "comment": "Wallet12", + "state": { + "algo": 320000000000000, + "onl": 1, + "sel": "+AtsgunCR8dzO9UGUJ6sFtAaX/E+ssK6JNmvAljQG2E=", + "vote": "Rx21vGt6pnixU2g6NS/TknVtAGbf8hWMJiEtNuV5lb4=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "KXILJUKZJEOS4OCPGENS72JWIZOXGZSK4R235EQPGQ3JLG6R2BBT3ODXEI", + "comment": "Wallet13", + "state": { + "algo": 320000000000000, + "onl": 1, + "sel": "6s09aJVaGfPdbWy5zUSyBJEX/EGVvsn2moUOvakQdBQ=", + "vote": "1oTW6ZpIHhQP6xeNCSqHOZZJYrKiP5D52OHXGzbVz4k=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "R4DCCBODM4L7C6CKVOV5NYDPEYS2G5L7KC7LUYPLUCKBCOIZMYJPFUDTKE", + "comment": "Wallet14", + "state": { + "algo": 320000000000000, + "onl": 1, + "sel": "XsqeQcLz5nPP316ntIp0X9OfJi5ZSfUNrlRSitWXJRg=", + "vote": "r+e0lAD9FnNqOKoWdYdFko13pm9fk/zCJkxVVCqzjaU=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "VKM6KSCTDHEM6KGEAMSYCNEGIPFJMHDSEMIRAQLK76CJDIRMMDHKAIRMFQ", + "comment": "Wallet15", + "state": { + "algo": 320000000000000, + "onl": 1, + "sel": "64Xkj7z3rHZT7syihd0OmgNExHfnOLdLojDJZgtB1d8=", + "vote": "um2RrGFmZ5Coned2WSbo/htYMKjW7XFE5h25M2IFsDs=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "YTOO52XR6UWNM6OUUDOGWVTNJYBWR5NJ3VCJTZUSR42JERFJFAG3NFD47U", + "comment": "Wallet16", + "state": { + "algo": 320000000000000, + "onl": 1, + "sel": "9f9aNsmJxXgMZke5sRYFbfnH5fIFclSosqSl1mK4Vd8=", + "vote": "h8ybeZLDhNG/53oJGAzZ2TFAXDXaslXMzNBOR3Pd+i4=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "EQ5XMOLC2JY5RNFXM725LRVKSTOHWBOQE344ZC6O2K4NW2S3G4XQIJNKAA", + "comment": "Wallet17", + "state": { + "algo": 320000000000000, + "onl": 1, + "sel": "R2LzBwBOEoMEcN6j2Pq9F1RKgrLrqnTyW/iT/tlIRZg=", + "vote": "FnP52cIaWwqpJ6dE3KuM3WSGaz+TNlb/iM7EO0j7EZQ=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "3PUAOGK2PIEH6K5JTQ55SCV3E52KSLDPUAWDURMUNST6IIFCH347X5SNAI", + "comment": "Wallet18", + "state": { + "algo": 320000000000000, + "onl": 1, + "sel": "HfTcCIGCoAgUMCHalBv2dSC2L7XCPqPmCmWmxO26Vqo=", + "vote": "knBY5MY9DkIguN41/ZoKvSGAg92/fhw64BLHUw0o1BU=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "DUQR2JOFHCTNRRI546OZDYLCVBIVRYOSWKNR7A43YKVH437QS3XGJWTQ6I", + "comment": "Wallet19", + "state": { + "algo": 320000000000000, + "onl": 1, + "sel": "DRSm3BAHOXLJLPHwrkKILG/cvHLXuDQYIceHgNPnQds=", + "vote": "9G4AtYrLO26Jc3BsUfNl+0+3IjeHdOOSM+8ASj9x7Tg=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "NWBZBIROXZQEETCDKX6IZVVBV4EY637KCIX56LE5EHIQERCTSDYGXWG6PU", + "comment": "Wallet2", + "state": { + "algo": 320000000000000, + "onl": 1, + "sel": "0eG0edle+ejWcS4Q8DNlITgqaKqNvOtCxNQs+4AncGo=", + "vote": "V4YUoGYXrgDjCluBBbBx2Kq9kkbCZudsuSwmSlCUnK0=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "U2573KTKRCC7I47FJUTW6DBEUN2VZQ63ZVYISQMIUEJTWDNOGSUTL67HBE", + "comment": "Wallet20", + "state": { + "algo": 320000000000000, + "onl": 1, + "sel": "cDT+xkHQJ13RgfkAUoNMfGk890z2C1V4HSmkxbm6gRk=", + "vote": "r66g4ULatIt179X+2embK0RgwoLdPEq3R3uTTMfP9Hk=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "DBGTTXBPXGKL4TBBISC73RMB3NNZIZBSH2EICWZTQRA42QKNA4S2W4SP7U", + "comment": "Wallet3", + "state": { + "algo": 320000000000000, + "onl": 1, + "sel": "DmlAnKrkD8lgUB1ahLsy/FIjbZ0fypaowyDc8GKwWZA=", + "vote": "ROBSmA9EfZitGyubHMTfmw8kSiohADB3n4McvTR8g88=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "XKZWM4PWPLZZWIANNT4S7LU26SPVIKMCDVQAAYRD4G3QJIOJL2X6RZOKK4", + "comment": "Wallet4", + "state": { + "algo": 320000000000000, + "onl": 1, + "sel": "74a0jcs/Y/uCh24vej1rb6CHu64yvW2nYrM0ZUVEhMo=", + "vote": "rwkur9iwJbzNECWvELxzFeJpbZl7dpiThgPJOHnRykg=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "LPBKDDUNKPXE7GAICEDXGTNCAJNC6IFJUSD4IK2H2IIB3OAFXLM3RLLIVQ", + "comment": "Wallet5", + "state": { + "algo": 320000000000000, + "onl": 1, + "sel": "V4ldV+IY068YK/h7Wb6aNRIo8pr2bYQg8KDgFd25xVw=", + "vote": "d2KdyajjKvpukuGmM2MxEC9XDEgjjF/Spsevjd877RI=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "MZZS43WEFY56LV3WXEVLROT3LYFLEBZ536UY3Z3J56S7EI3SYYOJVO6YRM", + "comment": "Wallet6", + "state": { + "algo": 320000000000000, + "onl": 1, + "sel": "BoBmrNpHTxySZ8DIlg5ZlINKwTPd/K75CCdhNzs9alo=", + "vote": "N6v+PVEUn9fLZb+9sQDu5lpCpsXLHY0skx/8bWDqk7Q=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "RP7BOFGBCPNHWPRJEGPNNQRNC3WXJUUAVSBTHMGUXLF36IEHSBGJOHOYZ4", + "comment": "Wallet7", + "state": { + "algo": 320000000000000, + "onl": 1, + "sel": "n0LW+MxrO2S8/AmPClPaGdTDC5PM/MENdEwrm21KmgU=", + "vote": "/e1z3LMbc8C4m9DZ6NCILpv7bZ/yVdmZUp/M32OSUN4=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "RDHKWTWXOE5AOWUWTROSR4WFLAHMUCRDZIA7OFBXXMMRBXGQ4BYQRPOXXU", + "comment": "Wallet8", + "state": { + "algo": 320000000000000, + "onl": 1, + "sel": "AGJ4v2nOA62A8rGm4H56VEo/6QdhVVJUuEASUybDPNI=", + "vote": "eL2GxfrIoG2kuknlGa8I6vPtMbpygYflrye0u/hE4Lg=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "UXPVVSG7EYC7YR7PRVOZKWYYYZPKEXWGYR6XHBMSAV6BHKQEVFYVYJBVQI", + "comment": "Wallet9", + "state": { + "algo": 320000000000000, + "onl": 1, + "sel": "P4tRdjhyJ9dSNItTY+r2+tQmPfHa6oBAzIh4X3df4gM=", + "vote": "VHITXAytk0804xXBLBVKGlRAcAcDSZKcR2fiz4HtWBU=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "GD64YIY3TWGDMCNPP553DZPPR6LDUSFQOIJVFDPPXWEG3FVOJCCDBBHU5A", + "comment": "bank-testnet", + "state": { + "algo": 200000000000000, + "onl": 1, + "sel": "r6aMJIPeqUPB8u4IvOU/wihF+sgqJVsjibvsYHVqj1s=", + "vote": "mPB1VDBFOPSIEFhXo7VJRLxn45ylDSRnO8J1nXQf4f0=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "GFICEF3GYRENRQHINLRPG7TS7TUIOARUIN7KWXWFROSG55BWFFRCRX5DAA", + "comment": "n1-testnet", + "state": { + "algo": 150000000000000, + "onl": 1, + "sel": "38qDzZjLPfernXNx7leElHsl39WLXMSgLHbEACeNgn4=", + "vote": "8ITl30j5PTSDjmR26G3/rZL7IQM3cSfqqxnJSZf3X0w=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "GFY7ND6YSM5OGNSMAJDYCO6O75SWQRCYOJHCWOPYHUYCWQFWML52TWREBQ", + "comment": "n10-testnet", + "state": { + "algo": 150000000000000, + "onl": 1, + "sel": "iwwKBjoUUUePkoG0ldxc0v6i1fIhVySn2l2kWwekn2A=", + "vote": "DaZFFz72XkcUIuPXcEz6VxWj4SVjzMpOwpTfO2k308g=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "VQFEAD2SXHMLJ3BNSGYUHRZZWBOI7HUQZGFFJEKYD3SGNS667FTMPRDC4Y", + "comment": "n11-testnet", + "state": { + "algo": 50000000000000, + "onl": 1, + "sel": "ckpVY6EaDInNeU1WLHQQXNsAaQnh+bpFhzNWzw0ZirI=", + "vote": "4N1HJ9R2TrTEzLOyO1vUWPYi6sUcdAwQWoHQNBR/CME=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "6J7K7FIYKWTT3LSOZKYWAMSZC5RDID4CJ24C2S5DBQ5V7YUIHOBHPAO4KY", + "comment": "n12-testnet", + "state": { + "algo": 50000000000000, + "onl": 1, + "sel": "n16osH+x1UIrzDNa7PCZHn/UtheRoLcTBwGRnx0fTa8=", + "vote": "Tj0inLse0V3sQRPw+5rVQTIWOqTxn7/URDzUaWGHftg=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "G5KCM3LSFV4GHRYQBXGWTNMR5XESE3PIRODD7ZLASPIGOHPV7CO7UKLZFM", + "comment": "n13-testnet", + "state": { + "algo": 50000000000000, + "onl": 1, + "sel": "tveXF/sDXqBXQY52IEMuvTeVguKzPfN8GLdKgtv3gRg=", + "vote": "uwQJnVuqEtdGnWbbfu+TTLe++56z8wQCzv22IDioALE=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "XNQAMZMMLQV3TGYGJYYLYZUHP4YNEKAJM6RAMJ5SBXFLS3XDBIUVGCZPH4", + "comment": "n14-testnet", + "state": { + "algo": 50000000000000, + "onl": 1, + "sel": "8xotecjUoo1YVzWME3ib9uh+kPUNnzsFcuHrjxxhjZM=", + "vote": "oQ/iakoP5B6gTTm0+xfHHGFS4Ink30I6FWUGkxRNfo8=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "WXCLU5C6QH6KPVNAHNBGFUMC5JAOQCZP3HF76OT2TH3IAI3XTSPCLVILSU", + "comment": "n15-testnet", + "state": { + "algo": 200000000000000, + "onl": 1, + "sel": "NRxs0rM5dov2oZrf6XrFSmG9CRlS3Bmzt0be7uF/nHw=", + "vote": "R8xKtpYYNuTuTqMui/qzxYpc1m8KpbaK/eizYxVQDaY=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "7NRVO2ABPGFRX3374TIJZ46BR72CCSHKTR6PG5VVYNLUPWUVXGOU3O5YQA", + "comment": "n16-testnet", + "state": { + "algo": 200000000000000, + "onl": 1, + "sel": "IQG+jgm2daCxMLxm/f9tTVrDk/hD0ZhB5dxDQn47BSE=", + "vote": "CGwAHrq3QFFlsP7NmHed+Xx4BwFsE2f6dB30Os75KxY=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "537URFEXANB7M6UVND6WDM75DPRRORDXWFLSOG7EGILSKDIU4T32N4KAN4", + "comment": "n17-testnet", + "state": { + "algo": 200000000000000, + "onl": 1, + "sel": "SdLlaWBe8B1JanMq0Y7T1Z9C8dKhI36MQiSffXQt7Lo=", + "vote": "k4Xr6Bg6VpcY0GKwfr6kI89KqOihmCOToLLuIgFjv9c=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "ZNQXW7V5MISZFOZGVLAHKXS7GLWLXCLRPZTTIAZSTFRZPYTC54NWDZ6XZY", + "comment": "n18-testnet", + "state": { + "algo": 200000000000000, + "onl": 1, + "sel": "TNMELlR1C+r4OmGVp9vc9XlehgD3a0EwfrepuMiDe+c=", + "vote": "060veVAG/L2r2IAjqs2TcYy2cthocqrhgrCCoP5lzZ4=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "G3WQEPSGZOQVVJ2H3F6ICMHRIE2JL6U3X3JDABWJRN4HNDUJIAT4YTOGXA", + "comment": "n19-testnet", + "state": { + "algo": 300000000000000, + "onl": 1, + "sel": "ktbtHTm1mUU5u/VMrOuMujMgemUf496zilQsGBynsxQ=", + "vote": "XHXYdLvxKIIjtlmwHVqxvtAyRDE+SQR1tpzgXoNo5FA=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "2YNZ5XDUHYXL2COTVLZBRYV2A7VETFKQZQCPYMQRBOKTAANHP37DUH5BOI", + "comment": "n2-testnet", + "state": { + "algo": 150000000000000, + "onl": 1, + "sel": "u7lR9NcWfssuMvFYuqCi5/nX0Fj9qBKbE0B2OpRhmMg=", + "vote": "/UGQ/1dcp7OTmguYALryqQYRj0oMWhs/ahAbQTL/mRA=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "IH5Z5UZCZKNAH5OICUGHFEYM2JDMJRUSIUV4TZEQYHRNS3T2ROOV32CDIA", + "comment": "n20-testnet", + "state": { + "algo": 300000000000000, + "onl": 1, + "sel": "Jbcg+BVB6EOTe42U0dq1psQfoFZItb6Phst22z33j60=", + "vote": "8Y1QY+WJIziffLecmnr0ZRGJFKtA3oVALQoD3nVKlt8=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "FFJZOPQCYSRZISSJF33MBQJGGTIB2JFUEGBJIY6GXRWEU23ONC65GUZXHM", + "comment": "n3-testnet", + "state": { + "algo": 150000000000000, + "onl": 1, + "sel": "+K8AsLfvuTEuHMANNp2LxGuotgEjFtqOjuR/o4KR6LA=", + "vote": "SerMKyY37A1jFkE0BdrP+vuTdVn9oOJc5QjC5f98Dz8=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "ZWYIEI37V6HI62ZQCPJ5I6AIVKZP6JVCBQJKZEQQCWF4A4G2QGFENKS5XU", + "comment": "n4-testnet", + "state": { + "algo": 150000000000000, + "onl": 1, + "sel": "SmhBpQdh23++6xC01unged2JU1Wgm2zZ8v5LQiG/VqA=", + "vote": "U2lZo9ahjkKBvcS3qSWsmSx+PGI/m6OtnQrQOH1iuII=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "V32YQ6LMMT7X6MML35KOX4MKY7LXWEH4JETZYKAXQ5RX4ZQQ6FAJJ6EGJQ", + "comment": "n5-testnet", + "state": { + "algo": 150000000000000, + "onl": 1, + "sel": "0yRtE7WSj32D5e/ov4o22ZgipQvqJZ6nx9NX1LdxFJI=", + "vote": "scoN8x6Eq0bV4tBLT5R59jU+8gmHgh/6FX6mfV2tIKY=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "OEFWPZHFT25CSDHFRFW62JANGQLB5WD25GJBCGYTTPHFUMAYYD7SEAIVDI", + "comment": "n6-testnet", + "state": { + "algo": 150000000000000, + "onl": 1, + "sel": "dWChUcA1ONX3iNEvHu9GST67XRePhAv6jd3XWt5clvI=", + "vote": "rTfQ/l3lEfGQtzwjFii5ir2nCLSU+RT+0xI5af/XDEU=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "KCQLDL4GCVDLDYW5PYK7GJTUGHYRJ6CZ4QSRIZTXVRUIUAMDKYDFNUIFHU", + "comment": "n7-testnet", + "state": { + "algo": 150000000000000, + "onl": 1, + "sel": "gNXMo6XiZvuQs2mtomJZtra7XiZHySIOWLuWivu4iso=", + "vote": "okgQcI/L7YDAMOyqrLKs6CUB91k+mMFfMTaEb+ixvyY=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "UMMQNIYQXSI4VBGBXJUQ64ABURY6TPR7F4M5CMCOHYMB7GPVIZETZRNRBM", + "comment": "n8-testnet", + "state": { + "algo": 150000000000000, + "onl": 1, + "sel": "ukzMIkE2U33xKq6LGX19NBLirZNANQAf3oiZtlkn5ls=", + "vote": "HYHBaeVeN0DXYBNjRBuGtZqrBr3bSBC1YDQrv93dNrc=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "2INEY2MWIWIUNQS24YVXKT4M3RIKMEZGTVAOJG47N7EOJE7MKXOC6GJSMU", + "comment": "n9-testnet", + "state": { + "algo": 150000000000000, + "onl": 1, + "sel": "7aUtPCawOYpPYjVd6oZOnZ+1CZXApr8QR4q1cOkVyWo=", + "vote": "kcq1XWHnMrjbv/fvMmzIfGZzDtJtdL7i70lpWZ0kGi0=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "IE4C3BNWT4EYKPUZXGWDOOKBTJFVOYAZKBCWFYRC37U7BJKBIUH6NEB7SQ", + "comment": "pp1-testnet", + "state": { + "algo": 50000000000000, + "onl": 1, + "sel": "C3PdYqoDjrjyaGvZ6M/W0E56Mv5BXdtRwj7+4unpxDM=", + "vote": "8fdNikU3nMNyZb3AZlNTnsfsytvrd8bK2b/dYQgJj30=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "7WCI7XPEMWY6XNWHG2VXGYGDLHPTJ333CZ2WBGGUHCSYPTXPBWYCHZYTSE", + "comment": "pp2-testnet", + "state": { + "algo": 25000000000000, + "onl": 1, + "sel": "l3K4aA15T42mTM+QE7GpOzbOcth6hMljBxna7gSR8IA=", + "vote": "NsjSVQJj4XxK5Tt0R7pvU6wQB0MRKHDwC9F2bfUX/vM=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "WYX5JGDYM7TBTMBBEE2OI4GC4KVCTLB2P67B3PUQQS4OMUERE7NIIZDWO4", + "comment": "pp3-testnet", + "state": { + "algo": 25000000000000, + "onl": 1, + "sel": "YmLs97jSdlbYU1H0PwZdzo6hlp0eyBwJ+ydM9ggEENI=", + "vote": "GeDnbm9KKEu2dZ1FACwI0NsVWgoU0udpZef06IiTdfQ=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "2GJF4FEEPNCFKNYSOP6EOQGDQQCGDXPQHWE474DCKP5QO3HFBO73IBLBBY", + "comment": "u1-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "NHZ3VOL34MVWENM72QB6ZBRDMFJTU6R57HAJALSBERH4BNAGR4QDYYBT7A", + "comment": "u10-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "PTLGEQAIGTDWHPKA3IC5BL5UQE52XDZHQH7FUXRV4S6ZBRR5HGZENQ7LTQ", + "comment": "u100-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "3IE2GDYYSI56U53AQ6UUWRGAIGG5D4RHWLMCXJOPWQJA2ABF2X2OLFXGJE", + "comment": "u11-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "IAMUOCM2SEISQZYZZYTLHKSAALDJIXS2IQRU2GPZUOZWB2NLMFZPJSQ7VQ", + "comment": "u12-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "54GKXNGS7HNFHZGO7OIWK3H2KPKZYWSARW7PV4ITVTNCA65K6ESRKI6N3U", + "comment": "u13-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "5ZSFGF66FIJMMRORTYD2PLDAN67FA2J7LF3IYF4ZKD4DJHLEBYJ76DXGVU", + "comment": "u14-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "DY7K3FLRZTW2ZTYVOC4TCGK4JBL7NSJ4GR4BU252QNAVOCVTGEBCPCSJME", + "comment": "u15-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "JG4JQZNYP2524UDVRPPIMSFCIVQPVXLB5AKHM76VXIIRFNMIN3ROIYW65E", + "comment": "u16-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "7J4QX5DVIXSWBC2NJB44LPPUJXOAJQFMBCOS4EDI3XOE5WS76IY7WFTBQI", + "comment": "u17-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "6SA2WG5XM5Q6SSMBRK3TOHY552A75RVANBQQMKTT67PLUN44T3CJZAQOPM", + "comment": "u18-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "64DCC5CMTM4SMMO3QRTY3EDCHS73KDSNNH2XZL262DBK2LR4GJRETWUWIE", + "comment": "u19-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "TQ2B4MTCC6TARNEP4QPPMCKNBBNXKFTQKPVLAFC5XXRR2SWV5DICZELJOY", + "comment": "u2-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "ATNCIRLQLVZ7I4QBGW54DI6CY4AJVBQBPECVNS645RBMYDTK6VV55HXFUU", + "comment": "u20-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "4LP77VEVJ7QNESED4GICPRBZUNP7ZLKKLEVBRDSKX5NZSUFXPSEA575K5E", + "comment": "u21-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "7D34RBEHVI3A7YTQWOUTCSKNQYS5BDBN4E647DOC6WDVOLHPDPSSBY4MWI", + "comment": "u22-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "UMMKTTPNHIURGX24K7UYJ7T3WBB5J7OYBOQJ5WLPRG3BDYWJAEJLVBNHME", + "comment": "u23-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "EOPSQC3QTL7QJ4AQ2J4OJIJMKQLTMIEETJI7OFWYADIMHDWMHQ6MWCTUMQ", + "comment": "u24-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "XT3AVLURALOWTIMGZKB37J2M22NUQCRXTL4DJZHSTPCGLNQKVL7MR3MKFM", + "comment": "u25-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "WS63FDTLLYHC2NS7NXTEO7RPLNMAFM2D2BPJLTMAQJWPR2JCNYTTRMSOAE", + "comment": "u26-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "P5S5GGUHOMVOKWOZPJO74MBYVRXQWDBW6AOTHQZVKJKFGM7VBU6CNR4ATI", + "comment": "u27-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "PXVAI3MUYH4WWJXEQP7XNH3YIMO5ZBAFJWYUL7DOGPAHALE4K6GZBF4THU", + "comment": "u28-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "VGTKWLFANSULZAFDGBONHF55VVKE4V4F63JRDB66XM4K6KCQX6CL22WPRE", + "comment": "u29-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "QB2OTQ6DKUEJFP66A37ASIT4O3UZUOX24DAMWU2D3GCBDIYIXSIDHSXO4E", + "comment": "u3-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "4F6LA64ZLFN33ATWJ74UPAX56OLTXPL74SS5ATXUL7RGX7NKEFKMAWUQYE", + "comment": "u30-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "3JBNL7BZECXKYWZRPWETNL65XEYMAHLC6G3MZN2YMPFL3V7XSDXZEMBHVQ", + "comment": "u31-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "4M2QSKTXKPPZMNUAQ4UDS7ASMQCEUE4WTWGV6AM326425IJ64UNZBCIRGA", + "comment": "u32-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "J37V3LXHPRRKBODXNMNYNUJQIICCFFC4O4XB4YJCPVUAVZNOUG5DWDCEIA", + "comment": "u33-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "I75JBQHNYEYM3J742RBVW4W6RR3YY3BLG2PKO4PXYLVNEX5L646ASDJOOY", + "comment": "u34-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "ZHEIOZ7E2BEBCCKK5QM7DCZAOPTTONMQWHNJ6FOLKBHY466VON6DCZERD4", + "comment": "u35-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "4QMGP4C6OMSCNJI25H7UQGBFHRHL7KXAEQI57JNAXEO2EW3VT6D6LODT5Y", + "comment": "u36-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "KRED3JOLOJE3SLL5NGHAWSUGEMHCYJLD6PX43SIJYN2GC6MS6HPUPPO2LY", + "comment": "u37-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "SVFLDISKS4PDMJKOB6DVVVN6NQ776FHZMGWCOUQVQCH6GXTKCXIHTLYRRQ", + "comment": "u38-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "7IWGAPZ4VWRZLP2IHFSAC3JYOKNAZP6ONBNGGWUWHAUT7F23YFT3XKGNVU", + "comment": "u39-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "O2QVZMKATOIEU2OD4X42MLXAYVRXLRDKJTDXKBFCN3PCKN2Z3PUS5HKIVA", + "comment": "u4-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "H2YN73YPRWKY4GT744RRD65CXSQZO7MK72MV4RDHTIBV6YQUB2G56TVF2Y", + "comment": "u40-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "WGUAFWHRRX7VXPO3XXYCJL5ELO6REUGD57HRMBKTALT2TTXOLSHNOUEQCE", + "comment": "u41-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "RYHCD7GPAEBRV657FJJAG2ZZUDVPR66IU7CA5Y7UDMYSEEIWR4QDNSPLYQ", + "comment": "u42-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "BKTO5TKB4L57YWTZKQBOQ37EWH2HVXGJPXP3L6YSYOAWP3CYYBWLZ2PHTQ", + "comment": "u43-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "FL7LZ57VQQNW5NDJK2IKEAHIXRTB7VFBJEA2MIAEK3QVZPIBGLYW7XSZDY", + "comment": "u44-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "MXXQXZS2TAMIULLXXLX6MM6AHJAOQLHEIB2U3LR4KYKK7ZKRVUSHTU62QA", + "comment": "u45-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "UGOPPKTJQ2KPHU5I56733IMT3B7ECT5O44GW2FYX5SNDVIEDG72Z5GC5IA", + "comment": "u46-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "Y7MGWPRBHQN2PF3I2A3RWCQMVA42VR6FJONJ3W26WGKE4KMCGCVJIDLHEY", + "comment": "u47-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "NNFIWU43AUEZIUIQQECDXM3HRPUEJMPPZLXTM4ZFJKHWSZ2FEGCVMMJUBQ", + "comment": "u48-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "RN3HTSJKSUO6OECM3OPDFQQ2FYZWEY2OWAQGSMQSGY4DI7JJ4HBV2OIJJU", + "comment": "u49-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "OLYQUMZKLYDX2FVHECURBX4SRQSLMIIWN7D7VRJG7B6DS3IU6M5WYVNAAY", + "comment": "u5-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "PIG4P6JA2WDG7HBBR4FFDMVUCUD5Y5CTQ3K3KY34Y4AMT3CWEMVIKQLZZI", + "comment": "u50-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "QIDX47JRS37LRIYVY744SV7KTFGYXY5ABEK2VALNZCMN2H4FBLO7WWKYRM", + "comment": "u51-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "VQZCPUMOYIGCXOK2AK4XYYLWJNRBLS457IL4OSBKGVBHFZ5QPLTCUOTW4A", + "comment": "u52-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "WE2AIYHXI2LHABITCPTZRBTLFT54HPL4MKIR4HTASARNGCCZLXXDE67H3M", + "comment": "u53-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "HAIGM3LXXVKDCGCNQELNOBFZKP6C4A2ZY464F4TB7GWSVDN6I4SI7EOZUE", + "comment": "u54-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "MVZLGPXT6DZQIORE4PIO7NZD7QMJOZZZCOEVPZ3EQX2V4WG3PFU3BXUGDI", + "comment": "u55-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "MB5XJGVVKQU7NSEWWP65QW6H4JVEQYPA5626J4NGQP2E4BUMXRTEGW5X5Y", + "comment": "u56-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "EODZLNWFSRYZKLLF2YAOST2CYQCBRQGXPFQJLDW4CCMYFTYKBSWMF6QUAU", + "comment": "u57-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "LPAMNP7GJC5CNOMWRDII47WWYPF3TOVEIBDSSJA6PKOCPZ5AKRUWMIU2OM", + "comment": "u58-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "THRYS4MAIMEKG7BSAZ4EOKCVUJ7HA6AOCTK2UOKDGZ4TF7Q4BRVTBOUSYU", + "comment": "u59-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "7V7YITMPBTJ3IHHS2D35PVWRZGNFYWWQVRMTI4QP2CBPSKNDRGG66W2HFQ", + "comment": "u6-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "FHA2V46TK5CW66HQPOMLTH5PSKX2JX2IWLWZIYJUZ2RI7SK6HSSBTJBNHM", + "comment": "u60-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "7EJAXCVH7XLWDCWSXID4FNZ6T2SZRA4S7XIZOWA74ITAB272ZF2T5LSWSE", + "comment": "u61-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "K5L3YNZPU6SVNJOWAOKULCWBPIBNMR2VBCASVI4NWDM2APZ6GL36DFDR5Y", + "comment": "u62-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "5BY6RFBNUYHBYH4E4AWVMEOMI7YFKX7X3IPB5GRGAHH4BSXHIL34P3H43A", + "comment": "u63-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "BX2UBG5VCT2ASTGXHVG5NS6VVCYVB6GLKBN4NAAN7ABSTP7BMYCX2T2WEY", + "comment": "u64-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "37JPBYKXMWF6DO3FFWW53LBQCG636MTC7WG6DTRAPDFVXUIATFOMFR5ZLQ", + "comment": "u65-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "ODSPT3NISYMGEE3TJ6U6JCVC44L7DUCPHIV2QMPPRKBWJDALALGVCAPMRE", + "comment": "u66-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "CQA775B5TCU72Y2BNL6VCURBVJE45QV77RXHQ5KYRMMP6NCQ5BR7XJRYRA", + "comment": "u67-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "3Q4SYOBDOAVXUUTKBXEFFSK3BQMUQX5ORZPDA4PHB56KJJONPFFJ7YZ6HU", + "comment": "u68-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "K23ME4QVDHSJWMGUHPGCL2OODAGBHIBW2KGYLLIR3UAEFD5ZW2KFB4WJ34", + "comment": "u69-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "UD2OLL24RFDFMAKK7CCHKFIABPAP7ET4CYQUEYCJVGEIEJUAMDOGJZT26Y", + "comment": "u7-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "KYXWZODLYDHTDMRUBOGOEV42G6H6KJ2JSBFZBP6XNWT42A6QEMEW23JWAM", + "comment": "u70-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "V464X6D3XJVVJ372FFC2NBBDZLBNQA6H55J57WJMMSNOLHOJQ5UF3EUGNY", + "comment": "u71-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "K27ODRPQARZM3236D2XC27QIV27GO2MUR65RGAJKO7UACIFYHG5QKPOCFU", + "comment": "u72-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "FT3JD6TXUZOLOMN4O5CFZYSIHR4T5XJIF2YNV6WGEORNO2X65QW3VUP77I", + "comment": "u73-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "WOTGZ4WOQ4S7YWVAOQ52GGOQPYQI2M7EPZENR27AOZLYFIEJDI3RYFB7OU", + "comment": "u74-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "46MGTGNCTAC62NVNAVXAGP7PUJJIW5GXYYTSUDURCBSRZEDLGME7ICGE4E", + "comment": "u75-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "MBTXWM5M5XQNUEKLBTW7GPU4LFPUETQQPVUBRCOA7FQ47H4J727NFRKKQE", + "comment": "u76-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "4MCTFKPQCY25X6QARHGVD75OYUMQAAU5QLWCE2EM37NWOS7IFJSABMGKBI", + "comment": "u77-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "PY6K3OGCXZVYQYZVA7W3MVZCAU5AFAWQ5J5THILXYIBYCKCGH4ELFU6TNU", + "comment": "u78-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "4ABEMED4I7UYU6CJSLWYQXQHOK2XCQ443BSHR3SL7QJGXNYJ5QCYILSSNU", + "comment": "u79-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "AXBINC5KA3I6IF3JAMKYQU3JLYTA5P2U4PUW3M4L53NEBNCRLHDHHOT2HY", + "comment": "u8-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "5SXA2C6CGZ63OYDY5G4NFLIPJLKCZAMQWLMD2CBNSHUEXVS3ZYHAQCI5TI", + "comment": "u80-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "EVP6MJIZWN6EE64TKEI4ANETP25MHYVXFWESU626TFA5VDVC75KSBGAA54", + "comment": "u81-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "QAUV22GPBAOCO2JGAJF7U474S5SKXVWSZ7KG6P22P4MH3GNBGEJXAVDQLM", + "comment": "u82-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "4FOOFGIWV4H7AXTEJXV2C4ONZ5NXAMUDKJSZDLSKACZ4JA4SWIU6UTLZAU", + "comment": "u83-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "ARUMRBUW3HBQXE4QAL25PPVWAJSKGORTNUIOW3VA5GAMDECOVNYC7GJJS4", + "comment": "u84-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "EJGCYTFUZPJDL2JBZJFQXKZIYJUDB7IBF3E2BH6GXWYWXUHSBCKYFJUKSU", + "comment": "u85-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "FJMEFROCSGQ7C7IXMAPUST37QTQ2Y4A7RMLGK6YTUGHOCLOEL5BDE4AM2M", + "comment": "u86-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "4V635E2WOGIKKWZ6QMYXDWQLYTUKRN7YAYADBQPETS75MKCR66ZC5IEG5M", + "comment": "u87-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "AFJB4HWJLTMMA45VZAJJSUOFF7NROAEEMGT4Z3FQI5APWY472SJ6RNBWU4", + "comment": "u88-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "BYO56YQOSRBUTNPXYO4XDMG7FU7SIP3QGVKAYQIJVJ4UIIMBRG3E4JMVD4", + "comment": "u89-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "FQJO4LDTXEVQ2ZBFYDEAOYPQQZCZTMASMSXJ6V7LBYKOTFSCBUKKIU3DXA", + "comment": "u9-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "WUCEVFNJGUNLMNG2AJMVYJRGQUFXRAFVX2ZRT7AC47WS6IRHPXHSUZ4NUA", + "comment": "u90-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "5J5Q72IHCVAK5NE54ZI2RUZUF3HN2EAQEYQ674H3VX4UUHBMRYAZFRQDIY", + "comment": "u91-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "2LK2SZ3L4PWUXXM4XYFFSCFIV7V5VQJUDFVK7QXK6HJL4OUQKQLWG77EUI", + "comment": "u92-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "QUWHMJLFQAIIG5LV7NK5VNESUUW23RINBSHKKKQDIV4AP56RSTYSNZHDRQ", + "comment": "u93-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "YJEGUEJ2UW2ABLO6XI5QIHQID5ZKUDUDQPHQEN7MH5SS2FLZ573CHRHCZM", + "comment": "u94-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "XOUVBGEZMDVYPES4MGTAEBYU5O6LOCOH27ZJ3ML7ATWEU63N6IWW6F4BLM", + "comment": "u95-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "6CFS2YVK2IMVVFBGGHSPUQBIKMNWRRB44EIUUB4EFXAL7IOJXAHRGXKAGA", + "comment": "u96-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "W5ITKFRKK265A4WKF7IRCZ4MCC7HM3INCJGKPPH3AEKDFYMOJJ4FDLQWYI", + "comment": "u97-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "MBMU3IODI6OFX34MBDMNTD6WSVA6B3XLDVB3IHZJQY3TZUYBPKRNFTUQSM", + "comment": "u98-testnet", + "state": { + "algo": 2000000000000 + } + }, + { + "addr": "CKNVTB7DPRZO3MB64RQFPZIHCHCC4GBSTAAJKVQ2SLYNKVYPK4EJFBCQKM", + "comment": "u99-testnet", + "state": { + "algo": 2000000000000 + } + } + ], + "fees": "A7NMWS3NT3IUDMLVO26ULGXGIIOUQ3ND2TXSER6EBGRZNOBOUIQXHIBGDE", + "id": "v1.0", + "network": "testnet", + "proto": "https://github.com/algorand/spec/tree/a26ed78ed8f834e2b9ccb6eb7d3ee9f629a6e622", + "rwd": "7777777777777777777777777777777777777777777777777774MSJUVU", + "timestamp": 1560210455 +}`) + genesisBetanet = []byte(`{ + "alloc": [ + { + "addr": "7777777777777777777777777777777777777777777777777774MSJUVU", + "comment": "RewardsPool", + "state": { + "algo": 125000000000000, + "onl": 2 + } + }, + { + "addr": "A7NMWS3NT3IUDMLVO26ULGXGIIOUQ3ND2TXSER6EBGRZNOBOUIQXHIBGDE", + "comment": "FeeSink", + "state": { + "algo": 100000, + "onl": 2 + } + }, + { + "addr": "E6JSNTY4PVCY3IRZ6XEDHEO6VIHCQ5KGXCIQKFQCMB2N6HXRY4IB43VSHI", + "comment": "Wallet1", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "KsJHGwqm40hKgq91j3e5/RgK8XDiWloeN8FfYB4UKHs=", + "vote": "21YWFk+gtv9AP0vXPXHubfXSWwstKfbKwIIPOYB395I=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "SEMQ3EH6AHVCXZDHCDH3OYBJJGGLHDUFGYVCTJUUJMLO4J5F4E6AIXH3R4", + "comment": "Wallet10", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "kRtZiTWtKjFbx58DxEllyZ0/7mQYjT4gdilgNLEEcIQ=", + "vote": "QN1+DlX+2JE8O0NiFTSH+50sXpTYT79HVIYf0YRp1P4=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "BIKIMTXSESQTR5BMPELZO2TFASGCGSXZ2ZA2MSHEUYLJNNXUGJCX6JV2TU", + "comment": "Wallet11", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "GVGFHDix++jaHjeVqHQd2tvlkaJzPpkFOqM/xOV8HEs=", + "vote": "Qb20Au5yVWckwkgLS1VrCA867xrBwMwpWvvdVeOgbfE=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "7ERQUUQLQ5K6GVYVAFE25Z42OQMI5JCSBOWORHRT4GMSC3GZFWCOBI67YE", + "comment": "Wallet12", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "kBuLytQUQIp9NrAyYbXZk4L9Qf7voFh7B3t4zsdX9tc=", + "vote": "SOB4dO+4R93RvzXZop17kn4wS/YjnmELqQapQ0PDFZM=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "MIZXEAYWBLOMNXCU52OF6ZTYH7LP7W47SKLHIGKLTGEXJHQGD7RHGMUPQQ", + "comment": "Wallet13", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "KqpOt2cIsDwGbnNhzRzET4/UR0NhPhKSCG6g86ewFQA=", + "vote": "FIwKS4PBidGgLmAqYMPlxOP0H2LlCF9GC9lWE8Jl4As=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "77FPBCDQOMSOUWOY47HWPGOKSTLQITEZ7QR7GU4TOV3KVIFV2YS3WQG2OI", + "comment": "Wallet14", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "M71rgLk28vIZgk73ag1K+2cH33J9viIzXnsrbISmc4Q=", + "vote": "B7O1giNLhEIJWCcXUmZ9X4j/dsVw9Zm5dmXDbn+3ack=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "JDTPB2DSAH42CRL6SKZ3BZ37WIGCHAYRO6DT6PBJNV47566EVQLEOINXEY", + "comment": "Wallet15", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "sj1Ap7Wz5GmfQfAJTiv1+eoL0q/2IsER14jxMtxsQok=", + "vote": "P1igemO61V2fz9nb4jaiOaFbpnUZPhKuyNx3j09swSY=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "H6BA5HI7TTKCP76QFTO4EO4MKTOI6XM6R75QRZLGV2H4VAOXIMGCXGIH5Y", + "comment": "Wallet16", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "RjsQgzT6eUx88673bdCQm12TmDLi93v92s+E3TK1XWA=", + "vote": "tQtvPw70hZDbrROzsSz27UdN6EIPj2dQFTtzsY6pCVQ=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "FCHLCNFIQ3L5QELMQDADI6BU2ANK2A2ICKXXG7ACJBNEAB64J7UJUPJHJE", + "comment": "Wallet17", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "22Dvgroawrb1g7LotUhbTOV/7g1Rn410I1X8CmDeT0A=", + "vote": "SGXiNwAfMRI00SYVpVClqTNJcwBrQF3X77DsWSAO5jo=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "LKH4JTUIOE6I4PH4HVJN6PYZ23WGGWDVJGHM2YXI6IYV5TEECQSTNKMQ2E", + "comment": "Wallet18", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "uzGW1wXnBiny4kB4JSpEbCVQvKE8BeO+/o/pdkgfFaY=", + "vote": "ahu0YwixBhpEc+Xvw5oqgwDMnemXHWk8g/Uf/EI5nmA=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "QFH2SS4MGPFNUUDMNLKIUKX5HKAZRXT765WH7WTUBAQNEM7IJAVKAE6NWM", + "comment": "Wallet19", + "state": { + "algo": 400000000000000, + "onl": 1, + "sel": "eE4Wcuz8VeGclgU99Q9rDpehNR+yP2afFYuDAxb/Ebo=", + "vote": "4wsLw785udvYCpn5jzdLqcEHmIQIbRPmbyPt4oTLD2U=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "6SKIRCMLFSSY3EJUC6QGFM3TFIJH72ZYUHX7GCUBDBUBYCAHJBJ5PWB344", + "comment": "Wallet2", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "j7WaD43EwoxM5U18kMWn5HfIdn/ICVuMmsj3O5EbFWM=", + "vote": "jAuOIqeQH81zZs4+6YBircvi63xXMN1MIABcOiuzXXs=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "OYD4RZDUBQBVQL4WEPTBVLU6YC7HWHDAS4MMTLQ643Q3O7JRQW6FTWXIWQ", + "comment": "Wallet20", + "state": { + "algo": 400000000000000, + "onl": 1, + "sel": "9LdCYfMPglvbManNcmVLztu/yPhPPkaRaSKMzj5E24w=", + "vote": "ZbN0ELPvL5QizuLvVc7oInsju+irjDRcdYDNnKJV2bg=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "SSKILTKR47YW2IXCJCNUK66ATVLMU53IV5SEC2IXQ4WEPV5EKCAVPCEKMA", + "comment": "Wallet3", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "4cxWnAD3DoIel3OuRqOpYgtWP7J873g688P4pXPVhBc=", + "vote": "keW3j4bRW0uvd6ofaDNUuMBdz/v/eWZsLhdFIOlXWCg=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "FE4FDICQLO63S33NL75GBDKAKPGX7B3UMRBBSM5V2JYO4LCLRSE4HQ4YJI", + "comment": "Wallet4", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "AILWKIbgQzCSPaaYAMFek1mu6uWYqm2QoIvP97h9wFg=", + "vote": "YXmnzyrRI4c16DauzENAK9bOqatN7qjLAbWUp0L6qXM=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "2N3Y42EA3OPXCOFPKRH4HFOF6FX7QUT45A7CZH4WXGGQDDYSHP6NZGNL24", + "comment": "Wallet5", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "lOU6PeVi+AT4lc2tj90AoNQyw3un0Smzk9sOpKCWI1k=", + "vote": "PztZkAup9rAMUreL+HQXCy7mbM39PZ5xl+YiTT4L9YE=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "UJ3HDASRQG2QRPZUS5TOESFIMIDB4ELNE7DO2WGO5LJQ2KT32VGFGGCQKA", + "comment": "Wallet6", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "rPMShsyg18Ho9JOQQjcG2yhPMBM0JIgZsr5ndy+0buo=", + "vote": "TFVn1TMHAmcM+St5QLhaFG/dlSGqqlTdGjgjcfSax5M=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "QBQ5ODCH6PWCB5TFQVCOFLHSJKN6NYYB3E3HPCJJTTNRVM5XD3B3KPWFJA", + "comment": "Wallet7", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "cxhpl3wBnc9bVW6G5ePiya8nzPvUUaprIoTWvTXJmpY=", + "vote": "W8tVBEdWGDArQFj43qXDw18LRJKaGjgZWUv54tsus+A=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "WILFZPBQMJ7GYSPNA6JPXIZZUZ27XWDJ2NKC7WIODXXGOF73C4TEDEHE3U", + "comment": "Wallet8", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "SMSZnIm3GSD1Dr5AEq5ksxxCIqPIrn19WSDNtJSJuiM=", + "vote": "absDJtKafyc4KbrB1GnLcFGv8xQjuqB46gPXXTpIsTU=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "4LSVIF5EY2BQZ6GENL6GT4SQTKX3UVDTBDJXFESGY7GI7FXHZA522KMG5I", + "comment": "Wallet9", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "h3aKVPyQSpXAI2zcDD2f1CCBqf9fQd4Z+oJjQ6erFLI=", + "vote": "nNfIrFtpPR6zo4hH6F7HCMA44PDcNOEWtDVRf7dnKe4=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "IDUTJEUIEVSMXTU4LGTJWZ2UE2E6TIODUKU6UW3FU3UKIQQ77RLUBBBFLA", + "comment": "bank", + "state": { + "algo": 100000000000000, + "onl": 1, + "sel": "6Rax2zpOehfDXHyyvMFJwc22A//Pm6rxW4MiEBGIwog=", + "vote": "5JbOqqGn1Ypw+uH3t2i61DcjWYo1AslT0jyOGgcVC6Y=", + "voteKD": 10000, + "voteLst": 3000000 + } + }, + { + "addr": "PNWOET7LLOWMBMLE4KOCELCX6X3D3Q4H2Q4QJASYIEOF7YIPPQBG3YQ5YI", + "comment": "pp1", + "state": { + "algo": 50000000000000 + } + }, + { + "addr": "F5FALDSUFYO5LQU4OQY2HPZTXSUPRHUAERZ7IDG5QCBC76AOHEPK2VUJ34", + "comment": "pp2", + "state": { + "algo": 50000000000000 + } + } + ], + "fees": "A7NMWS3NT3IUDMLVO26ULGXGIIOUQ3ND2TXSER6EBGRZNOBOUIQXHIBGDE", + "id": "v1.0", + "network": "betanet", + "proto": "https://github.com/algorand/spec/tree/a26ed78ed8f834e2b9ccb6eb7d3ee9f629a6e622", + "rwd": "7777777777777777777777777777777777777777777777777774MSJUVU", + "timestamp": 1564572341 +}`) + genesisDevnet = []byte(`{ + "alloc": [ + { + "addr": "7777777777777777777777777777777777777777777777777774MSJUVU", + "comment": "RewardsPool", + "state": { + "algo": 125000000000000, + "onl": 2 + } + }, + { + "addr": "A7NMWS3NT3IUDMLVO26ULGXGIIOUQ3ND2TXSER6EBGRZNOBOUIQXHIBGDE", + "comment": "FeeSink", + "state": { + "algo": 100000, + "onl": 2 + } + }, + { + "addr": "ZQ45INL2IMX66LP4ZEI2WNPESMGQKKVQADISKXNXRJKNXKJFKANOVMRYCQ", + "comment": "Wallet1", + "state": { + "algo": 300000000000000, + "onl": 1, + "sel": "jx49tNyOGVz/yKkmjmJIFzta5SyeJxyYD7znjiwwlRs=", + "vote": "CG6x+hWIFGJcSZVFuuRvtDD0CF1SCpeO4Hxe4YTVojQ=", + "voteKD": 10000, + "voteLst": 10000000 + } + }, + { + "addr": "FCEV42VP5ESVQY7NZT2B327NXE53HHND5TCIXYRIANBEH2PBOD3W4EQPTM", + "comment": "Wallet10", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "HexL5RAyE37UC/fd1UH/6Kwbomit6MkLtpe1Pi7USbU=", + "vote": "bTqiNA6+GWmeLQjdiuKvMpiBEFfh/SGRTUewF/BPzUY=", + "voteKD": 10000, + "voteLst": 10000000 + } + }, + { + "addr": "4HT4YQU2WPVV6EYPWYJ3L3IF2MOXQEBMJJOWMGVCBQY2TFFOB5QXMV5EPY", + "comment": "Wallet11", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "hP67tzuIoZrXYO9Ln4I8ce/jYtfhpEaqAFoP0Gk4mSk=", + "vote": "lA0se5QSffyxIjKlMntM/0ge5QtDaLGnwI/0GZC3BfU=", + "voteKD": 10000, + "voteLst": 10000000 + } + }, + { + "addr": "VKAXPXHZQX5Z6ECNEDV6RFKM3QANXTGX23Z7O3PPRLCTQGZ4WHVCYJB5X4", + "comment": "Wallet12", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "N5ivQdIOTRHAuaazCPwqGB6R0vzs4oE5C/HX5QoWJ1w=", + "vote": "c2KiifMNoLuCpEnvLL97c6b9YuRdqhKntXyQizV7rQA=", + "voteKD": 10000, + "voteLst": 10000000 + } + }, + { + "addr": "HWNVDWBYNO42ZEH46UVHV26HY5ABWZ2EGY5RY4SZY5SGPGMBCWPVP4GRHU", + "comment": "Wallet13", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "lBU/qgAYZFI4HOWNA4ENWjNyS2QMNdcuh/tgeJgfuBY=", + "vote": "+3YbNs94emm4vUzQm+rIYcKwdF5PuHcnKL5ork5pUZg=", + "voteKD": 10000, + "voteLst": 10000000 + } + }, + { + "addr": "AK3JQTFREJMQQXKYY7DGDGMXVRDUKK63DKNXJG3BTP6EMLZ62JD455Y5TM", + "comment": "Wallet14", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "zIJa2IwZb5wBeXgEDN7oI9Z8mgBXySRJYulW/3klDqQ=", + "vote": "bOLmPR2wdEohQfA3OzEr5SuJyZfsyCQoOS4kxBIhO8s=", + "voteKD": 10000, + "voteLst": 10000000 + } + }, + { + "addr": "75DBTPH3U4NBJ5IYLVEFSBVN3PIRF3OGBKTSQGJFLQBFN6MYXPZLDTQ4QI", + "comment": "Wallet15", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "gjGwMoylS7mmmn0xcO5s91X6jyqMvyfOQykBTUqdSZo=", + "vote": "SeNznA406oiGF/8CL/SUNZuQ9Er6o8syd3giX34jRmo=", + "voteKD": 10000, + "voteLst": 10000000 + } + }, + { + "addr": "5K7GCWCI4MT2LWAWFP4WZUHU4WNB6AWZ5NEJCX2DSIRBEYECOW6WJSHVME", + "comment": "Wallet16", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "C6eOqo65UBvVkzp8UpO7Wp/v89rfIChsHR/2C5nPcSE=", + "vote": "87ZcLZx04HFyf6XUKkm9inOdYmCrnXyWw84BMBBwtUc=", + "voteKD": 10000, + "voteLst": 10000000 + } + }, + { + "addr": "ZJMREOYU3USMDCQDMWVRECY6JGZD6LC44JTY4TC55ZYTXTQUBFRBEIPY6A", + "comment": "Wallet17", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "l77BpNvhHEEiAjY+RNi8ht62+qgb90DXNqKzB+4uHew=", + "vote": "9iuQKJNBXjiKTRhPHPYqEJlmLo0g04in4ABdo7elkFA=", + "voteKD": 10000, + "voteLst": 10000000 + } + }, + { + "addr": "XLI4GVZKYHXVK4MU2YRQMT6TZVCB772NLWW7TEGQIGCH4JXSZA6PARNBVQ", + "comment": "Wallet18", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "gAweEod0UC6CN1fjFt/ZFVbyw2kON3hcG5HSPUY7X7A=", + "vote": "1/Vyqjf5sHiZrq5StV+lOK8I0NZCSUbQ5p4QiCFW4a0=", + "voteKD": 10000, + "voteLst": 10000000 + } + }, + { + "addr": "XLQBCY6TK5JSDOIMC4U22ZQ7O35VHJS6QWQUQY6KFV2HD4T3QXCNOEZHMY", + "comment": "Wallet19", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "P3zYirarJ4QIMGz2h4SK6rCD5wJMrGPtfIop99ZTCYg=", + "vote": "J3kmHUeU21FvOP46A9OB1QUamatT32oBy2dmZQFVfi0=", + "voteKD": 10000, + "voteLst": 10000000 + } + }, + { + "addr": "LVFCXGJ4H2QXLXS67H7JPQ6HDLSIQ4UBDJ7RNWKI6UUG4QC3GZX53R3BLA", + "comment": "Wallet2", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "VyZiFcfly5SCIZhs79IbxYbfYw8od38ecs6vm8UH760=", + "vote": "hGNbwxyqnTEq8rw3d6Ezt4kYDVsk49X4Ousi6z2MPaU=", + "voteKD": 10000, + "voteLst": 10000000 + } + }, + { + "addr": "2BMHSRKHDYBJTW673MLERUX24MOGSXOPFWYLMAVW3QCFRNRB4M6ZDNAFCI", + "comment": "Wallet20", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "jHCe2j1mpV9GWRqdhHt3NtZpppVbkc1o5jUaykpdDkw=", + "vote": "nw8oxQjT5IS8GKBWucYtKQB3kY3ywzgMjyY0+6Xi5+s=", + "voteKD": 10000, + "voteLst": 10000000 + } + }, + { + "addr": "3LGSIMLC44UB4NQHSFVM6ZDE7BVJFJVDVYESZZ4SJU4EYDZQV32CIH6JM4", + "comment": "Wallet3", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "jGQIdnRvYaokSw7iRG29AdSR81OFqgdnU3sFvd/g0gI=", + "vote": "3bu4xBXbFh/Bpqtdwg9eqlUXGa6nkVE6QDf2gSr7kng=", + "voteKD": 10000, + "voteLst": 10000000 + } + }, + { + "addr": "UXECRB7D5NDQEKVK5ISA5FUKPX6UC3XFI5JEJEYV3CUHJRMEYY2ZBUGVHI", + "comment": "Wallet4", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "F2GF2fUODTFsk6NyGAOYDAsS2pdeqxJ0XgJT4C+xh50=", + "vote": "SLw4LA5EdOiUHhQ2r99fsKMytbJCQZWaUxuDrgigyLo=", + "voteKD": 10000, + "voteLst": 10000000 + } + }, + { + "addr": "IXPBHLMKILBRSG3ZTM34UFORUQ2XHTZMEXK5LODNZTS3M3IPKPE6ZOQADY", + "comment": "Wallet5", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "KqUKfEEC7pkR+4K4Tnp+V+Rwu/yXAbuAyXlU83ZGPNA=", + "vote": "7vyFvIGRixNbisSJW23yfMW2wE4xRRm41IlgzaZDgjQ=", + "voteKD": 10000, + "voteLst": 10000000 + } + }, + { + "addr": "H5AEMBGBAVVEZOLGNX22OMNDJLEU7PG5VSCBNHB46PKRBBKQBZWA7R2DNA", + "comment": "Wallet6", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "kthetjPfSMTOa04Oo3ZQ7GGfXNNE4nCNC8tYVW9qFNE=", + "vote": "WQBnwqMm6f9+GKR0Sz+X6ej65KCkB2I971dYtuoG7tk=", + "voteKD": 10000, + "voteLst": 10000000 + } + }, + { + "addr": "436JPU37D2J5EGLMQCVKU236ZAMJM3XUXGGK35MZ43P3LAB3AWBZS73HME", + "comment": "Wallet7", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "o8RSgaF1leM7Mdux9hk/cxypO4XMEZRZjrw6R3JqKZc=", + "vote": "e44SozE14TV9B3Raam7B2Fm9rxRH9O4ruRJmdErr55w=", + "voteKD": 10000, + "voteLst": 10000000 + } + }, + { + "addr": "TP5S4EO7CBRZMXSNMNEEJ7232DCRXHK5YN7W7SKA2W4A2Y5JBFFWCKJJKU", + "comment": "Wallet8", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "r/wqmzTQaVYnPBZPGL8W+5i/FYqNz0/1FqewGAyRiiw=", + "vote": "XxrwQh/SE72Q/IA18YNEUAnujR3V+ntd94S554HyQBw=", + "voteKD": 10000, + "voteLst": 10000000 + } + }, + { + "addr": "DMOZSZ3TE65RR5UX2KLDD56LGI75W6LEVOD275S56W2AYCGDD4UYGU4URM", + "comment": "Wallet9", + "state": { + "algo": 500000000000000, + "onl": 1, + "sel": "+LIJ3xi3SuoSuAK/RKirPUMFNltJucuFMa9H9KxB5vQ=", + "vote": "+irtKnZKr1d4G7Fqvc7i4QYqN/NEXunPzdneHKboMUU=", + "voteKD": 10000, + "voteLst": 10000000 + } + }, + { + "addr": "RGKUXFHCDDGN7EJHSDF533KVTCS5EFHAR57SCUV3RDOTQKIXAFRB6ME25M", + "comment": "bank", + "state": { + "algo": 100000000000000, + "onl": 1, + "sel": "SKZZJvgPQImzzn9Ft5e7ZWitXR/1TZwk2aaBM35YcIc=", + "vote": "jB8AMuWZn1m5go/dIVzB6DFIV8hD7UpcLLV2XGjK8FM=", + "voteKD": 10000, + "voteLst": 10000000 + } + }, + { + "addr": "VF4LPDP2OCQIN4Q2PJ4VZV725NBHMGUZZC35SO3EHX7XUB7SRMLFNRHVB4", + "comment": "pp1", + "state": { + "algo": 50000000000000 + } + }, + { + "addr": "ZJOL26NAJMBNMAOKKTBRZTFAPSODASPKV4Z2A4EYMNMTZVT65CEAIBFTNQ", + "comment": "pp2", + "state": { + "algo": 50000000000000 + } + } + ], + "fees": "A7NMWS3NT3IUDMLVO26ULGXGIIOUQ3ND2TXSER6EBGRZNOBOUIQXHIBGDE", + "id": "v1.0", + "network": "devnet", + "proto": "https://github.com/algorandfoundation/specs/tree/3a83c4c743f8b17adfd73944b4319c25722a6782", + "rwd": "7777777777777777777777777777777777777777777777777774MSJUVU" +}`) +} diff --git a/cmd/goal/node.go b/cmd/goal/node.go index a7dcad550d..67fccbf41e 100644 --- a/cmd/goal/node.go +++ b/cmd/goal/node.go @@ -16,11 +16,14 @@ package main +//go:generate ./bundle_genesis_json.sh + import ( "encoding/base64" "encoding/json" "errors" "fmt" + "io/ioutil" "net" "os" "path/filepath" @@ -53,6 +56,7 @@ var newNodeDestination string var newNodeArchival bool var newNodeIndexer bool var newNodeRelay string +var newNodeFullConfig bool var watchMillisecond uint64 var abortCatchup bool @@ -92,6 +96,7 @@ func init() { createCmd.Flags().BoolVarP(&newNodeIndexer, "indexer", "i", localDefaults.IsIndexerActive, "Configure the new node to enable the indexer feature (implies --archival)") createCmd.Flags().StringVar(&newNodeRelay, "relay", localDefaults.NetAddress, "Configure as a relay with specified listening address (NetAddress)") createCmd.Flags().StringVar(&listenIP, "api", "", "REST API Endpoint") + createCmd.Flags().BoolVar(&newNodeFullConfig, "full-config", false, "Store full config file") createCmd.MarkFlagRequired("destination") createCmd.MarkFlagRequired("network") @@ -559,8 +564,15 @@ var createCmd = &cobra.Command{ Run: func(cmd *cobra.Command, _ []string) { // validate network input - validNetworks := map[string]bool{"mainnet": true, "testnet": true, "devnet": true, "betanet": true} - if !validNetworks[newNodeNetwork] { + validNetworks := map[string][]byte{ + "mainnet": genesisMainnet, + "testnet": genesisTestnet, + "betanet": genesisBetanet, + "devnet": genesisDevnet, + } + var genesisContent []byte + var ok bool + if genesisContent, ok = validNetworks[newNodeNetwork]; !ok { reportErrorf(errorNodeCreation, "passed network name invalid") } @@ -586,44 +598,28 @@ var createCmd = &cobra.Command{ localConfig.EnableLedgerService = localConfig.Archival localConfig.EnableBlockService = localConfig.Archival - // locate genesis block - exePath, err := util.ExeDir() - if err != nil { - reportErrorln(errorNodeCreation, err) - } - firstChoicePath := filepath.Join(exePath, "genesisfiles", newNodeNetwork, "genesis.json") - secondChoicePath := filepath.Join("var", "lib", "algorand", "genesis", newNodeNetwork, "genesis.json") - thirdChoicePath := filepath.Join(exePath, "genesisfiles", "genesis", newNodeNetwork, "genesis.json") - paths := []string{firstChoicePath, secondChoicePath, thirdChoicePath} - correctPath := "" - for _, pathCandidate := range paths { - if util.FileExists(pathCandidate) { - correctPath = pathCandidate - break - } - } - if correctPath == "" { - reportErrorf("Could not find genesis.json file. Paths checked: %v", strings.Join(paths, ",")) - } - // verify destination does not exist, and attempt to create destination folder if util.FileExists(newNodeDestination) { reportErrorf(errorNodeCreation, "destination folder already exists") } destPath := filepath.Join(newNodeDestination, "genesis.json") - err = os.MkdirAll(newNodeDestination, 0766) + err := os.MkdirAll(newNodeDestination, 0766) if err != nil { reportErrorf(errorNodeCreation, "could not create destination folder") } // copy genesis block to destination - _, err = util.CopyFile(correctPath, destPath) + err = ioutil.WriteFile(destPath, genesisContent, 0644) if err != nil { reportErrorf(errorNodeCreation, err) } // save config to destination - err = localConfig.SaveToDisk(newNodeDestination) + if newNodeFullConfig { + err = localConfig.SaveAllToDisk(newNodeDestination) + } else { + err = localConfig.SaveToDisk(newNodeDestination) + } if err != nil { reportErrorf(errorNodeCreation, err) } diff --git a/config/localTemplate.go b/config/localTemplate.go index 53c2c3f778..da9453c149 100644 --- a/config/localTemplate.go +++ b/config/localTemplate.go @@ -460,13 +460,21 @@ func (cfg Local) DNSBootstrap(network protocol.NetworkID) string { return strings.Replace(cfg.DNSBootstrapID, "", string(network), -1) } -// SaveToDisk writes the Local settings into a root/ConfigFilename file +// SaveToDisk writes the non-default Local settings into a root/ConfigFilename file func (cfg Local) SaveToDisk(root string) error { configpath := filepath.Join(root, ConfigFilename) filename := os.ExpandEnv(configpath) return cfg.SaveToFile(filename) } +// SaveAllToDisk writes the all Local settings into a root/ConfigFilename file +func (cfg Local) SaveAllToDisk(root string) error { + configpath := filepath.Join(root, ConfigFilename) + filename := os.ExpandEnv(configpath) + prettyPrint := true + return codecs.SaveObjectToFile(filename, cfg, prettyPrint) +} + // SaveToFile saves the config to a specific filename, allowing overriding the default name func (cfg Local) SaveToFile(filename string) error { var alwaysInclude []string diff --git a/crypto/compactcert/structs.go b/crypto/compactcert/structs.go index d8a6e2100d..dd1a4f3156 100644 --- a/crypto/compactcert/structs.go +++ b/crypto/compactcert/structs.go @@ -29,8 +29,6 @@ type Params struct { ProvenWeight uint64 // Weight threshold proven by the certificate SigRound basics.Round // The round for which the ephemeral key is committed to SecKQ uint64 // Security parameter (k+q) from analysis document - - EnableBatchVerification bool // whether ED25519 batch verification is enabled } // CompactOneTimeSignature is crypto.OneTimeSignature with omitempty diff --git a/crypto/merklearray/proof.go b/crypto/merklearray/proof.go index c4f35a304e..ed05b76e66 100644 --- a/crypto/merklearray/proof.go +++ b/crypto/merklearray/proof.go @@ -82,3 +82,17 @@ func (p *SingleLeafProof) GetFixedLengthHashableRepresentation() []byte { func (p *SingleLeafProof) ToProof() *Proof { return &p.Proof } + +// GetConcatenatedProof concats the verification path to a single slice +// This function converts an empty element in the path (i.e occurs when the tree is not a full tree) +// into a sequence of digest result of zero. +func (p *SingleLeafProof) GetConcatenatedProof() []byte { + digestSize := p.HashFactory.NewHash().Size() + proofconcat := make([]byte, digestSize*int(p.TreeDepth)) + for i := 0; i < int(p.TreeDepth); i++ { + if p.Path[i] != nil { + copy(proofconcat[i*digestSize:(i+1)*digestSize], p.Path[i]) + } + } + return proofconcat +} diff --git a/crypto/merklearray/proof_test.go b/crypto/merklearray/proof_test.go index 17498e3f86..547268515a 100644 --- a/crypto/merklearray/proof_test.go +++ b/crypto/merklearray/proof_test.go @@ -132,3 +132,85 @@ func TestProofSerializationOneLeafTree(t *testing.T) { } } + +func TestConcatenatedProofsMissingChild(t *testing.T) { + partitiontest.PartitionTest(t) + a := require.New(t) + + array := make(TestArray, 7) + for i := 0; i < 7; i++ { + crypto.RandBytes(array[i][:]) + } + + tree, err := Build(array, crypto.HashFactory{HashType: crypto.Sha512_256}) + a.NoError(err) + + p, err := tree.ProveSingleLeaf(6) + a.NoError(err) + + newP := SingleLeafProof{Proof: Proof{TreeDepth: p.TreeDepth, Path: []crypto.GenericDigest{}, HashFactory: p.HashFactory}} + + computedPath := recomputePath(p) + + newP.Path = computedPath + err = Verify(tree.Root(), map[uint64]crypto.Hashable{6: array[6]}, newP.ToProof()) + a.NoError(err) +} + +func TestConcatenatedProofsFullTree(t *testing.T) { + partitiontest.PartitionTest(t) + a := require.New(t) + + array := make(TestArray, 8) + for i := 0; i < 8; i++ { + crypto.RandBytes(array[i][:]) + } + + tree, err := Build(array, crypto.HashFactory{HashType: crypto.Sha512_256}) + a.NoError(err) + + p, err := tree.ProveSingleLeaf(6) + a.NoError(err) + + newP := SingleLeafProof{Proof: Proof{TreeDepth: p.TreeDepth, Path: []crypto.GenericDigest{}, HashFactory: p.HashFactory}} + + computedPath := recomputePath(p) + + newP.Path = computedPath + err = Verify(tree.Root(), map[uint64]crypto.Hashable{6: array[6]}, newP.ToProof()) + a.NoError(err) +} + +func TestConcatenatedProofsOneLeaf(t *testing.T) { + partitiontest.PartitionTest(t) + a := require.New(t) + + array := make(TestArray, 1) + crypto.RandBytes(array[0][:]) + + tree, err := Build(array, crypto.HashFactory{HashType: crypto.Sha512_256}) + a.NoError(err) + + p, err := tree.ProveSingleLeaf(0) + a.NoError(err) + + newP := SingleLeafProof{Proof: Proof{TreeDepth: p.TreeDepth, Path: []crypto.GenericDigest{}, HashFactory: p.HashFactory}} + + computedPath := recomputePath(p) + + newP.Path = computedPath + err = Verify(tree.Root(), map[uint64]crypto.Hashable{0: array[0]}, newP.ToProof()) + a.NoError(err) +} + +func recomputePath(p *SingleLeafProof) []crypto.GenericDigest { + var computedPath []crypto.GenericDigest + proofconcat := p.GetConcatenatedProof() + for len(proofconcat) > 0 { + var d crypto.Digest + copy(d[:], proofconcat) + computedPath = append(computedPath, d[:]) + proofconcat = proofconcat[len(d):] + } + return computedPath +} diff --git a/crypto/secp256k1/secp256_test.go b/crypto/secp256k1/secp256_test.go index ef2a3a3790..3ee7d2c0b1 100644 --- a/crypto/secp256k1/secp256_test.go +++ b/crypto/secp256k1/secp256_test.go @@ -12,6 +12,8 @@ import ( "encoding/hex" "io" "testing" + + "github.com/algorand/go-algorand/test/partitiontest" ) const TestCount = 1000 @@ -84,6 +86,8 @@ func TestSignatureValidity(t *testing.T) { } func TestInvalidRecoveryID(t *testing.T) { + partitiontest.PartitionTest(t) + _, seckey := generateKeyPair() msg := csprngEntropy(32) sig, _ := Sign(msg, seckey) @@ -95,6 +99,8 @@ func TestInvalidRecoveryID(t *testing.T) { } func TestSignAndRecover(t *testing.T) { + partitiontest.PartitionTest(t) + pubkey1, seckey := generateKeyPair() msg := csprngEntropy(32) sig, err := Sign(msg, seckey) @@ -111,6 +117,8 @@ func TestSignAndRecover(t *testing.T) { } func TestSignDeterministic(t *testing.T) { + partitiontest.PartitionTest(t) + _, seckey := generateKeyPair() msg := make([]byte, 32) copy(msg, "hi there") @@ -129,6 +137,8 @@ func TestSignDeterministic(t *testing.T) { } func TestRandomMessagesWithSameKey(t *testing.T) { + partitiontest.PartitionTest(t) + pubkey, seckey := generateKeyPair() keys := func() ([]byte, []byte) { return pubkey, seckey @@ -137,6 +147,8 @@ func TestRandomMessagesWithSameKey(t *testing.T) { } func TestRandomMessagesWithRandomKeys(t *testing.T) { + partitiontest.PartitionTest(t) + keys := func() ([]byte, []byte) { pubkey, seckey := generateKeyPair() return pubkey, seckey @@ -174,6 +186,8 @@ func signAndRecoverWithRandomMessages(t *testing.T, keys func() ([]byte, []byte) } func TestRecoveryOfRandomSignature(t *testing.T) { + partitiontest.PartitionTest(t) + pubkey1, _ := generateKeyPair() msg := csprngEntropy(32) @@ -187,6 +201,8 @@ func TestRecoveryOfRandomSignature(t *testing.T) { } func TestRandomMessagesAgainstValidSig(t *testing.T) { + partitiontest.PartitionTest(t) + pubkey1, seckey := generateKeyPair() msg := csprngEntropy(32) sig, _ := Sign(msg, seckey) @@ -204,6 +220,8 @@ func TestRandomMessagesAgainstValidSig(t *testing.T) { // Useful when the underlying libsecp256k1 API changes to quickly // check only recover function without use of signature function func TestRecoverSanity(t *testing.T) { + partitiontest.PartitionTest(t) + msg, _ := hex.DecodeString("ce0677bb30baa8cf067c88db9811f4333d131bf8bcf12fe7065d211dce971008") sig, _ := hex.DecodeString("90f27b8b488db00b00606796d2987f6a5f59ae62ea05effe84fef5b8b0e549984a691139ad57a3f0b906637673aa2f63d1f55cb1a69199d4009eea23ceaddc9301") pubkey1, _ := hex.DecodeString("04e32df42865e97135acfb65f3bae71bdc86f4d49150ad6a440b6f15878109880a0a2b2667f7e725ceea70c673093bf67663e0312623c8e091b13cf2c0f11ef652") diff --git a/daemon/algod/api/server/v2/dryrun_test.go b/daemon/algod/api/server/v2/dryrun_test.go index f5c850e317..0ca7d882fb 100644 --- a/daemon/algod/api/server/v2/dryrun_test.go +++ b/daemon/algod/api/server/v2/dryrun_test.go @@ -382,9 +382,14 @@ func checkAppCallPass(t *testing.T, response *generated.DryrunResponse) { } else if response.Txns[0].AppCallMessages == nil || len(*response.Txns[0].AppCallMessages) < 1 { t.Error("no response app msg") } else { - messages := *response.Txns[0].AppCallMessages - assert.GreaterOrEqual(t, len(messages), 1) - assert.Equal(t, "PASS", messages[len(messages)-1]) + assert.NotNil(t, response.Txns[0].AppCallMessages) + for idx := range response.Txns { + if response.Txns[idx].AppCallMessages != nil { + messages := *response.Txns[idx].AppCallMessages + assert.GreaterOrEqual(t, len(messages), 1) + assert.Equal(t, "PASS", messages[len(messages)-1]) + } + } } } @@ -1522,3 +1527,74 @@ int 1 logResponse(t, &response) } } + +func TestDryrunScratchSpace(t *testing.T) { + partitiontest.PartitionTest(t) + a := require.New(t) + + approvalOps, err := logic.AssembleString(` +#pragma version 5 +txn GroupIndex +int 3 +== +bnz checkgload +txn GroupIndex +store 254 +b exit +checkgload: +int 0 +gloads 254 +int 0 +== +int 1 +gloads 254 +int 1 +== +&& +int 2 +gloads 254 +int 2 +== +&& +assert +exit: +int 1`) + require.NoError(t, err) + + ops, err := logic.AssembleString("int 1") + clst := ops.Program + require.NoError(t, err) + + sender, err := basics.UnmarshalChecksumAddress("47YPQTIGQEO7T4Y4RWDYWEKV6RTR2UNBQXBABEEGM72ESWDQNCQ52OPASU") + a.NoError(err) + + txns := make([]transactions.SignedTxn, 0, 4) + apps := make([]generated.Application, 0, 4) + for appIdx := basics.AppIndex(1); appIdx <= basics.AppIndex(4); appIdx++ { + txns = append(txns, txntest.Txn{ + Type: protocol.ApplicationCallTx, + Sender: sender, + ApplicationID: appIdx}.SignedTxn()) + apps = append(apps, generated.Application{ + Id: uint64(appIdx), + Params: generated.ApplicationParams{ + ApprovalProgram: approvalOps.Program, + ClearStateProgram: clst, + }, + }) + } + dr := DryrunRequest{ + ProtocolVersion: string(dryrunProtoVersion), + Txns: txns, + Apps: apps, + Accounts: []generated.Account{ + {Address: sender.String(), Status: "Offline", Amount: 100_000_000}, // sender + }, + } + var response generated.DryrunResponse + doDryrunRequest(&dr, &response) + checkAppCallPass(t, &response) + if t.Failed() { + logResponse(t, &response) + } +} diff --git a/daemon/algod/api/server/v2/handlers.go b/daemon/algod/api/server/v2/handlers.go index f93467e80a..f8f84392ce 100644 --- a/daemon/algod/api/server/v2/handlers.go +++ b/daemon/algod/api/server/v2/handlers.go @@ -388,20 +388,15 @@ func (v2 *Handlers) GetProof(ctx echo.Context, round uint64, txid string, params return internalError(ctx, err, "building Merkle tree", v2.Log) } - proof, err := tree.Prove([]uint64{uint64(idx)}) + proof, err := tree.ProveSingleLeaf(uint64(idx)) if err != nil { return internalError(ctx, err, "generating proof", v2.Log) } - proofconcat := make([]byte, 0) - for _, proofelem := range proof.Path { - proofconcat = append(proofconcat, proofelem[:]...) - } - stibhash := block.Payset[idx].Hash() response := generated.ProofResponse{ - Proof: proofconcat, + Proof: proof.GetConcatenatedProof(), Stibhash: stibhash[:], Idx: uint64(idx), Treedepth: uint64(proof.TreeDepth), diff --git a/data/transactions/logic/evalAppTxn_test.go b/data/transactions/logic/evalAppTxn_test.go index ad120600a5..cb1a16408d 100644 --- a/data/transactions/logic/evalAppTxn_test.go +++ b/data/transactions/logic/evalAppTxn_test.go @@ -33,6 +33,8 @@ import ( ) func TestInnerTypesV5(t *testing.T) { + partitiontest.PartitionTest(t) + v5, _, _ := MakeSampleEnvWithVersion(5) // not alllowed in v5 TestApp(t, "itxn_begin; byte \"keyreg\"; itxn_field Type; itxn_submit; int 1;", v5, "keyreg is not a valid Type for itxn_field") @@ -43,6 +45,8 @@ func TestInnerTypesV5(t *testing.T) { } func TestCurrentInnerTypes(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, ledger := MakeSampleEnv() TestApp(t, "itxn_submit; int 1;", ep, "itxn_submit without itxn_begin") TestApp(t, "int pay; itxn_field TypeEnum; itxn_submit; int 1;", ep, "itxn_field without itxn_begin") @@ -93,6 +97,8 @@ func TestCurrentInnerTypes(t *testing.T) { } func TestFieldTypes(t *testing.T) { + partitiontest.PartitionTest(t) + ep, _, _ := MakeSampleEnv() TestApp(t, "itxn_begin; byte \"pay\"; itxn_field Sender;", ep, "not an address") TestApp(t, Obfuscate("itxn_begin; int 7; itxn_field Receiver;"), ep, "not an address") @@ -117,6 +123,8 @@ func appAddr(id int) basics.Address { } func TestAppPay(t *testing.T) { + partitiontest.PartitionTest(t) + pay := ` itxn_begin itxn_field Amount @@ -162,6 +170,8 @@ func TestAppPay(t *testing.T) { } func TestAppAssetOptIn(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, ledger := MakeSampleEnv() // Establish 888 as the app id, and fund it. ledger.NewApp(tx.Receiver, 888, basics.AppParams{}) @@ -221,6 +231,8 @@ int 1 } func TestRekeyPay(t *testing.T) { + partitiontest.PartitionTest(t) + pay := ` itxn_begin itxn_field Amount @@ -244,6 +256,8 @@ func TestRekeyPay(t *testing.T) { } func TestRekeyBack(t *testing.T) { + partitiontest.PartitionTest(t) + payAndUnkey := ` itxn_begin itxn_field Amount @@ -268,6 +282,8 @@ func TestRekeyBack(t *testing.T) { } func TestDefaultSender(t *testing.T) { + partitiontest.PartitionTest(t) + pay := ` itxn_begin itxn_field Amount @@ -287,6 +303,8 @@ func TestDefaultSender(t *testing.T) { } func TestAppAxfer(t *testing.T) { + partitiontest.PartitionTest(t) + axfer := ` itxn_begin int 77 @@ -348,6 +366,8 @@ func TestAppAxfer(t *testing.T) { } func TestExtraFields(t *testing.T) { + partitiontest.PartitionTest(t) + pay := ` itxn_begin int 7; itxn_field AssetAmount; @@ -368,6 +388,8 @@ func TestExtraFields(t *testing.T) { } func TestBadFieldV5(t *testing.T) { + partitiontest.PartitionTest(t) + pay := ` itxn_begin int 7; itxn_field AssetAmount; @@ -390,6 +412,8 @@ func TestBadFieldV5(t *testing.T) { } func TestBadField(t *testing.T) { + partitiontest.PartitionTest(t) + pay := ` itxn_begin int 7; itxn_field AssetAmount; @@ -413,6 +437,8 @@ func TestBadField(t *testing.T) { } func TestNumInnerShallow(t *testing.T) { + partitiontest.PartitionTest(t) + pay := ` itxn_begin int 1 @@ -453,6 +479,8 @@ func TestNumInnerShallow(t *testing.T) { // TestNumInnerPooled ensures that inner call limits are pooled across app calls // in a group. func TestNumInnerPooled(t *testing.T) { + partitiontest.PartitionTest(t) + pay := ` itxn_begin int 1 @@ -489,6 +517,8 @@ func TestNumInnerPooled(t *testing.T) { } func TestAssetCreate(t *testing.T) { + partitiontest.PartitionTest(t) + create := ` itxn_begin int acfg @@ -515,6 +545,8 @@ func TestAssetCreate(t *testing.T) { } func TestAssetFreeze(t *testing.T) { + partitiontest.PartitionTest(t) + create := ` itxn_begin int acfg ; itxn_field TypeEnum @@ -704,6 +736,8 @@ func TestKeyReg(t *testing.T) { } func TestFieldSetting(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, ledger := MakeSampleEnv() ledger.NewApp(tx.Receiver, 888, basics.AppParams{}) ledger.NewAccount(appAddr(888), 10*MakeTestProto().MinTxnFee) @@ -744,6 +778,8 @@ func TestFieldSetting(t *testing.T) { } func TestInnerGroup(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, ledger := MakeSampleEnv() ledger.NewApp(tx.Receiver, 888, basics.AppParams{}) // Need both fees and both payments @@ -762,6 +798,8 @@ txn Sender; itxn_field Receiver; } func TestInnerFeePooling(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, ledger := MakeSampleEnv() ledger.NewApp(tx.Receiver, 888, basics.AppParams{}) ledger.NewAccount(appAddr(888), 50_000) @@ -828,6 +866,8 @@ txn Sender; itxn_field Receiver; // constructed not what can be submitted, so it tests what "bad" fields cause // immediate failures. func TestApplCreation(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, _ := MakeSampleEnv() p := "itxn_begin;" @@ -912,6 +952,8 @@ func TestApplCreation(t *testing.T) { // error. These are not exhaustive, but certainly demonstrate that // transactions.WellFormed is getting a crack at the txn. func TestApplSubmission(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, ledger := MakeSampleEnv() ledger.NewApp(tx.Receiver, 888, basics.AppParams{}) // Since the fee is moved first, fund the app @@ -956,6 +998,8 @@ func TestApplSubmission(t *testing.T) { } func TestInnerApplCreate(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, ledger := MakeSampleEnv() ledger.NewApp(tx.Receiver, 888, basics.AppParams{}) ledger.NewAccount(appAddr(888), 50_000) @@ -1021,6 +1065,8 @@ int 5000; app_params_get AppGlobalNumByteSlice; !; assert; !; assert; int 1 } func TestCreateOldAppFails(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, ledger := MakeSampleEnv() ledger.NewApp(tx.Receiver, 888, basics.AppParams{}) ledger.NewAccount(appAddr(888), 50_000) @@ -1082,6 +1128,8 @@ int 1 } func TestSelfReentrancy(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, ledger := MakeSampleEnv() ledger.NewApp(tx.Receiver, 888, basics.AppParams{}) ledger.NewAccount(appAddr(888), 50_000) @@ -1096,6 +1144,8 @@ int 1 } func TestIndirectReentrancy(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, ledger := MakeSampleEnv() call888 := TestProg(t, `itxn_begin int appl; itxn_field TypeEnum @@ -1123,6 +1173,8 @@ int 1 // TestInnerAppID ensures that inner app properly sees its AppId. This seems // needlessly picky to test, but the appID used to be stored outside the cx. func TestInnerAppID(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, ledger := MakeSampleEnv() logID := TestProg(t, `global CurrentApplicationID; itob; log; int 1`, AssemblerMaxVersion) ledger.NewApp(tx.Receiver, 222, basics.AppParams{ @@ -1149,6 +1201,8 @@ int 222 // bit to create the call, and the app itself consumes 1, so it ends up being // about 690 (see next test). func TestInnerBudgetIncrement(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, ledger := MakeSampleEnv() gasup := TestProg(t, "pushint 1", AssemblerMaxVersion) ledger.NewApp(tx.Receiver, 222, basics.AppParams{ @@ -1176,6 +1230,8 @@ itxn_submit; } func TestIncrementCheck(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, ledger := MakeSampleEnv() gasup := TestProg(t, "pushint 1", AssemblerMaxVersion) ledger.NewApp(tx.Receiver, 222, basics.AppParams{ @@ -1207,6 +1263,8 @@ int 1 // TestInnerTxIDs confirms that TxIDs are available and different func TestInnerTxIDs(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, ledger := MakeSampleEnv() txid := TestProg(t, "txn TxID; log; int 1", AssemblerMaxVersion) ledger.NewApp(tx.Receiver, 222, basics.AppParams{ @@ -1235,6 +1293,8 @@ itxn Logs 0 // TestInnerGroupIDs confirms that GroupIDs are unset on size one inner groups, // but set and unique on non-singletons func TestInnerGroupIDs(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, ledger := MakeSampleEnv() gid := TestProg(t, "global GroupID; log; int 1", AssemblerMaxVersion) ledger.NewApp(tx.Receiver, 222, basics.AppParams{ @@ -1295,6 +1355,8 @@ itxn Logs 0 // TestGtixn confirms access to itxn groups func TestGtixn(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, ledger := MakeSampleEnv() two := TestProg(t, "byte 0x22; log; int 1", AssemblerMaxVersion) ledger.NewApp(tx.Receiver, 222, basics.AppParams{ @@ -1379,6 +1441,8 @@ int 1 // TestGtxnLog confirms that gtxn can now access previous txn's Logs. func TestGtxnLog(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, ledger := MakeSampleEnv() two := TestProg(t, "byte 0x22; log; int 1", AssemblerMaxVersion) ledger.NewApp(tx.Receiver, 222, basics.AppParams{ @@ -1406,6 +1470,8 @@ int 1 // TestGtxnApps confirms that gtxn can now access previous txn's created app id. func TestGtxnApps(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, ledger := MakeSampleEnv() appcheck := TestProg(t, ` gtxn 0 CreatedApplicationID; itob; log; @@ -1451,6 +1517,8 @@ int 5001 // TestGtxnAsa confirms that gtxn can now access previous txn's created asa id. func TestGtxnAsa(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, ledger := MakeSampleEnv() appcheck := TestProg(t, ` gtxn 0 CreatedAssetID; itob; log; @@ -1486,6 +1554,8 @@ int 5001 // TestCallerGlobals checks that a called app can see its caller. func TestCallerGlobals(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, ledger := MakeSampleEnv() globals := TestProg(t, fmt.Sprintf(` global CallerApplicationID @@ -1514,6 +1584,8 @@ int 1 // TestNumInnerDeep ensures that inner call limits apply to inner calls of inner // transactions. func TestNumInnerDeep(t *testing.T) { + partitiontest.PartitionTest(t) + pay := ` itxn_begin int 1 @@ -1562,6 +1634,8 @@ itxn_submit // used. This was not allowed until v6, because of the strict adherence to the // foreign-arrays rules. func TestCreateAndUse(t *testing.T) { + partitiontest.PartitionTest(t) + axfer := ` itxn_begin int acfg; itxn_field TypeEnum @@ -1675,6 +1749,8 @@ func hexProgram(t *testing.T, source string) string { // TestCreateAndUseApp checks that an app can be created in an inner txn, and then // the address for it can be looked up. func TestCreateUseApp(t *testing.T) { + partitiontest.PartitionTest(t) + pay5back := main(` itxn_begin int pay; itxn_field TypeEnum @@ -1707,6 +1783,8 @@ int 1 // a pay can be done to the app's account. This was not allowed until v6, // because of the strict adherence to the foreign-accounts rules. func TestCreateAndPay(t *testing.T) { + partitiontest.PartitionTest(t) + pay5back := main(` itxn_begin int pay; itxn_field TypeEnum @@ -1748,6 +1826,8 @@ int 1 // TestInnerGaid ensures there's no confusion over the tracking of ids // across multiple inner transaction groups func TestInnerGaid(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, ledger := MakeSampleEnv() ep.Proto.MaxInnerTransactions = 100 // App to log the aid of slot[apparg[0]] @@ -1838,6 +1918,8 @@ int 1 // TestInnerCallDepth ensures that inner calls are limited in depth func TestInnerCallDepth(t *testing.T) { + partitiontest.PartitionTest(t) + t.Parallel() ep, tx, ledger := MakeSampleEnv() @@ -1901,6 +1983,8 @@ done: } func TestInfiniteRecursion(t *testing.T) { + partitiontest.PartitionTest(t) + ep, tx, ledger := MakeSampleEnv() source := ` itxn_begin diff --git a/go.mod b/go.mod index 19a67f8119..8db89a7b8b 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/algorand/falcon v0.0.0-20220130164023-c9e1d466f123 github.com/algorand/go-codec/codec v0.0.0-20190507210007-269d70b6135d github.com/algorand/go-deadlock v0.2.1 - github.com/algorand/go-sumhash v0.0.0-20211021081112-0ea867c5153a + github.com/algorand/go-sumhash v0.1.0 github.com/algorand/graphtrace v0.0.0-20201117160756-e524ed1a6f64 github.com/algorand/msgp v1.1.49 github.com/algorand/oapi-codegen v1.3.5-algorand5 diff --git a/go.sum b/go.sum index 1e73be8d00..92f339d4f0 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,8 @@ github.com/algorand/go-codec/codec v0.0.0-20190507210007-269d70b6135d h1:W9MgGUo github.com/algorand/go-codec/codec v0.0.0-20190507210007-269d70b6135d/go.mod h1:qm6LyXvDa1+uZJxaVg8X+OEjBqt/zDinDa2EohtTDxU= github.com/algorand/go-deadlock v0.2.1 h1:TQPQwWAB133bS5uwHpmrgH5hCMyZK5hnUW26aqWMvq4= github.com/algorand/go-deadlock v0.2.1/go.mod h1:HgdF2cwtBIBCL7qmUaozuG/UIZFR6PLpSMR58pvWiXE= -github.com/algorand/go-sumhash v0.0.0-20211021081112-0ea867c5153a h1:H+gCngy1bT6m8OB6IGzv/UXbAorPoqefa4J2NMuK0v8= -github.com/algorand/go-sumhash v0.0.0-20211021081112-0ea867c5153a/go.mod h1:OOe7jdDWUhLkuP1XytkK5gnLu9entAviN5DfDZh6XAc= +github.com/algorand/go-sumhash v0.1.0 h1:b/QRhyLuF//vOcicBIxBXYW8bERNoeLxieht/dUYpVg= +github.com/algorand/go-sumhash v0.1.0/go.mod h1:OOe7jdDWUhLkuP1XytkK5gnLu9entAviN5DfDZh6XAc= github.com/algorand/graphtrace v0.0.0-20201117160756-e524ed1a6f64 h1:yvKeJdS/mvLRiyIxu8j5BQDXIzs1XbC9/22KycJnt3A= github.com/algorand/graphtrace v0.0.0-20201117160756-e524ed1a6f64/go.mod h1:qFtQmC+kmsfnLfS9j3xgKtzsWyozemL5ek1R4dWZa5c= github.com/algorand/msgp v1.1.49 h1:YBFRcYZNsD2WgzXONvzFrjv1/887pWzJSx874VL4P6g= diff --git a/ledger/accountdb_test.go b/ledger/accountdb_test.go index aa45350f02..4f4c8a6f66 100644 --- a/ledger/accountdb_test.go +++ b/ledger/accountdb_test.go @@ -290,6 +290,8 @@ func TestAccountDBRound(t *testing.T) { } func TestAccountStorageWithStateProofID(t *testing.T) { + partitiontest.PartitionTest(t) + proto := config.Consensus[protocol.ConsensusCurrentVersion] dbs, _ := dbOpenTest(t, true) diff --git a/ledger/internal/apptxn_test.go b/ledger/internal/apptxn_test.go index d000f53f7f..daf56b4652 100644 --- a/ledger/internal/apptxn_test.go +++ b/ledger/internal/apptxn_test.go @@ -1396,6 +1396,8 @@ next2: // used in a later app call tx (in the same group). This was not allowed until // v6, because of the strict adherence to the foreign-arrays rules. func TestCreateAndUse(t *testing.T) { + partitiontest.PartitionTest(t) + genBalances, addrs, _ := ledgertesting.NewTestGenesis() l := newTestLedger(t, genBalances) defer l.Close() @@ -1455,6 +1457,8 @@ func TestCreateAndUse(t *testing.T) { } func TestGtxnEffects(t *testing.T) { + partitiontest.PartitionTest(t) + genBalances, addrs, _ := ledgertesting.NewTestGenesis() l := newTestLedger(t, genBalances) defer l.Close() diff --git a/ledger/internal/compactcert.go b/ledger/internal/compactcert.go index 623cdc5263..ca2be6d19e 100644 --- a/ledger/internal/compactcert.go +++ b/ledger/internal/compactcert.go @@ -136,8 +136,6 @@ func CompactCertParams(votersHdr bookkeeping.BlockHeader, hdr bookkeeping.BlockH ProvenWeight: provenWeight, SigRound: hdr.Round, SecKQ: proto.CompactCertSecKQ, - - EnableBatchVerification: proto.EnableBatchVerification, } return } diff --git a/ledger/metrics.go b/ledger/metrics.go index c7ac7dc001..de4cd6aedc 100644 --- a/ledger/metrics.go +++ b/ledger/metrics.go @@ -40,6 +40,18 @@ func (mt *metricsTracker) loadFromDisk(l ledgerForTracker, _ basics.Round) error } func (mt *metricsTracker) close() { + if mt.ledgerTransactionsTotal != nil { + mt.ledgerTransactionsTotal.Deregister(nil) + mt.ledgerTransactionsTotal = nil + } + if mt.ledgerRewardClaimsTotal != nil { + mt.ledgerRewardClaimsTotal.Deregister(nil) + mt.ledgerRewardClaimsTotal = nil + } + if mt.ledgerRound != nil { + mt.ledgerRound.Deregister(nil) + mt.ledgerRound = nil + } } func (mt *metricsTracker) newBlock(blk bookkeeping.Block, delta ledgercore.StateDelta) { diff --git a/ledger/metrics_test.go b/ledger/metrics_test.go new file mode 100644 index 0000000000..ca24e0f0f2 --- /dev/null +++ b/ledger/metrics_test.go @@ -0,0 +1,76 @@ +// Copyright (C) 2019-2022 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 ledger + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/algorand/go-algorand/data/basics" + "github.com/algorand/go-algorand/data/bookkeeping" + "github.com/algorand/go-algorand/ledger/ledgercore" + 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/metrics" +) + +func TestMetricsReload(t *testing.T) { + partitiontest.PartitionTest(t) + + mt := metricsTracker{} + accts := ledgertesting.RandomAccounts(1, true) + ml := makeMockLedgerForTracker(t, true, 1, protocol.ConsensusCurrentVersion, []map[basics.Address]basics.AccountData{accts}) + + mt.loadFromDisk(ml, 0) + blk := bookkeeping.Block{BlockHeader: bookkeeping.BlockHeader{Round: 1}} + mt.newBlock(blk, ledgercore.StateDelta{}) + mt.close() + + mt.loadFromDisk(ml, 0) + blk = bookkeeping.Block{BlockHeader: bookkeeping.BlockHeader{Round: 2}} + mt.newBlock(blk, ledgercore.StateDelta{}) + + var buf strings.Builder + metrics.DefaultRegistry().WriteMetrics(&buf, "") + lines := strings.Split(buf.String(), "\n") + txCount := 0 + rcCount := 0 + rCount := 0 + for _, line := range lines { + if strings.HasPrefix(line, "# HELP") || strings.HasPrefix(line, "# TYPE") { + // ignore comments + continue + } + if strings.HasPrefix(line, metrics.LedgerTransactionsTotal.Name) { + txCount++ + } + if strings.HasPrefix(line, metrics.LedgerRewardClaimsTotal.Name) { + rcCount++ + } + if strings.HasPrefix(line, metrics.LedgerRound.Name) { + rCount++ + } + } + require.Equal(t, 1, txCount) + require.Equal(t, 1, rcCount) + require.Equal(t, 1, rCount) + + mt.close() +} diff --git a/test/e2e-go/features/transactions/proof_test.go b/test/e2e-go/features/transactions/proof_test.go index 462f80f40c..118e725f74 100644 --- a/test/e2e-go/features/transactions/proof_test.go +++ b/test/e2e-go/features/transactions/proof_test.go @@ -50,6 +50,7 @@ func TestTxnMerkleProof(t *testing.T) { partitiontest.PartitionTest(t) defer fixtures.ShutdownSynchronizedTest(t) + t.Parallel() a := require.New(fixtures.SynchronizedTest(t)) var fixture fixtures.RestClientFixture @@ -76,7 +77,8 @@ func TestTxnMerkleProof(t *testing.T) { // Transfer some money to acct0, as well as other random accounts to // fill up the Merkle tree with more than one element. - for i := 0; i < 10; i++ { + // we do not want to have a full tree in order the catch an empty element edge case + for i := 0; i < 5; i++ { accti, err := client.GenerateAddress(walletHandle) a.NoError(err) @@ -87,14 +89,6 @@ func TestTxnMerkleProof(t *testing.T) { tx, err := client.SendPaymentFromUnencryptedWallet(baseAcct, acct0, 1000, 10000000, nil) a.NoError(err) - for i := 0; i < 10; i++ { - accti, err := client.GenerateAddress(walletHandle) - a.NoError(err) - - _, err = client.SendPaymentFromUnencryptedWallet(baseAcct, accti, 1000, 10000000, nil) - a.NoError(err) - } - txid := tx.ID() confirmedTx, err := fixture.WaitForConfirmedTxn(status.LastRound+10, baseAcct, txid.String()) a.NoError(err) @@ -128,7 +122,7 @@ func TestTxnMerkleProof(t *testing.T) { elems[proofresp.Idx] = &element err = merklearray.Verify(blk.TxnRoot.ToSlice(), elems, &proof) if err != nil { - t.Logf("blk.TxnRoot : %v \nproof path %v \ndepth: %d \nStibhash %v", blk.TxnRoot.ToSlice(), proof.Path, proof.TreeDepth, proofresp.Stibhash) + t.Logf("blk.TxnRoot : %v \nproof path %v \ndepth: %d \nStibhash %v\nIndex: %d", blk.TxnRoot.ToSlice(), proof.Path, proof.TreeDepth, proofresp.Stibhash, proofresp.Idx) a.NoError(err) } diff --git a/test/scripts/e2e_subs/keyreg.sh b/test/scripts/e2e_subs/keyreg.sh new file mode 100755 index 0000000000..b3d852f268 --- /dev/null +++ b/test/scripts/e2e_subs/keyreg.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +date '+e2e_subs/keyreg.sh start %Y%m%d_%H%M%S' + +set -exo pipefail +export SHELLOPTS + +WALLET=$1 + +gcmd="goal -w ${WALLET}" + +ACCOUNT=$(${gcmd} account list|awk '{ print $3 }') + +# secret algokey override +ALGOKEY_GENESIS_HASH=$(goal node status | grep 'Genesis hash:'|awk '{ print $3 }') +export ALGOKEY_GENESIS_HASH +# Test key registration +KEYS="${TEMPDIR}/foo.keys" +TXN="${TEMPDIR}/keyreg.txn" +STXN="${TEMPDIR}/keyreg.stxn" +algokey part generate --first 1 --last 1000 --parent "${ACCOUNT}" --keyfile "${KEYS}" +algokey part keyreg --network placeholder --keyfile "${KEYS}" --firstvalid 1 --outputFile "${TXN}" +# technically algokey could be used to sign at this point, that would require +# exporting secrets from the wallet. +${gcmd} clerk sign -i "${TXN}" -o "${STXN}" +${gcmd} clerk rawsend -f "${STXN}" + +TXN2="${TEMPDIR}/keydereg.txn" +STXN2="${TEMPDIR}/keydereg.stxn" +# Test key de-registration +algokey part keyreg --network placeholder --offline --account "${ACCOUNT}" --firstvalid 1 --outputFile "${TXN2}" +${gcmd} clerk sign -i "${TXN2}" -o "${STXN2}" +${gcmd} clerk rawsend -f "${STXN2}" diff --git a/test/testdata/deployednettemplates/recipes/custom/configs/node.json b/test/testdata/deployednettemplates/recipes/custom/configs/node.json index f9b05a87f2..4cfd52b5c8 100644 --- a/test/testdata/deployednettemplates/recipes/custom/configs/node.json +++ b/test/testdata/deployednettemplates/recipes/custom/configs/node.json @@ -1,5 +1,4 @@ { - "NetAddress": "{{NetworkPort}}", "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableBlockStats": false, @@ -10,7 +9,6 @@ "ConfigJSONOverride": "{ \"TxPoolExponentialIncreaseFactor\": 1, \"DNSBootstrapID\": \".algodev.network\", \"DeadlockDetection\": -1, \"PeerPingPeriodSeconds\": 30, \"BaseLoggerDebugLevel\": 4, \"EnableProfiler\": true, \"CadaverSizeTarget\": 0 }", "AltConfigs": [ { - "NetAddress": "{{NetworkPort}}", "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableBlockStats": true, diff --git a/test/testdata/deployednettemplates/recipes/custom/configs/nonPartNode.json b/test/testdata/deployednettemplates/recipes/custom/configs/nonPartNode.json index 0e22877432..5b0a52d9d9 100644 --- a/test/testdata/deployednettemplates/recipes/custom/configs/nonPartNode.json +++ b/test/testdata/deployednettemplates/recipes/custom/configs/nonPartNode.json @@ -1,5 +1,4 @@ { - "NetAddress": "{{NetworkPort}}", "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "ConfigJSONOverride": "{ \"TxPoolExponentialIncreaseFactor\": 1, \"DNSBootstrapID\": \".algodev.network\", \"DeadlockDetection\": -1, \"BaseLoggerDebugLevel\": 4, \"CadaverSizeTarget\": 0 }" diff --git a/test/testdata/deployednettemplates/recipes/feature-networks/genesis.json b/test/testdata/deployednettemplates/recipes/feature-networks/genesis.json index 943e9f5150..55b7289210 100644 --- a/test/testdata/deployednettemplates/recipes/feature-networks/genesis.json +++ b/test/testdata/deployednettemplates/recipes/feature-networks/genesis.json @@ -3,7 +3,7 @@ "VersionModifier": "", "ConsensusProtocol": "future", "FirstPartKeyRound": 0, - "LastPartKeyRound": 100000000, + "LastPartKeyRound": 3000000, "Wallets": [ { "Name": "Wallet1-R1", diff --git a/test/testdata/deployednettemplates/recipes/scenario2/net.json b/test/testdata/deployednettemplates/recipes/scenario2/net.json index e816dfd048..4c1c0d6c2b 100644 --- a/test/testdata/deployednettemplates/recipes/scenario2/net.json +++ b/test/testdata/deployednettemplates/recipes/scenario2/net.json @@ -416,6 +416,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -527,6 +528,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -638,6 +640,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -749,6 +752,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -860,6 +864,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -971,6 +976,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -1082,6 +1088,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -1193,6 +1200,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -1304,6 +1312,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -1415,6 +1424,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -1526,6 +1536,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -1637,6 +1648,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -1748,6 +1760,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -1859,6 +1872,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -1970,6 +1984,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -2081,6 +2096,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -2192,6 +2208,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -2303,6 +2320,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -2414,6 +2432,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -2525,6 +2544,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -2636,6 +2656,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -2747,6 +2768,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -2858,6 +2880,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -2969,6 +2992,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -3080,6 +3104,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -3191,6 +3216,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -3302,6 +3328,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -3413,6 +3440,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -3524,6 +3552,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -3635,6 +3664,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -3746,6 +3776,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -3857,6 +3888,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -3968,6 +4000,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -4079,6 +4112,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -4190,6 +4224,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -4301,6 +4336,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -4412,6 +4448,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -4523,6 +4560,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -4634,6 +4672,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", @@ -4745,6 +4784,7 @@ "ParticipationOnly": false } ], + "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableTelemetry": true, "TelemetryURI": "{{TelemetryURI}}", diff --git a/test/testdata/deployednettemplates/recipes/scenario2/node.json b/test/testdata/deployednettemplates/recipes/scenario2/node.json index a5b72567e0..7b505bb212 100644 --- a/test/testdata/deployednettemplates/recipes/scenario2/node.json +++ b/test/testdata/deployednettemplates/recipes/scenario2/node.json @@ -1,5 +1,4 @@ { - "NetAddress": "{{NetworkPort}}", "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "EnableBlockStats": true, diff --git a/test/testdata/deployednettemplates/recipes/scenario2/nonPartNode.json b/test/testdata/deployednettemplates/recipes/scenario2/nonPartNode.json index 0e22877432..5b0a52d9d9 100644 --- a/test/testdata/deployednettemplates/recipes/scenario2/nonPartNode.json +++ b/test/testdata/deployednettemplates/recipes/scenario2/nonPartNode.json @@ -1,5 +1,4 @@ { - "NetAddress": "{{NetworkPort}}", "APIEndpoint": "{{APIEndpoint}}", "APIToken": "{{APIToken}}", "ConfigJSONOverride": "{ \"TxPoolExponentialIncreaseFactor\": 1, \"DNSBootstrapID\": \".algodev.network\", \"DeadlockDetection\": -1, \"BaseLoggerDebugLevel\": 4, \"CadaverSizeTarget\": 0 }" diff --git a/util/metrics/counter.go b/util/metrics/counter.go index 3a7b363570..1fb33f67e8 100644 --- a/util/metrics/counter.go +++ b/util/metrics/counter.go @@ -63,7 +63,7 @@ func (counter *Counter) Deregister(reg *Registry) { // Inc increases counter by 1 // Much faster if labels is nil or empty. func (counter *Counter) Inc(labels map[string]string) { - if labels == nil || len(labels) == 0 { + if len(labels) == 0 { counter.fastAddUint64(1) } else { counter.Add(1.0, labels) @@ -98,7 +98,7 @@ func (counter *Counter) Add(x float64, labels map[string]string) { // If labels is nil this is much faster than Add() // Calls through to Add() if labels is not nil. func (counter *Counter) AddUint64(x uint64, labels map[string]string) { - if labels == nil || len(labels) == 0 { + if len(labels) == 0 { counter.fastAddUint64(x) } else { counter.Add(float64(x), labels) @@ -108,7 +108,7 @@ func (counter *Counter) AddUint64(x uint64, labels map[string]string) { // AddMicrosecondsSince increases counter by microseconds between Time t and now. // Fastest if labels is nil func (counter *Counter) AddMicrosecondsSince(t time.Time, labels map[string]string) { - counter.AddUint64(uint64(time.Now().Sub(t).Microseconds()), labels) + counter.AddUint64(uint64(time.Since(t).Microseconds()), labels) } func (counter *Counter) fastAddUint64(x uint64) { diff --git a/util/metrics/registry.go b/util/metrics/registry.go index d82b49367c..33b902da3a 100644 --- a/util/metrics/registry.go +++ b/util/metrics/registry.go @@ -50,6 +50,8 @@ func (r *Registry) Register(metric Metric) { // Deregister removes the given metric to the registry func (r *Registry) Deregister(metric Metric) { + r.metricsMu.Lock() + defer r.metricsMu.Unlock() for i, m := range r.metrics { if m == metric { r.metrics = append(r.metrics[:i], r.metrics[i+1:]...) diff --git a/util/metrics/service.go b/util/metrics/service.go index 576d14404f..e37f5c7341 100644 --- a/util/metrics/service.go +++ b/util/metrics/service.go @@ -37,6 +37,7 @@ var ( var ( // the duration of which we'll keep a metric in-memory and keep reporting it. // when a metric time expires, it would get removed. + // TODO: implement or remove maxMetricRetensionDuration = time.Duration(5) * time.Minute )