diff --git a/Dockerfile b/Dockerfile index ff68ff7b..1bcfcbf0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,6 +2,9 @@ FROM alpine:latest AS rosetta RUN apk update && apk upgrade && apk add --update go gcc g++ vips-dev +COPY --from=golang:1.22-alpine /usr/local/go/ /usr/local/go/ +ENV PATH="/usr/local/go/bin:${PATH}" + WORKDIR /deso/src COPY rosetta-deso/go.mod rosetta-deso/ @@ -20,10 +23,13 @@ COPY rosetta-deso/services services COPY rosetta-deso/main.go . # include core src -COPY core/desohash ../core/desohash -COPY core/cmd ../core/cmd -COPY core/lib ../core/lib -COPY core/migrate ../core/migrate +COPY core/desohash ../core/desohash +COPY core/cmd ../core/cmd +COPY core/lib ../core/lib +COPY core/migrate ../core/migrate +COPY core/bls ../core/bls +COPY core/collections ../core/collections +COPY core/consensus ../core/consensus # build rosetta-deso RUN GOOS=linux go build -mod=mod -a -installsuffix cgo -o bin/rosetta-deso main.go diff --git a/README.md b/README.md index c8d43e00..1b32b958 100644 --- a/README.md +++ b/README.md @@ -64,3 +64,19 @@ To run the construction checks, execute: ``` bin/rosetta-cli check:construction --configuration-file rosetta-cli-conf/testnet/deso.conf ``` + +### M1 Mac Users + +There are some issues with running the rosetta cli w/ M1 Macs. To fix this, you can run the following command to build +the rosetta cli docker image: +``` +docker build github.com/coinbase/mesh-cli --platform linux/amd64 -t rosetta-cli +``` + +Then update the configuration file to use `http://host.docker.internal:17005` instead of `http://localhost:17005` - +basically replacing all usages of `localhost` with `host.docker.internal`. + +Then to run the rosetta cli check:data tests, you can run the following command: +``` +docker run -v "$(pwd):/data" --rm -it --platform linux/amd64 rosetta-cli check:data --configuration-file /data/rosetta-cli-conf/testnet/deso.conf +``` \ No newline at end of file diff --git a/cmd/run.go b/cmd/run.go index cee9ed7f..0f57dfdc 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -2,11 +2,14 @@ package cmd import ( "fmt" - coreCmd "github.com/deso-protocol/core/cmd" "log" "net/http" "os" + coreCmd "github.com/deso-protocol/core/cmd" + "github.com/deso-protocol/core/lib" + "github.com/dgraph-io/badger/v4" + "github.com/coinbase/rosetta-sdk-go/asserter" "github.com/coinbase/rosetta-sdk-go/server" "github.com/coinbase/rosetta-sdk-go/types" @@ -45,6 +48,7 @@ to quickly create a Cobra application.`, []*types.NetworkIdentifier{config.Network}, nil, false, + "", // TODO: Figure out what we should supply for validation path. ) if err != nil { glog.Fatalf("unable to create new server asserter", "error", err) @@ -64,19 +68,110 @@ to quickly create a Cobra application.`, }, } -func init() { - // Add all the core node flags - coreCmd.SetupRunFlags(runCmd) +// debugCmd represents the debug command. It can help you debug the chain by +// printing txns directly from the badgerdb, among other things. You must modify +// the go code directly to suit your needs. It's not an "out of the box" thing. +var debugCmd = &cobra.Command{ + Use: "debug", + Short: "A brief description of your command", + Long: `A longer description that spans multiple lines and likely contains examples +and usage of using your command. For example: + +Cobra is a CLI library for Go that empowers applications. +This application is a tool to generate the needed files +to quickly create a Cobra application.`, + RunE: func(cmd *cobra.Command, args []string) error { + config, err := deso.LoadConfig() + if err != nil { + return err + } + // You need to set this or else the block cutovers will mess up your GetBlockIndex in + // DeserializeBlockNode. + // Check for regtest mode + if config.Regtest { + config.Params.EnableRegtest() + } + lib.GlobalDeSoParams = *config.Params + + dbDir := lib.GetBadgerDbPath(config.DataDirectory) + opts := lib.PerformanceBadgerOptions(dbDir) + opts.ValueDir = dbDir + chainDB, err := badger.Open(opts) + if err != nil { + panic(err) + } - runCmd.PersistentFlags().String("network", string(deso.Mainnet), "network to connect to") - runCmd.PersistentFlags().String("mode", string(deso.Online), "mode to start in") - runCmd.PersistentFlags().Int("port", 17005, "rosetta api listener port") - runCmd.PersistentFlags().Int("node-port", 17000, "node api listener port") - runCmd.PersistentFlags().String("data-directory", "/data", "location to store persistent data") + // See if we have a best chain hash stored in the db. + bestBlockHash := lib.DbGetBestHash(chainDB, nil, lib.ChainTypeDeSoBlock) - runCmd.PersistentFlags().VisitAll(func(flag *pflag.Flag) { + // If there is no best chain hash in the db then it means we've never + // initialized anything so take the time to do it now. + if bestBlockHash == nil { + panic("bestBlockHash is nil") + } + + blockIndexByHash, err := lib.GetBlockIndex(chainDB, false /*bitcoinNodes*/, config.Params) + if err != nil { + panic(fmt.Sprintf("Problem reading block index from db: %v", err)) + } + + tipNode := blockIndexByHash[*bestBlockHash] + if tipNode == nil { + panic(fmt.Sprintf("Best hash (%#v) not found in block index", bestBlockHash.String())) + } + bestChain, err := lib.GetBestChain(tipNode, blockIndexByHash) + if err != nil { + panic(fmt.Sprintf("Problem reading best chain from db: %v", err)) + } + + for _, bestChainNode := range bestChain { + block, err := lib.GetBlock(bestChainNode.Hash, chainDB, nil) + if err != nil { + panic(fmt.Sprintf("Problem reading block from db: %v", err)) + } + if len(block.Txns) > 1 { + fmt.Println(block.Header.Height, bestChainNode.Hash.String(), len(block.Txns)) + for _, txn := range block.Txns { + fmt.Println("\t", txn.Hash().String()) + pubkeyString := "block reward" + if len(txn.PublicKey) != 0 { + pubkeyString = lib.PkToStringTestnet(txn.PublicKey) + } + fmt.Println("\t\tSender: \t", pubkeyString) + for _, output := range txn.TxOutputs { + fmt.Println("\t\tRecipient: \t", lib.PkToStringTestnet(output.PublicKey)) + fmt.Println("\t\tAmount: \t", output.AmountNanos) + } + } + } + } + return nil + }, +} + +func initFlags(cmdIter *cobra.Command) { + coreCmd.SetupRunFlags(cmdIter) + + cmdIter.PersistentFlags().String("network", string(deso.Mainnet), "network to connect to") + cmdIter.PersistentFlags().String("mode", string(deso.Online), "mode to start in") + cmdIter.PersistentFlags().Int("port", 17005, "rosetta api listener port") + cmdIter.PersistentFlags().Int("node-port", 17000, "node api listener port") + cmdIter.PersistentFlags().String("data-directory", "/data", "location to store persistent data") + + cmdIter.PersistentFlags().VisitAll(func(flag *pflag.Flag) { viper.BindPFlag(flag.Name, flag) }) - rootCmd.AddCommand(runCmd) + rootCmd.AddCommand(cmdIter) +} + +func init() { + // This is a dirty hack. When we run in debug mode, we need to set the flags on the debugCmd rather + // than the runCmd. There is probably a "right" way to do this, but the below works for now... + if len(os.Args) > 1 && os.Args[1] == "debug" { + fmt.Println("DEBUGGING!") + initFlags(debugCmd) + } else { + initFlags(runCmd) + } } diff --git a/deso/block.go b/deso/block.go index 132cfbf0..6c428de1 100644 --- a/deso/block.go +++ b/deso/block.go @@ -9,6 +9,7 @@ import ( "github.com/pkg/errors" "sort" "strconv" + "strings" "github.com/coinbase/rosetta-sdk-go/types" "github.com/deso-protocol/core/lib" @@ -61,7 +62,7 @@ func (node *Node) GetBlock(hash string) *types.Block { return &types.Block{ BlockIdentifier: blockIdentifier, ParentBlockIdentifier: parentBlockIdentifier, - Timestamp: int64(blockNode.Header.TstampSecs) * 1000, + Timestamp: int64(blockNode.Header.TstampNanoSecs) / 1e6, // Convert nanoseconds to milliseconds Transactions: transactions, } } @@ -76,7 +77,7 @@ func (node *Node) GetBlock(hash string) *types.Block { return &types.Block{ BlockIdentifier: blockIdentifier, ParentBlockIdentifier: parentBlockIdentifier, - Timestamp: int64(blockNode.Header.TstampSecs) * 1000, + Timestamp: int64(blockNode.Header.TstampNanoSecs) / 1e6, // Convert nanoseconds to milliseconds Transactions: node.GetTransactionsForConvertBlock(block), } } @@ -154,111 +155,200 @@ func (node *Node) GetTransactionsForConvertBlock(block *lib.MsgDeSoBlock) []*typ TransactionIdentifier: &types.TransactionIdentifier{Hash: txnHash}, Metadata: metadata, } + var utxoOpsForTxn []*lib.UtxoOperation + if len(utxoOpsForBlock) > 0 { + utxoOpsForTxn = utxoOpsForBlock[txnIndexInBlock] + } + + transaction.Operations = squashOperations( + node.getOperationsForTransaction(txn, block, spentUtxos, utxoOpsForTxn)) + + transactions = append(transactions, transaction) + } + // Create a dummy transaction for the "block level" operations + // when we have the additional slice of utxo operations. This is used + // to capture staking rewards that are paid out at the block level, but + // have no transaction associated with them. The array of utxo operations + // at the index of # transactions in block + 1 is ALWAYS the block level + // utxo operations. At the end of a PoS epoch, we distribute staking rewards + // by either adding to the stake entry with the specified validator or + // directly deposit staking rewards to the staker's DESO balance. This is based + // on the configuration a user specifies when staking with a validator. + // We capture the non-restaked rewards the same way we capture basic transfer outputs, + // but with a dummy transaction. These are simple OUTPUTS to a staker's DESO balance. + // We capture the restaked rewards by adding an OUTPUT + // to the valiator's subaccount. + if len(utxoOpsForBlock) == len(block.Txns)+1 { + blockHash, err := block.Hash() + if err != nil { + // This is bad if this happens. + glog.Error(errors.Wrapf(err, "GetTransactionsForConvertBlock: Problem fetching block hash")) + return transactions + } + utxoOpsForBlockLevel := utxoOpsForBlock[len(utxoOpsForBlock)-1] var ops []*types.Operation + // Add outputs for Stake Reward Distributions that are not re-staked. We use a fake transaction to + // avoid panic in getStakingRewardDistributionOps. + implicitOutputOps := node.getImplicitOutputs(&lib.MsgDeSoTxn{TxOutputs: nil}, utxoOpsForBlockLevel, len(ops)) + ops = append(ops, implicitOutputOps...) + // Add outputs for Stake Reward Distributions that are re-staked + stakeRewardOps := node.getStakingRewardDistributionOps(utxoOpsForBlockLevel, len(ops)) + ops = append(ops, stakeRewardOps...) - for _, input := range txn.TxInputs { - // Fetch the input amount from Rosetta Index - spentAmount, amountExists := spentUtxos[lib.UtxoKey{ - TxID: input.TxID, - Index: input.Index, - }] - if !amountExists { - fmt.Printf("Error: input missing for txn %v index %v\n", lib.PkToStringBoth(input.TxID[:]), input.Index) - } + transaction := &types.Transaction{ + TransactionIdentifier: &types.TransactionIdentifier{Hash: fmt.Sprintf("blockHash-%v", blockHash.String())}, + } + transaction.Operations = squashOperations(ops) + transactions = append(transactions, transaction) + } - amount := &types.Amount{ - Value: strconv.FormatInt(int64(spentAmount)*-1, 10), - Currency: &Currency, + return transactions +} + +func (node *Node) getOperationsForTransaction( + txn *lib.MsgDeSoTxn, + block *lib.MsgDeSoBlock, + spentUtxos map[lib.UtxoKey]uint64, + utxoOpsForTxn []*lib.UtxoOperation, +) []*types.Operation { + if txn.TxnMeta.GetTxnType() == lib.TxnTypeAtomicTxnsWrapper { + // There are no operations for the wrapper, but we need to parse + // operations for all inner txns. + innerTxns := txn.TxnMeta.(*lib.AtomicTxnsWrapperMetadata).Txns + ops := []*types.Operation{} + var opsForInnerTxns [][]*lib.UtxoOperation + for _, utxoOp := range utxoOpsForTxn { + if utxoOp.Type == lib.OperationTypeAtomicTxnsWrapper { + opsForInnerTxns = utxoOp.AtomicTxnsInnerUtxoOps + break } + } + if len(opsForInnerTxns) != len(innerTxns) { + glog.Errorf( + "Error: opsForInnerTxns length %v != innerTxns length %v\n", len(opsForInnerTxns), len(innerTxns)) + return ops + } + for ii, innerTxn := range innerTxns { + ops = append(ops, node.getOperationsForTransaction(innerTxn, block, spentUtxos, opsForInnerTxns[ii])...) + } + return ops + } + // DeSo started with a UTXO model but switched to a balance model at a particular block + // height. We need to handle both cases here. + isBalanceModelTxn := false + if block.Header.Height >= uint64(node.Params.ForkHeights.BalanceModelBlockHeight) { + isBalanceModelTxn = true + } + + var ops []*types.Operation + + for _, input := range txn.TxInputs { + // Fetch the input amount from Rosetta Index + spentAmount, amountExists := spentUtxos[lib.UtxoKey{ + TxID: input.TxID, + Index: input.Index, + }] + if !amountExists { + fmt.Printf("Error: input missing for txn %v index %v\n", lib.PkToStringBoth(input.TxID[:]), input.Index) + } + + amount := &types.Amount{ + Value: strconv.FormatInt(int64(spentAmount)*-1, 10), + Currency: &Currency, + } + op := &types.Operation{ + OperationIdentifier: &types.OperationIdentifier{ + Index: int64(len(ops)), + }, + + Account: &types.AccountIdentifier{ + Address: lib.Base58CheckEncode(txn.PublicKey, false, node.Params), + }, + + Amount: amount, + + Status: &SuccessStatus, + Type: InputOpType, + } + + ops = append(ops, op) + } + + // If we are dealing with a legacy UTXO transaction, then we need to add the outputs from + // the transaction directly rather than relying on the UtxoOps. + if !isBalanceModelTxn { + for _, output := range txn.TxOutputs { op := &types.Operation{ OperationIdentifier: &types.OperationIdentifier{ Index: int64(len(ops)), }, Account: &types.AccountIdentifier{ - Address: lib.Base58CheckEncode(txn.PublicKey, false, node.Params), + Address: lib.Base58CheckEncode(output.PublicKey, false, node.Params), }, - Amount: amount, + Amount: &types.Amount{ + Value: strconv.FormatUint(output.AmountNanos, 10), + Currency: &Currency, + }, Status: &SuccessStatus, - Type: InputOpType, + Type: OutputOpType, } ops = append(ops, op) } + } - // If we are dealing with a legacy UTXO transaction, then we need to add the outputs from - // the transaction directly rather than relying on the UtxoOps. - if !isBalanceModelTxn { - for _, output := range txn.TxOutputs { - op := &types.Operation{ - OperationIdentifier: &types.OperationIdentifier{ - Index: int64(len(ops)), - }, - - Account: &types.AccountIdentifier{ - Address: lib.Base58CheckEncode(output.PublicKey, false, node.Params), - }, - - Amount: &types.Amount{ - Value: strconv.FormatUint(output.AmountNanos, 10), - Currency: &Currency, - }, - - Status: &SuccessStatus, - Type: OutputOpType, - } - - ops = append(ops, op) - } - } - - // Add all the special ops for specific txn types. - if len(utxoOpsForBlock) > 0 { - utxoOpsForTxn := utxoOpsForBlock[txnIndexInBlock] + // Add all the special ops for specific txn types. + if len(utxoOpsForTxn) > 0 { + // Get balance model spends + balanceModelSpends := node.getBalanceModelSpends(txn, utxoOpsForTxn, len(ops)) + ops = append(ops, balanceModelSpends...) - // Get balance model spends - balanceModelSpends := node.getBalanceModelSpends(txn, utxoOpsForTxn, len(ops)) - ops = append(ops, balanceModelSpends...) + // Add implicit outputs from UtxoOps + implicitOutputs := node.getImplicitOutputs(txn, utxoOpsForTxn, len(ops)) + ops = append(ops, implicitOutputs...) - // Add implicit outputs from UtxoOps - implicitOutputs := node.getImplicitOutputs(txn, utxoOpsForTxn, len(ops)) - ops = append(ops, implicitOutputs...) + // Add inputs/outputs for creator coins + creatorCoinOps := node.getCreatorCoinOps(txn, utxoOpsForTxn, len(ops)) + ops = append(ops, creatorCoinOps...) - // Add inputs/outputs for creator coins - creatorCoinOps := node.getCreatorCoinOps(txn, utxoOpsForTxn, len(ops)) - ops = append(ops, creatorCoinOps...) + // Add inputs/outputs for swap identity + swapIdentityOps := node.getSwapIdentityOps(txn, utxoOpsForTxn, len(ops)) + ops = append(ops, swapIdentityOps...) - // Add inputs/outputs for swap identity - swapIdentityOps := node.getSwapIdentityOps(txn, utxoOpsForTxn, len(ops)) - ops = append(ops, swapIdentityOps...) + // Add inputs for accept nft bid + acceptNftOps := node.getAcceptNFTOps(txn, utxoOpsForTxn, len(ops)) + ops = append(ops, acceptNftOps...) - // Add inputs for accept nft bid - acceptNftOps := node.getAcceptNFTOps(txn, utxoOpsForTxn, len(ops)) - ops = append(ops, acceptNftOps...) + // Add inputs for bids on Buy Now NFTs + buyNowNftBidOps := node.getBuyNowNFTBidOps(txn, utxoOpsForTxn, len(ops)) + ops = append(ops, buyNowNftBidOps...) - // Add inputs for bids on Buy Now NFTs - buyNowNftBidOps := node.getBuyNowNFTBidOps(txn, utxoOpsForTxn, len(ops)) - ops = append(ops, buyNowNftBidOps...) + // Add inputs for update profile + updateProfileOps := node.getUpdateProfileOps(txn, utxoOpsForTxn, len(ops)) + ops = append(ops, updateProfileOps...) - // Add inputs for update profile - updateProfileOps := node.getUpdateProfileOps(txn, utxoOpsForTxn, len(ops)) - ops = append(ops, updateProfileOps...) + // Add inputs for DAO Coin Limit Orders + daoCoinLimitOrderOps := node.getDAOCoinLimitOrderOps(txn, utxoOpsForTxn, len(ops)) + ops = append(ops, daoCoinLimitOrderOps...) - // Add inputs for DAO Coin Limit Orders - daoCoinLimitOrderOps := node.getDAOCoinLimitOrderOps(txn, utxoOpsForTxn, len(ops)) - ops = append(ops, daoCoinLimitOrderOps...) - } + // Add operations for stake transactions + stakeOps := node.getStakeOps(txn, utxoOpsForTxn, len(ops)) + ops = append(ops, stakeOps...) - transaction.Operations = squashOperations(ops) + // Add operations for unstake transactions + unstakeOps := node.getUnstakeOps(txn, utxoOpsForTxn, len(ops)) + ops = append(ops, unstakeOps...) - transactions = append(transactions, transaction) + // Add operations for unlock stake transactions + unlockStakeOps := node.getUnlockStakeOps(txn, utxoOpsForTxn, len(ops)) + ops = append(ops, unlockStakeOps...) } - - return transactions + return ops } func (node *Node) getBlockTransactionsWithHypersync(blockHeight uint64, blockHash *lib.BlockHash) []*types.Transaction { @@ -273,7 +363,7 @@ func (node *Node) getBlockTransactionsWithHypersync(blockHeight uint64, blockHas return []*types.Transaction{} } - balances, lockedBalances := node.Index.GetHypersyncBlockBalances(blockHeight) + balances, lockedBalances, stakedDESOBalances, lockedStakeDESOBalances := node.Index.GetHypersyncBlockBalances(blockHeight) // We create a fake genesis block that will contain a portion of the balances downloaded during hypersync. // In addition, we need to lowkey reinvent these transactions, including, in particular, their transaction @@ -302,7 +392,7 @@ func (node *Node) getBlockTransactionsWithHypersync(blockHeight uint64, blockHas TransactionIdentifier: &types.TransactionIdentifier{ Hash: nextHash.String(), }, - Operations: squashOperations([]*types.Operation{ + Operations: []*types.Operation{ { OperationIdentifier: &types.OperationIdentifier{ Index: 0, @@ -317,7 +407,7 @@ func (node *Node) getBlockTransactionsWithHypersync(blockHeight uint64, blockHas Status: &SuccessStatus, Type: OutputOpType, }, - }), + }, }) } for pk, balance := range lockedBalances { @@ -331,7 +421,7 @@ func (node *Node) getBlockTransactionsWithHypersync(blockHeight uint64, blockHas TransactionIdentifier: &types.TransactionIdentifier{ Hash: nextHash.String(), }, - Operations: squashOperations([]*types.Operation{ + Operations: []*types.Operation{ { OperationIdentifier: &types.OperationIdentifier{ Index: 0, @@ -349,7 +439,83 @@ func (node *Node) getBlockTransactionsWithHypersync(blockHeight uint64, blockHas Status: &SuccessStatus, Type: OutputOpType, }, - }), + }, + }) + } + + // We create a fake genesis block of all the staked DESO at the latest snapshot height. + // We represent all DESO staked to a single validator as a single subaccount. + // This mirrors how we treat creator coins, a pool of DESO as a subaccount of the creator. + // This acts as a pool of all the DESO staked in StakeEntry objects with a given Validator. + // We chose to use validators instead of stakers here as there are fewer validators and + // thus fewer subaccounts to keep track of. Note that we are using PKIDs for the validator + // instead of a public key, so we do not need to track balance changes when a validator + // has a swap identity performed on it. + // Account identifier: Validator PKID + // Subaccount identifier: VALIDATOR_ENTRY + for pkid, balance := range stakedDESOBalances { + if balance == 0 { + continue + } + nextHash := lib.Sha256DoubleHash([]byte(currentHash)) + currentHash = string(nextHash[:]) + transactions = append(transactions, &types.Transaction{ + TransactionIdentifier: &types.TransactionIdentifier{ + Hash: nextHash.String(), + }, + Operations: []*types.Operation{ + { + OperationIdentifier: &types.OperationIdentifier{ + Index: 0, + }, + Account: node.getValidatorEntrySubAccountIdentifierForValidator(lib.NewPKID(pkid[:])), + Amount: &types.Amount{ + Value: strconv.FormatUint(balance, 10), + Currency: &Currency, + }, + Status: &SuccessStatus, + Type: OutputOpType, + }, + }, + }) + } + + // We create a fake genesis block of all the locked stake DESO at the latest snapshot height. + // Locked stake DESO is represented as a subaccount of the staker. A locked stake entry is + // unique by the combination of Staker PKID + Validator PKID + LockedAtEpochNumber, so we + // use Validator PKID + LockedAtEpochNumber as the subaccount identifier. Note that we are + // using PKIDs for the validator and staker instead of public keys, so we do not need to + // track balance changes if a swap identity were performed on either. + // Account Identifier: Staker PKID + // Subaccount Identifier: LOCKED_STAKE_ENTRY || Validator PKID || LockedAtEpochNumber + for lockedStakeBalanceMapKey, balance := range lockedStakeDESOBalances { + if balance == 0 { + continue + } + nextHash := lib.Sha256DoubleHash([]byte(currentHash)) + currentHash = string(nextHash[:]) + transactions = append(transactions, &types.Transaction{ + TransactionIdentifier: &types.TransactionIdentifier{ + Hash: nextHash.String(), + }, + Operations: []*types.Operation{ + { + OperationIdentifier: &types.OperationIdentifier{ + Index: 0, + }, + Account: node.getLockedStakeEntryIdentifierForValidator( + &lockedStakeBalanceMapKey.StakerPKID, + &lockedStakeBalanceMapKey.ValidatorPKID, + lockedStakeBalanceMapKey.LockedAtEpochNumber, + ), + Amount: &types.Amount{ + Value: strconv.FormatUint(balance, 10), + Currency: &Currency, + }, + Status: &SuccessStatus, + Type: OutputOpType, + }, + }, }) } @@ -858,6 +1024,217 @@ func (node *Node) getBalanceModelSpends(txn *lib.MsgDeSoTxn, utxoOpsForTxn []*li return operations } +// getLockedStakeEntrySubAccountIdentifierForValidator returns a SubAccountIdentifier for a locked stake entry. +func (node *Node) getLockedStakeEntryIdentifierForValidator(stakerPKID *lib.PKID, validatorPKID *lib.PKID, lockedAtEpochNumber uint64) *types.AccountIdentifier { + return &types.AccountIdentifier{ + Address: lib.Base58CheckEncode(stakerPKID.ToBytes(), false, node.Params), + SubAccount: &types.SubAccountIdentifier{ + Address: fmt.Sprintf("%v-%v-%v", LockedStakeEntry, lib.Base58CheckEncode(validatorPKID.ToBytes(), false, node.Params), lockedAtEpochNumber), + }, + } +} + +func (node *Node) getValidatorEntrySubAccountIdentifierForValidator(validatorPKID *lib.PKID) *types.AccountIdentifier { + return &types.AccountIdentifier{ + Address: lib.Base58CheckEncode(validatorPKID.ToBytes(), false, node.Params), + SubAccount: &types.SubAccountIdentifier{ + Address: ValidatorEntry, + }, + } +} + +func (node *Node) GetValidatorPKIDFromSubAccountIdentifier(subAccount *types.SubAccountIdentifier) (*lib.PKID, error) { + if subAccount == nil || !strings.HasPrefix(subAccount.Address, LockedStakeEntry) { + return nil, fmt.Errorf("invalid subaccount for validator PKID extraction") + } + segments := strings.Split(subAccount.Address, "-") + if len(segments) != 2 { + return nil, fmt.Errorf("invalid subaccount for validator PKID extraction") + } + validatorPKIDBytes, _, err := lib.Base58CheckDecode(segments[1]) + if err != nil { + return nil, fmt.Errorf("invalid subaccount for validator PKID extraction") + } + return lib.NewPKID(validatorPKIDBytes), nil +} + +func (node *Node) getStakeOps(txn *lib.MsgDeSoTxn, utxoOps []*lib.UtxoOperation, numOps int) []*types.Operation { + if txn.TxnMeta.GetTxnType() != lib.TxnTypeStake { + return nil + } + + var operations []*types.Operation + for _, utxoOp := range utxoOps { + // We only need an OUTPUT operation here as the INPUT operation + // is covered by the getBalanceModelSpends function. + if utxoOp.Type == lib.OperationTypeStake { + prevValidatorEntry := utxoOp.PrevValidatorEntry + if prevValidatorEntry == nil { + // TODO: This is a bad error... + glog.Error("getStakeOps: prevValidatorEntry was nil") + continue + } + realTxMeta := txn.TxnMeta.(*lib.StakeMetadata) + if realTxMeta == nil { + glog.Error("getStakeOps: realTxMeta was nil") + continue + } + stakeAmountNanos := realTxMeta.StakeAmountNanos + if !stakeAmountNanos.IsUint64() { + glog.Error("getStakeOps: stakeAmountNanos was not a uint64") + continue + } + stakeAmountNanosUint64 := stakeAmountNanos.Uint64() + + operations = append(operations, &types.Operation{ + OperationIdentifier: &types.OperationIdentifier{ + Index: int64(numOps), + }, + Account: node.getValidatorEntrySubAccountIdentifierForValidator(prevValidatorEntry.ValidatorPKID), + Amount: &types.Amount{ + Value: strconv.FormatUint(stakeAmountNanosUint64, 10), + Currency: &Currency, + }, + Status: &SuccessStatus, + Type: OutputOpType, + }) + numOps++ + } + } + return operations +} + +func (node *Node) getUnstakeOps(txn *lib.MsgDeSoTxn, utxoOps []*lib.UtxoOperation, numOps int) []*types.Operation { + if txn.TxnMeta.GetTxnType() != lib.TxnTypeUnstake { + return nil + } + + var operations []*types.Operation + for _, utxoOp := range utxoOps { + if utxoOp.Type == lib.OperationTypeUnstake { + prevValidatorEntry := utxoOp.PrevValidatorEntry + if prevValidatorEntry == nil { + glog.Error("getUnstakeOps: prevValidatorEntry was nil") + continue + } + prevStakeEntries := utxoOp.PrevStakeEntries + if len(prevStakeEntries) != 1 { + glog.Error("getUnstakeOps: prevStakeEntries was not of length 1") + continue + } + prevStakeEntry := prevStakeEntries[0] + realTxMeta := txn.TxnMeta.(*lib.UnstakeMetadata) + if realTxMeta == nil { + glog.Error("getUnstakeOps: realTxMeta was nil") + continue + } + unstakeAmountNanos := realTxMeta.UnstakeAmountNanos + if !unstakeAmountNanos.IsUint64() { + glog.Error("getUnstakeOps: unstakeAmountNanos was not a uint64") + continue + } + unstakeAmountNanosUint64 := unstakeAmountNanos.Uint64() + // First use an "input" from the ValidatorEntry + operations = append(operations, &types.Operation{ + OperationIdentifier: &types.OperationIdentifier{ + Index: int64(numOps), + }, + Account: node.getValidatorEntrySubAccountIdentifierForValidator(prevValidatorEntry.ValidatorPKID), + Amount: &types.Amount{ + Value: strconv.FormatUint(unstakeAmountNanosUint64, 10), + Currency: &Currency, + }, + Status: &SuccessStatus, + Type: InputOpType, + }) + numOps++ + operations = append(operations, &types.Operation{ + OperationIdentifier: &types.OperationIdentifier{ + Index: int64(numOps), + }, + Account: node.getLockedStakeEntryIdentifierForValidator( + prevStakeEntry.StakerPKID, + prevValidatorEntry.ValidatorPKID, + utxoOp.LockedAtEpochNumber, + ), + Amount: &types.Amount{ + Value: strconv.FormatUint(unstakeAmountNanosUint64, 10), + Currency: &Currency, + }, + Status: &SuccessStatus, + Type: OutputOpType, + }) + numOps++ + } + } + return operations +} + +func (node *Node) getUnlockStakeOps(txn *lib.MsgDeSoTxn, utxoOps []*lib.UtxoOperation, numOps int) []*types.Operation { + if txn.TxnMeta.GetTxnType() != lib.TxnTypeUnlockStake { + return nil + } + + var operations []*types.Operation + for _, utxoOp := range utxoOps { + if utxoOp.Type == lib.OperationTypeUnlockStake { + for _, prevLockedStakeEntry := range utxoOp.PrevLockedStakeEntries { + if !prevLockedStakeEntry.LockedAmountNanos.IsUint64() { + glog.Error("getUnlockStakeOps: lockedAmountNanos was not a uint64") + continue + } + lockedAmountNanosUint64 := prevLockedStakeEntry.LockedAmountNanos.Uint64() + // Each locked stake entry is an "input" to the UnlockStake txn + // We spend ALL the lockedAmountNanos from each locked stake entry in + // an unlocked transaction + operations = append(operations, &types.Operation{ + OperationIdentifier: &types.OperationIdentifier{ + Index: int64(numOps), + }, + Account: node.getLockedStakeEntryIdentifierForValidator( + prevLockedStakeEntry.StakerPKID, + prevLockedStakeEntry.ValidatorPKID, + prevLockedStakeEntry.LockedAtEpochNumber, + ), + Amount: &types.Amount{ + Value: strconv.FormatUint(lockedAmountNanosUint64, 10), + Currency: &Currency, + }, + Status: &SuccessStatus, + Type: InputOpType, + }) + numOps++ + } + } + } + return operations +} + +func (node *Node) getStakingRewardDistributionOps(utxoOps []*lib.UtxoOperation, numOps int) []*types.Operation { + var operations []*types.Operation + + for _, utxoOp := range utxoOps { + if utxoOp.Type == lib.OperationTypeStakeDistributionRestake { + prevValidatorEntry := utxoOp.PrevValidatorEntry + operations = append(operations, &types.Operation{ + OperationIdentifier: &types.OperationIdentifier{ + Index: int64(numOps), + }, + Account: node.getValidatorEntrySubAccountIdentifierForValidator(prevValidatorEntry.ValidatorPKID), + Amount: &types.Amount{ + Value: strconv.FormatUint(utxoOp.StakeAmountNanosDiff, 10), + Currency: &Currency, + }, + + Status: &SuccessStatus, + Type: OutputOpType, + }) + numOps++ + } + } + return operations +} + func (node *Node) getImplicitOutputs(txn *lib.MsgDeSoTxn, utxoOpsForTxn []*lib.UtxoOperation, numOps int) []*types.Operation { var operations []*types.Operation numOutputs := uint32(len(txn.TxOutputs)) @@ -887,7 +1264,8 @@ func (node *Node) getImplicitOutputs(txn *lib.MsgDeSoTxn, utxoOpsForTxn []*lib.U numOps++ } - if utxoOp.Type == lib.OperationTypeAddBalance { + if utxoOp.Type == lib.OperationTypeAddBalance || + utxoOp.Type == lib.OperationTypeStakeDistributionPayToBalance { operations = append(operations, &types.Operation{ OperationIdentifier: &types.OperationIdentifier{ Index: int64(numOps), diff --git a/deso/block_test.go b/deso/block_test.go index 9b1382be..d2c81302 100644 --- a/deso/block_test.go +++ b/deso/block_test.go @@ -3,11 +3,12 @@ package deso import ( "encoding/hex" "fmt" - "github.com/deso-protocol/core/lib" - "github.com/dgraph-io/badger/v3" - "github.com/stretchr/testify/require" "path/filepath" "testing" + + "github.com/deso-protocol/core/lib" + "github.com/dgraph-io/badger/v4" + "github.com/stretchr/testify/require" ) // This test is no longer needed, but we keep it here because it initializes a simplified node and index and might be @@ -37,12 +38,12 @@ func TestUtxoOpsProblem(t *testing.T) { rosettaIndexOpts.ValueDir = rosettaIndexDir rosettaIndex, err := badger.Open(rosettaIndexOpts) require.NoError(err) - node.Index = NewIndex(rosettaIndex) + node.Index = NewIndex(rosettaIndex, node.chainDB) // Listen to transaction and block events so we can fill RosettaIndex with relevant data node.EventManager = lib.NewEventManager() node.EventManager.OnTransactionConnected(node.handleTransactionConnected) - node.EventManager.OnBlockConnected(node.handleBlockConnected) + node.EventManager.OnBlockConnected(node.handleBlockCommitted) node.EventManager.OnSnapshotCompleted(node.handleSnapshotCompleted) minerCount := uint64(1) @@ -59,16 +60,18 @@ func TestUtxoOpsProblem(t *testing.T) { node.Server, err, _ = lib.NewServer( node.Config.Params, - nil, - nil, - []string{}, - node.chainDB, - nil, + node.Config.Regtest, + nil, // listeners + nil, // addrMgr + []string{}, // connectIPs + node.chainDB, // db + nil, // postgres targetOutboundPeers, maxInboundPeers, - []string{}, + []string{}, // miner public keys minerCount, true, + 10000, // peer connection refresh interval millis false, lib.NodeSyncTypeBlockSync, 0, @@ -95,6 +98,12 @@ func TestUtxoOpsProblem(t *testing.T) { node.Config.ForceChecksum, "", lib.HypersyncDefaultMaxQueueSize, + nil, // TODO: support for rosetta as a validator? + 30000, // 30 seconds mempool back up time millis + 10000, // mempool max validation view connects + 1500, // 1500 milliseconds, pos block production interval milliseconds + 10000, // State syncer mempool txn sync limit + nil, // checkpoint syncing providers ) require.NoError(err) diff --git a/deso/config.go b/deso/config.go index 09b07aec..741cbe3b 100644 --- a/deso/config.go +++ b/deso/config.go @@ -22,6 +22,8 @@ type Config struct { NodePort int DataDirectory string MinerPublicKeys []string + BlockProducerSeed string + PosValidatorSeed string Regtest bool ConnectIPs []string HyperSync bool @@ -72,6 +74,8 @@ func LoadConfig() (*Config, error) { result.Port = viper.GetInt("port") result.NodePort = viper.GetInt("node-port") result.MinerPublicKeys = viper.GetStringSlice("miner-public-keys") + result.BlockProducerSeed = viper.GetString("block-producer-seed") + result.PosValidatorSeed = viper.GetString("pos-validator-seed") result.Regtest = viper.GetBool("regtest") result.ConnectIPs = viper.GetStringSlice("connect-ips") diff --git a/deso/events.go b/deso/events.go index 45b5a3da..e154de35 100644 --- a/deso/events.go +++ b/deso/events.go @@ -1,14 +1,23 @@ package deso import ( + "bytes" "fmt" - "github.com/btcsuite/btcd/btcec" + "github.com/btcsuite/btcd/btcec/v2" "github.com/deso-protocol/core/lib" - "github.com/dgraph-io/badger/v3" + "github.com/dgraph-io/badger/v4" "github.com/golang/glog" "github.com/pkg/errors" + "math" + "time" ) +type LockedStakeBalanceMapKey struct { + StakerPKID lib.PKID + ValidatorPKID lib.PKID + LockedAtEpochNumber uint64 +} + func (node *Node) handleSnapshotCompleted() { node.Index.dbMutex.Lock() defer node.Index.dbMutex.Unlock() @@ -18,6 +27,12 @@ func (node *Node) handleSnapshotCompleted() { if snapshot != nil && snapshot.CurrentEpochSnapshotMetadata.FirstSnapshotBlockHeight != 0 { + writeBatchSize := uint64(100) + glog.Infof("handleSnapshotCompleted: handling snapshot with first snapshot block height %d "+ + "and snapshot block height of %d with batch size of %v", + snapshot.CurrentEpochSnapshotMetadata.FirstSnapshotBlockHeight, + snapshot.CurrentEpochSnapshotMetadata.SnapshotBlockHeight, + writeBatchSize) // If we're at exactly the snapshot height then we've got some work to do. // Output every single balance in the db to a special index. This will // bootstrap Rosetta, and allow us to pass check:data. This is because we @@ -32,67 +47,93 @@ func (node *Node) handleSnapshotCompleted() { // the snapshot height rather than the true genesis. This allows us to pass // check:data without introducing complications for Coinbase. snapshotBlockHeight := snapshot.CurrentEpochSnapshotMetadata.FirstSnapshotBlockHeight + statusLoggingInterval := uint64(100) { // Iterate through every single public key and put a balance snapshot down // for it for this block. We don't need to worry about ancestral records here // because we haven't generated any yet. - - err := node.Index.db.Update(func(indexTxn *badger.Txn) error { - return node.GetBlockchain().DB().View(func(chainTxn *badger.Txn) error { - opts := badger.DefaultIteratorOptions - nodeIterator := chainTxn.NewIterator(opts) - defer nodeIterator.Close() - prefix := lib.Prefixes.PrefixPublicKeyToDeSoBalanceNanos - - // Partition the balances across the blocks before the snapshot block height. - totalCount := uint64(0) - for nodeIterator.Seek(prefix); nodeIterator.ValidForPrefix(prefix); nodeIterator.Next() { - totalCount++ + wb := node.Index.db.NewWriteBatch() + defer wb.Cancel() + err := node.GetBlockchain().DB().View(func(chainTxn *badger.Txn) error { + opts := badger.DefaultIteratorOptions + //// We don't prefetch values when iterating over the keys. + //opts.PrefetchValues = false + // Set prefix on iterator options + opts.Prefix = lib.Prefixes.PrefixPublicKeyToDeSoBalanceNanos + nodeIterator := chainTxn.NewIterator(opts) + defer nodeIterator.Close() + prefix := lib.Prefixes.PrefixPublicKeyToDeSoBalanceNanos + + // Partition the balances across the blocks before the snapshot block height. + totalCount := uint64(0) + startTime := time.Now() + for nodeIterator.Seek(prefix); nodeIterator.ValidForPrefix(prefix); nodeIterator.Next() { + totalCount++ + } + glog.Infof("handleSnapshotCompleted: Counting public keys took: %v", time.Since(startTime)) + currentBlockHeight := uint64(1) + // We'll force a ceiling on this because otherwise the last block could amass O(snapshotBlockHeight) balances + balancesPerBlock := totalCount / snapshotBlockHeight + balancesMap := make(map[lib.PublicKey]uint64) + if totalCount < snapshotBlockHeight { + balancesPerBlock = 1 + } + currentCounter := uint64(0) + currentTime := time.Now() + //// Create a new node iterator w/ prefetch values set to true. + //opts.PrefetchValues = true + //nodeIterator = chainTxn.NewIterator(opts) + for nodeIterator.Seek(prefix); nodeIterator.ValidForPrefix(prefix); nodeIterator.Next() { + key := nodeIterator.Item().Key() + keyCopy := make([]byte, len(key)) + copy(keyCopy[:], key[:]) + + valCopy, err := nodeIterator.Item().ValueCopy(nil) + if err != nil { + return errors.Wrapf(err, "Problem iterating over chain database, "+ + "on key (%v) and value (%v)", keyCopy, valCopy) } - currentBlockHeight := uint64(1) - // We'll force a ceiling on this because otherwise the last block could amass O(snapshotBlockHeight) balances - balancesPerBlock := totalCount / snapshotBlockHeight - balancesMap := make(map[lib.PublicKey]uint64) - if totalCount < snapshotBlockHeight { - balancesPerBlock = 1 - } - currentCounter := uint64(0) - - for nodeIterator.Seek(prefix); nodeIterator.ValidForPrefix(prefix); nodeIterator.Next() { - key := nodeIterator.Item().Key() - keyCopy := make([]byte, len(key)) - copy(keyCopy[:], key[:]) - valCopy, err := nodeIterator.Item().ValueCopy(nil) - if err != nil { - return errors.Wrapf(err, "Problem iterating over chain database, "+ - "on key (%v) and value (%v)", keyCopy, valCopy) - } + balance := lib.DecodeUint64(valCopy) + pubKey := lib.NewPublicKey(key[1:]) + balancesMap[*pubKey] = balance - balance := lib.DecodeUint64(valCopy) - pubKey := lib.NewPublicKey(key[1:]) - balancesMap[*pubKey] = balance - - if err := node.Index.PutSingleBalanceSnapshotWithTxn( - indexTxn, currentBlockHeight, false, *pubKey, balance); err != nil { - return errors.Wrapf(err, "Problem updating balance snapshot in index, "+ - "on key (%v), value (%v), and height (%v)", keyCopy, valCopy, - snapshot.CurrentEpochSnapshotMetadata.FirstSnapshotBlockHeight) - } + if err := node.Index.PutSingleBalanceSnapshotWithWB( + wb, currentBlockHeight, DESOBalance, *pubKey, balance); err != nil { + return errors.Wrapf(err, "Problem updating balance snapshot in index, "+ + "on key (%v), value (%v), and height (%v)", keyCopy, valCopy, + snapshot.CurrentEpochSnapshotMetadata.FirstSnapshotBlockHeight) + } - currentCounter += 1 - if currentCounter >= balancesPerBlock && currentBlockHeight < snapshotBlockHeight { - node.Index.PutHypersyncBlockBalances(currentBlockHeight, false, balancesMap) - balancesMap = make(map[lib.PublicKey]uint64) - currentBlockHeight++ - currentCounter = 0 + currentCounter += 1 + if currentCounter%statusLoggingInterval == 0 { + glog.Infof("handleSnapshotCompleted: Processed %d of %d balances in %v. %d%% complete", + currentCounter, totalCount, time.Since(currentTime), (100*currentCounter)/totalCount) + currentTime = time.Now() + } + if currentCounter >= balancesPerBlock && currentBlockHeight < snapshotBlockHeight { + node.Index.PutHypersyncBlockBalancesWithWB(wb, currentBlockHeight, DESOBalance, balancesMap) + balancesMap = make(map[lib.PublicKey]uint64) + currentBlockHeight++ + currentCounter = 0 + if currentBlockHeight%writeBatchSize == 0 { + flushTime := time.Now() + if err = wb.Flush(); err != nil { + return errors.Wrapf(err, "Problem flushing write batch") + } + glog.Infof("handleSnapshotCompleted: Flush took: %v", time.Since(flushTime)) } } - if currentCounter > 0 { - node.Index.PutHypersyncBlockBalances(currentBlockHeight, false, balancesMap) + } + if currentCounter > 0 { + node.Index.PutHypersyncBlockBalancesWithWB(wb, currentBlockHeight, DESOBalance, balancesMap) + flushTime := time.Now() + if err := wb.Flush(); err != nil { + return errors.Wrapf(err, "Problem flushing write batch") } - return nil - }) + glog.Infof("handleSnapshotCompleted: Flush took: %v", time.Since(flushTime)) + } + return nil }) if err != nil { glog.Errorf(lib.CLog(lib.Red, fmt.Sprintf("handleSnapshotCompleted: error: (%v)", err))) @@ -109,87 +150,110 @@ func (node *Node) handleSnapshotCompleted() { // // TODO: Do we need to do anything special for SwapIdentity? See below for // some tricky logic there. - - err := node.Index.db.Update(func(indexTxn *badger.Txn) error { - // This is pretty much the same as lib.DBGetAllProfilesByCoinValue but we don't load all entries into memory. - return node.GetBlockchain().DB().View(func(chainTxn *badger.Txn) error { - dbPrefixx := append([]byte{}, lib.Prefixes.PrefixCreatorDeSoLockedNanosCreatorPKID...) - opts := badger.DefaultIteratorOptions - opts.PrefetchValues = false - // Go in reverse order since a larger count is better. - opts.Reverse = true - - it := chainTxn.NewIterator(opts) - defer it.Close() - - totalCount := uint64(0) - for it.Seek(dbPrefixx); it.ValidForPrefix(dbPrefixx); it.Next() { - totalCount++ + wb := node.Index.db.NewWriteBatch() + defer wb.Cancel() + // This is pretty much the same as lib.DBGetAllProfilesByCoinValue but we don't load all entries into memory. + err := node.GetBlockchain().DB().View(func(chainTxn *badger.Txn) error { + dbPrefixx := append([]byte{}, lib.Prefixes.PrefixCreatorDeSoLockedNanosCreatorPKID...) + opts := badger.DefaultIteratorOptions + opts.PrefetchValues = false + // Go in reverse order since a larger count is better. + opts.Reverse = true + + // Set the prefix on the iterator options + opts.Prefix = dbPrefixx + + it := chainTxn.NewIterator(opts) + defer it.Close() + + totalCount := uint64(0) + startTime := time.Now() + for it.Seek(dbPrefixx); it.ValidForPrefix(dbPrefixx); it.Next() { + totalCount++ + } + glog.Infof("handleSnapshotCompleted: Counting CC locked balance public keys took: %v", time.Since(startTime)) + currentBlockHeight := uint64(1) + balancesPerBlock := totalCount / snapshotBlockHeight + balancesMap := make(map[lib.PublicKey]uint64) + if totalCount < snapshotBlockHeight { + balancesPerBlock = 1 + } + currentCounter := uint64(0) + currentTime := time.Now() + // Since we iterate backwards, the prefix must be bigger than all possible + // counts that could actually exist. We use eight bytes since the count is + // encoded as a 64-bit big-endian byte slice, which will be eight bytes long. + maxBigEndianUint64Bytes := []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} + prefix := append(dbPrefixx, maxBigEndianUint64Bytes...) + for it.Seek(prefix); it.ValidForPrefix(dbPrefixx); it.Next() { + rawKey := it.Item().Key() + + // Strip the prefix off the key and check its length. If it contains + // a big-endian uint64 then it should be at least eight bytes. + lockedDeSoPubKeyConcatKey := rawKey[1:] + uint64BytesLen := len(maxBigEndianUint64Bytes) + expectedLength := uint64BytesLen + btcec.PubKeyBytesLenCompressed + if len(lockedDeSoPubKeyConcatKey) != expectedLength { + return fmt.Errorf("Invalid key length %d should be at least %d", + len(lockedDeSoPubKeyConcatKey), expectedLength) } - currentBlockHeight := uint64(1) - balancesPerBlock := totalCount / snapshotBlockHeight - balancesMap := make(map[lib.PublicKey]uint64) - if totalCount < snapshotBlockHeight { - balancesPerBlock = 1 - } - currentCounter := uint64(0) - - // Since we iterate backwards, the prefix must be bigger than all possible - // counts that could actually exist. We use eight bytes since the count is - // encoded as a 64-bit big-endian byte slice, which will be eight bytes long. - maxBigEndianUint64Bytes := []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} - prefix := append(dbPrefixx, maxBigEndianUint64Bytes...) - for it.Seek(prefix); it.ValidForPrefix(dbPrefixx); it.Next() { - rawKey := it.Item().Key() - - // Strip the prefix off the key and check its length. If it contains - // a big-endian uint64 then it should be at least eight bytes. - lockedDeSoPubKeyConcatKey := rawKey[1:] - uint64BytesLen := len(maxBigEndianUint64Bytes) - expectedLength := uint64BytesLen + btcec.PubKeyBytesLenCompressed - if len(lockedDeSoPubKeyConcatKey) != expectedLength { - return fmt.Errorf("Invalid key length %d should be at least %d", - len(lockedDeSoPubKeyConcatKey), expectedLength) - } - lockedDeSoNanos := lib.DecodeUint64(lockedDeSoPubKeyConcatKey[:uint64BytesLen]) + lockedDeSoNanos := lib.DecodeUint64(lockedDeSoPubKeyConcatKey[:uint64BytesLen]) - // Appended to the stake should be the profile pub key so extract it here. - profilePKIDbytes := make([]byte, btcec.PubKeyBytesLenCompressed) - copy(profilePKIDbytes[:], lockedDeSoPubKeyConcatKey[uint64BytesLen:]) - profilePKID := lib.PublicKeyToPKID(profilePKIDbytes) + // Appended to the stake should be the profile pub key so extract it here. + profilePKIDbytes := make([]byte, btcec.PubKeyBytesLenCompressed) + copy(profilePKIDbytes[:], lockedDeSoPubKeyConcatKey[uint64BytesLen:]) + profilePKID := lib.PublicKeyToPKID(profilePKIDbytes) - pkBytes := lib.DBGetPublicKeyForPKIDWithTxn(chainTxn, nil, profilePKID) - if pkBytes == nil { - return fmt.Errorf("DBGetPublicKeyForPKIDWithTxn: Nil pkBytes for pkid %v", - lib.PkToStringMainnet(profilePKID[:])) - } - pubKey := *lib.NewPublicKey(pkBytes) - balancesMap[pubKey] = lockedDeSoNanos + pkBytes := lib.DBGetPublicKeyForPKIDWithTxn(chainTxn, nil, profilePKID) + if pkBytes == nil { + return fmt.Errorf("DBGetPublicKeyForPKIDWithTxn: Nil pkBytes for pkid %v", + lib.PkToStringMainnet(profilePKID[:])) + } + pubKey := *lib.NewPublicKey(pkBytes) + balancesMap[pubKey] = lockedDeSoNanos - // We have to also put the balances in the other index. Not doing this would cause - // balances to return zero when we're PAST the first snapshot block height. - if err := node.Index.PutSingleBalanceSnapshotWithTxn( - indexTxn, currentBlockHeight, true, pubKey, lockedDeSoNanos); err != nil { + // We have to also put the balances in the other index. Not doing this would cause + // balances to return zero when we're PAST the first snapshot block height. + if err := node.Index.PutSingleBalanceSnapshotWithWB( + wb, currentBlockHeight, CreatorCoinLockedBalance, pubKey, lockedDeSoNanos); err != nil { - return errors.Wrapf(err, "PutSingleBalanceSnapshotWithTxn: problem with "+ - "pubkey (%v), lockedDeSoNanos (%v) and firstSnapshotHeight (%v)", - pubKey, lockedDeSoNanos, snapshot.CurrentEpochSnapshotMetadata.FirstSnapshotBlockHeight) - } + return errors.Wrapf(err, "PutSingleBalanceSnapshotWithWB: problem with "+ + "pubkey (%v), lockedDeSoNanos (%v) and firstSnapshotHeight (%v)", + pubKey, lockedDeSoNanos, snapshot.CurrentEpochSnapshotMetadata.FirstSnapshotBlockHeight) + } - currentCounter += 1 - if currentCounter >= balancesPerBlock && currentBlockHeight < snapshotBlockHeight { - node.Index.PutHypersyncBlockBalances(currentBlockHeight, true, balancesMap) - balancesMap = make(map[lib.PublicKey]uint64) - currentBlockHeight++ - currentCounter = 0 + currentCounter += 1 + if currentCounter%statusLoggingInterval == 0 { + glog.Infof("handleSnapshotCompleted: Processed %d of %d locked creator coin balances in %v. %d%% complete", + currentCounter, totalCount, time.Since(currentTime), (100*currentCounter)/totalCount) + currentTime = time.Now() + } + if currentCounter >= balancesPerBlock && currentBlockHeight < snapshotBlockHeight { + node.Index.PutHypersyncBlockBalancesWithWB( + wb, currentBlockHeight, CreatorCoinLockedBalance, balancesMap) + balancesMap = make(map[lib.PublicKey]uint64) + currentBlockHeight++ + currentCounter = 0 + if currentBlockHeight%writeBatchSize == 0 { + flushTime := time.Now() + if err := wb.Flush(); err != nil { + return errors.Wrapf(err, "Problem flushing write batch") + } + glog.Infof("handleSnapshotCompleted: CC Locked balance Flush took: %v", time.Since(flushTime)) } } - if currentCounter > 0 { - node.Index.PutHypersyncBlockBalances(currentBlockHeight, true, balancesMap) + } + if currentCounter > 0 { + node.Index.PutHypersyncBlockBalancesWithWB( + wb, currentBlockHeight, CreatorCoinLockedBalance, balancesMap) + flushTime := time.Now() + if err := wb.Flush(); err != nil { + return errors.Wrapf(err, "Problem flushing write batch") } - return nil - }) + glog.Infof("handleSnapshotCompleted: CC Locked balance Flush took: %v", time.Since(flushTime)) + } + return nil }) if err != nil { glog.Errorf(lib.CLog(lib.Red, fmt.Sprintf("handleSnapshotCompleted: Problem iterating locked "+ @@ -197,11 +261,250 @@ func (node *Node) handleSnapshotCompleted() { } } - return + // Create a new scope to avoid name collision errors + { + // Iterate over all the validator entries in the db, look up the corresponding public + // keys, and then set all the validator entry balances in the db. + // + // No need to pass the snapshot because we know we don't have any ancestral + // records yet. + wb := node.Index.db.NewWriteBatch() + defer wb.Cancel() + // TODO: check all these comments. + err := node.GetBlockchain().DB().View(func(chainTxn *badger.Txn) error { + dbPrefixx := append([]byte{}, lib.Prefixes.PrefixValidatorByStatusAndStakeAmount...) + opts := badger.DefaultIteratorOptions + opts.PrefetchValues = false + // Go in reverse order since a larger count is better. + opts.Reverse = true + + // Set prefix on iterator + opts.Prefix = dbPrefixx + + it := chainTxn.NewIterator(opts) + defer it.Close() + + totalCount := uint64(0) + startTime := time.Now() + // TODO: I really hate how we iterate over the index twice + // for each balance type. We can do better. + for it.Seek(dbPrefixx); it.ValidForPrefix(dbPrefixx); it.Next() { + totalCount++ + } + glog.Infof("handleSnapshotCompleted: Counting validator entries took: %v", time.Since(startTime)) + currentBlockHeight := uint64(1) + balancesPerBlock := totalCount / snapshotBlockHeight + validatorEntryBalances := make(map[lib.PublicKey]uint64) + if totalCount < snapshotBlockHeight { + balancesPerBlock = 1 + } + currentCounter := uint64(0) + currentTime := time.Now() + // The key for the validator by status and stake amount looks like + // this: Prefix, , , -> nil + // So we need to chop off the status to pull out the total stake amount nanos and the validator PKID + maxUint256 := lib.FixedWidthEncodeUint256(lib.MaxUint256) + prefix := append(dbPrefixx, lib.EncodeUint8(math.MaxUint8)...) + prefix = append(prefix, maxUint256...) + for it.Seek(prefix); it.ValidForPrefix(dbPrefixx); it.Next() { + rawKey := it.Item().Key() + + // Strip the prefix and status off the key and check its length. It + // should contain a uint256 followed by a validator PKID. + totalStakeAmountAndValidatorPKIDKey := rawKey[2:] + expectedLength := len(maxUint256) + btcec.PubKeyBytesLenCompressed + if len(totalStakeAmountAndValidatorPKIDKey) != expectedLength { + return fmt.Errorf("invalid key length %d should be at least %d", + len(totalStakeAmountAndValidatorPKIDKey), expectedLength) + } + rr := bytes.NewReader(totalStakeAmountAndValidatorPKIDKey) + totalStakeAmountNanos, err := lib.FixedWidthDecodeUint256(rr) + if err != nil { + return fmt.Errorf("problem decoding stake amount: %v", err) + } + if !totalStakeAmountNanos.IsUint64() { + return fmt.Errorf("FixedWidthDecodeUint256: Stake amount is not a uint64") + } + validatorPKIDBytes := make([]byte, btcec.PubKeyBytesLenCompressed) + _, err = rr.Read(validatorPKIDBytes[:]) + if err != nil { + return fmt.Errorf("problem reading validator PKID: %v", err) + } + // For simplicity, we just interpret the PKID as a public key + // so we can reuse existing functions. + validatorPubKey := *lib.NewPublicKey(validatorPKIDBytes) + validatorEntryBalances[validatorPubKey] = totalStakeAmountNanos.Uint64() + + // We have to also put the balances in the other index. Not doing this would cause + // balances to return zero when we're PAST the first snapshot block height. + if err = node.Index.PutSingleBalanceSnapshotWithWB( + wb, currentBlockHeight, ValidatorStakedDESOBalance, validatorPubKey, + totalStakeAmountNanos.Uint64()); err != nil { + return errors.Wrapf(err, "PutSingleBalanceSnapshotWithWB: problem with "+ + "validatorPubKey (%v), totalStakeAmountNanos (%v) and firstSnapshotHeight (%v)", + validatorPubKey, totalStakeAmountNanos, + snapshot.CurrentEpochSnapshotMetadata.FirstSnapshotBlockHeight) + } + + currentCounter++ + if currentCounter%statusLoggingInterval == 0 { + glog.Infof("handleSnapshotCompleted: Processed %d of %d validator staked balances in %v. %d%% complete", + currentCounter, totalCount, time.Since(currentTime), (100*currentCounter)/totalCount) + currentTime = time.Now() + } + if currentCounter >= balancesPerBlock && currentBlockHeight < snapshotBlockHeight { + node.Index.PutHypersyncBlockBalancesWithWB( + wb, currentBlockHeight, ValidatorStakedDESOBalance, validatorEntryBalances) + validatorEntryBalances = make(map[lib.PublicKey]uint64) + currentBlockHeight++ + currentCounter = 0 + if currentBlockHeight%writeBatchSize == 0 { + flushTime := time.Now() + if err = wb.Flush(); err != nil { + return errors.Wrapf(err, "Problem flushing write batch") + } + glog.Infof("handleSnapshotCompleted: Validator staked balance Flush took: %v", time.Since(flushTime)) + } + } + } + if currentCounter > 0 { + node.Index.PutHypersyncBlockBalancesWithWB( + wb, currentBlockHeight, ValidatorStakedDESOBalance, validatorEntryBalances) + flushTime := time.Now() + if err := wb.Flush(); err != nil { + return errors.Wrapf(err, "Problem flushing write batch") + } + glog.Infof("handleSnapshotCompleted: Validator staked balance Flush took: %v", time.Since(flushTime)) + } + return nil + }) + if err != nil { + glog.Errorf(lib.CLog(lib.Red, fmt.Sprintf("handleSnapshotCompleted: Problem iterating staked "+ + "balances DeSo nanos: error: (%v)", err))) + } + } + + // Create a new scope to avoid name collision errors + { + // Iterate over all the locked stake entries in the db, look up the corresponding public + // keys, and then set all the locked stake entry balances in the db. + // + // No need to pass the snapshot because we know we don't have any ancestral + // records yet. + + wb := node.Index.db.NewWriteBatch() + // TODO: check all these comments. + err := node.GetBlockchain().DB().View(func(chainTxn *badger.Txn) error { + dbPrefixx := append([]byte{}, lib.Prefixes.PrefixLockedStakeByValidatorAndStakerAndLockedAt...) + opts := badger.DefaultIteratorOptions + opts.PrefetchValues = true + // Go in reverse order since a larger count is better. + opts.Reverse = true + + // Set prefix on iterator + opts.Prefix = dbPrefixx + + it := chainTxn.NewIterator(opts) + defer it.Close() + + totalCount := uint64(0) + startTime := time.Now() + // TODO: I really hate how we iterate over the index twice + // for each balance type. We can do better. + for it.Seek(dbPrefixx); it.ValidForPrefix(dbPrefixx); it.Next() { + totalCount++ + } + glog.Infof("handleSnapshotCompleted: Counting locked stake entries took: %v", time.Since(startTime)) + currentBlockHeight := uint64(1) + balancesPerBlock := totalCount / snapshotBlockHeight + lockedStakerValidatorBalances := make(map[LockedStakeBalanceMapKey]uint64) + if totalCount < snapshotBlockHeight { + balancesPerBlock = 1 + } + currentCounter := uint64(0) + currentTime := time.Now() + for it.Seek(dbPrefixx); it.ValidForPrefix(dbPrefixx); it.Next() { + rawValueCopy, err := it.Item().ValueCopy(nil) + if err != nil { + return errors.Wrapf(err, "Problem iterating over chain database, "+ + "on key (%v) and value (%v)", it.Item().Key(), rawValueCopy) + } + rr := bytes.NewReader(rawValueCopy) + lockedStakeEntry, err := lib.DecodeDeSoEncoder(&lib.LockedStakeEntry{}, rr) + if err != nil { + return errors.Wrapf(err, "Problem decoding locked stake entry: %v", err) + } + if !lockedStakeEntry.LockedAmountNanos.IsUint64() { + return fmt.Errorf("LockedAmountNanos is not a uint64") + } + if !lockedStakeEntry.LockedAmountNanos.IsUint64() { + return fmt.Errorf("LockedAtEpochNumber is not a uint64") + } + lockedStakeAmountNanos := lockedStakeEntry.LockedAmountNanos.Uint64() + + lockedStakerMapKey := LockedStakeBalanceMapKey{ + StakerPKID: *lockedStakeEntry.StakerPKID, + ValidatorPKID: *lockedStakeEntry.ValidatorPKID, + LockedAtEpochNumber: lockedStakeEntry.LockedAtEpochNumber, + } + lockedStakerValidatorBalances[lockedStakerMapKey] = lockedStakeAmountNanos + + // We have to also put the balances in the other index. Not doing this would cause + // balances to return zero when we're PAST the first snapshot block height. We are + // writing to the same key multiple times, but this is okay since we just need the sum + // which gets updated each time we write to the map. + if err = node.Index.PutSingleLockedStakeBalanceSnapshotWithWB( + wb, currentBlockHeight, LockedStakeDESOBalance, lockedStakeEntry.StakerPKID, + lockedStakeEntry.ValidatorPKID, lockedStakeEntry.LockedAtEpochNumber, + lockedStakeEntry.LockedAmountNanos.Uint64()); err != nil { + return errors.Wrapf(err, "PutSingleBalanceSnapshotWithWB: problem with "+ + "stakerPKID (%v), validatorPKID (%v) stakeAmountNanos (%v) and firstSnapshotHeight "+ + "(%v)", lockedStakeEntry.StakerPKID, lockedStakeEntry.ValidatorPKID, + lockedStakeEntry.LockedAmountNanos.Uint64(), + snapshot.CurrentEpochSnapshotMetadata.FirstSnapshotBlockHeight) + } + + currentCounter++ + if currentCounter%statusLoggingInterval == 0 { + glog.Infof("handleSnapshotCompleted: Processed %d of %d locked stake balances in %v. %d%% complete", + currentCounter, totalCount, time.Since(currentTime), (100*currentCounter)/totalCount) + currentTime = time.Now() + } + if currentCounter >= balancesPerBlock && currentBlockHeight < snapshotBlockHeight { + node.Index.PutHypersyncBlockLockedStakeBalancesWithWB(wb, currentBlockHeight, + lockedStakerValidatorBalances, LockedStakeDESOBalance) + lockedStakerValidatorBalances = make(map[LockedStakeBalanceMapKey]uint64) + currentBlockHeight++ + currentCounter = 0 + if currentBlockHeight%writeBatchSize == 0 { + flushTime := time.Now() + if err = wb.Flush(); err != nil { + return errors.Wrapf(err, "Problem flushing write batch") + } + glog.Infof("handleSnapshotCompleted: Locked stake balance Flush took: %v", time.Since(flushTime)) + } + } + } + if currentCounter > 0 { + node.Index.PutHypersyncBlockLockedStakeBalancesWithWB(wb, currentBlockHeight, + lockedStakerValidatorBalances, LockedStakeDESOBalance) + flushTime := time.Now() + if err := wb.Flush(); err != nil { + return errors.Wrapf(err, "Problem flushing write batch") + } + glog.Infof("handleSnapshotCompleted: Locked stake balance Flush took: %v", time.Since(flushTime)) + } + return nil + }) + if err != nil { + glog.Errorf(lib.CLog(lib.Red, fmt.Sprintf("handleSnapshotCompleted: Problem iterating locked stake "+ + "balances DeSo nanos: error: (%v)", err))) + } + } } } -func (node *Node) handleBlockConnected(event *lib.BlockEvent) { +func (node *Node) handleBlockCommitted(event *lib.BlockEvent) { node.Index.dbMutex.Lock() defer node.Index.dbMutex.Unlock() // We do some special logic if we have a snapshot. @@ -219,21 +522,21 @@ func (node *Node) handleBlockConnected(event *lib.BlockEvent) { } } } + glog.Infof("handleBlockCommitted: height: %d", event.Block.Header.Height) + if event.UtxoView == nil { + glog.Errorf("handleBlockCommitted: utxoView is nil for height: %d", event.Block.Header.Height) + return + } + currentTime := time.Now() // If we get here, then we're connecting a block after the first snapshot OR we // don't have a snapshot. We output extra metadata for this block to ensure // Rosetta connects it appropriately. - // Save the UTXOOps. These are used to compute all of the meta information - // that Rosetta needs. - err := node.Index.PutUtxoOps(event.Block, event.UtxoOps) - if err != nil { - glog.Errorf("PutSpentUtxos: %v", err) - } - + wb := node.Index.db.NewWriteBatch() + defer wb.Cancel() // Save a balance snapshot balances := event.UtxoView.PublicKeyToDeSoBalanceNanos - err = node.Index.PutBalanceSnapshot(event.Block.Header.Height, false, balances) - if err != nil { + if err := node.Index.PutBalanceSnapshotWithWB(wb, event.Block.Header.Height, DESOBalance, balances); err != nil { glog.Errorf("PutBalanceSnapshot: %v", err) } @@ -260,10 +563,59 @@ func (node *Node) handleBlockConnected(event *lib.BlockEvent) { lockedBalances[*lib.NewPublicKey(profile.PublicKey)] = balanceToPut } - err = node.Index.PutBalanceSnapshot(event.Block.Header.Height, true, lockedBalances) - if err != nil { + if err := node.Index.PutBalanceSnapshotWithWB(wb, event.Block.Header.Height, CreatorCoinLockedBalance, + lockedBalances); err != nil { glog.Errorf("PutLockedBalanceSnapshot: %v", err) } + + // Iterate over all validator entries that may have been modified. + validatorEntries := event.UtxoView.ValidatorPKIDToValidatorEntry + validatorEntryBalances := make(map[lib.PublicKey]uint64, len(validatorEntries)) + for _, validator := range validatorEntries { + balanceToPut := uint64(0) + if !validator.IsDeleted() { + if !validator.TotalStakeAmountNanos.IsUint64() { + glog.Errorf("handleBlockCommitted: TotalStakeAmountNanos is not a uint64") + continue + } + balanceToPut = validator.TotalStakeAmountNanos.Uint64() + } + validatorEntryBalances[*lib.NewPublicKey(validator.ValidatorPKID.ToBytes())] = balanceToPut + } + + if err := node.Index.PutBalanceSnapshotWithWB(wb, event.Block.Header.Height, ValidatorStakedDESOBalance, + validatorEntryBalances); err != nil { + glog.Errorf("PutStakedBalanceSnapshot: %v", err) + } + + // Iterate over all locked stake entries that may have been modified. + lockedStakeEntries := event.UtxoView.LockedStakeMapKeyToLockedStakeEntry + lockedStakeEntryBalances := make(map[LockedStakeBalanceMapKey]uint64, len(lockedStakeEntries)) + for _, lockedStakeEntry := range lockedStakeEntries { + balanceToPut := uint64(0) + if !lockedStakeEntry.IsDeleted() { + if !lockedStakeEntry.LockedAmountNanos.IsUint64() { + glog.Errorf("handleBlockCommitted: LockedAmountNanos is not a uint64") + continue + } + balanceToPut = lockedStakeEntry.LockedAmountNanos.Uint64() + } + lockedStakeEntryBalances[LockedStakeBalanceMapKey{ + StakerPKID: *lockedStakeEntry.StakerPKID, + ValidatorPKID: *lockedStakeEntry.ValidatorPKID, + LockedAtEpochNumber: lockedStakeEntry.LockedAtEpochNumber, + }] = balanceToPut + } + + if err := node.Index.PutLockedStakeBalanceSnapshotWithWB(wb, event.Block.Header.Height, LockedStakeDESOBalance, + lockedStakeEntryBalances); err != nil { + glog.Errorf("handleBlockCommitted: PutLockedStakeBalanceSnapshot: %v", err) + } + + if err := wb.Flush(); err != nil { + glog.Errorf("Flush: %v", err) + } + glog.Infof("handleBlockCommitted: Processed block %d in %v", event.Block.Header.Height, time.Since(currentTime)) } func (node *Node) handleTransactionConnected(event *lib.TransactionEvent) { diff --git a/deso/index.go b/deso/index.go index 65ddf714..bff68289 100644 --- a/deso/index.go +++ b/deso/index.go @@ -4,14 +4,18 @@ import ( "bytes" "encoding/gob" "github.com/deso-protocol/core/lib" - "github.com/dgraph-io/badger/v3" + "github.com/dgraph-io/badger/v4" "github.com/golang/glog" "github.com/pkg/errors" "math" "sync" + "time" ) const ( + // Note: UtxoOps are no longer used because we directly pull them from the node's + // badger db. We keep this prefix around so it is clear why the others are numbered + // as they are. PrefixUtxoOps = byte(0) // Public key balances @@ -24,18 +28,29 @@ const ( // Fake genesis balances we use to initialize Rosetta when running hypersync. // See comments in block.go and convertBlock() for more details. - // -> map[lib.PublicKey]uint64 + // -> map[lib.PublicKey]uint64 PrefixHypersyncBlockHeightToBalances = byte(3) + + // DESO staked to validators + // -> <> + PrefixValidatorStakedBalanceSnapshots = byte(4) + + // Locked Stake entries + // -> <> + PrefixLockedStakeBalanceSnapshots = byte(5) ) type RosettaIndex struct { - db *badger.DB - dbMutex sync.Mutex + db *badger.DB + dbMutex sync.Mutex + chainDB *badger.DB + snapshot *lib.Snapshot } -func NewIndex(db *badger.DB) *RosettaIndex { +func NewIndex(db *badger.DB, chainDB *badger.DB) *RosettaIndex { return &RosettaIndex{ - db: db, + db: db, + chainDB: chainDB, } } @@ -43,152 +58,210 @@ func NewIndex(db *badger.DB) *RosettaIndex { // Utxo Operations // -func (index *RosettaIndex) utxoOpsKey(blockHash *lib.BlockHash) []byte { - prefix := append([]byte{}, PrefixUtxoOps) - prefix = append(prefix, blockHash.ToBytes()...) - return prefix -} - -func (index *RosettaIndex) PutUtxoOps(block *lib.MsgDeSoBlock, utxoOps [][]*lib.UtxoOperation) error { - blockHash, err := block.Hash() - if err != nil { - return err - } - - opBundle := &lib.UtxoOperationBundle{ - UtxoOpBundle: utxoOps, - } - bytes := lib.EncodeToBytes(block.Header.Height, opBundle) - - return index.db.Update(func(txn *badger.Txn) error { - return txn.Set(index.utxoOpsKey(blockHash), bytes) - }) -} - func (index *RosettaIndex) GetUtxoOps(block *lib.MsgDeSoBlock) ([][]*lib.UtxoOperation, error) { blockHash, err := block.Hash() if err != nil { return nil, err } - - opBundle := &lib.UtxoOperationBundle{} - - err = index.db.View(func(txn *badger.Txn) error { - utxoOpsItem, err := txn.Get(index.utxoOpsKey(blockHash)) - if err != nil { - return err - } - - return utxoOpsItem.Value(func(valBytes []byte) error { - rr := bytes.NewReader(valBytes) - if exist, err := lib.DecodeFromBytes(opBundle, rr); !exist || err != nil { - return errors.Wrapf(err, "Problem decoding utxoops, exist: (%v)", exist) - } - return nil - }) - }) - if err != nil { - return nil, err - } - - return opBundle.UtxoOpBundle, nil + return lib.GetUtxoOperationsForBlock(index.chainDB, index.snapshot, blockHash) } // // Balance Snapshots // -func balanceSnapshotKey(isLockedBalance bool, publicKey *lib.PublicKey, blockHeight uint64, balance uint64) []byte { - startPrefix := PrefixBalanceSnapshots - if isLockedBalance { - startPrefix = PrefixLockedBalanceSnapshots +// BalanceType is introduced with PoS to differentiate between different types of balances. +// Previously, there were only two types - DESOBalance and CreatorCoinLockedBalance. These +// were distinguished by a boolean "locked". We took advantage of the fact that +// DESOBalance was represented by false (byte representation of 0) and CreatorCoinLockedBalance +// was represented by true (byte representation of 1). This allows us to avoid a resync of +// rosetta with this upgrade. +type BalanceType uint8 + +const ( + DESOBalance BalanceType = 0 + CreatorCoinLockedBalance BalanceType = 1 + ValidatorStakedDESOBalance BalanceType = 2 + LockedStakeDESOBalance BalanceType = 3 +) + +func (balanceType BalanceType) BalanceTypePrefix() byte { + switch balanceType { + case DESOBalance: + return PrefixBalanceSnapshots + case CreatorCoinLockedBalance: + return PrefixLockedBalanceSnapshots + case ValidatorStakedDESOBalance: + return PrefixValidatorStakedBalanceSnapshots + case LockedStakeDESOBalance: + return PrefixLockedStakeBalanceSnapshots + default: + panic("unknown balance type") } +} - prefix := append([]byte{}, startPrefix) +func balanceSnapshotKey(balanceType BalanceType, publicKey *lib.PublicKey, blockHeight uint64, balance uint64) []byte { + prefix := append([]byte{}, balanceType.BalanceTypePrefix()) prefix = append(prefix, publicKey[:]...) prefix = append(prefix, lib.EncodeUint64(blockHeight)...) prefix = append(prefix, lib.EncodeUint64(balance)...) return prefix } -func hypersyncHeightToBlockKey(blockHeight uint64, isLocked bool) []byte { - - lockedByte := byte(0) - if isLocked { - lockedByte = byte(1) - } +func lockedStakeBalanceSnapshotKey( + balanceType BalanceType, stakerPKID *lib.PKID, validatorPKID *lib.PKID, lockedAtEpochNumber uint64, + blockHeight uint64, balance uint64, +) []byte { + prefix := append([]byte{}, balanceType.BalanceTypePrefix()) + prefix = append(prefix, stakerPKID[:]...) + prefix = append(prefix, validatorPKID[:]...) + prefix = append(prefix, lib.EncodeUint64(lockedAtEpochNumber)...) + prefix = append(prefix, lib.EncodeUint64(blockHeight)...) + prefix = append(prefix, lib.EncodeUint64(balance)...) + return prefix +} +func hypersyncHeightToBlockKey(blockHeight uint64, balanceType BalanceType) []byte { prefix := append([]byte{}, PrefixHypersyncBlockHeightToBalances) prefix = append(prefix, lib.EncodeUint64(blockHeight)...) - prefix = append(prefix, lockedByte) + prefix = append(prefix, byte(balanceType)) return prefix } -func (index *RosettaIndex) PutHypersyncBlockBalances(blockHeight uint64, isLocked bool, balances map[lib.PublicKey]uint64) { +func (index *RosettaIndex) PutHypersyncBlockBalancesWithWB( + wb *badger.WriteBatch, blockHeight uint64, balanceType BalanceType, balances map[lib.PublicKey]uint64) { + putBlockStartTime := time.Now() + if balanceType != DESOBalance && balanceType != CreatorCoinLockedBalance && + balanceType != ValidatorStakedDESOBalance { + glog.Error("PutHypersyncBlockBalancesWithWB: Invalid balance type passed in") + return + } + currentTime := time.Now() + blockBytes := bytes.NewBuffer([]byte{}) + if err := gob.NewEncoder(blockBytes).Encode(&balances); err != nil { + glog.Errorf("PutHypersyncBlockBalancesWithWB: error gob encoding balances: %v", err) + return + } + glog.Infof("Time to gob encode %d balances: %v", len(balances), time.Since(currentTime)) + if err := wb.Set(hypersyncHeightToBlockKey(blockHeight, balanceType), blockBytes.Bytes()); err != nil { + glog.Error(errors.Wrapf(err, "PutHypersyncBlockBalancesWithWB: Problem putting block: Error:")) + } + glog.Infof("Time to put %d balances: %v", len(balances), time.Since(putBlockStartTime)) +} - err := index.db.Update(func(txn *badger.Txn) error { - blockBytes := bytes.NewBuffer([]byte{}) - if err := gob.NewEncoder(blockBytes).Encode(&balances); err != nil { - return err - } - return txn.Set(hypersyncHeightToBlockKey(blockHeight, isLocked), blockBytes.Bytes()) - }) - if err != nil { - glog.Error(errors.Wrapf(err, "PutHypersyncBlockBalances: Problem putting block: Error:")) +func (index *RosettaIndex) PutHypersyncBlockLockedStakeBalancesWithWB( + wb *badger.WriteBatch, blockHeight uint64, stakeEntries map[LockedStakeBalanceMapKey]uint64, balanceType BalanceType) { + putBlockStartTime := time.Now() + if balanceType != LockedStakeDESOBalance { + glog.Error("PutHypersyncBlockLockedStakeBalancesWithWB: Invalid balance type passed in") + return } + currentTime := time.Now() + blockBytes := bytes.NewBuffer([]byte{}) + if err := gob.NewEncoder(blockBytes).Encode(&stakeEntries); err != nil { + glog.Errorf("PutHypersyncBlockLockedStakeBalancesWithDB: error gob encoding locked stake entries: %v", err) + return + } + glog.Infof("Time to gob encode %d locked stake entries: %v", len(stakeEntries), time.Since(currentTime)) + if err := wb.Set(hypersyncHeightToBlockKey(blockHeight, balanceType), blockBytes.Bytes()); err != nil { + glog.Error(errors.Wrapf(err, "PutHypersyncBlockLockedStakeBalancesWithWB: Problem putting block: Error:")) + } + glog.Infof("Time to put %d locked stake entries: %v", len(stakeEntries), time.Since(putBlockStartTime)) } func (index *RosettaIndex) GetHypersyncBlockBalances(blockHeight uint64) ( - _balances map[lib.PublicKey]uint64, _lockedBalances map[lib.PublicKey]uint64) { + _balances map[lib.PublicKey]uint64, _lockedBalances map[lib.PublicKey]uint64, + _stakedDESOBalances map[lib.PublicKey]uint64, _lockedStakeDESOBalances map[LockedStakeBalanceMapKey]uint64) { balances := make(map[lib.PublicKey]uint64) - lockedBalances := make(map[lib.PublicKey]uint64) + creatorCoinLockedBalances := make(map[lib.PublicKey]uint64) + validatorStakedDESOBalances := make(map[lib.PublicKey]uint64) + lockedStakeDESOBalances := make(map[LockedStakeBalanceMapKey]uint64) err := index.db.View(func(txn *badger.Txn) error { - itemBalances, err := txn.Get(hypersyncHeightToBlockKey(blockHeight, false)) - if err != nil { - return err - } - balancesBytes, err := itemBalances.ValueCopy(nil) - if err != nil { - return err - } - if err := gob.NewDecoder(bytes.NewReader(balancesBytes)).Decode(&balances); err != nil { - return err + itemBalances, err := txn.Get(hypersyncHeightToBlockKey(blockHeight, DESOBalance)) + if errors.Is(err, badger.ErrKeyNotFound) { + glog.Infof("GetHypersyncBlockBalances: No balances found for block at height (%v)", blockHeight) + } else { + if err != nil { + return err + } + balancesBytes, err := itemBalances.ValueCopy(nil) + if err != nil { + return err + } + if err = gob.NewDecoder(bytes.NewReader(balancesBytes)).Decode(&balances); err != nil { + return err + } } - itemLocked, err := txn.Get(hypersyncHeightToBlockKey(blockHeight, true)) - if err != nil { - return err + itemCreatorCoinLockedBalances, err := txn.Get(hypersyncHeightToBlockKey(blockHeight, CreatorCoinLockedBalance)) + if errors.Is(err, badger.ErrKeyNotFound) { + glog.Infof("GetHypersyncBlockBalances: No creator coin locked balances found for block at height (%v)", blockHeight) + } else { + if err != nil { + return err + } + creatorCoinLockedBalancesBytes, err := itemCreatorCoinLockedBalances.ValueCopy(nil) + if err != nil { + return err + } + if err = gob.NewDecoder(bytes.NewReader(creatorCoinLockedBalancesBytes)).Decode( + &creatorCoinLockedBalances); err != nil { + return err + } } - lockedBytes, err := itemLocked.ValueCopy(nil) - if err != nil { - return err + + itemValidatorStakedBalances, err := txn.Get(hypersyncHeightToBlockKey(blockHeight, ValidatorStakedDESOBalance)) + if errors.Is(err, badger.ErrKeyNotFound) { + glog.Infof("GetHypersyncBlockBalances: No validator staked balances found for block at height (%v)", blockHeight) + } else { + if err != nil { + return err + } + validatorStakedBalancesBytes, err := itemValidatorStakedBalances.ValueCopy(nil) + if err != nil { + return err + } + if err = gob.NewDecoder(bytes.NewReader(validatorStakedBalancesBytes)). + Decode(&validatorStakedDESOBalances); err != nil { + return err + } } - if err := gob.NewDecoder(bytes.NewReader(lockedBytes)).Decode(&lockedBalances); err != nil { - return err + + lockedStakedItemBalances, err := txn.Get(hypersyncHeightToBlockKey(blockHeight, LockedStakeDESOBalance)) + if errors.Is(err, badger.ErrKeyNotFound) { + glog.Infof("GetHypersyncBlockBalances: No locked stake balances found for block at height (%v)", blockHeight) + } else { + if err != nil { + return err + } + lockedStakedBalancesBytes, err := lockedStakedItemBalances.ValueCopy(nil) + if err != nil { + return err + } + if err = gob.NewDecoder(bytes.NewReader(lockedStakedBalancesBytes)). + Decode(&lockedStakeDESOBalances); err != nil { + return err + } } return nil }) + // TODO: Handle this error better. if err != nil { glog.Error(errors.Wrapf(err, "GetHypersyncBlockBalances: Problem getting block at height (%v)", blockHeight)) } - return balances, lockedBalances -} - -func (index *RosettaIndex) PutBalanceSnapshot( - height uint64, isLockedBalance bool, balances map[lib.PublicKey]uint64) error { - - return index.db.Update(func(txn *badger.Txn) error { - return index.PutBalanceSnapshotWithTxn(txn, height, isLockedBalance, balances) - }) + return balances, creatorCoinLockedBalances, validatorStakedDESOBalances, lockedStakeDESOBalances } -func (index *RosettaIndex) PutBalanceSnapshotWithTxn( - txn *badger.Txn, height uint64, isLockedBalance bool, balances map[lib.PublicKey]uint64) error { - +func (index *RosettaIndex) PutBalanceSnapshotWithWB( + wb *badger.WriteBatch, height uint64, balanceType BalanceType, balances map[lib.PublicKey]uint64) error { + if balanceType != DESOBalance && balanceType != CreatorCoinLockedBalance && + balanceType != ValidatorStakedDESOBalance { + return errors.New("PutBalanceSnapshotWithTxn: Invalid balance type passed in") + } for pk, bal := range balances { - if err := txn.Set(balanceSnapshotKey(isLockedBalance, &pk, height, bal), []byte{}); err != nil { + if err := wb.Set(balanceSnapshotKey(balanceType, &pk, height, bal), []byte{}); err != nil { return errors.Wrapf(err, "Error in PutBalanceSnapshot for block height: "+ "%v pub key: %v balance: %v", height, pk, bal) } @@ -196,19 +269,56 @@ func (index *RosettaIndex) PutBalanceSnapshotWithTxn( return nil } -func (index *RosettaIndex) PutSingleBalanceSnapshotWithTxn( - txn *badger.Txn, height uint64, isLockedBalance bool, publicKey lib.PublicKey, balance uint64) error { - - if err := txn.Set(balanceSnapshotKey(isLockedBalance, &publicKey, height, balance), []byte{}); err != nil { +func (index *RosettaIndex) PutSingleBalanceSnapshotWithWB( + wb *badger.WriteBatch, height uint64, balanceType BalanceType, publicKey lib.PublicKey, balance uint64) error { + if balanceType != DESOBalance && balanceType != CreatorCoinLockedBalance && + balanceType != ValidatorStakedDESOBalance { + return errors.New("PutSingleBalanceSnapshotWithWB: Invalid balance type passed in") + } + if err := wb.Set(balanceSnapshotKey(balanceType, &publicKey, height, balance), []byte{}); err != nil { return errors.Wrapf(err, "Error in PutBalanceSnapshot for block height: "+ "%v pub key: %v balance: %v", height, publicKey, balance) } return nil } -func GetBalanceForPublicKeyAtBlockHeightWithTxn( - txn *badger.Txn, isLockedBalance bool, publicKey *lib.PublicKey, blockHeight uint64) uint64 { +func (index *RosettaIndex) PutLockedStakeBalanceSnapshotWithWB( + wb *badger.WriteBatch, height uint64, balanceType BalanceType, balances map[LockedStakeBalanceMapKey]uint64) error { + if balanceType != LockedStakeDESOBalance { + return errors.New("PutLockedStakeBalanceSnapshotWithTxn: Invalid balance type passed in") + } + for pk, bal := range balances { + if err := wb.Set(lockedStakeBalanceSnapshotKey( + balanceType, &pk.StakerPKID, &pk.ValidatorPKID, pk.LockedAtEpochNumber, height, bal), []byte{}, + ); err != nil { + return errors.Wrapf(err, "Error in PutLockedStakeBalanceSnapshotWithTxn for block height: "+ + "%v pub key: %v balance: %v", height, pk, bal) + } + } + return nil +} + +func (index *RosettaIndex) PutSingleLockedStakeBalanceSnapshotWithWB( + wb *badger.WriteBatch, height uint64, balanceType BalanceType, stakerPKID *lib.PKID, + validatorPKID *lib.PKID, lockedAtEpochNumber uint64, balance uint64) error { + if balanceType != LockedStakeDESOBalance { + return errors.New("PutSingleLockedStakeBalanceSnapshotWithWB: Invalid balance type passed in") + } + if err := wb.Set(lockedStakeBalanceSnapshotKey( + balanceType, stakerPKID, validatorPKID, lockedAtEpochNumber, height, balance), []byte{}); err != nil { + return errors.Wrapf(err, "Error in PutSingleLockedStakeBalanceSnapshotWithWB for block height: "+ + "%v staker pkid: %v validator pkid: %v balance: %v", height, stakerPKID, validatorPKID, balance) + } + return nil +} +func GetBalanceForPublicKeyAtBlockHeightWithTxn( + txn *badger.Txn, balanceType BalanceType, publicKey *lib.PublicKey, blockHeight uint64) uint64 { + if balanceType != DESOBalance && balanceType != CreatorCoinLockedBalance && + balanceType != ValidatorStakedDESOBalance { + glog.Errorf("GetBalanceForPublicKeyAtBlockHeightWithTxn: Invalid balance type passed in") + return 0 + } opts := badger.DefaultIteratorOptions opts.PrefetchValues = false @@ -221,7 +331,7 @@ func GetBalanceForPublicKeyAtBlockHeightWithTxn( // Since we iterate backwards, the prefix must be bigger than all possible // values that could actually exist. This means the key we use the pubkey // and block height with max balance. - maxPrefix := balanceSnapshotKey(isLockedBalance, publicKey, blockHeight, math.MaxUint64) + maxPrefix := balanceSnapshotKey(balanceType, publicKey, blockHeight, math.MaxUint64) // We don't want to consider any keys that don't involve our public key. This // will cause the iteration to stop if we don't have any values for our current // public key. @@ -246,11 +356,82 @@ func GetBalanceForPublicKeyAtBlockHeightWithTxn( return lib.DecodeUint64(keyFound[1+len(publicKey)+len(lib.EncodeUint64(blockHeight)):]) } -func (index *RosettaIndex) GetBalanceSnapshot(isLockedBalance bool, publicKey *lib.PublicKey, blockHeight uint64) uint64 { +func (index *RosettaIndex) GetBalanceSnapshot( + balanceType BalanceType, publicKey *lib.PublicKey, blockHeight uint64, +) uint64 { + if balanceType != DESOBalance && balanceType != CreatorCoinLockedBalance && + balanceType != ValidatorStakedDESOBalance { + glog.Errorf("GetBalanceSnapshot: Invalid balance type passed in") + return 0 + } balanceFound := uint64(0) index.db.View(func(txn *badger.Txn) error { balanceFound = GetBalanceForPublicKeyAtBlockHeightWithTxn( - txn, isLockedBalance, publicKey, blockHeight) + txn, balanceType, publicKey, blockHeight) + return nil + }) + + return balanceFound +} + +func GetLockedStakeBalanceForPublicKeyAtBlockHeightWithTxn( + txn *badger.Txn, balanceType BalanceType, stakerPKID *lib.PKID, validatorPKID *lib.PKID, lockedAtEpochNumber uint64, + blockHeight uint64, +) uint64 { + if balanceType != LockedStakeDESOBalance { + glog.Errorf("GetLockedStakeBalanceForPublicKeyAtBlockHeightWithTxn: Invalid balance type passed in") + return 0 + } + opts := badger.DefaultIteratorOptions + opts.PrefetchValues = false + + // Go in reverse order. + opts.Reverse = true + + it := txn.NewIterator(opts) + defer it.Close() + + // Since we iterate backwards, the prefix must be bigger than all possible + // values that could actually exist. This means the key we use the pubkey + // and block height with max balance. + maxPrefix := lockedStakeBalanceSnapshotKey( + balanceType, stakerPKID, validatorPKID, lockedAtEpochNumber, blockHeight, math.MaxUint64) + // We don't want to consider any keys that don't involve our public key. This + // will cause the iteration to stop if we don't have any values for our current + // public key. + // One byte for the prefix + validForPrefix := maxPrefix[:1+len(stakerPKID.ToBytes())] + var keyFound []byte + for it.Seek(maxPrefix); it.ValidForPrefix(validForPrefix); it.Next() { + item := it.Item() + keyFound = item.Key() + // Break after the first key we iterate over because we only + // want the first one. + break + } + // No key found means this user's balance has never appeared in a block. + if keyFound == nil { + return 0 + } + + // If we get here we found a valid key. Decode the balance from it + // and return it. + // One byte for the prefix + return lib.DecodeUint64(keyFound[1+len(stakerPKID.ToBytes())+len(lib.EncodeUint64(blockHeight)):]) +} + +func (index *RosettaIndex) GetLockedStakeBalanceSnapshot( + balanceType BalanceType, stakerPKID *lib.PKID, validatorPKID *lib.PKID, lockedAtEpochNumber uint64, + blockHeight uint64, +) uint64 { + if balanceType != LockedStakeDESOBalance { + glog.Errorf("GetLockedStakeBalanceSnapshot: Invalid balance type passed in") + return 0 + } + balanceFound := uint64(0) + index.db.View(func(txn *badger.Txn) error { + balanceFound = GetLockedStakeBalanceForPublicKeyAtBlockHeightWithTxn( + txn, balanceType, stakerPKID, validatorPKID, lockedAtEpochNumber, blockHeight) return nil }) diff --git a/deso/node.go b/deso/node.go index ab23e2c9..317f7f0d 100644 --- a/deso/node.go +++ b/deso/node.go @@ -3,8 +3,6 @@ package deso import ( "flag" "fmt" - "github.com/deso-protocol/go-deadlock" - "github.com/dgraph-io/badger/v3" "math/rand" "net" "os" @@ -14,6 +12,9 @@ import ( "syscall" "time" + "github.com/deso-protocol/go-deadlock" + "github.com/dgraph-io/badger/v4" + "github.com/btcsuite/btcd/addrmgr" "github.com/btcsuite/btcd/wire" "github.com/davecgh/go-spew/spew" @@ -83,9 +84,9 @@ func addIPsForHost(desoAddrMgr *addrmgr.AddrManager, host string, params *lib.De glog.V(1).Infof("_addSeedAddrs: Adding seed IPs from seed %s: %v\n", host, ipAddrs) // Convert addresses to NetAddress'es. - netAddrs := make([]*wire.NetAddress, len(ipAddrs)) + netAddrs := make([]*wire.NetAddressV2, len(ipAddrs)) for ii, ip := range ipAddrs { - netAddrs[ii] = wire.NewNetAddressTimestamp( + netAddrs[ii] = wire.NetAddressV2FromBytes( // We initialize addresses with a // randomly selected "last seen time" between 3 // and 7 days ago similar to what bitcoind does. @@ -202,7 +203,13 @@ func (node *Node) Start(exitChannels ...*chan os.Signal) { if node.Online && len(node.Config.ConnectIPs) == 0 { for _, addr := range listeningAddrs { - netAddr := wire.NewNetAddress(&addr, 0) + netAddressLegacy := wire.NewNetAddress(&addr, 0) + netAddr := wire.NetAddressV2FromBytes( + netAddressLegacy.Timestamp, + netAddressLegacy.Services, + netAddressLegacy.IP, + netAddressLegacy.Port, + ) _ = desoAddrMgr.AddLocalAddress(netAddr, addrmgr.BoundPrio) } @@ -234,12 +241,12 @@ func (node *Node) Start(exitChannels ...*chan os.Signal) { rosettaIndexOpts := lib.PerformanceBadgerOptions(rosettaIndexDir) rosettaIndexOpts.ValueDir = rosettaIndexDir rosettaIndex, err := badger.Open(rosettaIndexOpts) - node.Index = NewIndex(rosettaIndex) + node.Index = NewIndex(rosettaIndex, node.chainDB) // Listen to transaction and block events so we can fill RosettaIndex with relevant data node.EventManager = lib.NewEventManager() node.EventManager.OnTransactionConnected(node.handleTransactionConnected) - node.EventManager.OnBlockConnected(node.handleBlockConnected) + node.EventManager.OnBlockCommitted(node.handleBlockCommitted) node.EventManager.OnSnapshotCompleted(node.handleSnapshotCompleted) minerCount := uint64(1) @@ -254,9 +261,23 @@ func (node *Node) Start(exitChannels ...*chan os.Signal) { rateLimitFeerateNanosPerKB := uint64(0) stallTimeoutSeconds := uint64(900) + var blsKeyStore *lib.BLSKeystore + if node.Config.PosValidatorSeed != "" { + blsKeyStore, err = lib.NewBLSKeystore(node.Config.PosValidatorSeed) + if err != nil { + panic(err) + } + } shouldRestart := false + var checkpointSyncingProviders []string + if node.Config.Params.NetworkType == lib.NetworkType_MAINNET { + checkpointSyncingProviders = []string{"https://node.deso.org"} + } else { + checkpointSyncingProviders = []string{"https://test.deso.org"} + } node.Server, err, shouldRestart = lib.NewServer( node.Config.Params, + node.Config.Regtest, listeners, desoAddrMgr, connectIPs, @@ -267,6 +288,7 @@ func (node *Node) Start(exitChannels ...*chan os.Signal) { node.Config.MinerPublicKeys, minerCount, true, + 10000, // peer connection refresh interval millis node.Config.HyperSync, node.Config.SyncType, node.Config.MaxSyncBlockHeight, @@ -278,14 +300,14 @@ func (node *Node) Start(exitChannels ...*chan os.Signal) { minBlockUpdateInterval, blockCypherAPIKey, true, - lib.SnapshotBlockHeightPeriod, + lib.DefaultSnapshotEpochPeriodPoS, node.Config.DataDirectory, mempoolDumpDir, disableNetworking, readOnly, false, nil, - "", + node.Config.BlockProducerSeed, []string{}, 0, node.EventManager, @@ -293,7 +315,15 @@ func (node *Node) Start(exitChannels ...*chan os.Signal) { node.Config.ForceChecksum, "", lib.HypersyncDefaultMaxQueueSize, + blsKeyStore, + 30000, // 30 seconds mempool back up time millis + 100, // 100, mempool max vlaidation view connects + 10, // 10 milliseconds, transaction validation refresh interval millis + 10000, // State syncer mempool txn sync limit + checkpointSyncingProviders, ) + // Set the snapshot on the rosetta index. + node.Index.snapshot = node.GetBlockchain().Snapshot() if err != nil { if shouldRestart { glog.Infof(lib.CLog(lib.Red, fmt.Sprintf("Start: Got en error while starting server and shouldRestart "+ @@ -358,7 +388,6 @@ func (node *Node) Stop() { if snap != nil { glog.Infof(lib.CLog(lib.Yellow, "Node.Stop: Stopping snapshot...")) snap.Stop() - node.closeDb(snap.SnapshotDb, "snapshot") glog.Infof(lib.CLog(lib.Yellow, "Node.Stop: Snapshot successfully stopped.")) } diff --git a/deso/types.go b/deso/types.go index 64e632f4..954172da 100644 --- a/deso/types.go +++ b/deso/types.go @@ -18,6 +18,15 @@ const ( // CreatorCoin is the SubAccount address for a public key's // total DESO locked in their creator coin. CreatorCoin = "CREATOR_COIN" + + // ValidatorEntry is the SubAccount address prefix for a + // PKID's total DESO staked to a given validator entry. + ValidatorEntry = "VALIDATOR_ENTRY" + + // LockedStakeEntry is the SubAccount address prefix for + // a PKID's total DESO locked in a given locked + // stake entry. + LockedStakeEntry = "LOCKED_STAKE_ENTRY" ) var ( diff --git a/go.mod b/go.mod index c0429163..9a7735c6 100644 --- a/go.mod +++ b/go.mod @@ -1,106 +1,148 @@ module github.com/deso-protocol/rosetta-deso -go 1.20 +go 1.22 replace github.com/deso-protocol/core => ../core/ require ( - github.com/btcsuite/btcd v0.21.0-beta - github.com/coinbase/rosetta-sdk-go v0.6.10 - github.com/davecgh/go-spew v1.1.1 - github.com/deso-protocol/core v1.1.0 + github.com/btcsuite/btcd v0.24.0 + github.com/btcsuite/btcd/btcec/v2 v2.3.3 + github.com/coinbase/rosetta-sdk-go v0.8.5 + github.com/coinbase/rosetta-sdk-go/types v1.0.0 + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc + github.com/deso-protocol/core v1.2.9 github.com/deso-protocol/go-deadlock v1.0.0 github.com/deso-protocol/go-merkle-tree v1.0.0 - github.com/dgraph-io/badger/v3 v3.2103.0 - github.com/golang/glog v1.0.0 + github.com/dgraph-io/badger/v4 v4.2.0 + github.com/golang/glog v1.2.1 github.com/mitchellh/go-homedir v1.1.0 github.com/pkg/errors v0.9.1 - github.com/spf13/cobra v1.1.3 + github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.7.1 - github.com/stretchr/testify v1.8.0 + github.com/spf13/viper v1.18.2 + github.com/stretchr/testify v1.9.0 ) require ( - github.com/DataDog/datadog-go v4.5.0+incompatible // indirect - github.com/DataDog/zstd v1.4.8 // indirect - github.com/Microsoft/go-winio v0.4.16 // indirect + github.com/AlecAivazis/survey/v2 v2.3.7 // indirect + github.com/DataDog/appsec-internal-go v1.5.0 // indirect + github.com/DataDog/datadog-agent/pkg/obfuscate v0.52.1 // indirect + github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.52.1 // indirect + github.com/DataDog/datadog-go v4.8.3+incompatible // indirect + github.com/DataDog/datadog-go/v5 v5.5.0 // indirect + github.com/DataDog/go-libddwaf/v2 v2.4.2 // indirect + github.com/DataDog/go-sqllexer v0.0.11 // indirect + github.com/DataDog/go-tuf v1.1.0-0.5.2 // indirect + github.com/DataDog/gostackparse v0.7.0 // indirect + github.com/DataDog/sketches-go v1.4.4 // indirect + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver/v3 v3.2.1 // indirect + github.com/Masterminds/sprig/v3 v3.2.3 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/andygrunwald/go-jira v1.16.0 // indirect + github.com/btcsuite/btcd/btcutil v1.1.5 // indirect + github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f // indirect - github.com/btcsuite/btcutil v1.0.2 // indirect - github.com/bwesterb/go-ristretto v1.2.0 // indirect - github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.1.1 // indirect - github.com/cloudflare/circl v1.1.0 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect - github.com/decred/dcrd/lru v1.1.1 // indirect - github.com/dgraph-io/ristretto v0.1.0 // indirect - github.com/dustin/go-humanize v1.0.0 // indirect - github.com/ethereum/go-ethereum v1.9.25 // indirect - github.com/fatih/color v1.13.0 // indirect - github.com/fsnotify/fsnotify v1.4.9 // indirect + github.com/bwesterb/go-ristretto v1.2.3 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cloudflare/circl v1.3.7 // indirect + github.com/coreos/go-semver v0.3.1 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect + github.com/decred/dcrd/crypto/blake256 v1.0.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect + github.com/decred/dcrd/lru v1.1.2 // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/ebitengine/purego v0.7.1 // indirect + github.com/emirpasic/gods v1.18.1 // indirect + github.com/ethereum/go-ethereum v1.13.14 // indirect + github.com/fatih/color v1.16.0 // indirect + github.com/fatih/structs v1.1.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gernest/mention v2.0.0+incompatible // indirect - github.com/git-chglog/git-chglog v0.0.0-20200414013904-db796966b373 // indirect - github.com/go-pg/pg/v10 v10.10.0 // indirect + github.com/git-chglog/git-chglog v0.15.4 // indirect + github.com/go-pg/pg/v10 v10.12.0 // indirect github.com/go-pg/zerochecker v0.2.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.2 // indirect - github.com/golang/snappy v0.0.3 // indirect - github.com/google/flatbuffers v2.0.0+incompatible // indirect - github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5 // indirect - github.com/google/uuid v1.2.0 // indirect - github.com/gorilla/mux v1.8.0 // indirect - github.com/hashicorp/hcl v1.0.0 // indirect - github.com/holiman/uint256 v1.1.1 // indirect - github.com/imdario/mergo v0.3.8 // indirect - github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect + github.com/google/flatbuffers v24.3.25+incompatible // indirect + github.com/google/go-querystring v1.1.0 // indirect + github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/mux v1.8.1 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/hcl v1.0.1-vault-5 // indirect + github.com/holiman/uint256 v1.2.4 // indirect + github.com/huandu/xstrings v1.4.0 // indirect + github.com/imdario/mergo v0.3.16 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/magiconair/properties v1.8.1 // indirect - github.com/mattn/go-colorable v0.1.9 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect - github.com/mattn/goveralls v0.0.6 // indirect - github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect - github.com/mitchellh/mapstructure v1.3.3 // indirect + github.com/klauspost/compress v1.17.8 // indirect + github.com/kyokomi/emoji/v2 v2.2.12 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/goveralls v0.0.12 // indirect + github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/oleiade/lane v1.0.1 // indirect - github.com/pelletier/go-toml v1.7.0 // indirect - github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect - github.com/philhofer/fwd v1.1.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/onflow/crypto v0.25.1 // indirect + github.com/outcaste-io/ristretto v0.2.3 // indirect + github.com/pelletier/go-toml/v2 v2.2.0 // indirect + github.com/petermattis/goid v0.0.0-20240327183114-c42a807a84ba // indirect + github.com/philhofer/fwd v1.1.2 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/richardartoul/molecule v1.0.1-0.20221107223329-32cfee06a052 // indirect github.com/robinjoseph08/go-pg-migrations/v3 v3.0.0 // indirect - github.com/russross/blackfriday/v2 v2.0.1 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/secure-systems-lab/go-securesystemslib v0.8.0 // indirect github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 // indirect - github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect - github.com/spf13/afero v1.1.2 // indirect - github.com/spf13/cast v1.3.0 // indirect - github.com/spf13/jwalterweatherman v1.0.0 // indirect - github.com/subosito/gotenv v1.2.0 // indirect - github.com/tinylib/msgp v1.1.2 // indirect + github.com/shopspring/decimal v1.3.1 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cast v1.6.0 // indirect + github.com/subosito/gotenv v1.6.0 // indirect + github.com/tinylib/msgp v1.1.9 // indirect github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect + github.com/trivago/tgo v1.0.7 // indirect github.com/tsuyoshiwada/go-gitcmd v0.0.0-20180205145712-5f1f5f9475df // indirect - github.com/tyler-smith/go-bip39 v1.0.2 // indirect - github.com/unrolled/secure v1.0.8 // indirect - github.com/urfave/cli v1.22.1 // indirect + github.com/tyler-smith/go-bip39 v1.1.0 // indirect + github.com/unrolled/secure v1.14.0 // indirect + github.com/urfave/cli/v2 v2.27.1 // indirect github.com/vmihailenco/bufpool v0.1.11 // indirect - github.com/vmihailenco/msgpack/v5 v5.3.1 // indirect + github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser v0.1.2 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - go.opencensus.io v0.23.0 // indirect - golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect - golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect - golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect - golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2 // indirect - golang.org/x/text v0.3.6 // indirect - golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 // indirect - golang.org/x/tools v0.1.5 // indirect - golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect - google.golang.org/protobuf v1.26.0 // indirect - gopkg.in/AlecAivazis/survey.v1 v1.8.7 // indirect - gopkg.in/DataDog/dd-trace-go.v1 v1.29.0 // indirect - gopkg.in/ini.v1 v1.51.0 // indirect - gopkg.in/kyokomi/emoji.v1 v1.5.1 // indirect + github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect + go.opencensus.io v0.24.0 // indirect + go.uber.org/atomic v1.11.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + golang.org/x/crypto v0.22.0 // indirect + golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.19.0 // indirect + golang.org/x/term v0.19.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.20.0 // indirect + golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect + gonum.org/v1/gonum v0.15.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect + gopkg.in/DataDog/dd-trace-go.v1 v1.62.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - mellium.im/sasl v0.2.1 // indirect + mellium.im/sasl v0.3.1 // indirect ) diff --git a/go.sum b/go.sum index 9838699a..a75cb67f 100644 --- a/go.sum +++ b/go.sum @@ -1,200 +1,170 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= -github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= -github.com/Azure/azure-storage-blob-go v0.7.0/go.mod h1:f9YQKtsG1nMisotuTPpO0tjNuEjKRYAcJU8/ydDI++4= -github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= -github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= -github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= -github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= -github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= -github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= -github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= +github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/DataDog/datadog-go v4.4.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/datadog-go v4.5.0+incompatible h1:MyyuIz5LVAI3Im+0F/tfo64ETyH4sNVynZ29yOiHm50= -github.com/DataDog/datadog-go v4.5.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/DataDog/zstd v1.4.8 h1:Rpmta4xZ/MgZnriKNd24iZMhGpP5dvUcs/uqfBapKZY= -github.com/DataDog/zstd v1.4.8/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= -github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= -github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= -github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw= +github.com/DataDog/appsec-internal-go v1.5.0 h1:8kS5zSx5T49uZ8dZTdT19QVAvC/B8ByyZdhQKYQWHno= +github.com/DataDog/appsec-internal-go v1.5.0/go.mod h1:pEp8gjfNLtEOmz+iZqC8bXhu0h4k7NUsW/qiQb34k1U= +github.com/DataDog/datadog-agent/pkg/obfuscate v0.52.1 h1:/oxF4p/4XUGNpNw2TE7vDu/pJV3elEAZ+jES0/MWtiI= +github.com/DataDog/datadog-agent/pkg/obfuscate v0.52.1/go.mod h1:AVPQWekk3h9AOC7+plBlNB68Sy6UIGFoMMVUDeSoNoI= +github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.52.1 h1:mmkGuCHBFuDBpuwNMcqtY1x1I2fCaPH2Br4xPAAjbkM= +github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.52.1/go.mod h1:JhAilx32dkIgoDkFXquCTfaWDsAOfe+vfBaxbiZoPI0= +github.com/DataDog/datadog-go v4.8.3+incompatible h1:fNGaYSuObuQb5nzeTQqowRAd9bpDIRRV4/gUtIBjh8Q= +github.com/DataDog/datadog-go v4.8.3+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/DataDog/datadog-go/v5 v5.5.0 h1:G5KHeB8pWBNXT4Jtw0zAkhdxEAWSpWH00geHI6LDrKU= +github.com/DataDog/datadog-go/v5 v5.5.0/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw= +github.com/DataDog/go-libddwaf/v2 v2.4.2 h1:ilquGKUmN9/Ty0sIxiEyznVRxP3hKfmH15Y1SMq5gjA= +github.com/DataDog/go-libddwaf/v2 v2.4.2/go.mod h1:gsCdoijYQfj8ce/T2bEDNPZFIYnmHluAgVDpuQOWMZE= +github.com/DataDog/go-sqllexer v0.0.11 h1:OfPBjmayreblOXreszbrOTICNZ3qWrA6Bg4sypvxpbw= +github.com/DataDog/go-sqllexer v0.0.11/go.mod h1:KwkYhpFEVIq+BfobkTC1vfqm4gTi65skV/DpDBXtexc= +github.com/DataDog/go-tuf v1.1.0-0.5.2 h1:4CagiIekonLSfL8GMHRHcHudo1fQnxELS9g4tiAupQ4= +github.com/DataDog/go-tuf v1.1.0-0.5.2/go.mod h1:zBcq6f654iVqmkk8n2Cx81E1JnNTMOAx1UEO/wZR+P0= +github.com/DataDog/gostackparse v0.7.0 h1:i7dLkXHvYzHV308hnkvVGDL3BR4FWl7IsXNPz/IGQh4= +github.com/DataDog/gostackparse v0.7.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= +github.com/DataDog/sketches-go v1.4.4 h1:dF52vzXRFSPOj2IjXSWLvXq3jubL4CI69kwYjJ1w5Z8= +github.com/DataDog/sketches-go v1.4.4/go.mod h1:XR0ns2RtEEF09mDKXiKZiQg+nfZStrq1ZuL1eezeZe0= +github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= +github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= +github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc= -github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8= -github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20201201074141-dd0ecada1be6/go.mod h1:eSYp2T6f0apnuW8TzhV3f6Aff2SE8Dwio++U4ha4yEM= +github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= +github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= -github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/andygrunwald/go-jira v1.16.0 h1:PU7C7Fkk5L96JvPc6vDVIrd99vdPnYudHu4ju2c2ikQ= +github.com/andygrunwald/go-jira v1.16.0/go.mod h1:UQH4IBVxIYWbgagc0LF/k9FRs9xjIiQ8hIcC6HfLwFU= github.com/brianvoe/gofakeit v3.18.0+incompatible h1:wDOmHc9DLG4nRjUVVaxA+CEglKOW72Y5+4WNxUIkjM8= -github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ= -github.com/btcsuite/btcd v0.0.0-20190315201642-aa6e0f35703c/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/brianvoe/gofakeit v3.18.0+incompatible/go.mod h1:kfwdRA90vvNhPutZWfH7WPaDzUjz+CZFqG+rPkOjGOc= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btcd v0.21.0-beta h1:At9hIZdJW0s9E/fAz28nrz6AmcNlSVucCH796ZteX1M= -github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= +github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= +github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6zh6bWP60UxwoT5LzdGJsQJaPo6HjduXq9p6A= +github.com/btcsuite/btcd v0.24.0 h1:gL3uHE/IaFj6fcZSu03SvqPMSx7s/dPzfpG/atRwWdo= +github.com/btcsuite/btcd v0.24.0/go.mod h1:K4IDc1593s8jKXIF7yS7yCTSxrknB9z0STzc2j6XgE4= +github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= +github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= +github.com/btcsuite/btcd/btcec/v2 v2.3.3 h1:6+iXlDKE8RMtKsvK0gshlXIuPbyWM/h84Ensb7o3sC0= +github.com/btcsuite/btcd/btcec/v2 v2.3.3/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A= +github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE= +github.com/btcsuite/btcd/btcutil v1.1.5 h1:+wER79R5670vs/ZusMTF1yTcRYE5GUsFbdjdisflzM8= +github.com/btcsuite/btcd/btcutil v1.1.5/go.mod h1:PSZZ4UitpLBWzxGd5VGOrLnmOjtPP/a6HaFo12zMs00= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= -github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v1.0.2 h1:9iZ1Terx9fMIOtq1VrwdqfsATL9MC2l8ZrUY6YZ2uts= -github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= -github.com/btcsuite/goleveldb v1.0.0 h1:Tvd0BfvqX9o823q1j2UZ/epQo09eJh6dTcRp79ilIN4= github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/snappy-go v1.0.0 h1:ZxaA6lo2EpxGddsA8JwWOcxlzRybb444sgmeJQMJGQE= github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= -github.com/bwesterb/go-ristretto v1.2.0 h1:xxWOVbN5m8NNKiSDZXE1jtZvZnC6JSJ9cYFADiZcWtw= -github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/bwesterb/go-ristretto v1.2.3 h1:1w53tCkGhCQ5djbat3+MH0BAQ5Kfgbt56UZQ/JMzngw= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bxcodec/faker v2.0.1+incompatible h1:P0KUpUw5w6WJXwrPfv35oc91i4d8nf40Nwln+M/+faA= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/bxcodec/faker v2.0.1+incompatible/go.mod h1:BNzfpVdTwnFJ6GtfYTcQu6l6rHShT+veBxNCnjCx5XM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/circl v1.1.0 h1:bZgT/A+cikZnKIwn7xL2OBj012Bmvho/o6RpRvv3GKY= -github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= -github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/coinbase/rosetta-sdk-go v0.6.10 h1:rgHD/nHjxLh0lMEdfGDqpTtlvtSBwULqrrZ2qPdNaCM= -github.com/coinbase/rosetta-sdk-go v0.6.10/go.mod h1:J/JFMsfcePrjJZkwQFLh+hJErkAmdm9Iyy3D5Y0LfXo= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/coinbase/rosetta-sdk-go v0.8.5 h1:spP8996SFsRnfU8k12dxOHqDyeLXnFOpqshkclo4tMc= +github.com/coinbase/rosetta-sdk-go v0.8.5/go.mod h1:hFaqXH62zEgjZ/NFj58Sip1+JCEckTLM+xgmAUkbSIQ= +github.com/coinbase/rosetta-sdk-go/types v1.0.0 h1:jpVIwLcPoOeCR6o1tU+Xv7r5bMONNbHU7MuEHboiFuA= +github.com/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c= +github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= +github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI= +github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= -github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= +github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= -github.com/decred/dcrd/lru v1.1.1 h1:kWFDaW0OWx6AD6Ki342c+JPmHbiVdE6rK81pT3fuo/Y= -github.com/decred/dcrd/lru v1.1.1/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/decred/dcrd/lru v1.1.2 h1:KdCzlkxppuoIDGEvCGah1fZRicrDH36IipvlB1ROkFY= +github.com/decred/dcrd/lru v1.1.2/go.mod h1:gEdCVgXs1/YoBvFWt7Scgknbhwik3FgVSzlnCcXL2N8= github.com/deso-protocol/go-deadlock v1.0.0 h1:mw0pHy/19zgC+JFBStuQt1+1Ehv5OKA5NxXqecnL5ic= github.com/deso-protocol/go-deadlock v1.0.0/go.mod h1:K0Wd2OV2x7ck7SMYDraWerpKjFKUeBqaFcwz21tmkb8= github.com/deso-protocol/go-merkle-tree v1.0.0 h1:9zkI5dQsITYy77s4kbTGPQmZnhQ+LsH/kRdL5l/Yzvg= github.com/deso-protocol/go-merkle-tree v1.0.0/go.mod h1:V/vbg/maaNv6G7zf9VVs645nLFx/jsO2L/awFB/S/ZU= -github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= -github.com/dgraph-io/badger/v3 v3.2103.0 h1:abkD2EnP3+6Tj8h5LI1y00dJ9ICKTIAzvG9WmZ8S2c4= -github.com/dgraph-io/badger/v3 v3.2103.0/go.mod h1:GHMCYxuDWyzbHkh4k3yyg4PM61tJPFfEGSMbE3Vd5QE= -github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v0.0.4-0.20210309073149-3836124cdc5a/go.mod h1:MIonLggsKgZLUSt414ExgwNtlOL5MuEoAJP514mwGe8= -github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= -github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgraph-io/badger/v4 v4.2.0 h1:kJrlajbXXL9DFTNuhhu9yCx7JJa4qpYWxtE8BzuWsEs= +github.com/dgraph-io/badger/v4 v4.2.0/go.mod h1:qfCqhPoWDFJRx1gp5QwwyGo8xk1lbHUxvK9nK0OGAak= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= -github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= -github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/ebitengine/purego v0.7.1 h1:6/55d26lG3o9VCZX8lping+bZcmShseiqlh2bnUDiPA= +github.com/ebitengine/purego v0.7.1/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/ethereum/go-ethereum v1.9.25 h1:mMiw/zOOtCLdGLWfcekua0qPrJTe7FVIiHJ4IKNTfR0= -github.com/ethereum/go-ethereum v1.9.25/go.mod h1:vMkFiYLHI4tgPw4k2j4MHKoovchFE8plZ0M9VMk4/oM= -github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/ethereum/go-ethereum v1.13.14 h1:EwiY3FZP94derMCIam1iW4HFVrSgIcpsu0HwTQtm6CQ= +github.com/ethereum/go-ethereum v1.13.14/go.mod h1:TN8ZiHrdJwSe8Cb6x+p0hs5CxhJZPbqB7hHkaUXcmIU= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fergusstrange/embedded-postgres v1.19.0 h1:NqDufJHeA03U7biULlPHZ0pZ10/mDOMKPILEpT50Fyk= -github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fergusstrange/embedded-postgres v1.26.0 h1:mTgUBNST+6zro0TkIb9Fuo9Qg8mSU0ILus9jZKmFmJg= +github.com/fergusstrange/embedded-postgres v1.26.0/go.mod h1:t/MLs0h9ukYM6FSt99R7InCHs1nW0ordoVCcnzmpTYw= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gernest/mention v2.0.0+incompatible h1:pTXnujBC6tqlw5awDkLojq92TXbt0F+4+8FBlQC+di8= github.com/gernest/mention v2.0.0+incompatible/go.mod h1:/z3Hb+4gaPF+vL8og/lj6Au5j8hh5EfU7/EknmDUuO4= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/git-chglog/git-chglog v0.0.0-20200414013904-db796966b373 h1:MHrlpWOOFhCfY1L9iCIUy5cv5HgDtempICenzJt+7ws= github.com/git-chglog/git-chglog v0.0.0-20200414013904-db796966b373/go.mod h1:Dcsy1kii/xFyNad5JqY/d0GO5mu91sungp5xotbm3Yk= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= +github.com/git-chglog/git-chglog v0.15.4 h1:BwPDj7AghQTfpXO+UxG4mZM5MUTe9wfDuenF3jpyNf0= +github.com/git-chglog/git-chglog v0.15.4/go.mod h1:BmWdTpqBVzPjKNrBTZGcQCrQV9zq6gFKurhWNnJbYDA= github.com/go-pg/pg/v10 v10.5.0/go.mod h1:BfgPoQnD2wXNd986RYEHzikqv9iE875PrFaZ9vXvtNM= -github.com/go-pg/pg/v10 v10.10.0 h1:xc5zWYQ/55XI8pk5NkK+ixXqbJh1vnOun3VODPmbYfY= -github.com/go-pg/pg/v10 v10.10.0/go.mod h1:EmoJGYErc+stNN/1Jf+o4csXuprjxcRztBnn6cHe38E= +github.com/go-pg/pg/v10 v10.12.0 h1:rBmfDDHTN7FQW0OemYmcn5UuBy6wkYWgh/Oqt1OBEB8= +github.com/go-pg/pg/v10 v10.12.0/go.mod h1:USA08CdIasAn0F6wC1nBf5nQhMHewVQodWoH89RPXaI= github.com/go-pg/zerochecker v0.2.0 h1:pp7f72c3DobMWOb2ErtZsnrPaSvHd2W4o9//8HtF4mU= github.com/go-pg/zerochecker v0.2.0/go.mod h1:NJZ4wKL0NmTtz0GKCoJ8kym6Xn/EQzXRl2OnAe7MmDo= -github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= +github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -208,17 +178,13 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/flatbuffers v1.12.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/flatbuffers v2.0.0+incompatible h1:dicJ2oXwypfwUGnB2/TYWYEKiuk9eYQlQO/AnOHl5mI= -github.com/google/flatbuffers v2.0.0+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/flatbuffers v24.3.25+incompatible h1:CX395cjN9Kke9mmalRoL3d81AtFUxJM+yDthflgJGkI= +github.com/google/flatbuffers v24.3.25+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -226,246 +192,180 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20210125172800-10e9aeb4a998/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5 h1:zIaiqGYDQwa4HVx5wGRTXbx38Pqxjemn4BP98wpzpXo= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo= +github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= +github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A= -github.com/holiman/uint256 v1.1.1 h1:4JywC80b+/hSfljFlEBLHrrh+CIONLDz9NuFl0af4Mw= -github.com/holiman/uint256 v1.1.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= +github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= +github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= +github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= +github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= -github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= +github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= +github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= -github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk= -github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kyokomi/emoji/v2 v2.2.12 h1:sSVA5nH9ebR3Zji1o31wu3yOwD1zKXQA2z0zUyeit60= +github.com/kyokomi/emoji/v2 v2.2.12/go.mod h1:JUcn42DTdsXJo1SWanHh4HKDEyPaR5CqkmoirZZP9qE= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= -github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/goveralls v0.0.6 h1:cr8Y0VMo/MnEZBjxNN/vh6G90SZ7IMb6lms1dzMoO+Y= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/goveralls v0.0.6/go.mod h1:h8b4ow6FxSPMQHF6o2ve3qsclnffZjYTNEKmLesRwqw= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= +github.com/mattn/goveralls v0.0.12 h1:PEEeF0k1SsTjOBQ8FOmrOAoCu4ytuMaWCnWe94zxbCg= +github.com/mattn/goveralls v0.0.12/go.mod h1:44ImGEUfmqH8bBtaMrYKsM65LXfNLWmwaxFGjZwgMSQ= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= +github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8= -github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= -github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= -github.com/neilotoole/errgroup v0.1.5/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oleiade/lane v1.0.1 h1:hXofkn7GEOubzTwNpeL9MaNy8WxolCYb9cInAIeqShU= github.com/oleiade/lane v1.0.1/go.mod h1:IyTkraa4maLfjq/GmHR+Dxb4kCMtEGeb+qmhlrQ5Mk4= -github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/onflow/crypto v0.25.1 h1:0txy2PKPMM873JbpxQNbJmuOJtD56bfs48RQfm0ts5A= +github.com/onflow/crypto v0.25.1/go.mod h1:C8FbaX0x8y+FxWjbkHy0Q4EASCDR9bSPWZqlpCLYyVI= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.15.0 h1:1V1NfVQR87RtWAgp1lv9JZJ5Jap+XFGKPi00andXGi4= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= -github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ= -github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.7.0 h1:7utD74fnzVc/cpcyy8sjrlFr5vYpypUixARcHIMIGuI= -github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= -github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= -github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= +github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk= +github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/outcaste-io/ristretto v0.2.3 h1:AK4zt/fJ76kjlYObOeNwh4T3asEuaCmp26pOvUOL9w0= +github.com/outcaste-io/ristretto v0.2.3/go.mod h1:W8HywhmtlopSB1jeMg3JtdIhf+DYkLAr0VN/s4+MHac= +github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo= +github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= -github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ= -github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/petermattis/goid v0.0.0-20240327183114-c42a807a84ba h1:3jPgmsFGBID1wFfU2AbYocNcN4wqU68UaHSdMjiw/7U= +github.com/petermattis/goid v0.0.0-20240327183114-c42a807a84ba/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw= +github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= +github.com/richardartoul/molecule v1.0.1-0.20221107223329-32cfee06a052 h1:Qp27Idfgi6ACvFQat5+VJvlYToylpM/hcyLBI3WaKPA= +github.com/richardartoul/molecule v1.0.1-0.20221107223329-32cfee06a052/go.mod h1:uvX/8buq8uVeiZiFht+0lqSLBHF+uGV8BrTv8W/SIwk= github.com/robinjoseph08/go-pg-migrations/v3 v3.0.0 h1:0/H63lDsoNYVn5YmP6VLDEnnKkoVYiHx7udTWCK4BUI= github.com/robinjoseph08/go-pg-migrations/v3 v3.0.0/go.mod h1:nOkSFfwwDUBFnDDQqMRC2p4PDE7GZb/KSVqILVB3bmw= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/secure-systems-lab/go-securesystemslib v0.8.0 h1:mr5An6X45Kb2nddcFlbmfHkLguCE9laoZCUzEEpIZXA= +github.com/secure-systems-lab/go-securesystemslib v0.8.0/go.mod h1:UH2VZVuJfCYR8WgMlCU1uFsOUU+KeyrTWcSS73NBOzU= github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 h1:Xuk8ma/ibJ1fOy4Ee11vHhUFHQNpHhrBneOCNHVXS5w= github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0/go.mod h1:7AwjWCpdPhkSmNAgUv5C7EJ4AbmjEB3r047r3DXWu3Y= -github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= +github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M= -github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= -github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= -github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= -github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= -github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU= +github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= +github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -474,258 +374,207 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= -github.com/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= -github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tidwall/sjson v1.1.4/go.mod h1:wXpKXu8CtDjKAZ+3DrKY5ROCorDFahq8l0tey/Lx1fg= -github.com/tinylib/msgp v1.1.2 h1:gWmO7n0Ys2RBEb7GPYB9Ujq8Mk5p2U08lRnmMcGy6BQ= -github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= +github.com/tinylib/msgp v1.1.9 h1:SHf3yoO2sGA0veCJeCBYLHuttAVFHGm2RHgNodW7wQU= +github.com/tinylib/msgp v1.1.9/go.mod h1:BCXGB54lDD8qUEPmiG0cQQUANC4IUQyB2ItS2UDlO/k= github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= +github.com/trivago/tgo v1.0.7 h1:uaWH/XIy9aWYWpjm2CU3RpcqZXmX2ysQ9/Go+d9gyrM= +github.com/trivago/tgo v1.0.7/go.mod h1:w4dpD+3tzNIIiIfkWWa85w5/B77tlvdZckQ+6PkFnhc= github.com/tsuyoshiwada/go-gitcmd v0.0.0-20180205145712-5f1f5f9475df h1:Y2l28Jr3vOEeYtxfVbMtVfOdAwuUqWaP9fvNKiBVeXY= github.com/tsuyoshiwada/go-gitcmd v0.0.0-20180205145712-5f1f5f9475df/go.mod h1:pnyouUty/nBr/zm3GYwTIt+qFTLWbdjeLjZmJdzJOu8= -github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= -github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8= -github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/unrolled/secure v1.0.8 h1:JaMvKbe4CRt8oyxVXn+xY+6jlqd7pyJNSVkmsBxxQsM= -github.com/unrolled/secure v1.0.8/go.mod h1:fO+mEan+FLB0CdEnHf6Q4ZZVNqG+5fuLFnP8p0BXDPI= -github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= +github.com/unrolled/secure v1.14.0 h1:u9vJTU/pR4Bny0ntLUMxdfLtmIRGvQf2sEFuA0TG9AE= +github.com/unrolled/secure v1.14.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc= -github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= +github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= +github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= github.com/vmihailenco/bufpool v0.1.11 h1:gOq2WmBrq0i2yW5QJ16ykccQ4wH9UyEsgLm6czKAd94= github.com/vmihailenco/bufpool v0.1.11/go.mod h1:AFf/MOy3l2CFTKbxwt0mp2MwnqjNEs5H/UxrkA5jxTQ= github.com/vmihailenco/msgpack/v4 v4.3.11/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= github.com/vmihailenco/msgpack/v5 v5.0.0-beta.1/go.mod h1:xlngVLeyQ/Qi05oQxhQ+oTuqa03RjMwMfk/7/TCs+QI= github.com/vmihailenco/msgpack/v5 v5.0.0-beta.8/go.mod h1:HVxBVPUK/+fZMonk4bi1islLa8V3cfnBug0+4dykPzo= -github.com/vmihailenco/msgpack/v5 v5.1.4/go.mod h1:C5gboKD0TJPqWDTVTtrQNfRbiBwHZGo8UTqP/9/XvLI= -github.com/vmihailenco/msgpack/v5 v5.3.1 h1:0i85a4dsZh8mC//wmyyTEzidDLPQfQAxZIOLtafGbFY= -github.com/vmihailenco/msgpack/v5 v5.3.1/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc= github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= +github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw= +github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/otel v0.13.0/go.mod h1:dlSNewoRYikTkotEnxdmuBHgzT+k/idJSfDv/FxEnOY= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 h1:ESSUROHIBHg7USnszlcdmjBEwdMj9VUvU+OPk4yl2mc= +golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mobile v0.0.0-20200801112145-973feb4309de/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201026091529-146b70c837a4/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180606202747-9527bec2660b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201026173827-119d4633e4d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2 h1:wM1k/lXfpc5HdkJJyW9GELpd8ERGdnh8sMGL6Gzq3Ho= -golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 h1:Hir2P/De0WpUhtrKGGjvSb2YxUgyZ7EFOSLIcSSpiwE= -golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ= +gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= @@ -740,35 +589,27 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/AlecAivazis/survey.v1 v1.8.7 h1:oBJqtgsyBLg9K5FK9twNUbcPnbCPoh+R9a+7nag3qJM= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/AlecAivazis/survey.v1 v1.8.7/go.mod h1:iBNOmqKz/NUbZx3bA+4hAGLRC7fSK7tgtVDT4tB22XA= -gopkg.in/DataDog/dd-trace-go.v1 v1.29.0 h1:3C1EEjgFTPqrnS2SXuSqkBbZGacIOPJ7ScGJk4nrP9s= -gopkg.in/DataDog/dd-trace-go.v1 v1.29.0/go.mod h1:FLwUDeuH0z5hkvgvd04/M3MHQN4AF5pQDnedeWRWvok= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/DataDog/dd-trace-go.v1 v1.62.0 h1:jeZxE4ZlfAc+R0zO5TEmJBwOLet3NThsOfYJeSQg1x0= +gopkg.in/DataDog/dd-trace-go.v1 v1.62.0/go.mod h1:YTvYkk3PTsfw0OWrRFxV/IQ5Gy4nZ5TRvxTAP3JcIzs= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/kyokomi/emoji.v1 v1.5.1 h1:beetH5mWDMzFznJ+Qzd5KVHp79YKhVUMcdO8LpRLeGw= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/kyokomi/emoji.v1 v1.5.1/go.mod h1:N9AZ6hi1jHOPn34PsbpufQZUcKftSD7WgS2pgpmH4Lg= -gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= -gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= @@ -776,11 +617,12 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +honnef.co/go/gotraceui v0.2.0 h1:dmNsfQ9Vl3GwbiVD7Z8d/osC6WtGGrasyrC2suc4ZIQ= +honnef.co/go/gotraceui v0.2.0/go.mod h1:qHo4/W75cA3bX0QQoSvDjbJa4R8mAyyFjbWAj63XElc= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -mellium.im/sasl v0.2.1 h1:nspKSRg7/SyO0cRGY71OkfHab8tf9kCts6a6oTDut0w= mellium.im/sasl v0.2.1/go.mod h1:ROaEDLQNuf9vjKqE1SrAfnsobm2YKXT1gnN1uDp1PjQ= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +mellium.im/sasl v0.3.1 h1:wE0LW6g7U83vhvxjC1IY8DnXM+EU095yeo8XClvCdfo= +mellium.im/sasl v0.3.1/go.mod h1:xm59PUYpZHhgQ9ZqoJ5QaCqzWMi8IeS49dhp6plPCzw= +pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g= +pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= diff --git a/rosetta-cli-conf/testnet/deso.ros b/rosetta-cli-conf/testnet/deso.ros index b26461a1..815c0580 100644 --- a/rosetta-cli-conf/testnet/deso.ros +++ b/rosetta-cli-conf/testnet/deso.ros @@ -123,11 +123,20 @@ return_funds(10){ transfer_dry_run.network = {"network":"TESTNET", "blockchain":"DeSo"}; currency = {"symbol":"DESO", "decimals":9}; + // Hardcode the recipient to be the one who sent everyone their money + recipient = { + "account_identifier": { + "address": "tBCKWCLyYKGa4Lb4buEsMGYePEWcaVAqcunvDVD4zVDcH8NoB5EgPF" + } + }; + // We look for a sender that is able to pay the // max_fee_amount + min_utxo size (reserved_amount is max_fee_amount + min_utxo size). + // We don't want max_fee_amount = "1200"; reserved_amount = "1800"; sender = find_balance({ + "not_account_identifier":[{{recipient.account_identifier}}], "minimum_balance":{ "value": {{reserved_amount}}, "currency": {{currency}} @@ -141,8 +150,6 @@ return_funds(10){ "recipient_amount":{{recipient_amount}} }); - recipient = {"address": "tBCKWCLyYKGa4Lb4buEsMGYePEWcaVAqcunvDVD4zVDcH8NoB5EgPF"}; - sender_amount = 0 - {{sender.balance.value}}; transfer_dry_run.confirmation_depth = "1"; transfer_dry_run.dry_run = true; @@ -156,7 +163,7 @@ return_funds(10){ { "operation_identifier":{"index":1}, "type":"OUTPUT", - "account":{{recipient}}, + "account":{{recipient.account_identifier}}, "amount":{"value":{{recipient_amount}},"currency":{{currency}}} } ]; @@ -188,7 +195,7 @@ return_funds(10){ { "operation_identifier":{"index":1}, "type":"OUTPUT", - "account":{{recipient}}, + "account":{{recipient.account_identifier}}, "amount":{"value":{{recipient_amount}},"currency":{{currency}}} } ]; diff --git a/scripts/testnet/online.sh b/scripts/testnet/online.sh index b99a8537..4286729c 100755 --- a/scripts/testnet/online.sh +++ b/scripts/testnet/online.sh @@ -2,13 +2,14 @@ set -v (cd ../../ && go build -o rosetta-deso -gcflags="all=-N -l" main.go && ./rosetta-deso run \ + --glog-v=0 \ + --glog-vmodule="*bitcoin_manager*=0,*balance*=0,*view*=0,*frontend*=0,*peer*=0,*addr*=0,*network*=0,*utils*=0,*connection*=0,*main*=0,*server*=0,*mempool*=0,*miner*=0,*blockchain*=0" \ --mode ONLINE \ --node-port=18000 \ --port 17005 \ --data-directory /tmp/rosetta-testnet-online-20230407-00000 \ --network TESTNET \ - --connect-ips=test.deso.org:18000 \ --glog-v=2 \ - --hypersync=true \ - --sync-type=hypersync \ + --hypersync=false \ + --sync-type=blocksync \ ) diff --git a/scripts/testnet/regtest.sh b/scripts/testnet/regtest.sh index 28f078c2..77684596 100755 --- a/scripts/testnet/regtest.sh +++ b/scripts/testnet/regtest.sh @@ -7,5 +7,7 @@ set -v --data-directory /tmp/rosetta-regtest-online-2023-04-09-00012 \ --network TESTNET \ --miner-public-keys tBCKWCLyYKGa4Lb4buEsMGYePEWcaVAqcunvDVD4zVDcH8NoB5EgPF \ + --pos-validator-seed "escape gown wasp foam super claw eager foot opera hold roast cement" \ + --block-producer-seed "0xb78043f5087bbaa079c5e2dadcba547dfacb9964b6d334749256d56c7c0f74fd" \ --regtest \ -) +) \ No newline at end of file diff --git a/scripts/testnet/send.sh b/scripts/testnet/send.sh index 644578f2..b3bb64f3 100755 --- a/scripts/testnet/send.sh +++ b/scripts/testnet/send.sh @@ -5,10 +5,8 @@ # For now, it uses a single, hardcoded public key to mine and send money. # The account used to mine and send coins is: -# - Seed: escape gown wasp foam super claw eager foot opera hold roast cement -# - Seed Hex: 623751da8e50c314de0e79e7857e0bba067b7ebf5cb853535da5cad2360a678e +# - Seed Hex: b78043f5087bbaa079c5e2dadcba547dfacb9964b6d334749256d56c7c0f74fd # - Testnet public key base58: tBCKWCLyYKGa4Lb4buEsMGYePEWcaVAqcunvDVD4zVDcH8NoB5EgPF -# - Testnet public key bytes: 02b872c1b6acd3be581a27e53a15a2c9d095d3204dad3c2d7fe9a31f8c077126fe # Online node is running on port 17005 ONLINE=http://localhost:17005 diff --git a/services/account_service.go b/services/account_service.go index 165e9d5c..b0ae06ca 100644 --- a/services/account_service.go +++ b/services/account_service.go @@ -5,7 +5,9 @@ import ( "encoding/hex" "fmt" "github.com/deso-protocol/rosetta-deso/deso" + "math" "strconv" + "strings" "github.com/coinbase/rosetta-sdk-go/server" "github.com/coinbase/rosetta-sdk-go/types" @@ -52,10 +54,7 @@ func accountBalanceCurrent(node *deso.Node, account *types.AccountIdentifier) (* blockchain := node.GetBlockchain() currentBlock := blockchain.BlockTip() - dbView, err := lib.NewUtxoView(blockchain.DB(), node.Params, nil, node.Server.GetBlockchain().Snapshot(), nil) - if err != nil { - return nil, wrapErr(ErrDeSo, err) - } + dbView := lib.NewUtxoView(blockchain.DB(), node.Params, nil, node.Server.GetBlockchain().Snapshot(), nil) mempoolView, err := node.GetMempool().GetAugmentedUniversalView() if err != nil { @@ -85,6 +84,78 @@ func accountBalanceCurrent(node *deso.Node, account *types.AccountIdentifier) (* if mempoolProfileEntry != nil { mempoolBalance = mempoolProfileEntry.CreatorCoinEntry.DeSoLockedNanos } + } else if account.SubAccount.Address == deso.ValidatorEntry { + + var dbValidatorEntry *lib.ValidatorEntry + dbValidatorPKID := dbView.GetPKIDForPublicKey(publicKeyBytes).PKID + dbValidatorEntry, err = dbView.GetValidatorByPKID(dbValidatorPKID) + if err != nil { + return nil, wrapErr(ErrDeSo, err) + } + if dbValidatorEntry != nil { + if !dbValidatorEntry.TotalStakeAmountNanos.IsUint64() { + return nil, wrapErr(ErrDeSo, fmt.Errorf("TotalStakeAmountNanos is not a uint64")) + } + dbBalance = dbValidatorEntry.TotalStakeAmountNanos.Uint64() + } + + mempoolValidatorPKID := mempoolView.GetPKIDForPublicKey(publicKeyBytes).PKID + + var mempoolValidatorEntry *lib.ValidatorEntry + mempoolValidatorEntry, err = mempoolView.GetValidatorByPKID(mempoolValidatorPKID) + if err != nil { + return nil, wrapErr(ErrDeSo, err) + } + if mempoolValidatorEntry != nil { + if !mempoolValidatorEntry.TotalStakeAmountNanos.IsUint64() { + return nil, wrapErr(ErrDeSo, fmt.Errorf("TotalStakeAmountNanos is not a uint64")) + } + mempoolBalance = mempoolValidatorEntry.TotalStakeAmountNanos.Uint64() + } + } else if strings.HasPrefix(account.SubAccount.Address, deso.LockedStakeEntry) { + // Pull out the validator PKID + var validatorPKID *lib.PKID + validatorPKID, err = node.GetValidatorPKIDFromSubAccountIdentifier(account.SubAccount) + if err != nil { + return nil, wrapErr(ErrDeSo, err) + } + + dbStakerPKID := dbView.GetPKIDForPublicKey(publicKeyBytes).PKID + dbLockedStakeEntries, err := dbView.GetLockedStakeEntriesInRange(validatorPKID, dbStakerPKID, 0, math.MaxUint64) + if err != nil { + return nil, wrapErr(ErrDeSo, err) + } + dbRunningBalance := uint64(0) + for _, dbLockedStakeEntry := range dbLockedStakeEntries { + if !dbLockedStakeEntry.LockedAmountNanos.IsUint64() { + return nil, wrapErr(ErrDeSo, fmt.Errorf("AmountNanos is not a uint64")) + } + dbRunningBalance, err = lib.SafeUint64().Add(dbRunningBalance, dbLockedStakeEntry.LockedAmountNanos.Uint64()) + if err != nil { + return nil, wrapErr(ErrDeSo, err) + } + } + dbBalance = dbRunningBalance + + mempoolStakerPKID := mempoolView.GetPKIDForPublicKey(publicKeyBytes).PKID + + mempoolStakeEntries, err := mempoolView.GetLockedStakeEntriesInRange(validatorPKID, mempoolStakerPKID, 0, math.MaxUint64) + if err != nil { + return nil, wrapErr(ErrDeSo, err) + } + mempoolRunningBalance := uint64(0) + for _, mempoolStakeEntry := range mempoolStakeEntries { + if !mempoolStakeEntry.LockedAmountNanos.IsUint64() { + return nil, wrapErr(ErrDeSo, fmt.Errorf("AmountNanos is not a uint64")) + } + mempoolRunningBalance, err = lib.SafeUint64().Add(mempoolRunningBalance, mempoolStakeEntry.LockedAmountNanos.Uint64()) + if err != nil { + return nil, wrapErr(ErrDeSo, err) + } + } + mempoolBalance = mempoolRunningBalance + } else { + return nil, wrapErr(ErrDeSo, fmt.Errorf("Invalid SubAccount")) } block := &types.BlockIdentifier{ @@ -141,12 +212,24 @@ func accountBalanceSnapshot(node *deso.Node, account *types.AccountIdentifier, b return nil, wrapErr(ErrInvalidPublicKey, err) } publicKey := lib.NewPublicKey(publicKeyBytes) - + // We assume that address is a PKID for certain subaccounts. Parsing the bytes + // as a NewPKID will give us the appropriate subaccount. + pkid := lib.NewPKID(publicKeyBytes) var balance uint64 if account.SubAccount == nil { - balance = node.Index.GetBalanceSnapshot(false, publicKey, blockHeight) + balance = node.Index.GetBalanceSnapshot(deso.DESOBalance, publicKey, blockHeight) } else if account.SubAccount.Address == deso.CreatorCoin { - balance = node.Index.GetBalanceSnapshot(true, publicKey, blockHeight) + balance = node.Index.GetBalanceSnapshot(deso.CreatorCoinLockedBalance, publicKey, blockHeight) + } else if strings.HasPrefix(account.SubAccount.Address, deso.ValidatorEntry) { + balance = node.Index.GetBalanceSnapshot(deso.ValidatorStakedDESOBalance, publicKey, blockHeight) + } else if strings.HasPrefix(account.SubAccount.Address, deso.LockedStakeEntry) { + validatorPKID, err := node.GetValidatorPKIDFromSubAccountIdentifier(account.SubAccount) + if err != nil { + return nil, wrapErr(ErrDeSo, err) + } + balance = node.Index.GetLockedStakeBalanceSnapshot(deso.LockedStakeDESOBalance, pkid, validatorPKID, 0, blockHeight) + } else { + return nil, wrapErr(ErrDeSo, fmt.Errorf("Invalid SubAccount")) } //fmt.Printf("height: %v, addr (cc): %v, bal: %v\n", desoBlock.Header.Height, lib.PkToStringTestnet(publicKeyBytes), balance) @@ -180,16 +263,14 @@ func (s *AccountAPIService) AccountCoins( return nil, wrapErr(ErrInvalidPublicKey, err) } - utxoView, err := lib.NewUtxoView(blockchain.DB(), s.node.Params, nil, s.node.Server.GetBlockchain().Snapshot(), nil) - if err != nil { - return nil, wrapErr(ErrDeSo, err) - } + utxoView := lib.NewUtxoView(blockchain.DB(), s.node.Params, nil, s.node.Server.GetBlockchain().Snapshot(), nil) utxoEntries, err := utxoView.GetUnspentUtxoEntrysForPublicKey(publicKeyBytes) if err != nil { return nil, wrapErr(ErrDeSo, err) } + // TODO: Update for balance model. coins := []*types.Coin{} for _, utxoEntry := range utxoEntries { diff --git a/services/construction_service.go b/services/construction_service.go index aa71564c..253e74ba 100644 --- a/services/construction_service.go +++ b/services/construction_service.go @@ -5,14 +5,12 @@ import ( "encoding/hex" "encoding/json" "fmt" - "github.com/btcsuite/btcd/btcec" "github.com/coinbase/rosetta-sdk-go/server" "github.com/coinbase/rosetta-sdk-go/types" "github.com/deso-protocol/core/lib" merkletree "github.com/deso-protocol/go-merkle-tree" "github.com/deso-protocol/rosetta-deso/deso" "github.com/pkg/errors" - "math/big" "reflect" "strconv" ) @@ -160,7 +158,7 @@ func (s *ConstructionAPIService) ConstructionMetadata(ctx context.Context, reque } var options preprocessOptions - if err := types.UnmarshalMap(request.Options, &options); err != nil { + if err = types.UnmarshalMap(request.Options, &options); err != nil { return nil, wrapErr(ErrUnableToParseIntermediateResult, err) } @@ -169,7 +167,7 @@ func (s *ConstructionAPIService) ConstructionMetadata(ctx context.Context, reque } // Determine the network-wide feePerKB rate - feePerKB := mempoolView.GlobalParamsEntry.MinimumNetworkFeeNanosPerKB + feePerKB := mempoolView.GetCurrentGlobalParamsEntry().MinimumNetworkFeeNanosPerKB if feePerKB == 0 { feePerKB = deso.MinFeeRateNanosPerKB } @@ -246,8 +244,8 @@ func (s *ConstructionAPIService) ConstructionMetadata(ctx context.Context, reque } // Get the current max nonce expiration block height offset and current block height currentMaxExpirationBlockHeightOffset := uint64(lib.DefaultMaxNonceExpirationBlockHeightOffset) - if mempoolView.GlobalParamsEntry.MaxNonceExpirationBlockHeightOffset > 0 { - currentMaxExpirationBlockHeightOffset = mempoolView.GlobalParamsEntry.MaxNonceExpirationBlockHeightOffset + if mempoolView.GetCurrentGlobalParamsEntry().MaxNonceExpirationBlockHeightOffset > 0 { + currentMaxExpirationBlockHeightOffset = mempoolView.GetCurrentGlobalParamsEntry().MaxNonceExpirationBlockHeightOffset } currentBlockHeight := uint64(s.node.GetBlockchain().BlockTip().Height) // If the caller specified a expiration block height offset, @@ -379,10 +377,9 @@ func (s *ConstructionAPIService) ConstructionCombine(ctx context.Context, reques // signature is in form of R || S signatureBytes := request.Signatures[0].Bytes - desoTxn.Signature.SetSignature(&btcec.Signature{ - R: new(big.Int).SetBytes(signatureBytes[:32]), - S: new(big.Int).SetBytes(signatureBytes[32:64]), - }) + if err = desoTxn.Signature.FromBytes(signatureBytes); err != nil { + return nil, wrapErr(ErrInvalidTransaction, err) + } signedTxnBytes, err := desoTxn.ToBytes(false) if err != nil { @@ -411,8 +408,13 @@ func (s *ConstructionAPIService) ConstructionHash(ctx context.Context, request * return nil, wrapErr(ErrInvalidTransaction, err) } + var signedTx transactionMetadata + if err := json.Unmarshal(txnBytes, &signedTx); err != nil { + return nil, wrapErr(ErrInvalidTransaction, err) + } + txn := &lib.MsgDeSoTxn{} - if err = txn.FromBytes(txnBytes); err != nil { + if err = txn.FromBytes(signedTx.Transaction); err != nil { return nil, wrapErr(ErrInvalidTransaction, err) } @@ -462,8 +464,9 @@ func (s *ConstructionAPIService) ConstructionParse(ctx context.Context, request } for _, output := range desoTxn.TxOutputs { - // Skip the change output when NOT using legacy utxo selection - if !metadata.LegacyUTXOSelection && reflect.DeepEqual(output.PublicKey, desoTxn.PublicKey) { + // Skip the change output when NOT using legacy utxo selection AND it's not a balance model transaction + if !metadata.LegacyUTXOSelection && reflect.DeepEqual(output.PublicKey, desoTxn.PublicKey) && + desoTxn.TxnNonce == nil { continue } @@ -521,7 +524,6 @@ func (s *ConstructionAPIService) ConstructionSubmit(ctx context.Context, request if err = desoTxn.FromBytes(txn.Transaction); err != nil { return nil, wrapErr(ErrInvalidTransaction, err) } - if err := s.node.VerifyAndBroadcastTransaction(desoTxn); err != nil { return nil, wrapErr(ErrDeSo, err) } diff --git a/services/mempool_service.go b/services/mempool_service.go index e0de29d1..011ebf0d 100644 --- a/services/mempool_service.go +++ b/services/mempool_service.go @@ -27,12 +27,7 @@ func (s *MempoolAPIService) Mempool(ctx context.Context, request *types.NetworkR //return nil, wrapErr(ErrUnavailableOffline, nil) } - mempool := s.node.GetMempool() - transactions, _, err := mempool.GetTransactionsOrderedByTimeAdded() - if err != nil { - return nil, ErrDeSo - } - + transactions := s.node.GetMempool().GetOrderedTransactions() transactionIdentifiers := []*types.TransactionIdentifier{} for _, transaction := range transactions { transactionIdentifiers = append(transactionIdentifiers, &types.TransactionIdentifier{Hash: transaction.Hash.String()}) diff --git a/services/network_service.go b/services/network_service.go index 0fe57bc1..a768e2f4 100644 --- a/services/network_service.go +++ b/services/network_service.go @@ -47,7 +47,9 @@ func (s *NetworkAPIService) NetworkStatus(ctx context.Context, request *types.Ne } blockchain := s.node.GetBlockchain() - *syncStatus.CurrentIndex = int64(blockchain.BlockTip().Height) + committedTip, _ := blockchain.GetCommittedTip() + + *syncStatus.CurrentIndex = int64(committedTip.Height) *syncStatus.TargetIndex = int64(blockchain.HeaderTip().Height) *syncStatus.Stage = blockchain.ChainState().String()