diff --git a/cometmock/abci_client/client.go b/cometmock/abci_client/client.go index e9ee21f..0527da0 100644 --- a/cometmock/abci_client/client.go +++ b/cometmock/abci_client/client.go @@ -13,12 +13,8 @@ import ( "github.com/cometbft/cometbft/crypto/merkle" cometlog "github.com/cometbft/cometbft/libs/log" cmtmath "github.com/cometbft/cometbft/libs/math" -<<<<<<< HEAD cmtstate "github.com/cometbft/cometbft/proto/tendermint/state" - cmttypes "github.com/cometbft/cometbft/proto/tendermint/types" -======= cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) "github.com/cometbft/cometbft/state" blockindexkv "github.com/cometbft/cometbft/state/indexer/block/kv" "github.com/cometbft/cometbft/state/txindex" @@ -48,13 +44,10 @@ const ( Equivocation ) -<<<<<<< HEAD -======= -// hardcode max data bytes to -1 (unlimited) since we do not utilize a mempool +// hardcode max data bytes to the maximal value since we do not utilize a mempool // to pick evidence/txs out of const maxDataBytes = cmttypes.MaxBlockSizeBytes ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) // AbciClient facilitates calls to the ABCI interface of multiple nodes. // It also tracks the current state and a common logger. type AbciClient struct { @@ -131,11 +124,7 @@ func (a *AbciClient) CauseLightClientAttack(address string, misbehaviourType str return fmt.Errorf("unknown misbehaviour type %s, possible types are: Equivocation, Lunatic, Amnesia", misbehaviourType) } -<<<<<<< HEAD - _, _, _, _, _, err = a.RunBlockWithEvidence(nil, map[*types.Validator]MisbehaviourType{validator: misbehaviour}) -======= err = a.RunBlockWithEvidence(map[*types.Validator]MisbehaviourType{validator: misbehaviour}) ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) return err } @@ -147,12 +136,7 @@ func (a *AbciClient) CauseDoubleSign(address string) error { return err } -<<<<<<< HEAD - _, _, _, _, _, err = a.RunBlockWithEvidence(nil, map[*types.Validator]MisbehaviourType{validator: DuplicateVote}) - return err -======= return a.RunBlockWithEvidence(map[*types.Validator]MisbehaviourType{validator: DuplicateVote}) ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) } func (a *AbciClient) GetValidatorFromAddress(address string) (*types.Validator, error) { @@ -222,20 +206,17 @@ func CreateAndStartIndexerService(eventBus *types.EventBus, logger cometlog.Logg return indexerService, txIndexer, blockIndexer, indexerService.Start() } -<<<<<<< HEAD -func NewAbciClient(clients []AbciCounterpartyClient, logger cometlog.Logger, curState state.State, lastBlock *types.Block, lastCommit *types.Commit, storage storage.Storage, privValidators map[string]types.PrivValidator, errorOnUnequalResponses bool) *AbciClient { -======= func NewAbciClient( - clients map[string]AbciCounterpartyClient, + clients []AbciCounterpartyClient, logger cometlog.Logger, curState state.State, lastBlock *types.Block, - lastCommit *types.ExtendedCommit, + lastCommit *types.Commit, storage storage.Storage, timeHandler TimeHandler, + privValidators map[string]types.PrivValidator, errorOnUnequalResponses bool, ) *AbciClient { ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) signingStatus := make(map[string]bool) for addr := range privValidators { signingStatus[addr] = true @@ -677,11 +658,7 @@ func (a *AbciClient) SendAbciQuery(data []byte, path string, height int64, prove // RunEmptyBlocks runs a specified number of empty blocks through ABCI. func (a *AbciClient) RunEmptyBlocks(numBlocks int) error { for i := 0; i < numBlocks; i++ { -<<<<<<< HEAD - _, _, _, _, _, err := a.RunBlock(nil) -======= err := a.RunBlock() ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) if err != nil { return err } @@ -689,115 +666,6 @@ func (a *AbciClient) RunEmptyBlocks(numBlocks int) error { return nil } -<<<<<<< HEAD -// RunBlock runs a block with a specified transaction through the ABCI application. -// It calls RunBlockWithTimeAndProposer with the current time and the LastValidators.Proposer. -func (a *AbciClient) RunBlock(tx *[]byte) (*abcitypes.ResponseBeginBlock, *abcitypes.ResponseCheckTx, *abcitypes.ResponseDeliverTx, *abcitypes.ResponseEndBlock, *abcitypes.ResponseCommit, error) { - return a.RunBlockWithTimeAndProposer(tx, time.Now().Add(a.timeOffset), a.CurState.LastValidators.Proposer, make(map[*types.Validator]MisbehaviourType, 0)) -======= -func (a *AbciClient) decideProposal( - proposerApp *AbciCounterpartyClient, - proposerVal *types.Validator, - height int64, - round int32, - txs *types.Txs, - misbehaviour []types.Evidence, -) (*types.Proposal, *types.Block, error) { - var block *types.Block - var blockParts *types.PartSet - - // Create a new proposal block from state/txs from the mempool. - var err error - numTxs := len(*txs) - _ = numTxs - block, err = a.CreateProposalBlock( - proposerApp, - proposerVal, - height, - a.CurState, - a.LastCommit, - txs, - &misbehaviour, - ) - if err != nil { - return nil, nil, err - } else if block == nil { - panic("Method createProposalBlock should not provide a nil block without errors") - } - blockParts, err = block.MakePartSet(types.BlockPartSizeBytes) - if err != nil { - return nil, nil, fmt.Errorf("unable to create proposal block part set: %v", err) - } - - // Make proposal - propBlockID := types.BlockID{Hash: block.Hash(), PartSetHeader: blockParts.Header()} - proposal := types.NewProposal(height, round, 0, propBlockID) - p := proposal.ToProto() - if err := proposerApp.PrivValidator.SignProposal(a.CurState.ChainID, p); err == nil { - proposal.Signature = p.Signature - - // TODO: evaluate if we need to emulate message sending - // send proposal and block parts on internal msg queue - // cs.sendInternalMessage(msgInfo{&ProposalMessage{proposal}, ""}) - - // for i := 0; i < int(blockParts.Total()); i++ { - // part := blockParts.GetPart(i) - // cs.sendInternalMessage(msgInfo{&BlockPartMessage{cs.Height, cs.Round, part}, ""}) - // } - - a.Logger.Debug("signed proposal", "height", height, "round", round, "proposal", proposal) - } else { - a.Logger.Error("propose step; failed signing proposal", "height", height, "round", round, "err", err) - } - - return proposal, block, nil -} - -// Create a proposal block with the given height and proposer, -// and including the given tx and misbehaviour. -// Essentially a hollowed-out version of CreateProposalBlock in CometBFT, see -// https://github.com/cometbft/cometbft/blob/33d276831843854881e6365b9696ac39dda12922/state/execution.go#L101 -func (a *AbciClient) CreateProposalBlock( - proposerApp *AbciCounterpartyClient, - proposerVal *types.Validator, - height int64, - curState state.State, - lastExtCommit *types.ExtendedCommit, - txs *types.Txs, - misbehaviour *[]types.Evidence, -) (*types.Block, error) { - commit := lastExtCommit.ToCommit() - - block := curState.MakeBlock(height, *txs, commit, *misbehaviour, proposerVal.Address) - - request := &abcitypes.RequestPrepareProposal{ - MaxTxBytes: maxDataBytes, - Txs: block.Txs.ToSliceOfBytes(), - LocalLastCommit: utils.BuildExtendedCommitInfo(lastExtCommit, curState.LastValidators, curState.InitialHeight, curState.ConsensusParams.ABCI), - Misbehavior: block.Evidence.Evidence.ToABCI(), - Height: block.Height, - Time: block.Time, - NextValidatorsHash: block.NextValidatorsHash, - ProposerAddress: block.ProposerAddress, - } - - ctx, cancel := context.WithTimeout(context.Background(), ABCI_TIMEOUT) - response, err := proposerApp.Client.PrepareProposal(ctx, request) - cancel() - if err != nil { - // We panic, since there is no meaninful recovery we can perform here. - panic(err) - } - - modifiedTxs := response.GetTxs() - txl := types.ToTxs(modifiedTxs) - if err := txl.Validate(maxDataBytes); err != nil { - return nil, err - } - - return curState.MakeBlock(height, txl, commit, *misbehaviour, block.ProposerAddress), nil -} - // RunBlock runs a block with a specified transaction through the ABCI application. // It calls RunBlockWithTimeAndProposer with the current time and the LastValidators.Proposer. func (a *AbciClient) RunBlock() error { @@ -807,19 +675,13 @@ func (a *AbciClient) RunBlock() error { func (a *AbciClient) RunBlockWithTime(t time.Time) error { return a.RunBlockWithTimeAndProposer(t, a.CurState.LastValidators.Proposer, make(map[*types.Validator]MisbehaviourType, 0)) ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) } // RunBlockWithEvidence runs a block with a specified transaction through the ABCI application. // It also produces the specified evidence for the specified misbehaving validators. -<<<<<<< HEAD -func (a *AbciClient) RunBlockWithEvidence(tx *[]byte, misbehavingValidators map[*types.Validator]MisbehaviourType) (*abcitypes.ResponseBeginBlock, *abcitypes.ResponseCheckTx, *abcitypes.ResponseDeliverTx, *abcitypes.ResponseEndBlock, *abcitypes.ResponseCommit, error) { - return a.RunBlockWithTimeAndProposer(tx, time.Now().Add(a.timeOffset), a.CurState.LastValidators.Proposer, misbehavingValidators) -======= func (a *AbciClient) RunBlockWithEvidence(misbehavingValidators map[*types.Validator]MisbehaviourType) error { blockTime := a.TimeHandler.GetBlockTime(a.LastBlock.Time) return a.RunBlockWithTimeAndProposer(blockTime, a.CurState.LastValidators.Proposer, misbehavingValidators) ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) } func (a *AbciClient) ConstructDuplicateVoteEvidence(v *types.Validator) (*types.DuplicateVoteEvidence, error) { @@ -945,154 +807,6 @@ func (a *AbciClient) ConstructLightClientAttackEvidence( }, nil } -<<<<<<< HEAD -// RunBlock runs a block with a specified transaction through the ABCI application. -// It calls BeginBlock, DeliverTx, EndBlock, Commit and then -// updates the state. -// RunBlock is safe for use by multiple goroutines simultaneously. -func (a *AbciClient) RunBlockWithTimeAndProposer( - tx *[]byte, - blockTime time.Time, - proposer *types.Validator, - misbehavingValidators map[*types.Validator]MisbehaviourType, -) (*abcitypes.ResponseBeginBlock, *abcitypes.ResponseCheckTx, *abcitypes.ResponseDeliverTx, *abcitypes.ResponseEndBlock, *abcitypes.ResponseCommit, error) { - // lock mutex to avoid running two blocks at the same time - a.Logger.Debug("Locking mutex") - blockMutex.Lock() - - defer blockMutex.Unlock() - defer a.Logger.Debug("Unlocking mutex") - -======= -// Calls ProcessProposal on a provided app, with the given block as -// proposed block. -func (a *AbciClient) ProcessProposal( - app *AbciCounterpartyClient, - block *types.Block, -) (bool, error) { - // call the temporary function on the client - timeoutContext, cancel := context.WithTimeout(context.Background(), ABCI_TIMEOUT) - defer cancel() - - response, err := app.Client.ProcessProposal(timeoutContext, &abcitypes.RequestProcessProposal{ - Hash: block.Header.Hash(), - Height: block.Header.Height, - Time: block.Header.Time, - Txs: block.Data.Txs.ToSliceOfBytes(), - ProposedLastCommit: utils.BuildLastCommitInfo(block, a.CurState.Validators, a.CurState.InitialHeight), - Misbehavior: block.Evidence.Evidence.ToABCI(), - ProposerAddress: block.ProposerAddress, - NextValidatorsHash: block.NextValidatorsHash, - }) - if err != nil { - return false, err - } - if response.IsStatusUnknown() { - panic(fmt.Sprintf("ProcessProposal responded with status %s", response.Status.String())) - } - - return response.IsAccepted(), nil -} - -func (a *AbciClient) ExtendAndSignVote( - app *AbciCounterpartyClient, - validator *types.Validator, - valIndex int32, - block *types.Block, -) (*types.Vote, error) { - // get the index of this validator in the current validator set - blockParts, err := block.MakePartSet(types.BlockPartSizeBytes) - if err != nil { - panic(fmt.Sprintf("error making block part set: %v", err)) - } - - vote := &types.Vote{ - ValidatorAddress: validator.Address, - ValidatorIndex: int32(valIndex), - Height: block.Height, - Round: block.LastCommit.Round, - Timestamp: block.Time, - Type: cmtproto.PrecommitType, - BlockID: types.BlockID{ - Hash: block.Hash(), - PartSetHeader: blockParts.Header(), - }, - } - - if a.CurState.ConsensusParams.ABCI.VoteExtensionsEnabled(vote.Height) { - ext, err := app.Client.ExtendVote(context.TODO(), &abcitypes.RequestExtendVote{ - Hash: vote.BlockID.Hash, - Height: vote.Height, - Time: block.Time, - Txs: block.Txs.ToSliceOfBytes(), - ProposedLastCommit: utils.BuildLastCommitInfo(block, a.CurState.Validators, a.CurState.InitialHeight), - Misbehavior: block.Evidence.Evidence.ToABCI(), - NextValidatorsHash: block.NextValidatorsHash, - ProposerAddress: block.ProposerAddress, - }) - if err != nil { - return nil, fmt.Errorf("error extending vote %v:\n %v", vote.String(), err) - } - vote.Extension = ext.VoteExtension - } - // going through ToProto looks weird but this is - // how signing is done in CometBFT https://github.com/cometbft/cometbft/blob/f63499c82c7defcdd82696f262f5a2eb495a3ac7/types/vote.go#L405 - protoVote := vote.ToProto() - err = app.PrivValidator.SignVote(a.CurState.ChainID, protoVote) - vote.Signature = protoVote.Signature - - vote.ExtensionSignature = nil - if a.CurState.ConsensusParams.ABCI.VoteExtensionsEnabled(vote.Height) { - vote.ExtensionSignature = protoVote.ExtensionSignature - } - if err != nil { - return nil, fmt.Errorf("error signing vote %v:\n %v", vote.String(), err) - } - return vote, nil -} - -// SendFinalizeBlock sends a FinalizeBlock request to all clients and collects the responses. -// The last commit of the AbciClient needs to be set when calling this. -func (a *AbciClient) SendFinalizeBlock( - block *types.Block, - lastCommitInfo *abcitypes.CommitInfo, -) (*abcitypes.ResponseFinalizeBlock, error) { - // build the FinalizeBlock request - request := abcitypes.RequestFinalizeBlock{ - Txs: block.Txs.ToSliceOfBytes(), - DecidedLastCommit: *lastCommitInfo, - Misbehavior: block.Evidence.Evidence.ToABCI(), - Height: block.Height, - Hash: block.Hash(), - Time: block.Time, - ProposerAddress: block.ProposerAddress, - NextValidatorsHash: block.NextValidatorsHash, - } - - // send FinalizeBlock to all clients and collect the responses - responses := make([]*abcitypes.ResponseFinalizeBlock, 0) - for _, client := range a.Clients { - ctx, cancel := context.WithTimeout(context.Background(), ABCI_TIMEOUT) - response, err := client.Client.FinalizeBlock(ctx, &request) - cancel() - if err != nil { - return nil, err - } - responses = append(responses, response) - } - - if a.ErrorOnUnequalResponses { - // return an error if the responses are not all equal - for i := 1; i < len(responses); i++ { - if !reflect.DeepEqual(responses[i], responses[0]) { - return nil, fmt.Errorf("responses are not all equal: %v is not equal to %v", responses[i], responses[0]) - } - } - } - - return responses[0], nil -} - // internal method that runs a block. // Should only be used after locking the blockMutex. func (a *AbciClient) runBlock_helper( @@ -1100,7 +814,6 @@ func (a *AbciClient) runBlock_helper( proposer *types.Validator, misbehavingValidators map[*types.Validator]MisbehaviourType, ) error { ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) a.Logger.Info("Running block") if verbose { a.Logger.Info("State at start of block", "state", a.CurState) @@ -1108,11 +821,6 @@ func (a *AbciClient) runBlock_helper( newHeight := a.CurState.LastBlockHeight + 1 -<<<<<<< HEAD - txs := make([]types.Tx, 0) - if tx != nil { - txs = append(txs, *tx) -======= var err error for index, tx := range a.FreshTxQueue { @@ -1126,7 +834,6 @@ func (a *AbciClient) runBlock_helper( // drop the tx by setting the index to empty a.FreshTxQueue[index] = cmttypes.Tx{} } ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) } // recheck txs from the stale queue @@ -1134,9 +841,6 @@ func (a *AbciClient) runBlock_helper( txBytes := []byte(tx) resCheckTx, err := a.SendCheckTx(abcitypes.CheckTxType_Recheck, &txBytes) if err != nil { -<<<<<<< HEAD - return nil, nil, nil, nil, nil, err -======= return fmt.Errorf("error from CheckTx: %v", err) } // if the CheckTx code is != 0 @@ -1152,10 +856,11 @@ func (a *AbciClient) runBlock_helper( txBytes := []byte(tx) if len(txBytes) > 0 { newTxQueue = append(newTxQueue, tx) ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) } } + txs := cmttypes.Txs(newTxQueue) + // TODO: handle special case where proposer is nil var proposerAddress types.Address if proposer != nil { @@ -1176,139 +881,52 @@ func (a *AbciClient) runBlock_helper( } if err != nil { -<<<<<<< HEAD - return nil, nil, nil, nil, nil, err -======= return fmt.Errorf("error constructing evidence: %v", err) ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) } evidences = append(evidences, evidence) } -<<<<<<< HEAD block := a.CurState.MakeBlock(a.CurState.LastBlockHeight+1, txs, a.LastCommit, evidences, proposerAddress) // override the block time, since we do not actually get votes from peers to median the time out of block.Time = blockTime blockId, err := utils.GetBlockIdFromBlock(block) if err != nil { - return nil, nil, nil, nil, nil, err - } - - commitSigs := []types.CommitSig{} - -======= - var proposerApp *AbciCounterpartyClient - for _, c := range a.Clients { - if c.ValidatorAddress == proposerAddress.String() { - proposerApp = &c - break - } - } - - if proposerApp == nil { - return fmt.Errorf("could not find proposer app for address %v", proposerAddress) + return err } - // The proposer runs PrepareProposal - txs := cmttypes.Txs(newTxQueue) - _, block, err := a.decideProposal( - proposerApp, - proposer, - a.CurState.LastBlockHeight+1, - 0, - &txs, - evidences, - ) - - // set the block time to the time passed as argument - block.Time = blockTime - - // clear the tx queues a.ClearTxs() - // for each tx not included in the block, - // put it in the stale queue - for _, tx := range newTxQueue { - if !utils.Contains(block.Txs, tx) { - a.StaleTxQueue = append(a.StaleTxQueue, tx) - } - } - - if err != nil { - return fmt.Errorf("error in decideProposal: %v", err) - } - - var nonProposers []*AbciCounterpartyClient - for _, val := range a.CurState.Validators.Validators { - client, err := a.GetCounterpartyFromAddress(val.Address.String()) - if err != nil { - return fmt.Errorf("error when getting counterparty client from address: address %v, error %v", val.Address.String(), err) - } - - if client.ValidatorAddress != proposerAddress.String() { - nonProposers = append(nonProposers, client) - } - } - - // non-proposers run ProcessProposal - for _, client := range nonProposers { - accepted, err := a.ProcessProposal(client, block) - if err != nil { - return fmt.Errorf("error in ProcessProposal for block %v, error %v", block.String(), err) - } - - if !accepted { - return fmt.Errorf("non-proposer %v did not accept the proposal for block %v", client.ValidatorAddress, block.String()) - } - } - - votes := []*types.Vote{} + commitSigs := []types.CommitSig{} - // sign the block with all current validators, and call ExtendVote (if necessary) ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) for index, val := range a.CurState.Validators.Validators { privVal := a.PrivValidators[val.Address.String()] shouldSign, err := a.GetSigningStatus(val.Address.String()) if err != nil { -<<<<<<< HEAD - return nil, nil, nil, nil, nil, err + return err } if shouldSign { // create and sign a precommit - vote := &cmttypes.Vote{ + vote := &cmtproto.Vote{ ValidatorAddress: val.Address, ValidatorIndex: int32(index), Height: block.Height, Round: 1, - Timestamp: time.Now().Add(a.timeOffset), - Type: cmttypes.PrecommitType, + Timestamp: blockTime, + Type: cmtproto.PrecommitType, BlockID: blockId.ToProto(), -======= - return fmt.Errorf("error getting signing status for validator %v, error %v", val.Address.String(), err) - } - - if shouldSign { - client, ok := a.Clients[val.Address.String()] - if !ok { - return fmt.Errorf("did not find privval for address: address %v", val.Address.String()) - } - vote, err := a.ExtendAndSignVote(&client, val, int32(index), block) - if err != nil { - return fmt.Errorf("error when signing vote for validator %v, error %v", val.Address.String(), err) ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) } err = privVal.SignVote(a.CurState.ChainID, vote) if err != nil { - return nil, nil, nil, nil, nil, err + return err } convertedVote, err := types.VoteFromProto(vote) if err != nil { - return nil, nil, nil, nil, nil, err + return err } commitSig := convertedVote.CommitSig() @@ -1319,99 +937,17 @@ func (a *AbciClient) runBlock_helper( } } -<<<<<<< HEAD a.LastCommit = types.NewCommit( block.Height, 1, *blockId, commitSigs, ) -======= - // verify vote extensions if necessary - if a.CurState.ConsensusParams.ABCI.VoteExtensionsEnabled(block.Height) { - for _, val := range a.CurState.Validators.Validators { - a.Logger.Info("Verifying vote extension for validator", val.Address.String()) - client, err := a.GetCounterpartyFromAddress(val.Address.String()) - if err != nil { - return fmt.Errorf("error when getting counterparty client from address: address %v, error %v", val.Address.String(), err) - } - - for _, vote := range votes { - if vote != nil && vote.ValidatorAddress.String() != client.ValidatorAddress { - // make a context to time out the request - ctx, cancel := context.WithTimeout(context.Background(), ABCI_TIMEOUT) - - resp, err := client.Client.VerifyVoteExtension(ctx, &abcitypes.RequestVerifyVoteExtension{ - Hash: block.Hash(), - ValidatorAddress: vote.ValidatorAddress, - Height: block.Height, - VoteExtension: vote.Extension, - }) - cancel() - // recovering from errors of VerifyVoteExtension seems hard because applications - // are typically not supposed to reject valid extensions created by ExtendVote. - if err != nil { - panic(fmt.Errorf("verify vote extension failed with error %v", err)) - } - - if resp.IsStatusUnknown() { - panic(fmt.Sprintf("verify vote extension responded with status %s", resp.Status.String())) - } - - if !resp.IsAccepted() { - panic(fmt.Sprintf("Verify vote extension rejected an extension for vote %v", vote.String())) - } - } - } - } - } - - // if vote extensions are enabled, we need an extended vote set - // otherwise, we need a regular vote set - var voteSet *types.VoteSet - if a.CurState.ConsensusParams.ABCI.VoteExtensionsEnabled(block.Height) { - voteSet = types.NewExtendedVoteSet( - a.CurState.ChainID, - block.Height, - 0, // round is hardcoded to 0 - cmtproto.PrecommitType, - a.CurState.Validators, - ) - } else { - voteSet = types.NewVoteSet( - a.CurState.ChainID, - block.Height, - 0, // round is hardcoded to 0 - cmtproto.PrecommitType, - a.CurState.Validators, - ) - } - - // add the votes to the vote set - for _, vote := range votes { - if vote != nil { - added, err := voteSet.AddVote(vote) - if err != nil { - return fmt.Errorf("error adding vote %v to vote set: %v", vote.String(), err) - } - if !added { - return fmt.Errorf("could not add vote %v to vote set", vote.String()) - } - } - } - - // set the last commit to the vote set - a.LastCommit = voteSet.MakeExtendedCommit(a.CurState.ConsensusParams.ABCI) ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) // sanity check that the commit is signed correctly err = a.CurState.Validators.VerifyCommitLightTrusting(a.CurState.ChainID, a.LastCommit, cmtmath.Fraction{Numerator: 1, Denominator: 3}) if err != nil { -<<<<<<< HEAD - return nil, nil, nil, nil, nil, err -======= - return fmt.Errorf("error verifying commit %v: %v", a.LastCommit.ToCommit().StringIndented("\t"), err) ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) + return fmt.Errorf("error verifying commit %v: %v", a.LastCommit.StringIndented("\t"), err) } // sanity check that the commit makes a proper light block @@ -1428,40 +964,27 @@ func (a *AbciClient) runBlock_helper( err = lightBlock.ValidateBasic(a.CurState.ChainID) if err != nil { a.Logger.Error("Light block validation failed", "err", err) -<<<<<<< HEAD - return nil, nil, nil, nil, nil, err -======= return err ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) } resBeginBlock, err := a.SendBeginBlock(block) if err != nil { -<<<<<<< HEAD - return nil, nil, nil, nil, nil, err + return fmt.Errorf("error from BeginBlock for block %v: %v", block.String(), err) } - var resDeliverTx *abcitypes.ResponseDeliverTx - if tx != nil { - resDeliverTx, err = a.SendDeliverTx(tx) + var deliverTxResponses []*abcitypes.ResponseDeliverTx + for _, tx := range newTxQueue { + txBytes := []byte(tx) + resDeliverTx, err := a.SendDeliverTx(&txBytes) if err != nil { - return nil, nil, nil, nil, nil, err + return err } - } else { - resDeliverTx = nil + deliverTxResponses = append(deliverTxResponses, resDeliverTx) } resEndBlock, err := a.SendEndBlock() if err != nil { - return nil, nil, nil, nil, nil, err - } - - deliverTxResponses := []*abcitypes.ResponseDeliverTx{} - if tx != nil { - deliverTxResponses = append(deliverTxResponses, resDeliverTx) -======= - return fmt.Errorf("error from FinalizeBlock for block %v: %v", block.String(), err) ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) + return err } // lock the state update mutex while the stores are updated to avoid @@ -1472,55 +995,33 @@ func (a *AbciClient) runBlock_helper( // copy state so that the historical state is not mutated state := a.CurState.Copy() -<<<<<<< HEAD // build components of the state update, then call the update function abciResponses := cmtstate.ABCIResponses{ DeliverTxs: deliverTxResponses, EndBlock: resEndBlock, BeginBlock: resBeginBlock, -======= - // insert entries into the storage - err = a.Storage.UpdateStores(newHeight, block, a.LastCommit.ToCommit(), &state, resFinalizeBlock) - if err != nil { - return fmt.Errorf("error updating stores: %v", err) ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) } // insert entries into the storage err = a.Storage.UpdateStores(newHeight, block, a.LastCommit, &state, &abciResponses) if err != nil { -<<<<<<< HEAD - return nil, nil, nil, nil, nil, err -======= return fmt.Errorf("error getting block id from block %v: %v", block.String(), err) ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) } // updates state as a side effect. returns an error if the state update fails err = a.UpdateStateFromBlock(blockId, block, abciResponses) if err != nil { -<<<<<<< HEAD - return nil, nil, nil, nil, nil, err -======= - return fmt.Errorf("error updating state for result %v, block %v: %v", resFinalizeBlock.String(), block.String(), err) ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) + return fmt.Errorf("error updating state for result %v, block %v: %v", abciResponses.String(), block.String(), err) } // unlock the state mutex, since we are done updating state a.Storage.UnlockAfterStateUpdate() - _, err = a.SendCommit() + resCommit, err := a.SendCommit() if err != nil { -<<<<<<< HEAD - return nil, nil, nil, nil, nil, err -======= return fmt.Errorf("error from Commit for block %v: %v", block.String(), err) ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) } a.CurState.AppHash = resCommit.Data -<<<<<<< HEAD - return resBeginBlock, resCheckTx, resDeliverTx, resEndBlock, resCommit, nil -======= return nil } @@ -1540,7 +1041,6 @@ func (a *AbciClient) RunBlockWithTimeAndProposer( blockMutex.Unlock() a.Logger.Debug("Unlocking mutex") return err ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) } // UpdateStateFromBlock updates the AbciClients state @@ -1580,11 +1080,7 @@ func (a *AbciClient) UpdateStateFromBlock( // Events are fired after everything else. // NOTE: if we crash between Commit and Save, events wont be fired during replay -<<<<<<< HEAD fireEvents(a.Logger, &a.EventBus, block, &abciResponses, validatorUpdates) -======= - fireEvents(a.Logger, &a.EventBus, block, *blockId, finalizeBlockRes, validatorUpdates) ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) return nil } @@ -1681,14 +1177,10 @@ func validateValidatorUpdates( return nil } -// Fire NewBlock, NewBlockHeader. -// Fire TxEvent for every tx. -// NOTE: if CometBFT crashes before commit, some or all of these events may be published again. func fireEvents( logger cometlog.Logger, eventBus types.BlockEventPublisher, block *types.Block, -<<<<<<< HEAD abciResponses *cmtstate.ABCIResponses, validatorUpdates []*types.Validator, ) { @@ -1696,40 +1188,19 @@ func fireEvents( Block: block, ResultBeginBlock: *abciResponses.BeginBlock, ResultEndBlock: *abciResponses.EndBlock, -======= - blockID types.BlockID, - abciResponse *abcitypes.ResponseFinalizeBlock, - validatorUpdates []*types.Validator, -) { - if err := eventBus.PublishEventNewBlock(types.EventDataNewBlock{ - Block: block, - BlockID: blockID, - ResultFinalizeBlock: *abciResponse, ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) }); err != nil { logger.Error("failed publishing new block", "err", err) } -<<<<<<< HEAD eventDataNewBlockHeader := types.EventDataNewBlockHeader{ Header: block.Header, NumTxs: int64(len(block.Txs)), ResultBeginBlock: *abciResponses.BeginBlock, ResultEndBlock: *abciResponses.EndBlock, -======= - if err := eventBus.PublishEventNewBlockHeader(types.EventDataNewBlockHeader{ - Header: block.Header, - }); err != nil { - logger.Error("failed publishing new block header", "err", err) ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) } - if err := eventBus.PublishEventNewBlockEvents(types.EventDataNewBlockEvents{ - Height: block.Height, - Events: abciResponse.Events, - NumTxs: int64(len(block.Txs)), - }); err != nil { - logger.Error("failed publishing new block events", "err", err) + if err := eventBus.PublishEventNewBlockHeader(eventDataNewBlockHeader); err != nil { + logger.Error("failed publishing new block header", "err", err) } if len(block.Evidence.Evidence) != 0 { @@ -1748,11 +1219,7 @@ func fireEvents( Height: block.Height, Index: uint32(i), Tx: tx, -<<<<<<< HEAD Result: *(abciResponses.DeliverTxs[i]), -======= - Result: *(abciResponse.TxResults[i]), ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) }}); err != nil { logger.Error("failed publishing event TX", "err", err) } diff --git a/cometmock/main.go b/cometmock/main.go index 5b4de39..b4f4d06 100644 --- a/cometmock/main.go +++ b/cometmock/main.go @@ -140,10 +140,8 @@ or the system time between creating the genesis request and producing the first logger.Error(err.Error()) } -<<<<<<< HEAD clients := []abci_client.AbciCounterpartyClient{} privValsMap := make(map[string]types.PrivValidator) -======= // read starting timestamp from args // if starting timestamp should be taken from genesis, // read it from there @@ -164,9 +162,6 @@ or the system time between creating the genesis request and producing the first blockTime := time.Duration(c.Int64("block-time")) * time.Millisecond fmt.Printf("Block time: %d\n", blockTime.Milliseconds()) - clientMap := make(map[string]abci_client.AbciCounterpartyClient) ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) - for i, appAddress := range appAddresses { logger.Info("Connecting to client at %v", appAddress) @@ -221,21 +216,13 @@ or the system time between creating the genesis request and producing the first &types.Block{}, &types.Commit{}, &storage.MapStorage{}, -<<<<<<< HEAD - privValsMap, - true, - ) - - // connect to clients - abci_client.GlobalClient.RetryDisconnectedClients() -======= timeHandler, + privValsMap, true, ) abci_client.GlobalClient.AutoIncludeTx = c.Bool("auto-tx") fmt.Printf("Auto include tx: %t\n", abci_client.GlobalClient.AutoIncludeTx) ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) // initialize chain err = abci_client.GlobalClient.SendInitChain(curState, genesisDoc) @@ -252,11 +239,7 @@ or the system time between creating the genesis request and producing the first } // run an empty block -<<<<<<< HEAD - _, _, _, _, _, err = abci_client.GlobalClient.RunBlock(nil) -======= err = abci_client.GlobalClient.RunBlockWithTime(firstBlockTime) ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) if err != nil { logger.Error(err.Error()) panic(err) @@ -267,11 +250,7 @@ or the system time between creating the genesis request and producing the first if blockProductionInterval > 0 { // produce blocks according to blockTime for { -<<<<<<< HEAD - _, _, _, _, _, err := abci_client.GlobalClient.RunBlock(nil) -======= err := abci_client.GlobalClient.RunBlock() ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) if err != nil { logger.Error(err.Error()) panic(err) diff --git a/cometmock/rpc_server/routes.go b/cometmock/rpc_server/routes.go index ff3d33e..7a62090 100644 --- a/cometmock/rpc_server/routes.go +++ b/cometmock/rpc_server/routes.go @@ -10,12 +10,9 @@ import ( cmtmath "github.com/cometbft/cometbft/libs/math" cmtquery "github.com/cometbft/cometbft/libs/pubsub/query" "github.com/cometbft/cometbft/p2p" -<<<<<<< HEAD cometp2p "github.com/cometbft/cometbft/p2p" -======= abcitypes "github.com/cometbft/cometbft/abci/types" ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) ctypes "github.com/cometbft/cometbft/rpc/core/types" rpc "github.com/cometbft/cometbft/rpc/jsonrpc/server" rpctypes "github.com/cometbft/cometbft/rpc/jsonrpc/types" @@ -448,9 +445,7 @@ func BroadcastTxCommit(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadc return nil, errors.New("BroadcastTxCommit is currently not supported. Try BroadcastTxSync or BroadcastTxAsync instead") } -// BroadcastTxSync would normally broadcast a transaction and wait until it gets the result from CheckTx. -// In our case, we run a block with just the transition in it, -// then return. +// BroadcastTxSync broadcasts a transaction and waits until it gets the result from CheckTx. func BroadcastTxSync(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { abci_client.GlobalClient.Logger.Info( "BroadcastTxSync called", "tx", tx) @@ -488,14 +483,8 @@ func BroadcastTx(tx *types.Tx) (*ctypes.ResultBroadcastTxCommit, error) { abci_client.GlobalClient.Logger.Info( "BroadcastTxs called", "tx", tx) -<<<<<<< HEAD - byteTx := []byte(*tx) - - _, responseCheckTx, responseDeliverTx, _, _, err := abci_client.GlobalClient.RunBlock(&byteTx) -======= txBytes := []byte(*tx) checkTxResponse, err := abci_client.GlobalClient.SendCheckTx(abcitypes.CheckTxType_New, &txBytes) ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) if err != nil { return nil, err } @@ -506,18 +495,10 @@ func BroadcastTx(tx *types.Tx) (*ctypes.ResultBroadcastTxCommit, error) { } return &ctypes.ResultBroadcastTxCommit{ -<<<<<<< HEAD - CheckTx: *responseCheckTx, - DeliverTx: *responseDeliverTx, - Height: abci_client.GlobalClient.LastBlock.Height, - Hash: tx.Hash(), - }, nil -======= CheckTx: *checkTxResponse, Hash: tx.Hash(), Height: abci_client.GlobalClient.CurState.LastBlockHeight, }, err ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) } func ABCIInfo(ctx *rpctypes.Context) (*ctypes.ResultABCIInfo, error) { diff --git a/e2e-tests/main_test.go b/e2e-tests/main_test.go index a345554..cdff55a 100644 --- a/e2e-tests/main_test.go +++ b/e2e-tests/main_test.go @@ -11,64 +11,16 @@ import ( "github.com/stretchr/testify/require" ) -<<<<<<< HEAD -func runCommandWithOutput(cmd *exec.Cmd) (string, error) { - var stdout, stderr bytes.Buffer - cmd.Stdout = &stdout - cmd.Stderr = &stderr - - err := cmd.Run() - if err != nil { - return "", fmt.Errorf("error running command: %v\nstdout: %s\nstderr: %s", err, stdout.String(), stderr.String()) - } - - return stdout.String(), nil -} - -// From the output of the AbciInfo command, extract the latest block height. -// The json bytes should look e.g. like this: -// {"jsonrpc":"2.0","id":1,"result":{"response":{"data":"interchain-security-p","last_block_height":"2566","last_block_app_hash":"R4Q3Si7+t7TIidl2oTHcQRDNEz+lP0IDWhU5OI89psg="}}} -func extractHeightFromInfo(jsonBytes []byte) (int, error) { - // Use a generic map to represent the JSON structure - var data map[string]interface{} - - if err := json.Unmarshal(jsonBytes, &data); err != nil { - return -1, fmt.Errorf("Failed to unmarshal JSON %s \n error was %v", string(jsonBytes), err) - } - - // Navigate the map and use type assertions to get the last_block_height - result, ok := data["result"].(map[string]interface{}) - if !ok { - return -1, fmt.Errorf("Failed to navigate abci_info output structure trying to access result: json was %s", string(jsonBytes)) - } - - response, ok := result["response"].(map[string]interface{}) - if !ok { - return -1, fmt.Errorf("Failed to navigate abci_info output structure trying to access response: json was %s", string(jsonBytes)) - } - - lastBlockHeight, ok := response["last_block_height"].(string) - if !ok { - return -1, fmt.Errorf("Failed to navigate abci_info output structure trying to access last_block_height: json was %s", string(jsonBytes)) - } - - return strconv.Atoi(lastBlockHeight) -} - -// Tests happy path functionality for Abci Info. -func TestAbciInfo(t *testing.T) { -======= func StartChain( t *testing.T, cometmockArgs string, ) error { ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) // execute the local-testnet-singlechain.sh script t.Log("Running local-testnet-singlechain.sh") cmd := exec.Command("./local-testnet-singlechain-restart.sh", "simd") _, err := runCommandWithOutput(cmd) if err != nil { - t.Fatalf("Error running local-testnet-singlechain.sh: %v", err) + return fmt.Errorf("Error running local-testnet-singlechain.sh: %v", err) } cmd = exec.Command("./local-testnet-singlechain-start.sh", cometmockArgs) @@ -81,7 +33,9 @@ func StartChain( // wait until we are producing blocks for { - out, err := exec.Command("bash", "-c", "simd q block --node tcp://127.0.0.1:22331 | jq -r '.block.header.height'").Output() + // --type height 0 gets the latest height + out, err := exec.Command("bash", "-c", "simd q block --node tcp://127.0.0.1:22331 | jq -r '.header.height'").Output() + if err == nil { t.Log("We are producing blocks: ", string(out)) break @@ -89,8 +43,6 @@ func StartChain( t.Log("Waiting for blocks to be produced, latest output: ", string(out)) time.Sleep(1 * time.Second) } -<<<<<<< HEAD -======= time.Sleep(5 * time.Second) return nil } @@ -102,12 +54,11 @@ func TestAbciInfo(t *testing.T) { if err != nil { t.Fatalf("Error starting chain: %v", err) } ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) // call the abci_info command by calling curl on the REST endpoint // curl -H 'Content-Type: application/json' -H 'Accept:application/json' --data '{"jsonrpc":"2.0","method":"abci_info","id":1}' 127.0.0.1:22331 args := []string{"bash", "-c", "curl -H 'Content-Type: application/json' -H 'Accept:application/json' --data '{\"jsonrpc\":\"2.0\",\"method\":\"abci_info\",\"id\":1}' 127.0.0.1:22331"} - cmd = exec.Command(args[0], args[1:]...) + cmd := exec.Command(args[0], args[1:]...) out, err := runCommandWithOutput(cmd) if err != nil { t.Fatalf("Error running curl\ncommand: %v\noutput: %v\nerror: %v", cmd, string(out), err) @@ -140,8 +91,6 @@ func TestAbciInfo(t *testing.T) { t.Fatalf("Expected block height to increase, but it did not. First height was %v, second height was %v", height, height2) } } -<<<<<<< HEAD -======= func TestAbciQuery(t *testing.T) { // start the chain @@ -385,4 +334,3 @@ func TestSystemStartingTime(t *testing.T) { require.True(t, diff <= delta, "expectedTime: %v, blockTime: %v", expectedTime, blockTime) } ->>>>>>> 7edb4c1 (Add fine-grained control of time (#88)) diff --git a/go.mod b/go.mod index bda249d..49c17de 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,8 @@ require ( github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df github.com/cometbft/cometbft v0.37.2 github.com/cometbft/cometbft-db v0.7.0 + github.com/stretchr/testify v1.8.1 + github.com/urfave/cli/v2 v2.25.7 ) require ( @@ -15,6 +17,7 @@ require ( github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cosmos/gogoproto v1.4.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect github.com/dgraph-io/badger/v2 v2.2007.4 // indirect github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de // indirect @@ -38,6 +41,7 @@ require ( github.com/onsi/gomega v1.19.0 // indirect github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.37.0 // indirect @@ -46,7 +50,6 @@ require ( github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect - github.com/urfave/cli/v2 v2.25.7 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect go.etcd.io/bbolt v1.3.6 // indirect golang.org/x/crypto v0.5.0 // indirect @@ -56,4 +59,5 @@ require ( google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6 // indirect google.golang.org/grpc v1.52.0 // indirect google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index c6d46f9..ab4d7be 100644 --- a/go.sum +++ b/go.sum @@ -74,7 +74,6 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d h1:49RLWk1j44Xu4fjHb6JFYmeUnDORVwHNkDxaQ0ctCVU= github.com/cosmos/gogoproto v1.4.1 h1:WoyH+0/jbCTzpKNvyav5FL1ZTWsp1im1MxEpJEzKUB8= github.com/cosmos/gogoproto v1.4.1/go.mod h1:Ac9lzL4vFpBMcptJROQ6dQ4M3pOEK5Z/l0Q9p+LoCr4= -github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -211,8 +210,10 @@ github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrD github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= @@ -279,7 +280,6 @@ github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= 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= @@ -299,11 +299,16 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= @@ -606,6 +611,7 @@ google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8/go.mod h1:HV8QO gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -618,7 +624,9 @@ gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 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=