diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 43ceca99a..63d0ae386 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -12,42 +12,66 @@ jobs: - name: Checkout the repository uses: actions/checkout@v3 with: - fetch-depth: 0 + fetch-depth: 1 - name: Setup Node.js uses: actions/setup-node@v3 with: node-version: '18' - - name: Generate Changelog Update + - name: Configure Git run: | - npm install -g conventional-changelog-cli - conventional-changelog -p angular -i CHANGELOG.md -s + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git config --global user.name "github-actions[bot]" - - name: Check if "auto-changelog-update" branch exists and update if needed + - name: Check if "auto-changelog-update-do-not-create-manually" branch exists id: check_branch run: | - git fetch origin auto-changelog-update:auto-changelog-update --no-tags - if git rev-parse --verify --quiet auto-changelog-update; then - echo "::set-output name=branch_exists::true" - git checkout auto-changelog-update - git merge main --no-edit + if [ -n "$(git ls-remote --heads origin auto-changelog-update-do-not-create-manually)" ]; then + git fetch origin auto-changelog-update-do-not-create-manually + echo "branch_exists=true" >> $GITHUB_ENV else - echo "::set-output name=branch_exists::false" - git checkout -b auto-changelog-update + echo "branch_exists=false" >> $GITHUB_ENV fi - - name: Create or Update Pull Request + - name: Generate Changelog Update and update if branch exists + run: | + npm install -g conventional-changelog-cli + if [ "$branch_exists" == "true" ]; then + git checkout auto-changelog-update-do-not-create-manually + git merge main --strategy-option theirs --allow-unrelated-histories --no-edit + conventional-changelog -p angular -i CHANGELOG.md -s -r 0 --append + git add CHANGELOG.md + git commit -m "Update CHANGELOG.md [skip ci]" + git push origin auto-changelog-update-do-not-create-manually + exit 0 + else + git checkout main + git checkout -b auto-changelog-update-do-not-create-manually + git push origin auto-changelog-update-do-not-create-manually + conventional-changelog -p angular -i CHANGELOG.md -s -r 0 --append + fi + + - name: Create Pull Request + if: env.branch_exists == 'false' id: cpr - uses: peter-evans/create-pull-request@v4 + uses: peter-evans/create-pull-request@v6 with: + token: ${{ secrets.GITHUB_TOKEN }} commit-message: "Update CHANGELOG.md [skip ci]" - title: "Automated Changelog Update" + title: "Chore(changelog): Automated Changelog Update [skip ci]" body: "Update the CHANGELOG.md with recent pushes to branch main." - branch: "auto-changelog-update" # Static branch name + base: "main" + branch: "auto-changelog-update-do-not-create-manually" delete-branch: true - branch-suffix: none - - name: Check if PR needs to be updated + + - name: Check outputs + if: env.branch_exists == 'false' + run: | + echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}" + echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}" + + - name: Log if PR updated if: steps.cpr.outputs.pull-request-operation == 'updated' run: | echo "Changelog PR updated due to new commit to main." diff --git a/.github/workflows/golangci_lint.yml b/.github/workflows/golangci_lint.yml new file mode 100644 index 000000000..69f6c8d67 --- /dev/null +++ b/.github/workflows/golangci_lint.yml @@ -0,0 +1,23 @@ +name: golangci-lint +on: + push: + tags: + - v* + branches: + - main + pull_request: + +jobs: + golangci: + name: golangci-lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: "1.22" + - name: golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + version: v1.58 + skip-cache: true diff --git a/.github/workflows/label-internal-pr.yml b/.github/workflows/label-internal-pr.yml new file mode 100644 index 000000000..8bbe50a8d --- /dev/null +++ b/.github/workflows/label-internal-pr.yml @@ -0,0 +1,38 @@ +name: "Label PRs from Dymension internal" +on: + pull_request: + types: [opened, synchronize] + +jobs: + label-prs: + runs-on: ubuntu-latest + steps: + - name: Checkout the repository + uses: actions/checkout@v3 + + - name: Get Pull Request Author and Check Membership + id: pr + run: | + pr_author=$(jq -r .pull_request.user.login "$GITHUB_EVENT_PATH") + echo "PR Author: ${pr_author}" + org="dymensionxyz" + membership_response=$(curl -s -L \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/orgs/${org}/public_members/${pr_author}) + echo "Membership response: ${membership_response}" + if [ -z "$membership_response" ]; then + is_member=false + else + is_member=true + fi + echo "is_member=${is_member}" >> $GITHUB_ENV + + - name: Add Label if Author is from Organization + if: env.is_member == 'true' + run: | + curl -s -X POST -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + -H "Accept: application/vnd.github.v3+json" \ + https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/labels \ + -d '{"labels":["dym-internal"]}' diff --git a/.github/workflows/stalebot.yml b/.github/workflows/stalebot.yml new file mode 100644 index 000000000..17128934b --- /dev/null +++ b/.github/workflows/stalebot.yml @@ -0,0 +1,27 @@ +name: "Close stale pull requests" +on: + schedule: + - cron: "0 0 * * *" + +permissions: + contents: read + +jobs: + stale: + permissions: + issues: write # for actions/stale to close stale issues + pull-requests: write # for actions/stale to close stale PRs + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v9 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-pr-message: > + This pull request has been automatically marked as stale because it + has not had any recent activity. It will be closed if no further + activity occurs. Thank you! + days-before-stale: -1 + days-before-close: -1 + days-before-pr-stale: 8 + days-before-pr-close: 3 + exempt-pr-labels: "security, proposal, blocked, dym-internal" diff --git a/.gitignore b/.gitignore index c046ac465..3004a5b74 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ proto/pb .go-version build -vendor/ \ No newline at end of file +vendor/ +da/grpc/mockserv/db/ diff --git a/.golangci.yml b/.golangci.yml index a8cba5db2..b69bea76f 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,31 +1,76 @@ run: concurrency: 4 timeout: 5m + tests: true modules-download-mode: readonly - # mempool and indexer code is borrowed from Tendermint + +output: + # Format: colored-line-number|line-number|json|colored-tab|tab|checkstyle|code-climate|junit-xml|github-actions|teamcity + # + # Multiple can be specified by separating them by comma, output can be provided + # for each of them by separating format name and path by colon symbol. + # Output path can be either `stdout`, `stderr` or path to the file to write to. + # Example: "checkstyle:report.xml,json:stdout,colored-line-number" + # + # Default: colored-line-number + format: colored-line-number + # Print lines of code with issue. + # Default: true + print-issued-lines: true + # Print linter name in the end of issue text. + # Default: true + print-linter-name: true + # Make issues output unique by line. + # Default: true + uniq-by-line: true + # Add a prefix to the output file references. + # Default: "" + path-prefix: "" + # Sort results by: filepath, line and column. + # Default: false + sort-results: true + linters: disable-all: true enable: - errcheck + - gocyclo - gofmt + - gofumpt - goimports + - gosec - gosimple - govet - ineffassign - misspell + - revive - staticcheck - typecheck + - unconvert - unused - - gosec - - gocyclo issues: exclude-use-default: false + exclude: + - "^.*SA1019.*$" # Excluding SA1019 errors exclude-files: - da/celestia/mock/server.go - - ./*_test.go + - ./*_test.go # TODO: bring back exclude-dirs: + # mempool and indexer code is borrowed from Tendermint - mempool - state/indexer - - state/txindex \ No newline at end of file + - state/txindex + + +linters-settings: + go-version-checker: + min-version: "1.22" + revive: + rules: + - name: exported + severity: warning + disabled: true + errcheck: + check-type-assertions: true \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 2de107fb7..969d79aa3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,36 @@ +# [](https://github.com/dymensionxyz/dymint/compare/v1.1.0-rc02...v) (2024-05-07) + + +### Bug Fixes + +* **bug:** sync from da and p2p when starting a node ([#763](https://github.com/dymensionxyz/dymint/issues/763)) ([68ffd05](https://github.com/dymensionxyz/dymint/commit/68ffd05794949ddc42df1c132d1fde5f21b505f4)) +* **celestia test:** fix race in test ([#755](https://github.com/dymensionxyz/dymint/issues/755)) ([0b36781](https://github.com/dymensionxyz/dymint/commit/0b367818bf6aa8da4a4fd8e4e5c78223b60b44e0)) +* **celestia:** impl retry on submit ([#748](https://github.com/dymensionxyz/dymint/issues/748)) ([61630eb](https://github.com/dymensionxyz/dymint/commit/61630eb458197abe2440a81426210000dff25d40)) +* **celestia:** use fixed delay in repeat attempts ([#753](https://github.com/dymensionxyz/dymint/issues/753)) ([53002b0](https://github.com/dymensionxyz/dymint/commit/53002b0a070743811295a98580ba038cac40cc7d)) +* **code standards:** renames error -> err in celestia ([#768](https://github.com/dymensionxyz/dymint/issues/768)) ([1189384](https://github.com/dymensionxyz/dymint/commit/1189384d1225b3dd65481c9dedbae423e4f8ac04)) +* **da:** fixed da path seperator and encoding issue ([#731](https://github.com/dymensionxyz/dymint/issues/731)) ([3a3b219](https://github.com/dymensionxyz/dymint/commit/3a3b21932750fee7eaaa9c186f78e36e3e597746)) +* **DA:** use expo backoff in retries ([#739](https://github.com/dymensionxyz/dymint/issues/739)) ([848085f](https://github.com/dymensionxyz/dymint/commit/848085f70bcaae81fb80da3ab78c4d8b399e13b1)) +* **doc:** manager cache comment ([#767](https://github.com/dymensionxyz/dymint/issues/767)) ([b88bf6e](https://github.com/dymensionxyz/dymint/commit/b88bf6e72820c944b290147724255cc8466ada50)) +* **logging:** added reason for websocket closed debug msg ([#746](https://github.com/dymensionxyz/dymint/issues/746)) ([3aa7d80](https://github.com/dymensionxyz/dymint/commit/3aa7d80ace92b3b0f79e4f338f10bb94c96ab6dd)) +* **logs:** make logs more readable in a couple places, fix race cond ([#749](https://github.com/dymensionxyz/dymint/issues/749)) ([f05ef39](https://github.com/dymensionxyz/dymint/commit/f05ef3957b754c05fbc90aa39eabce80bbe65933)) +* **manager:** get fresh height in loop ([#781](https://github.com/dymensionxyz/dymint/issues/781)) ([e4df480](https://github.com/dymensionxyz/dymint/commit/e4df48037a78965dbac9e747dd296f39360e396c)) +* **p2p:** validate block before applying and not before caching in p2p gossiping ([#723](https://github.com/dymensionxyz/dymint/issues/723)) ([98371b5](https://github.com/dymensionxyz/dymint/commit/98371b5220613e70f3274fab5593e02ba532f7db)) +* **p2p:** validating gossiped block is created by the proposer ([#737](https://github.com/dymensionxyz/dymint/issues/737)) ([851b312](https://github.com/dymensionxyz/dymint/commit/851b312620233a9fb1abe55214a678322e7b0c68)) +* **produce loop:** handle unauthenticated error in settlement layer ([#726](https://github.com/dymensionxyz/dymint/issues/726)) ([33e78d1](https://github.com/dymensionxyz/dymint/commit/33e78d116b5f14b91b8b3bda2b6cbfee9040e2d3)) +* **rpc:** nil panic in rpc/json/handler.go WriteError ([#750](https://github.com/dymensionxyz/dymint/issues/750)) ([e09709b](https://github.com/dymensionxyz/dymint/commit/e09709b428a33da002defb9f13178fa19b81a69b)) +* **settlement:** remove state index from proto ([#777](https://github.com/dymensionxyz/dymint/issues/777)) ([767b8fd](https://github.com/dymensionxyz/dymint/commit/767b8fdb490c37deee43ac023688410bbb98ccb0)) +* **sync:** make sure we use a latest state index as a start point ([#760](https://github.com/dymensionxyz/dymint/issues/760)) ([43e2d96](https://github.com/dymensionxyz/dymint/commit/43e2d965f2b505751f8e5260549e909c976141ee)) +* **sync:** removing height condition for applying cached blocks from p2p ([#787](https://github.com/dymensionxyz/dymint/issues/787)) ([b97299c](https://github.com/dymensionxyz/dymint/commit/b97299ce7f78168863c5e1c2d7fc479aed2ae6da)) +* **tests:** fix unit tests, mocks, cleanup/dry hub queries ([#782](https://github.com/dymensionxyz/dymint/issues/782)) ([c276aea](https://github.com/dymensionxyz/dymint/commit/c276aea12c9cd37f62fcf9d684c4efe901a510bf)) + + +### Features + +* **p2p:** header gossiper removed ([#813](https://github.com/dymensionxyz/dymint/issues/813)) ([737b412](https://github.com/dymensionxyz/dymint/commit/737b4126c59846a2be57049a249843de5648dde8)) +* **produce:** limiting block size by maxBatchSize ([#784](https://github.com/dymensionxyz/dymint/issues/784)) ([f90042c](https://github.com/dymensionxyz/dymint/commit/f90042cd61fc6b60093478cd65491f8aa1106457)) + + + # [](https://github.com/dymensionxyz/dymint/compare/v1.1.0-rc02...v) (2024-05-05) diff --git a/block/block.go b/block/block.go index 02c7ce3c2..78d8255f9 100644 --- a/block/block.go +++ b/block/block.go @@ -1,27 +1,23 @@ package block import ( - "context" "fmt" errorsmod "cosmossdk.io/errors" - "github.com/dymensionxyz/dymint/p2p" "github.com/dymensionxyz/dymint/types" - tmtypes "github.com/tendermint/tendermint/types" ) // applyBlock applies the block to the store and the abci app. // Contract: block and commit must be validated before calling this function! -// steps: save block -> execute block with app -> update state -> commit block to app -> update store height and state hash. +// steps: save block -> execute block with app -> update state -> commit block to app -> update state's height and commit result. // As the entire process can't be atomic we need to make sure the following condition apply before // - block height is the expected block height on the store (height + 1). // - block height is the expected block height on the app (last block height + 1). func (m *Manager) applyBlock(block *types.Block, commit *types.Commit, blockMetaData blockMetaData) error { - // TODO (#330): allow genesis block with height > 0 to be applied. // TODO: add switch case to have defined behavior for each case. // validate block height - if block.Header.Height != m.Store.NextHeight() { + if block.Header.Height != m.State.NextHeight() { return types.ErrInvalidBlockHeight } @@ -35,6 +31,8 @@ func (m *Manager) applyBlock(block *types.Block, commit *types.Commit, blockMeta // In case the following true, it means we crashed after the commit and before updating the store height. // In that case we'll want to align the store with the app state and continue to the next block. if isBlockAlreadyApplied { + // In this case, where the app was committed, but the state wasn't updated + // it will update the state from appInfo, saved responses and validators. err := m.UpdateStateFromApp() if err != nil { return fmt.Errorf("update state from app: %w", err) @@ -48,83 +46,82 @@ func (m *Manager) applyBlock(block *types.Block, commit *types.Commit, blockMeta return fmt.Errorf("save block: %w", err) } - responses, err := m.Executor.ExecuteBlock(m.LastState, block) + responses, err := m.Executor.ExecuteBlock(m.State, block) if err != nil { return fmt.Errorf("execute block: %w", err) } - newState, err := m.Executor.UpdateStateFromResponses(responses, m.LastState, block) + dbBatch := m.Store.NewBatch() + dbBatch, err = m.Store.SaveBlockResponses(block.Header.Height, responses, dbBatch) if err != nil { - return fmt.Errorf("update state from responses: %w", err) - } - - batch := m.Store.NewBatch() - - batch, err = m.Store.SaveBlockResponses(block.Header.Height, responses, batch) - if err != nil { - batch.Discard() + dbBatch.Discard() return fmt.Errorf("save block responses: %w", err) } - m.LastState = newState - batch, err = m.Store.UpdateState(m.LastState, batch) + // Get the validator changes from the app + validators, err := m.Executor.NextValSetFromResponses(m.State, responses, block) if err != nil { - batch.Discard() - return fmt.Errorf("update state: %w", err) + return fmt.Errorf("update state from responses: %w", err) } - batch, err = m.Store.SaveValidators(block.Header.Height, m.LastState.Validators, batch) + + dbBatch, err = m.Store.SaveValidators(block.Header.Height, validators, dbBatch) if err != nil { - batch.Discard() + dbBatch.Discard() return fmt.Errorf("save validators: %w", err) } - err = batch.Commit() + err = dbBatch.Commit() if err != nil { return fmt.Errorf("commit batch to disk: %w", err) } // Commit block to app - retainHeight, err := m.Executor.Commit(&newState, block, responses) + appHash, retainHeight, err := m.Executor.Commit(m.State, block, responses) if err != nil { return fmt.Errorf("commit block: %w", err) } + // If failed here, after the app committed, but before the state is updated, we'll update the state on + // UpdateStateFromApp using the saved responses and validators. + + // Update the state with the new app hash, last validators and store height from the commit. + // Every one of those, if happens before commit, prevents us from re-executing the block in case failed during commit. + m.Executor.UpdateStateAfterCommit(m.State, responses, appHash, block.Header.Height, validators) + _, err = m.Store.SaveState(m.State, nil) + if err != nil { + return fmt.Errorf("update state: %w", err) + } + // Prune old heights, if requested by ABCI app. if retainHeight > 0 { - pruned, err := m.pruneBlocks(retainHeight) + _, err := m.pruneBlocks(uint64(retainHeight)) if err != nil { m.logger.Error("prune blocks", "retain_height", retainHeight, "err", err) - } else { - m.logger.Debug("pruned blocks", "pruned", pruned, "retain_height", retainHeight) } } + return nil +} - // Update the state with the new app hash, last validators and store height from the commit. - // Every one of those, if happens before commit, prevents us from re-executing the block in case failed during commit. - newState.LastValidators = m.LastState.Validators.Copy() - newState.LastStoreHeight = block.Header.Height - newState.BaseHeight = m.Store.Base() - - _, err = m.Store.UpdateState(newState, nil) +// isHeightAlreadyApplied checks if the block height is already applied to the app. +func (m *Manager) isHeightAlreadyApplied(blockHeight uint64) (bool, error) { + proxyAppInfo, err := m.Executor.GetAppInfo() if err != nil { - return fmt.Errorf("final update state: %w", err) + return false, errorsmod.Wrap(err, "get app info") } - m.LastState = newState - if ok := m.Store.SetHeight(block.Header.Height); !ok { - return fmt.Errorf("store set height: %d", block.Header.Height) - } + isBlockAlreadyApplied := uint64(proxyAppInfo.LastBlockHeight) == blockHeight - return nil + // TODO: add switch case to validate better the current app state + + return isBlockAlreadyApplied, nil } -// TODO: move to gossip.go func (m *Manager) attemptApplyCachedBlocks() error { m.retrieverMutex.Lock() defer m.retrieverMutex.Unlock() for { - expectedHeight := m.Store.NextHeight() + expectedHeight := m.State.NextHeight() cachedBlock, blockExists := m.blockCache[expectedHeight] if !blockExists { @@ -148,68 +145,10 @@ func (m *Manager) attemptApplyCachedBlocks() error { return nil } -// isHeightAlreadyApplied checks if the block height is already applied to the app. -func (m *Manager) isHeightAlreadyApplied(blockHeight uint64) (bool, error) { - proxyAppInfo, err := m.Executor.GetAppInfo() - if err != nil { - return false, errorsmod.Wrap(err, "get app info") - } - - isBlockAlreadyApplied := uint64(proxyAppInfo.LastBlockHeight) == blockHeight - - // TODO: add switch case to validate better the current app state - - return isBlockAlreadyApplied, nil -} - -// UpdateStateFromApp is responsible for aligning the state of the store from the abci app -func (m *Manager) UpdateStateFromApp() error { - proxyAppInfo, err := m.Executor.GetAppInfo() - if err != nil { - return errorsmod.Wrap(err, "get app info") - } - - appHeight := uint64(proxyAppInfo.LastBlockHeight) - - // update the state with the hash, last store height and last validators. - m.LastState.AppHash = *(*[32]byte)(proxyAppInfo.LastBlockAppHash) - m.LastState.LastStoreHeight = appHeight - m.LastState.LastValidators = m.LastState.Validators.Copy() - - resp, err := m.Store.LoadBlockResponses(appHeight) - if err != nil { - return errorsmod.Wrap(err, "load block responses") - } - copy(m.LastState.LastResultsHash[:], tmtypes.NewResults(resp.DeliverTxs).Hash()) - - _, err = m.Store.UpdateState(m.LastState, nil) - if err != nil { - return errorsmod.Wrap(err, "update state") - } - if ok := m.Store.SetHeight(appHeight); !ok { - return fmt.Errorf("store set height: %d", appHeight) - } - return nil -} - func (m *Manager) validateBlock(block *types.Block, commit *types.Commit) error { // Currently we're assuming proposer is never nil as it's a pre-condition for // dymint to start proposer := m.SLClient.GetProposer() - return types.ValidateProposedTransition(m.LastState, block, commit, proposer) -} - -func (m *Manager) gossipBlock(ctx context.Context, block types.Block, commit types.Commit) error { - gossipedBlock := p2p.GossipedBlock{Block: block, Commit: commit} - gossipedBlockBytes, err := gossipedBlock.MarshalBinary() - if err != nil { - return fmt.Errorf("marshal binary: %w: %w", err, ErrNonRecoverable) - } - if err := m.p2pClient.GossipBlock(ctx, gossipedBlockBytes); err != nil { - // Although this boils down to publishing on a topic, we don't want to speculate too much on what - // could cause that to fail, so we assume recoverable. - return fmt.Errorf("p2p gossip block: %w: %w", err, ErrRecoverable) - } - return nil + return types.ValidateProposedTransition(m.State, block, commit, proposer) } diff --git a/block/executor.go b/block/executor.go index 65f39ccc7..6d0fc1e7e 100644 --- a/block/executor.go +++ b/block/executor.go @@ -96,7 +96,7 @@ func (e *Executor) InitChain(genesis *tmtypes.GenesisDoc, validators []*tmtypes. } // CreateBlock reaps transactions from mempool and builds a block. -func (e *Executor) CreateBlock(height uint64, lastCommit *types.Commit, lastHeaderHash [32]byte, state types.State, maxBytes uint64) *types.Block { +func (e *Executor) CreateBlock(height uint64, lastCommit *types.Commit, lastHeaderHash [32]byte, state *types.State, maxBytes uint64) *types.Block { if state.ConsensusParams.Block.MaxBytes > 0 { maxBytes = min(maxBytes, uint64(state.ConsensusParams.Block.MaxBytes)) } @@ -128,27 +128,24 @@ func (e *Executor) CreateBlock(height uint64, lastCommit *types.Commit, lastHead } copy(block.Header.LastCommitHash[:], e.getLastCommitHash(lastCommit, &block.Header)) copy(block.Header.DataHash[:], e.getDataHash(block)) - copy(block.Header.AggregatorsHash[:], state.Validators.Hash()) + copy(block.Header.SequencersHash[:], state.Validators.Hash()) return block } // Commit commits the block -func (e *Executor) Commit(state *types.State, block *types.Block, resp *tmstate.ABCIResponses) (int64, error) { +func (e *Executor) Commit(state *types.State, block *types.Block, resp *tmstate.ABCIResponses) ([]byte, int64, error) { appHash, retainHeight, err := e.commit(state, block, resp.DeliverTxs) if err != nil { - return 0, err + return nil, 0, err } - copy(state.AppHash[:], appHash[:]) - copy(state.LastResultsHash[:], tmtypes.NewResults(resp.DeliverTxs).Hash()) - - err = e.publishEvents(resp, block, *state) + err = e.publishEvents(resp, block) if err != nil { e.logger.Error("fire block events", "error", err) - return 0, err + return nil, 0, err } - return retainHeight, nil + return appHash, retainHeight, nil } // GetAppInfo returns the latest AppInfo from the proxyApp. @@ -183,7 +180,7 @@ func (e *Executor) commit(state *types.State, block *types.Block, deliverTxs []* } // ExecuteBlock executes the block and returns the ABCIResponses. Block should be valid (passed validation checks). -func (e *Executor) ExecuteBlock(state types.State, block *types.Block) (*tmstate.ABCIResponses, error) { +func (e *Executor) ExecuteBlock(state *types.State, block *types.Block) (*tmstate.ABCIResponses, error) { abciResponses := new(tmstate.ABCIResponses) abciResponses.DeliverTxs = make([]*abci.ResponseDeliverTx, len(block.Data.Txs)) @@ -252,13 +249,12 @@ func (e *Executor) getDataHash(block *types.Block) []byte { return abciData.Hash() } -func (e *Executor) publishEvents(resp *tmstate.ABCIResponses, block *types.Block, state types.State) error { +func (e *Executor) publishEvents(resp *tmstate.ABCIResponses, block *types.Block) error { if e.eventBus == nil { return nil } abciBlock, err := types.ToABCIBlock(block) - abciBlock.Header.ValidatorsHash = state.Validators.Hash() if err != nil { return err } diff --git a/block/executor_test.go b/block/executor_test.go index d09a18be3..e4eca2f55 100644 --- a/block/executor_test.go +++ b/block/executor_test.go @@ -51,7 +51,7 @@ func TestCreateBlock(t *testing.T) { maxBytes := uint64(100) - state := types.State{} + state := &types.State{} state.ConsensusParams.Block.MaxBytes = int64(maxBytes) state.ConsensusParams.Block.MaxGas = 100000 state.Validators = tmtypes.NewValidatorSet(nil) @@ -140,13 +140,12 @@ func TestApplyBlock(t *testing.T) { require.NotNil(headerSub) // Init state - state := types.State{ + state := &types.State{ NextValidators: tmtypes.NewValidatorSet(nil), Validators: tmtypes.NewValidatorSet(nil), - LastValidators: tmtypes.NewValidatorSet(nil), } state.InitialHeight = 1 - state.LastBlockHeight = 0 + state.LastBlockHeight.Store(0) maxBytes := uint64(100) state.ConsensusParams.Block.MaxBytes = int64(maxBytes) state.ConsensusParams.Block.MaxGas = 100000 @@ -182,21 +181,18 @@ func TestApplyBlock(t *testing.T) { resp, err := executor.ExecuteBlock(state, block) require.NoError(err) require.NotNil(resp) - newState, err := executor.UpdateStateFromResponses(resp, state, block) + appHash, _, err := executor.Commit(state, block, resp) require.NoError(err) - require.NotNil(newState) - assert.Equal(int64(1), newState.LastBlockHeight) - _, err = executor.Commit(&newState, block, resp) - require.NoError(err) - assert.Equal(mockAppHash, newState.AppHash) - newState.LastStoreHeight = uint64(newState.LastBlockHeight) + executor.UpdateStateAfterCommit(state, resp, appHash, block.Header.Height, state.Validators) + assert.Equal(uint64(1), state.Height()) + assert.Equal(mockAppHash, state.AppHash) // Create another block with multiple Tx from mempool require.NoError(mpool.CheckTx([]byte{0, 1, 2, 3, 4}, func(r *abci.Response) {}, mempool.TxInfo{})) require.NoError(mpool.CheckTx([]byte{5, 6, 7, 8, 9}, func(r *abci.Response) {}, mempool.TxInfo{})) require.NoError(mpool.CheckTx([]byte{1, 2, 3, 4, 5}, func(r *abci.Response) {}, mempool.TxInfo{})) require.NoError(mpool.CheckTx(make([]byte, 90), func(r *abci.Response) {}, mempool.TxInfo{})) - block = executor.CreateBlock(2, commit, [32]byte{}, newState, maxBytes) + block = executor.CreateBlock(2, commit, [32]byte{}, state, maxBytes) require.NotNil(block) assert.Equal(uint64(2), block.Header.Height) assert.Len(block.Data.Txs, 3) @@ -217,7 +213,7 @@ func TestApplyBlock(t *testing.T) { } // Apply the block with an invalid commit - err = types.ValidateProposedTransition(newState, block, invalidCommit, proposer) + err = types.ValidateProposedTransition(state, block, invalidCommit, proposer) require.ErrorIs(err, types.ErrInvalidSignature) @@ -231,17 +227,17 @@ func TestApplyBlock(t *testing.T) { } // Apply the block - err = types.ValidateProposedTransition(newState, block, commit, proposer) + err = types.ValidateProposedTransition(state, block, commit, proposer) require.NoError(err) resp, err = executor.ExecuteBlock(state, block) require.NoError(err) require.NotNil(resp) - newState, err = executor.UpdateStateFromResponses(resp, state, block) + vals, err := executor.NextValSetFromResponses(state, resp, block) require.NoError(err) - require.NotNil(newState) - assert.Equal(int64(2), newState.LastBlockHeight) - _, err = executor.Commit(&newState, block, resp) + _, _, err = executor.Commit(state, block, resp) require.NoError(err) + executor.UpdateStateAfterCommit(state, resp, appHash, block.Header.Height, vals) + assert.Equal(uint64(2), state.Height()) // wait for at least 4 Tx events, for up to 3 second. // 3 seconds is a fail-scenario only diff --git a/block/gossip.go b/block/gossip.go new file mode 100644 index 000000000..9ba4fb2d4 --- /dev/null +++ b/block/gossip.go @@ -0,0 +1,54 @@ +package block + +import ( + "context" + "fmt" + + "github.com/dymensionxyz/dymint/p2p" + "github.com/dymensionxyz/dymint/types" + "github.com/tendermint/tendermint/libs/pubsub" +) + +// onNewGossippedBlock will take a block and apply it +func (m *Manager) onNewGossipedBlock(event pubsub.Message) { + eventData, _ := event.Data().(p2p.GossipedBlock) + block := eventData.Block + commit := eventData.Commit + m.retrieverMutex.Lock() // needed to protect blockCache access + _, found := m.blockCache[block.Header.Height] + // It is not strictly necessary to return early, for correctness, but doing so helps us avoid mutex pressure and unnecessary repeated attempts to apply cached blocks + if found { + m.retrieverMutex.Unlock() + return + } + + m.logger.Debug("Received new block via gossip", "block height", block.Header.Height, "store height", m.State.Height(), "n cachedBlocks", len(m.blockCache)) + + nextHeight := m.State.NextHeight() + if block.Header.Height >= nextHeight { + m.blockCache[block.Header.Height] = CachedBlock{ + Block: &block, + Commit: &commit, + } + } + m.retrieverMutex.Unlock() // have to give this up as it's locked again in attempt apply, and we're not re-entrant + + err := m.attemptApplyCachedBlocks() + if err != nil { + m.logger.Error("applying cached blocks", "err", err) + } +} + +func (m *Manager) gossipBlock(ctx context.Context, block types.Block, commit types.Commit) error { + gossipedBlock := p2p.GossipedBlock{Block: block, Commit: commit} + gossipedBlockBytes, err := gossipedBlock.MarshalBinary() + if err != nil { + return fmt.Errorf("marshal binary: %w: %w", err, ErrNonRecoverable) + } + if err := m.p2pClient.GossipBlock(ctx, gossipedBlockBytes); err != nil { + // Although this boils down to publishing on a topic, we don't want to speculate too much on what + // could cause that to fail, so we assume recoverable. + return fmt.Errorf("p2p gossip block: %w: %w", err, ErrRecoverable) + } + return nil +} diff --git a/block/initchain.go b/block/initchain.go index 467246155..c7c694c1f 100644 --- a/block/initchain.go +++ b/block/initchain.go @@ -23,10 +23,9 @@ func (m *Manager) RunInitChain(ctx context.Context) error { } // update the state with only the consensus pubkey - m.Executor.UpdateStateAfterInitChain(&m.LastState, res, gensisValSet) - m.Executor.UpdateMempoolAfterInitChain(&m.LastState) - - if _, err := m.Store.UpdateState(m.LastState, nil); err != nil { + m.Executor.UpdateStateAfterInitChain(m.State, res, gensisValSet) + m.Executor.UpdateMempoolAfterInitChain(m.State) + if _, err := m.Store.SaveState(m.State, nil); err != nil { return err } diff --git a/block/manager.go b/block/manager.go index b631a6348..41e1f014f 100644 --- a/block/manager.go +++ b/block/manager.go @@ -9,6 +9,7 @@ import ( "sync/atomic" "github.com/dymensionxyz/dymint/gerr" + "github.com/dymensionxyz/dymint/store" uevent "github.com/dymensionxyz/dymint/utils/event" @@ -16,8 +17,6 @@ import ( "github.com/dymensionxyz/dymint/p2p" "github.com/libp2p/go-libp2p/core/crypto" - - tmcrypto "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/libs/pubsub" tmtypes "github.com/tendermint/tendermint/types" @@ -27,7 +26,6 @@ import ( "github.com/dymensionxyz/dymint/da" "github.com/dymensionxyz/dymint/mempool" "github.com/dymensionxyz/dymint/settlement" - "github.com/dymensionxyz/dymint/store" "github.com/dymensionxyz/dymint/types" ) @@ -39,9 +37,9 @@ type Manager struct { ProposerKey crypto.PrivKey // Store and execution - Store store.Store - LastState types.State - Executor *Executor + Store store.Store + State *types.State + Executor *Executor // Clients and servers Pubsub *pubsub.Server @@ -108,7 +106,7 @@ func NewManager( ProposerKey: proposerKey, Conf: conf, Genesis: genesis, - LastState: s, + State: s, Store: store, Executor: exec, DAClient: dalc, @@ -127,22 +125,17 @@ func NewManager( func (m *Manager) Start(ctx context.Context) error { m.logger.Info("Starting the block manager") - // Check if proposer key matches to the one in the settlement layer - var isAggregator bool slProposerKey := m.SLClient.GetProposer().PublicKey.Bytes() localProposerKey, err := m.ProposerKey.GetPublic().Raw() if err != nil { return fmt.Errorf("get local node public key: %w", err) } - if bytes.Equal(slProposerKey, localProposerKey) { - m.logger.Info("Starting in aggregator mode") - isAggregator = true - } else { - m.logger.Info("Starting in non-aggregator mode") - } + + isSequencer := bytes.Equal(slProposerKey, localProposerKey) + m.logger.Info("Starting block manager", "isSequencer", isSequencer) // Check if InitChain flow is needed - if m.LastState.IsGenesis() { + if m.State.IsGenesis() { m.logger.Info("Running InitChain") err := m.RunInitChain(ctx) @@ -151,7 +144,7 @@ func (m *Manager) Start(ctx context.Context) error { } } - if !isAggregator { + if !isSequencer { go uevent.MustSubscribe(ctx, m.Pubsub, "applyGossipedBlocksLoop", p2p.EventQueryNewNewGossipedBlock, m.onNewGossipedBlock, m.logger) } @@ -160,7 +153,7 @@ func (m *Manager) Start(ctx context.Context) error { return fmt.Errorf("sync block manager: %w", err) } - if isAggregator { + if isSequencer { // TODO: populate the accumulatedSize on startup go m.ProduceBlockLoop(ctx) go m.SubmitLoop(ctx) @@ -177,7 +170,7 @@ func (m *Manager) syncBlockManager() error { res, err := m.SLClient.RetrieveBatch() if errors.Is(err, gerr.ErrNotFound) { // The SL hasn't got any batches for this chain yet. - m.logger.Info("No batches for chain found in SL. Start writing first batch.") + m.logger.Info("No batches for chain found in SL.") m.SyncTarget.Store(uint64(m.Genesis.InitialHeight - 1)) return nil } @@ -192,7 +185,7 @@ func (m *Manager) syncBlockManager() error { return err } - m.logger.Info("Synced.", "current height", m.Store.Height(), "syncTarget", m.SyncTarget.Load()) + m.logger.Info("Synced.", "current height", m.State.Height(), "syncTarget", m.SyncTarget.Load()) return nil } @@ -202,46 +195,3 @@ func (m *Manager) UpdateSyncParams(endHeight uint64) { m.logger.Info("Received new syncTarget", "syncTarget", endHeight) m.SyncTarget.Store(endHeight) } - -func getAddress(key crypto.PrivKey) ([]byte, error) { - rawKey, err := key.GetPublic().Raw() - if err != nil { - return nil, err - } - return tmcrypto.AddressHash(rawKey), nil -} - -// TODO: move to gossip.go -// onNewGossippedBlock will take a block and apply it -func (m *Manager) onNewGossipedBlock(event pubsub.Message) { - m.retrieverMutex.Lock() // needed to protect blockCache access - eventData := event.Data().(p2p.GossipedBlock) - block := eventData.Block - commit := eventData.Commit - m.logger.Debug("Received new block via gossip", "height", block.Header.Height, "n cachedBlocks", len(m.blockCache)) - - nextHeight := m.Store.NextHeight() - if block.Header.Height >= nextHeight { - m.blockCache[block.Header.Height] = CachedBlock{ - Block: &block, - Commit: &commit, - } - m.logger.Debug("caching block", "block height", block.Header.Height, "store height", m.Store.Height()) - } - m.retrieverMutex.Unlock() // have to give this up as it's locked again in attempt apply, and we're not re-entrant - err := m.attemptApplyCachedBlocks() - if err != nil { - m.logger.Error("applying cached blocks", "err", err) - } -} - -// getInitialState tries to load lastState from Store, and if it's not available it reads GenesisDoc. -func getInitialState(store store.Store, genesis *tmtypes.GenesisDoc, logger types.Logger) (types.State, error) { - s, err := store.LoadState() - if errors.Is(err, types.ErrNoStateFound) { - logger.Info("failed to find state in the store, creating new state from genesis") - return types.NewFromGenesisDoc(genesis) - } - - return s, err -} diff --git a/block/manager_test.go b/block/manager_test.go index ca23601b8..4c08adee6 100644 --- a/block/manager_test.go +++ b/block/manager_test.go @@ -47,7 +47,7 @@ func TestInitialState(t *testing.T) { // Init empty store and full store emptyStore := store.New(store.NewDefaultInMemoryKVStore()) fullStore := store.New(store.NewDefaultInMemoryKVStore()) - _, err = fullStore.UpdateState(sampleState, nil) + _, err = fullStore.SaveState(sampleState, nil) require.NoError(t, err) // Init p2p client @@ -69,15 +69,15 @@ func TestInitialState(t *testing.T) { name string store store.Store genesis *tmtypes.GenesisDoc - expectedInitialHeight int64 - expectedLastBlockHeight int64 + expectedInitialHeight uint64 + expectedLastBlockHeight uint64 expectedChainID string }{ { name: "empty store", store: emptyStore, genesis: genesis, - expectedInitialHeight: genesis.InitialHeight, + expectedInitialHeight: uint64(genesis.InitialHeight), expectedLastBlockHeight: 0, expectedChainID: genesis.ChainID, }, @@ -86,7 +86,7 @@ func TestInitialState(t *testing.T) { store: fullStore, genesis: genesis, expectedInitialHeight: sampleState.InitialHeight, - expectedLastBlockHeight: sampleState.LastBlockHeight, + expectedLastBlockHeight: sampleState.LastBlockHeight.Load(), expectedChainID: sampleState.ChainID, }, } @@ -98,9 +98,9 @@ func TestInitialState(t *testing.T) { nil, pubsubServer, p2pClient, logger) assert.NoError(err) assert.NotNil(agg) - assert.Equal(c.expectedChainID, agg.LastState.ChainID) - assert.Equal(c.expectedInitialHeight, agg.LastState.InitialHeight) - assert.Equal(c.expectedLastBlockHeight, agg.LastState.LastBlockHeight) + assert.Equal(c.expectedChainID, agg.State.ChainID) + assert.Equal(c.expectedInitialHeight, agg.State.InitialHeight) + assert.Equal(c.expectedLastBlockHeight, agg.State.LastBlockHeight.Load()) }) } } @@ -135,7 +135,7 @@ func TestProduceOnlyAfterSynced(t *testing.T) { // Initially sync target is 0 assert.Zero(t, manager.SyncTarget.Load()) - assert.True(t, manager.Store.Height() == 0) + assert.True(t, manager.State.Height() == 0) // enough time to sync and produce blocks ctx, cancel := context.WithTimeout(context.Background(), time.Second*4) @@ -150,7 +150,7 @@ func TestProduceOnlyAfterSynced(t *testing.T) { <-ctx.Done() assert.Equal(t, batch.EndHeight, manager.SyncTarget.Load()) // validate that we produced blocks - assert.Greater(t, manager.Store.Height(), batch.EndHeight) + assert.Greater(t, manager.State.Height(), batch.EndHeight) } func TestRetrieveDaBatchesFailed(t *testing.T) { @@ -184,8 +184,8 @@ func TestProduceNewBlock(t *testing.T) { _, _, err = manager.ProduceAndGossipBlock(context.Background(), true) require.NoError(t, err) // Validate state is updated with the commit hash - assert.Equal(t, uint64(1), manager.Store.Height()) - assert.Equal(t, commitHash, manager.LastState.AppHash) + assert.Equal(t, uint64(1), manager.State.Height()) + assert.Equal(t, commitHash, manager.State.AppHash) } func TestProducePendingBlock(t *testing.T) { @@ -202,16 +202,17 @@ func TestProducePendingBlock(t *testing.T) { manager, err := testutil.GetManager(testutil.GetManagerConfig(), nil, nil, 1, 1, 0, proxyApp, nil) require.NoError(t, err) // Generate block and commit and save it to the store - blocks, err := testutil.GenerateBlocks(1, 1, manager.ProposerKey) - require.NoError(t, err) - block := blocks[0] + block := testutil.GetRandomBlock(1, 3) _, err = manager.Store.SaveBlock(block, &block.LastCommit, nil) require.NoError(t, err) // Produce block _, _, err = manager.ProduceAndGossipBlock(context.Background(), true) require.NoError(t, err) // Validate state is updated with the block that was saved in the store - assert.Equal(t, block.Header.Hash(), *(*[32]byte)(manager.LastState.LastBlockID.Hash)) + + // TODO: fix this test + // hacky way to validate the block was indeed contain txs + assert.NotEqual(t, manager.State.LastResultsHash, testutil.GetEmptyLastResultsHash()) } // Test that in case we fail after the proxy app commit, next time we won't commit again to the proxy app @@ -223,6 +224,7 @@ func TestProducePendingBlock(t *testing.T) { // 5. Produce third block successfully func TestProduceBlockFailAfterCommit(t *testing.T) { require := require.New(t) + assert := assert.New(t) // Setup app app := testutil.GetAppMock(testutil.Info, testutil.Commit) // Create proxy app @@ -237,64 +239,50 @@ func TestProduceBlockFailAfterCommit(t *testing.T) { require.NoError(err) cases := []struct { - name string - shouldFailSetSetHeight bool - shouldFailUpdateState bool - LastAppBlockHeight int64 - AppCommitHash [32]byte - LastAppCommitHash [32]byte - expectedStoreHeight uint64 - expectedStateAppHash [32]byte + name string + shoudFailOnSaveState bool + LastAppBlockHeight int64 + AppCommitHash [32]byte + LastAppCommitHash [32]byte + expectedStoreHeight uint64 + expectedStateAppHash [32]byte }{ { - name: "ProduceFirstBlockSuccessfully", - shouldFailSetSetHeight: false, - shouldFailUpdateState: false, - AppCommitHash: [32]byte{1}, - LastAppCommitHash: [32]byte{0}, - LastAppBlockHeight: 0, - expectedStoreHeight: 1, - expectedStateAppHash: [32]byte{1}, + name: "ProduceFirstBlockSuccessfully", + shoudFailOnSaveState: false, + AppCommitHash: [32]byte{1}, + expectedStoreHeight: 1, + expectedStateAppHash: [32]byte{1}, }, { - name: "ProduceSecondBlockFailOnUpdateState", - shouldFailSetSetHeight: false, - shouldFailUpdateState: true, - AppCommitHash: [32]byte{2}, - LastAppCommitHash: [32]byte{}, - LastAppBlockHeight: 0, - expectedStoreHeight: 1, - expectedStateAppHash: [32]byte{1}, + name: "ProduceSecondBlockFailOnUpdateState", + shoudFailOnSaveState: true, + AppCommitHash: [32]byte{2}, + expectedStoreHeight: 1, // height not changed on failed save state + expectedStateAppHash: [32]byte{1}, }, { - name: "ProduceSecondBlockSuccessfully", - shouldFailSetSetHeight: false, - shouldFailUpdateState: false, - AppCommitHash: [32]byte{}, - LastAppCommitHash: [32]byte{2}, - LastAppBlockHeight: 2, - expectedStoreHeight: 2, - expectedStateAppHash: [32]byte{2}, + name: "ProduceSecondBlockSuccessfullyFromApp", + shoudFailOnSaveState: false, + LastAppCommitHash: [32]byte{2}, // loading state from app + LastAppBlockHeight: 2, + expectedStoreHeight: 2, + expectedStateAppHash: [32]byte{2}, }, { - name: "ProduceThirdBlockFailOnUpdateStoreHeight", - shouldFailSetSetHeight: true, - shouldFailUpdateState: false, - AppCommitHash: [32]byte{3}, - LastAppCommitHash: [32]byte{2}, - LastAppBlockHeight: 2, - expectedStoreHeight: 2, - expectedStateAppHash: [32]byte{3}, + name: "ProduceThirdBlockFailOnUpdateStoreHeight", + shoudFailOnSaveState: true, + AppCommitHash: [32]byte{3}, + expectedStoreHeight: 2, // height not changed on failed save state + expectedStateAppHash: [32]byte{2}, }, { - name: "ProduceThirdBlockSuccessfully", - shouldFailSetSetHeight: false, - shouldFailUpdateState: false, - AppCommitHash: [32]byte{}, - LastAppCommitHash: [32]byte{3}, - LastAppBlockHeight: 3, - expectedStoreHeight: 3, - expectedStateAppHash: [32]byte{3}, + name: "ProduceThirdBlockSuccessfully", + shoudFailOnSaveState: false, + LastAppCommitHash: [32]byte{3}, + LastAppBlockHeight: 3, + expectedStoreHeight: 3, + expectedStateAppHash: [32]byte{3}, }, } for _, tc := range cases { @@ -304,14 +292,13 @@ func TestProduceBlockFailAfterCommit(t *testing.T) { LastBlockHeight: tc.LastAppBlockHeight, LastBlockAppHash: tc.LastAppCommitHash[:], }) - mockStore.ShouldFailSetHeight = tc.shouldFailSetSetHeight - mockStore.ShoudFailUpdateState = tc.shouldFailUpdateState + mockStore.ShoudFailSaveState = tc.shoudFailOnSaveState _, _, _ = manager.ProduceAndGossipBlock(context.Background(), true) - require.Equal(tc.expectedStoreHeight, manager.Store.Height(), tc.name) - require.Equal(tc.expectedStateAppHash, manager.LastState.AppHash, tc.name) storeState, err := manager.Store.LoadState() - require.NoError(err) - require.Equal(tc.expectedStateAppHash, storeState.AppHash, tc.name) + assert.NoError(err) + manager.State = storeState + assert.Equal(tc.expectedStoreHeight, storeState.Height(), tc.name) + assert.Equal(tc.expectedStateAppHash, storeState.AppHash, tc.name) app.On("Commit", mock.Anything).Unset() app.On("Info", mock.Anything).Unset() diff --git a/block/produce.go b/block/produce.go index c3328392c..a68823d9b 100644 --- a/block/produce.go +++ b/block/produce.go @@ -87,33 +87,27 @@ func (m *Manager) ProduceAndGossipBlock(ctx context.Context, allowEmpty bool) (* return block, commit, nil } +func loadPrevBlock(store store.Store, height uint64) ([32]byte, *types.Commit, error) { + lastCommit, err := store.LoadCommit(height) + if err != nil { + return [32]byte{}, nil, fmt.Errorf("load commit: height: %d: %w", height, err) + } + lastBlock, err := store.LoadBlock(height) + if err != nil { + return [32]byte{}, nil, fmt.Errorf("load block after load commit: height: %d: %w", height, err) + } + return lastBlock.Header.Hash(), lastCommit, nil +} + func (m *Manager) produceBlock(allowEmpty bool) (*types.Block, *types.Commit, error) { - var ( - lastCommit *types.Commit - lastHeaderHash [32]byte - newHeight uint64 - err error - ) - - if m.LastState.IsGenesis() { - newHeight = uint64(m.LastState.InitialHeight) - lastCommit = &types.Commit{} - m.LastState.BaseHeight = newHeight - if ok := m.Store.SetBase(newHeight); !ok { - return nil, nil, fmt.Errorf("store set base: %d", newHeight) - } - } else { - height := m.Store.Height() - newHeight = height + 1 - lastCommit, err = m.Store.LoadCommit(height) - if err != nil { - return nil, nil, fmt.Errorf("load commit: height: %d: %w: %w", height, err, ErrNonRecoverable) - } - lastBlock, err := m.Store.LoadBlock(height) - if err != nil { - return nil, nil, fmt.Errorf("load block after load commit: height: %d: %w: %w", height, err, ErrNonRecoverable) + newHeight := m.State.NextHeight() + lastHeaderHash, lastCommit, err := loadPrevBlock(m.Store, newHeight-1) + if err != nil { + if !m.State.IsGenesis() { // allow prevBlock not to be found only on genesis + return nil, nil, fmt.Errorf("load prev block: %w: %w", err, ErrNonRecoverable) } - lastHeaderHash = lastBlock.Header.Hash() + lastHeaderHash = [32]byte{} + lastCommit = &types.Commit{} } var block *types.Block @@ -132,7 +126,7 @@ func (m *Manager) produceBlock(allowEmpty bool) (*types.Block, *types.Commit, er } else if !errors.Is(err, store.ErrKeyNotFound) { return nil, nil, fmt.Errorf("load block: height: %d: %w: %w", newHeight, err, ErrNonRecoverable) } else { - block = m.Executor.CreateBlock(newHeight, lastCommit, lastHeaderHash, m.LastState, m.Conf.BlockBatchMaxSizeBytes) + block = m.Executor.CreateBlock(newHeight, lastCommit, lastHeaderHash, m.State, m.Conf.BlockBatchMaxSizeBytes) if !allowEmpty && len(block.Data.Txs) == 0 { return nil, nil, fmt.Errorf("%w: %w", types.ErrSkippedEmptyBlock, ErrRecoverable) } @@ -192,19 +186,20 @@ func (m *Manager) createTMSignature(block *types.Block, proposerAddress []byte, } v := vote.ToProto() // convert libp2p key to tm key + // TODO: move to types raw_key, _ := m.ProposerKey.Raw() tmprivkey := tmed25519.PrivKey(raw_key) tmprivkey.PubKey().Bytes() // Create a mock validator to sign the vote tmvalidator := tmtypes.NewMockPVWithParams(tmprivkey, false, false) - err := tmvalidator.SignVote(m.LastState.ChainID, v) + err := tmvalidator.SignVote(m.State.ChainID, v) if err != nil { return nil, err } // Update the vote with the signature vote.Signature = v.Signature pubKey := tmprivkey.PubKey() - voteSignBytes := tmtypes.VoteSignBytes(m.LastState.ChainID, v) + voteSignBytes := tmtypes.VoteSignBytes(m.State.ChainID, v) if !pubKey.VerifySignature(voteSignBytes, vote.Signature) { return nil, fmt.Errorf("wrong signature") } diff --git a/block/production_test.go b/block/production_test.go index 3679f684d..bc7c44a9b 100644 --- a/block/production_test.go +++ b/block/production_test.go @@ -53,7 +53,7 @@ func TestCreateEmptyBlocksEnableDisable(t *testing.T) { // Check initial height initialHeight := uint64(0) - require.Equal(initialHeight, manager.Store.Height()) + require.Equal(initialHeight, manager.State.Height()) mCtx, cancel := context.WithTimeout(context.Background(), runTime) defer cancel() @@ -66,15 +66,15 @@ func TestCreateEmptyBlocksEnableDisable(t *testing.T) { go managerWithEmptyBlocks.AccumulatedDataLoop(mCtx, buf2) <-mCtx.Done() - require.Greater(manager.Store.Height(), initialHeight) - require.Greater(managerWithEmptyBlocks.Store.Height(), initialHeight) - assert.Greater(managerWithEmptyBlocks.Store.Height(), manager.Store.Height()) + require.Greater(manager.State.Height(), initialHeight) + require.Greater(managerWithEmptyBlocks.State.Height(), initialHeight) + assert.Greater(managerWithEmptyBlocks.State.Height(), manager.State.Height()) // Check that blocks are created with empty blocks feature disabled - assert.LessOrEqual(manager.Store.Height(), uint64(runTime/MaxIdleTime)) - assert.LessOrEqual(managerWithEmptyBlocks.Store.Height(), uint64(runTime/blockTime)) + assert.LessOrEqual(manager.State.Height(), uint64(runTime/MaxIdleTime)) + assert.LessOrEqual(managerWithEmptyBlocks.State.Height(), uint64(runTime/blockTime)) - for i := uint64(2); i < managerWithEmptyBlocks.Store.Height(); i++ { + for i := uint64(2); i < managerWithEmptyBlocks.State.Height(); i++ { prevBlock, err := managerWithEmptyBlocks.Store.LoadBlock(i - 1) assert.NoError(err) @@ -87,7 +87,7 @@ func TestCreateEmptyBlocksEnableDisable(t *testing.T) { assert.Less(diff, blockTime+blockTime/10) } - for i := uint64(2); i < manager.Store.Height(); i++ { + for i := uint64(2); i < manager.State.Height(); i++ { prevBlock, err := manager.Store.LoadBlock(i - 1) assert.NoError(err) @@ -139,7 +139,7 @@ func TestCreateEmptyBlocksNew(t *testing.T) { // Check initial height expectedHeight := uint64(0) - assert.Equal(expectedHeight, manager.Store.Height()) + assert.Equal(expectedHeight, manager.State.Height()) mCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() @@ -151,8 +151,8 @@ func TestCreateEmptyBlocksNew(t *testing.T) { <-mCtx.Done() foundTx := false - assert.LessOrEqual(manager.Store.Height(), uint64(10)) - for i := uint64(2); i < manager.Store.Height(); i++ { + assert.LessOrEqual(manager.State.Height(), uint64(10)) + for i := uint64(2); i < manager.State.Height(); i++ { prevBlock, err := manager.Store.LoadBlock(i - 1) assert.NoError(err) @@ -188,7 +188,7 @@ func TestStopBlockProduction(t *testing.T) { // validate initial accumulated is zero require.Equal(manager.AccumulatedBatchSize.Load(), uint64(0)) - assert.Equal(manager.Store.Height(), uint64(0)) + assert.Equal(manager.State.Height(), uint64(0)) // subscribe to health status event eventReceivedCh := make(chan error) @@ -216,7 +216,7 @@ func TestStopBlockProduction(t *testing.T) { // validate block production works time.Sleep(400 * time.Millisecond) - assert.Greater(manager.Store.Height(), uint64(0)) + assert.Greater(manager.State.Height(), uint64(0)) assert.Greater(manager.AccumulatedBatchSize.Load(), uint64(0)) // we don't read from the submit channel, so we assume it get full @@ -228,11 +228,11 @@ func TestStopBlockProduction(t *testing.T) { assert.Error(err) } - stoppedHeight := manager.Store.Height() + stoppedHeight := manager.State.Height() // make sure block production is stopped time.Sleep(400 * time.Millisecond) - assert.Equal(stoppedHeight, manager.Store.Height()) + assert.Equal(stoppedHeight, manager.State.Height()) // consume the signal <-toSubmit @@ -247,5 +247,5 @@ func TestStopBlockProduction(t *testing.T) { // make sure block production is resumed time.Sleep(400 * time.Millisecond) - assert.Greater(manager.Store.Height(), stoppedHeight) + assert.Greater(manager.State.Height(), stoppedHeight) } diff --git a/block/pruning.go b/block/pruning.go index 525e89840..70977cfc9 100644 --- a/block/pruning.go +++ b/block/pruning.go @@ -4,19 +4,26 @@ import ( "fmt" ) -func (m *Manager) pruneBlocks(retainHeight int64) (uint64, error) { +func (m *Manager) pruneBlocks(retainHeight uint64) (uint64, error) { syncTarget := m.SyncTarget.Load() - if retainHeight > int64(syncTarget) { + if retainHeight > syncTarget { return 0, fmt.Errorf("cannot prune uncommitted blocks") } - pruned, err := m.Store.PruneBlocks(retainHeight) + pruned, err := m.Store.PruneBlocks(m.State.BaseHeight, retainHeight) if err != nil { return 0, fmt.Errorf("prune block store: %w", err) } // TODO: prune state/indexer and state/txindexer?? + m.State.BaseHeight = retainHeight + _, err = m.Store.SaveState(m.State, nil) + if err != nil { + return 0, fmt.Errorf("save state: %w", err) + } + + m.logger.Info("pruned blocks", "pruned", pruned, "retain_height", retainHeight) return pruned, nil } diff --git a/block/retriever.go b/block/retriever.go index a144089c0..240d1a902 100644 --- a/block/retriever.go +++ b/block/retriever.go @@ -37,7 +37,7 @@ func (m *Manager) RetrieveLoop(ctx context.Context) { // It fetches the batches from the settlement, gets the DA height and gets // the actual blocks from the DA. func (m *Manager) syncUntilTarget(targetHeight uint64) error { - for currH := m.Store.Height(); currH < targetHeight; currH = m.Store.Height() { + for currH := m.State.Height(); currH < targetHeight; currH = m.State.Height() { // It's important that we query the state index before fetching the batch, rather // than e.g. keep it and increment it, because we might be concurrently applying blocks @@ -61,7 +61,7 @@ func (m *Manager) syncUntilTarget(targetHeight uint64) error { } - m.logger.Info("Synced", "store height", m.Store.Height(), "target height", targetHeight) + m.logger.Info("Synced", "store height", m.State.Height(), "target height", targetHeight) err := m.attemptApplyCachedBlocks() if err != nil { @@ -76,7 +76,7 @@ func (m *Manager) queryStateIndex() (uint64, error) { var stateIndex uint64 return stateIndex, retry.Do( func() error { - res, err := m.SLClient.GetHeightState(m.Store.Height() + 1) + res, err := m.SLClient.GetHeightState(m.State.NextHeight()) if err != nil { m.logger.Debug("sl client get height state", "error", err) return err @@ -106,7 +106,7 @@ func (m *Manager) ProcessNextDABatch(daMetaData *da.DASubmitMetaData) error { for _, batch := range batchResp.Batches { for i, block := range batch.Blocks { - if block.Header.Height != m.Store.NextHeight() { + if block.Header.Height != m.State.NextHeight() { continue } if err := m.validateBlock(block, batch.Commits[i]); err != nil { diff --git a/block/state.go b/block/state.go index 6c5770b65..35ca63c3d 100644 --- a/block/state.go +++ b/block/state.go @@ -1,7 +1,10 @@ package block import ( - "time" + "errors" + "fmt" + + errorsmod "cosmossdk.io/errors" "github.com/cometbft/cometbft/crypto/merkle" abci "github.com/tendermint/tendermint/abci/types" @@ -9,57 +12,51 @@ import ( tmtypes "github.com/tendermint/tendermint/types" "github.com/dymensionxyz/dymint/mempool" + "github.com/dymensionxyz/dymint/store" "github.com/dymensionxyz/dymint/types" ) -// TODO: move all those methods from blockExecutor to manager -func (e *Executor) updateState(state types.State, block *types.Block, abciResponses *tmstate.ABCIResponses, validatorUpdates []*tmtypes.Validator) (types.State, error) { - nValSet := state.NextValidators.Copy() - lastHeightValSetChanged := state.LastHeightValidatorsChanged - // Dymint can work without validators - if len(nValSet.Validators) > 0 { - if len(validatorUpdates) > 0 { - err := nValSet.UpdateWithChangeSet(validatorUpdates) - if err != nil { - return state, nil - } - // Change results from this height but only applies to the next next height. - lastHeightValSetChanged = int64(block.Header.Height + 1 + 1) - } - - // TODO(tzdybal): right now, it's for backward compatibility, may need to change this - nValSet.IncrementProposerPriority(1) +// getInitialState tries to load lastState from Store, and if it's not available it reads GenesisDoc. +func getInitialState(store store.Store, genesis *tmtypes.GenesisDoc, logger types.Logger) (*types.State, error) { + s, err := store.LoadState() + if errors.Is(err, types.ErrNoStateFound) { + logger.Info("failed to find state in the store, creating new state from genesis") + s, err = types.NewStateFromGenesis(genesis) } - hash := block.Header.Hash() - // TODO: we can probably pass the state as a pointer and update it directly - s := types.State{ - Version: state.Version, - ChainID: state.ChainID, - InitialHeight: state.InitialHeight, - LastBlockHeight: int64(block.Header.Height), - LastBlockTime: time.Unix(0, int64(block.Header.Time)), - LastBlockID: tmtypes.BlockID{ - Hash: hash[:], - // for now, we don't care about part set headers - }, - NextValidators: nValSet, - Validators: state.NextValidators.Copy(), - LastHeightValidatorsChanged: lastHeightValSetChanged, - ConsensusParams: state.ConsensusParams, - LastHeightConsensusParamsChanged: state.LastHeightConsensusParamsChanged, - // We're gonna update those fields only after we commit the blocks - AppHash: state.AppHash, - LastValidators: state.LastValidators.Copy(), - LastStoreHeight: state.LastStoreHeight, - - LastResultsHash: state.LastResultsHash, - BaseHeight: state.BaseHeight, + if err != nil { + return nil, fmt.Errorf("get initial state: %w", err) } return s, nil } +// UpdateStateFromApp is responsible for aligning the state of the store from the abci app +func (m *Manager) UpdateStateFromApp() error { + proxyAppInfo, err := m.Executor.GetAppInfo() + if err != nil { + return errorsmod.Wrap(err, "get app info") + } + + appHeight := uint64(proxyAppInfo.LastBlockHeight) + resp, err := m.Store.LoadBlockResponses(appHeight) + if err != nil { + return errorsmod.Wrap(err, "load block responses") + } + vals, err := m.Store.LoadValidators(appHeight) + if err != nil { + return errorsmod.Wrap(err, "load block responses") + } + + // update the state with the hash, last store height and last validators. + m.Executor.UpdateStateAfterCommit(m.State, resp, proxyAppInfo.LastBlockAppHash, appHeight, vals) + _, err = m.Store.SaveState(m.State, nil) + if err != nil { + return errorsmod.Wrap(err, "update state") + } + return nil +} + func (e *Executor) UpdateStateAfterInitChain(s *types.State, res *abci.ResponseInitChain, validators []*tmtypes.Validator) { // If the app did not return an app hash, we keep the one set from the genesis doc in // the state. We don't set appHash since we don't want the genesis doc app hash @@ -100,7 +97,6 @@ func (e *Executor) UpdateStateAfterInitChain(s *types.State, res *abci.ResponseI // Set the validators in the state s.Validators = tmtypes.NewValidatorSet(validators).CopyIncrementProposerPriority(1) s.NextValidators = s.Validators.Copy() - s.LastValidators = s.Validators.Copy() } func (e *Executor) UpdateMempoolAfterInitChain(s *types.State) { @@ -108,20 +104,22 @@ func (e *Executor) UpdateMempoolAfterInitChain(s *types.State) { e.mempool.SetPostCheckFn(mempool.PostCheckMaxGas(s.ConsensusParams.Block.MaxGas)) } -// UpdateStateFromResponses updates state based on the ABCIResponses. -func (e *Executor) UpdateStateFromResponses(resp *tmstate.ABCIResponses, state types.State, block *types.Block) (types.State, error) { +// NextValSetFromResponses updates state based on the ABCIResponses. +func (e *Executor) NextValSetFromResponses(state *types.State, resp *tmstate.ABCIResponses, block *types.Block) (*tmtypes.ValidatorSet, error) { // Dymint ignores any setValidator responses from the app, as it is manages the validator set based on the settlement consensus // TODO: this will be changed when supporting multiple sequencers from the hub - validatorUpdates := []*tmtypes.Validator{} + return state.NextValidators.Copy(), nil +} - if state.ConsensusParams.Block.MaxBytes == 0 { - e.logger.Error("maxBytes=0", "state.ConsensusParams.Block", state.ConsensusParams.Block) - } +// Update state from Commit response +func (e *Executor) UpdateStateAfterCommit(s *types.State, resp *tmstate.ABCIResponses, appHash []byte, height uint64, valSet *tmtypes.ValidatorSet) { + copy(s.AppHash[:], appHash[:]) + copy(s.LastResultsHash[:], tmtypes.NewResults(resp.DeliverTxs).Hash()) - state, err := e.updateState(state, block, resp, validatorUpdates) - if err != nil { - return types.State{}, err - } + // TODO: load consensus params from endblock? + + s.Validators = s.NextValidators.Copy() + s.NextValidators = valSet.Copy() - return state, nil + s.SetHeight(height) } diff --git a/block/submit.go b/block/submit.go index 2ae8b0978..f676795cc 100644 --- a/block/submit.go +++ b/block/submit.go @@ -5,9 +5,8 @@ import ( "fmt" "time" - "github.com/dymensionxyz/dymint/gerr" - "github.com/dymensionxyz/dymint/da" + "github.com/dymensionxyz/dymint/gerr" "github.com/dymensionxyz/dymint/node/events" "github.com/dymensionxyz/dymint/types" uevent "github.com/dymensionxyz/dymint/utils/event" @@ -46,11 +45,9 @@ func (m *Manager) SubmitLoop(ctx context.Context) { } /* - Note: since we dont explicitly coordinate changes to the accumulated size with actual batch creation - we don't have a guarantee that the accumulated size is the same as the actual batch size that will be made. - See https://github.com/dymensionxyz/dymint/issues/828 - Until that is fixed, it's technically possibly to undercount, by having a some blocks be produced in between - setting the counter to 0, and actually producing the batch. + Note: since we dont explicitly coordinate changes to the accumulated size with actual batch creation + we don't have a guarantee that the accumulated size is the same as the actual batch size that will be made. + But the batch creation step will also check the size is OK, so it's not a problem. */ m.AccumulatedBatchSize.Store(0) @@ -115,7 +112,7 @@ func (m *Manager) HandleSubmissionTrigger() error { // Load current sync target and height to determine if new blocks are available for submission. startHeight := m.SyncTarget.Load() + 1 - endHeightInclusive := m.Store.Height() + endHeightInclusive := m.State.Height() if endHeightInclusive < startHeight { return nil // No new blocks have been produced diff --git a/block/submit_test.go b/block/submit_test.go index b067d49e7..881644f65 100644 --- a/block/submit_test.go +++ b/block/submit_test.go @@ -38,18 +38,18 @@ func TestBatchSubmissionHappyFlow(t *testing.T) { // Check initial assertions initialHeight := uint64(0) - require.Zero(manager.Store.Height()) + require.Zero(manager.State.Height()) require.Zero(manager.SyncTarget.Load()) // Produce block and validate that we produced blocks _, _, err = manager.ProduceAndGossipBlock(ctx, true) require.NoError(err) - assert.Greater(t, manager.Store.Height(), initialHeight) + assert.Greater(t, manager.State.Height(), initialHeight) assert.Zero(t, manager.SyncTarget.Load()) // submit and validate sync target manager.HandleSubmissionTrigger() - assert.EqualValues(t, manager.Store.Height(), manager.SyncTarget.Load()) + assert.EqualValues(t, manager.State.Height(), manager.SyncTarget.Load()) } func TestBatchSubmissionFailedSubmission(t *testing.T) { @@ -85,13 +85,13 @@ func TestBatchSubmissionFailedSubmission(t *testing.T) { // Check initial assertions initialHeight := uint64(0) - require.Zero(manager.Store.Height()) + require.Zero(manager.State.Height()) require.Zero(manager.SyncTarget.Load()) // Produce block and validate that we produced blocks _, _, err = manager.ProduceAndGossipBlock(ctx, true) require.NoError(err) - assert.Greater(t, manager.Store.Height(), initialHeight) + assert.Greater(t, manager.State.Height(), initialHeight) assert.Zero(t, manager.SyncTarget.Load()) // try to submit, we expect failure @@ -101,7 +101,7 @@ func TestBatchSubmissionFailedSubmission(t *testing.T) { // try to submit again, we expect success mockLayerI.On("SubmitBatch", mock.Anything, mock.Anything, mock.Anything).Return(nil).Once() manager.HandleSubmissionTrigger() - assert.EqualValues(t, manager.Store.Height(), manager.SyncTarget.Load()) + assert.EqualValues(t, manager.State.Height(), manager.SyncTarget.Load()) } // TestSubmissionByTime tests the submission trigger by time @@ -135,7 +135,7 @@ func TestSubmissionByTime(t *testing.T) { // Check initial height initialHeight := uint64(0) - require.Equal(initialHeight, manager.Store.Height()) + require.Equal(initialHeight, manager.State.Height()) require.Zero(manager.SyncTarget.Load()) var wg sync.WaitGroup @@ -188,7 +188,7 @@ func TestSubmissionByBatchSize(t *testing.T) { // validate initial accumulated is zero require.Equal(manager.AccumulatedBatchSize.Load(), uint64(0)) - assert.Equal(manager.Store.Height(), uint64(0)) + assert.Equal(manager.State.Height(), uint64(0)) var wg sync.WaitGroup wg.Add(2) // Add 2 because we have 2 goroutines @@ -209,7 +209,7 @@ func TestSubmissionByBatchSize(t *testing.T) { // wait for block to be produced but not for submission threshold time.Sleep(200 * time.Millisecond) // assert block produced but nothing submitted yet - assert.Greater(manager.Store.Height(), uint64(0)) + assert.Greater(manager.State.Height(), uint64(0)) assert.Greater(manager.AccumulatedBatchSize.Load(), uint64(0)) assert.Zero(manager.SyncTarget.Load()) diff --git a/block/synctarget.go b/block/synctarget.go index 471a0334a..c101fddbf 100644 --- a/block/synctarget.go +++ b/block/synctarget.go @@ -8,7 +8,7 @@ import ( ) // SyncTargetLoop is responsible for getting real time updates about settlement batch submissions. -// For non aggregator: updating the sync target which will be used by retrieveLoop to sync until this target. +// For non sequencer: updating the sync target which will be used by retrieveLoop to sync until this target. // It publishes new sync height targets which will then be synced by another process. func (m *Manager) SyncTargetLoop(ctx context.Context) { m.logger.Info("Started sync target loop") @@ -23,22 +23,22 @@ func (m *Manager) SyncTargetLoop(ctx context.Context) { case <-ctx.Done(): return case event := <-subscription.Out(): - eventData := event.Data().(*settlement.EventDataNewBatchAccepted) + eventData, _ := event.Data().(*settlement.EventDataNewBatchAccepted) - if eventData.EndHeight <= m.Store.Height() { + if eventData.EndHeight <= m.State.Height() { m.logger.Debug( "syncTargetLoop: received new settlement batch accepted with batch end height <= current store height, skipping.", "height", eventData.EndHeight, "currentHeight", - m.Store.Height(), + m.State.Height(), ) continue } m.UpdateSyncParams(eventData.EndHeight) m.SyncTargetDiode.Set(diodes.GenericDataType(&eventData.EndHeight)) case <-subscription.Cancelled(): - m.logger.Info("syncTargetLoop subscription canceled") + m.logger.Error("syncTargetLoop subscription canceled") return } } diff --git a/block/types.go b/block/types.go index 3f5744f8f..7dfb02981 100644 --- a/block/types.go +++ b/block/types.go @@ -2,6 +2,9 @@ package block import ( "github.com/dymensionxyz/dymint/types" + + "github.com/libp2p/go-libp2p/core/crypto" + tmcrypto "github.com/tendermint/tendermint/crypto" ) // TODO: move to types package @@ -22,3 +25,11 @@ type CachedBlock struct { Block *types.Block Commit *types.Commit } + +func getAddress(key crypto.PrivKey) ([]byte, error) { + rawKey, err := key.GetPublic().Raw() + if err != nil { + return nil, err + } + return tmcrypto.AddressHash(rawKey), nil +} diff --git a/config/flags.go b/config/flags.go index 5dbeb57e7..b775f21ef 100644 --- a/config/flags.go +++ b/config/flags.go @@ -39,9 +39,9 @@ func AddNodeFlags(cmd *cobra.Command) { cmd.Flags().String(FlagDALayer, def.DALayer, "Data Availability Layer Client name (mock or grpc") cmd.Flags().String(FlagDAConfig, def.DAConfig, "Data Availability Layer Client config") - cmd.Flags().Duration(FlagBlockTime, def.BlockTime, "block time (for aggregator mode)") - cmd.Flags().Duration(FlagMaxIdleTime, def.MaxIdleTime, "max time for empty blocks (for aggregator mode)") - cmd.Flags().Duration(FlagBatchSubmitMaxTime, def.BatchSubmitMaxTime, "max time for batch submit (for aggregator mode)") + cmd.Flags().Duration(FlagBlockTime, def.BlockTime, "block time (for sequencer mode)") + cmd.Flags().Duration(FlagMaxIdleTime, def.MaxIdleTime, "max time for empty blocks (for sequencer mode)") + cmd.Flags().Duration(FlagBatchSubmitMaxTime, def.BatchSubmitMaxTime, "max time for batch submit (for sequencer mode)") cmd.Flags().String(FlagNamespaceID, def.NamespaceID, "namespace identifies (8 bytes in hex)") cmd.Flags().Uint64(FlagBlockBatchMaxSizeBytes, def.BlockBatchMaxSizeBytes, "block batch size in bytes") diff --git a/da/celestia/celestia.go b/da/celestia/celestia.go index bf59bee13..9ad65d298 100644 --- a/da/celestia/celestia.go +++ b/da/celestia/celestia.go @@ -162,6 +162,10 @@ func (c *DataAvailabilityLayerClient) Start() (err error) { } return nil case <-ticker.C: + state, err := rpc.Header.SyncState(c.ctx) + if err != nil { + return err + } c.logger.Info("celestia-node still syncing", "height", state.Height, "target", state.ToHeight) } } diff --git a/go.mod b/go.mod index 6aa73f21f..46a7f5d9f 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,6 @@ go 1.22.2 require ( code.cloudfoundry.org/go-diodes v0.0.0-20220725190411-383eb6634c40 cosmossdk.io/errors v1.0.1 - cosmossdk.io/math v1.3.0 github.com/avast/retry-go/v4 v4.5.0 github.com/celestiaorg/celestia-openrpc v0.4.0-rc.1 github.com/celestiaorg/go-cnc v0.4.2 @@ -21,15 +20,15 @@ require ( github.com/google/uuid v1.4.0 github.com/gorilla/mux v1.8.1 github.com/gorilla/rpc v1.2.0 - github.com/gorilla/websocket v1.5.0 + github.com/gorilla/websocket v1.5.1 github.com/hashicorp/go-multierror v1.1.1 github.com/ignite/cli v0.26.1 github.com/informalsystems/tm-load-test v1.3.0 - github.com/libp2p/go-libp2p v0.30.0 - github.com/libp2p/go-libp2p-kad-dht v0.21.1 + github.com/libp2p/go-libp2p v0.33.1 + github.com/libp2p/go-libp2p-kad-dht v0.25.2 github.com/libp2p/go-libp2p-pubsub v0.9.3 - github.com/multiformats/go-multiaddr v0.11.0 - github.com/prometheus/client_golang v1.16.0 + github.com/multiformats/go-multiaddr v0.12.2 + github.com/prometheus/client_golang v1.18.0 github.com/rs/cors v1.9.0 github.com/spf13/cobra v1.8.0 github.com/spf13/viper v1.15.0 @@ -72,12 +71,11 @@ require ( github.com/ethereum/go-ethereum v1.12.0 // indirect github.com/filecoin-project/go-jsonrpc v0.3.1 // indirect github.com/ghodss/yaml v1.0.0 // indirect - github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/logr v1.3.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-stack/stack v1.8.1 // indirect - github.com/golang/mock v1.6.0 // indirect github.com/google/go-cmp v0.6.0 // indirect - github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect + github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 // indirect github.com/hashicorp/go-uuid v1.0.1 // indirect github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect github.com/ipfs/go-log v1.0.5 // indirect @@ -85,12 +83,11 @@ require ( github.com/lib/pq v1.10.7 // indirect github.com/libp2p/go-yamux/v4 v4.0.1 // indirect github.com/minio/highwayhash v1.0.2 // indirect - github.com/onsi/ginkgo/v2 v2.11.0 // indirect + github.com/onsi/ginkgo/v2 v2.15.0 // indirect github.com/pierrec/xxHash v0.1.5 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-20 v0.3.2 // indirect - github.com/quic-go/quic-go v0.37.6 // indirect - github.com/quic-go/webtransport-go v0.5.3 // indirect + github.com/quic-go/quic-go v0.42.0 // indirect + github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/satori/go.uuid v1.2.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/tidwall/btree v1.5.0 // indirect @@ -104,9 +101,9 @@ require ( go.opentelemetry.io/otel v1.19.0 // indirect go.opentelemetry.io/otel/metric v1.19.0 // indirect go.opentelemetry.io/otel/trace v1.19.0 // indirect - go.uber.org/dig v1.17.0 // indirect - go.uber.org/fx v1.20.0 // indirect - golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect + go.uber.org/dig v1.17.1 // indirect + go.uber.org/fx v1.20.1 // indirect + golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240125205218-1f4bbc51befe // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe // indirect @@ -135,7 +132,7 @@ require ( github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac // indirect github.com/dvsekhvalnov/jose2go v1.5.0 // indirect github.com/elastic/gosigar v0.14.2 // indirect - github.com/flynn/noise v1.0.0 // indirect + github.com/flynn/noise v1.1.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-kit/log v0.2.1 // indirect @@ -161,26 +158,24 @@ require ( github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 // indirect - github.com/huin/goupnp v1.2.0 // indirect + github.com/huin/goupnp v1.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect - github.com/ipfs/go-ipfs-util v0.0.2 // indirect - github.com/ipfs/go-ipns v0.2.0 // indirect github.com/ipfs/go-log/v2 v2.5.1 // indirect - github.com/ipld/go-ipld-prime v0.9.0 // indirect + github.com/ipld/go-ipld-prime v0.20.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect github.com/jmhodges/levigo v1.0.0 // indirect - github.com/klauspost/compress v1.16.7 // indirect - github.com/klauspost/cpuid/v2 v2.2.5 // indirect + github.com/klauspost/compress v1.17.6 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect - github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect - github.com/libp2p/go-libp2p-kbucket v0.5.0 // indirect + github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect + github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.2.0 // indirect @@ -188,9 +183,8 @@ require ( github.com/libp2p/go-reuseport v0.4.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/miekg/dns v1.1.55 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/miekg/dns v1.1.58 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b // indirect @@ -205,17 +199,17 @@ require ( github.com/multiformats/go-multibase v0.2.0 // indirect github.com/multiformats/go-multicodec v0.9.0 // indirect github.com/multiformats/go-multihash v0.2.3 // indirect - github.com/multiformats/go-multistream v0.4.1 // indirect + github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/opencontainers/runtime-spec v1.1.0 // indirect + github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pelletier/go-toml/v2 v2.0.7 // indirect github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e // indirect - github.com/prometheus/client_model v0.4.0 // indirect - github.com/prometheus/procfs v0.10.1 // indirect + github.com/polydawn/refmt v0.89.0 // indirect + github.com/prometheus/client_model v0.6.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect @@ -233,10 +227,10 @@ require ( github.com/zondax/hid v0.9.2 // indirect go.etcd.io/bbolt v1.3.8 // indirect go.opencensus.io v0.24.0 // indirect - go.uber.org/zap v1.25.0 // indirect + go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.22.0 // indirect - golang.org/x/mod v0.12.0 // indirect - golang.org/x/sync v0.5.0 // indirect + golang.org/x/mod v0.15.0 // indirect + golang.org/x/sync v0.6.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 @@ -248,6 +242,7 @@ require ( ) require ( + cosmossdk.io/math v1.3.0 // indirect github.com/DataDog/zstd v1.5.2 // indirect github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 // indirect github.com/blang/semver/v4 v4.0.0 // indirect @@ -264,25 +259,25 @@ require ( github.com/getsentry/sentry-go v0.18.0 // indirect github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f // indirect github.com/holiman/uint256 v1.2.2 // indirect + github.com/ipfs/boxo v0.10.0 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect + github.com/libp2p/go-libp2p-routing-helpers v0.7.2 // indirect github.com/linxGnu/grocksdb v1.8.12 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/common v0.42.0 // indirect + github.com/prometheus/common v0.47.0 // indirect github.com/regen-network/cosmos-proto v0.3.1 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect - github.com/smartystreets/assertions v1.0.1 // indirect - golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect + go.uber.org/mock v0.4.0 // indirect + golang.org/x/tools v0.18.0 // indirect ) replace ( github.com/centrifuge/go-substrate-rpc-client/v4 => github.com/availproject/go-substrate-rpc-client/v4 v4.0.12-avail-1.4.0-rc1-5e286e3 github.com/evmos/evmos/v12 => github.com/dymensionxyz/evmos/v12 v12.1.6-dymension-v0.3 - github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.2-alpha.regen.4 github.com/gorilla/rpc => github.com/dymensionxyz/rpc v1.3.1 - github.com/libp2p/go-libp2p-pubsub => github.com/dymensionxyz/go-libp2p-pubsub v0.0.0-20231220125656-9e904c648367 - + github.com/libp2p/go-libp2p-pubsub => github.com/dymensionxyz/go-libp2p-pubsub v0.0.0-20240513081713-3ecd83c19ea2 github.com/tendermint/tendermint => github.com/cometbft/cometbft v0.34.28 ) diff --git a/go.sum b/go.sum index d3611644c..ac12b1c48 100644 --- a/go.sum +++ b/go.sum @@ -308,8 +308,8 @@ github.com/dymensionxyz/dymension/v3 v3.1.0-rc03.0.20240411195658-f7cd96f53b56 h github.com/dymensionxyz/dymension/v3 v3.1.0-rc03.0.20240411195658-f7cd96f53b56/go.mod h1:3Pfrr8j/BR9ztNKztGfC5PqDiO6CcrzMLCJtFtPEVW4= github.com/dymensionxyz/evmos/v12 v12.1.6-dymension-v0.3 h1:vmAdUGUc4rTIiO3Phezr7vGq+0uPDVKSA4WAe8+yl6w= github.com/dymensionxyz/evmos/v12 v12.1.6-dymension-v0.3/go.mod h1:LfPv2O1HXMgETpka81Pg3nXy+U/7urq8dn85ZnSXK5Y= -github.com/dymensionxyz/go-libp2p-pubsub v0.0.0-20231220125656-9e904c648367 h1:uuDi/ImqT9+vHUoVGA3oLipuwpErSzvS/dkilzl70kc= -github.com/dymensionxyz/go-libp2p-pubsub v0.0.0-20231220125656-9e904c648367/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc= +github.com/dymensionxyz/go-libp2p-pubsub v0.0.0-20240513081713-3ecd83c19ea2 h1:5FMEOpX5OuoRfwwjjA+LxRJXoDT0fFvg8/rlat7z8bE= +github.com/dymensionxyz/go-libp2p-pubsub v0.0.0-20240513081713-3ecd83c19ea2/go.mod h1:1OxbaT/pFRO5h+Dpze8hdHQ63R0ke55XTs6b6NwLLkw= github.com/dymensionxyz/rpc v1.3.1 h1:7EXWIobaBes5zldRvTIg7TmNsEKjicrWA/OjCc0NaGs= github.com/dymensionxyz/rpc v1.3.1/go.mod h1:f+WpX8ysy8wt95iGc6auYlHcnHj2bUkhiRVkkKNys8c= github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= @@ -334,13 +334,12 @@ github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw github.com/filecoin-project/go-jsonrpc v0.3.1 h1:qwvAUc5VwAkooquKJmfz9R2+F8znhiqcNHYjEp/NM10= github.com/filecoin-project/go-jsonrpc v0.3.1/go.mod h1:jBSvPTl8V1N7gSTuCR4bis8wnQnIjHbRPpROol6iQKM= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= -github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= +github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg= +github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -372,8 +371,8 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= @@ -388,6 +387,7 @@ github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -486,8 +486,8 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b h1:h9U78+dx9a4BKdQkBBos92HalKpaGKHrp+3Uo6yTodo= -github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7AsNS6C/ysHWYo+2qPCZKTQhRo= +github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= @@ -513,8 +513,8 @@ github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= 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 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= @@ -564,8 +564,8 @@ github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iU github.com/holiman/uint256 v1.2.2 h1:TXKcSGc2WaxPD2+bmzAsVthL4+pEN0YwXcL5qED83vk= github.com/holiman/uint256 v1.2.2/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= -github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ignite/cli v0.26.1 h1:T4qMjM9H38JOBsgCruilGcsfrlDGHO2K1V88gIe0ubs= @@ -579,7 +579,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/informalsystems/tm-load-test v1.3.0 h1:FGjKy7vBw6mXNakt+wmNWKggQZRsKkEYpaFk/zR64VA= github.com/informalsystems/tm-load-test v1.3.0/go.mod h1:OQ5AQ9TbT5hKWBNIwsMjn6Bf4O0U4b1kRc+0qZlQJKw= -github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= +github.com/ipfs/boxo v0.10.0 h1:tdDAxq8jrsbRkYoF+5Rcqyeb91hgWe2hp7iLu7ORZLY= +github.com/ipfs/boxo v0.10.0/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= @@ -588,15 +589,13 @@ github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= -github.com/ipfs/go-ipns v0.2.0 h1:BgmNtQhqOw5XEZ8RAfWEpK4DhqaYiuP6h71MhIp7xXU= -github.com/ipfs/go-ipns v0.2.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= -github.com/ipld/go-ipld-prime v0.9.0 h1:N2OjJMb+fhyFPwPnVvJcWU/NsumP8etal+d2v3G4eww= -github.com/ipld/go-ipld-prime v0.9.0/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= +github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= +github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= @@ -623,11 +622,10 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= -github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= +github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/klauspost/reedsolomon v1.11.8 h1:s8RpUW5TK4hjr+djiOpbZJB4ksx+TdYbRH7vHQpwPOY= github.com/klauspost/reedsolomon v1.11.8/go.mod h1:4bXRN+cVzMdml6ti7qLouuYi32KHJ5MGv0Qd8a47h6A= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -654,16 +652,18 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.30.0 h1:9EZwFtJPFBcs/yJTnP90TpN1hgrT/EsFfM+OZuwV87U= -github.com/libp2p/go-libp2p v0.30.0/go.mod h1:nr2g5V7lfftwgiJ78/HrID+pwvayLyqKCEirT2Y3Byg= -github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= -github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= -github.com/libp2p/go-libp2p-kad-dht v0.21.1 h1:xpfp8/t9+X2ip1l8Umap1/UGNnJ3RHJgKGAEsnRAlTo= -github.com/libp2p/go-libp2p-kad-dht v0.21.1/go.mod h1:Oy8wvbdjpB70eS5AaFaI68tOtrdo3KylTvXDjikxqFo= -github.com/libp2p/go-libp2p-kbucket v0.5.0 h1:g/7tVm8ACHDxH29BGrpsQlnNeu+6OF1A9bno/4/U1oA= -github.com/libp2p/go-libp2p-kbucket v0.5.0/go.mod h1:zGzGCpQd78b5BNTDGHNDLaTt9aDK/A02xeZp9QeFC4U= +github.com/libp2p/go-libp2p v0.33.1 h1:tvJl9b9M6nSLBtZSXSguq+/lRhRj2oLRkyhBmQNMFLA= +github.com/libp2p/go-libp2p v0.33.1/go.mod h1:zOUTMjG4I7TXwMndNyOBn/CNtVBLlvBlnxfi+8xzx+E= +github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= +github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= +github.com/libp2p/go-libp2p-kad-dht v0.25.2 h1:FOIk9gHoe4YRWXTu8SY9Z1d0RILol0TrtApsMDPjAVQ= +github.com/libp2p/go-libp2p-kad-dht v0.25.2/go.mod h1:6za56ncRHYXX4Nc2vn8z7CZK0P4QiMcrn77acKLM2Oo= +github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= +github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= +github.com/libp2p/go-libp2p-routing-helpers v0.7.2 h1:xJMFyhQ3Iuqnk9Q2dYE1eUTzsah7NLw3Qs2zjUV78T0= +github.com/libp2p/go-libp2p-routing-helpers v0.7.2/go.mod h1:cN4mJAD/7zfPKXBcs9ze31JGYAZgzdABEm+q/hkswb8= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= @@ -690,17 +690,15 @@ github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs 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.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +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/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= -github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= +github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -714,7 +712,6 @@ github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8Rv github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -730,42 +727,33 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= -github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.11.0 h1:XqGyJ8ufbCE0HmTDwx2kPdsrQ36AGPZNZX6s6xfJH10= -github.com/multiformats/go-multiaddr v0.11.0/go.mod h1:gWUm0QLR4thQ6+ZF6SXUw8YjtwQSPapICM+NmCkxHSM= +github.com/multiformats/go-multiaddr v0.12.2 h1:9G9sTY/wCYajKa9lyfWPmpZAwe6oV+Wb1zcmMS1HG24= +github.com/multiformats/go-multiaddr v0.12.2/go.mod h1:GKyaTYjZRdcUhyOetrxTk9z0cW+jA/YrnqTOvKgi44M= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= -github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= -github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= -github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= -github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= -github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= +github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE= +github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dydlEqV3l6N3/GBsX6ILA= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -785,16 +773,16 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv 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/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= -github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= +github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= +github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= 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.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= -github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ= +github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= +github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= @@ -802,8 +790,8 @@ github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6 github.com/opencontainers/runc v1.1.7 h1:y2EZDS8sNng4Ksf0GUYNhKbTShZJPJg1FiXJNH/uoCk= github.com/opencontainers/runc v1.1.7/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= -github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= +github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= 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= @@ -835,40 +823,37 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= -github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e h1:ZOcivgkkFRnjfoTcGsDq3UQYiBmekwLA+qg0OjyB/ls= -github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= +github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= -github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= +github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= +github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= +github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= -github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k= +github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= -github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-20 v0.3.2 h1:rRgN3WfnKbyik4dBV8A6girlJVxGand/d+jVKbQq5GI= -github.com/quic-go/qtls-go1-20 v0.3.2/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.37.6 h1:2IIUmQzT5YNxAiaPGjs++Z4hGOtIR0q79uS5qE9ccfY= -github.com/quic-go/quic-go v0.37.6/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU= -github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= -github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/quic-go/quic-go v0.42.0 h1:uSfdap0eveIl8KXnipv9K7nlwZ5IqLlYOpJ58u5utpM= +github.com/quic-go/quic-go v0.42.0/go.mod h1:132kz4kL3F9vxhW3CtQJLDVwcFe5wdWeJXXijhsO57M= +github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= +github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -928,11 +913,10 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd 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/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= -github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= -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/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= +github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= +github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= +github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -1010,12 +994,13 @@ github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljT github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vedhavyas/go-subkey v1.0.3 h1:iKR33BB/akKmcR2PMlXPBeeODjWLM90EL98OrOGs8CA= github.com/vedhavyas/go-subkey v1.0.3/go.mod h1:CloUaFQSSTdWnINfBRFjVMkWXZANW+nd8+TI5jYcl6Y= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= -github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te356JvdhaM8YS6nMsjLAYF7JxCv07w= -github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= +github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= @@ -1061,13 +1046,15 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= -go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.20.0 h1:ZMC/pnRvhsthOZh9MZjMq5U8Or3mA9zBSPaLnzs3ihQ= -go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0= +go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= +go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= +go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= @@ -1077,8 +1064,8 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= -go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1096,7 +1083,6 @@ golang.org/x/crypto v0.0.0-20200109152110-61a87790db17/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -1112,8 +1098,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1139,8 +1125,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= +golang.org/x/mod v0.15.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= @@ -1215,8 +1201,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1269,7 +1255,6 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1287,7 +1272,6 @@ 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.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-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= @@ -1306,6 +1290,8 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.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-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1362,10 +1348,9 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= +golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= +golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= 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= diff --git a/state/indexer/block.go b/indexers/blockindexer/block.go similarity index 100% rename from state/indexer/block.go rename to indexers/blockindexer/block.go diff --git a/state/indexer/block/kv/kv.go b/indexers/blockindexer/kv/kv.go similarity index 97% rename from state/indexer/block/kv/kv.go rename to indexers/blockindexer/kv/kv.go index 17fd430ba..dce0c572c 100644 --- a/state/indexer/block/kv/kv.go +++ b/indexers/blockindexer/kv/kv.go @@ -12,10 +12,11 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/pubsub/query" - "github.com/tendermint/tendermint/types" - "github.com/dymensionxyz/dymint/state/indexer" + indexer "github.com/dymensionxyz/dymint/indexers/blockindexer" "github.com/dymensionxyz/dymint/store" + + tmtypes "github.com/tendermint/tendermint/types" ) var _ indexer.BlockIndexer = (*BlockerIndexer)(nil) @@ -54,7 +55,7 @@ func (idx *BlockerIndexer) Has(height int64) (bool, error) { // primary key: encode(block.height | height) => encode(height) // BeginBlock events: encode(eventType.eventAttr|eventValue|height|begin_block) => encode(height) // EndBlock events: encode(eventType.eventAttr|eventValue|height|end_block) => encode(height) -func (idx *BlockerIndexer) Index(bh types.EventDataNewBlockHeader) error { +func (idx *BlockerIndexer) Index(bh tmtypes.EventDataNewBlockHeader) error { batch := idx.store.NewBatch() defer batch.Discard() @@ -255,7 +256,7 @@ LOOP: err error ) - if qr.Key == types.BlockHeightKey { + if qr.Key == tmtypes.BlockHeightKey { eventValue, err = parseValueFromPrimaryKey(it.Key()) } else { eventValue, err = parseValueFromEventKey(it.Key()) @@ -495,7 +496,7 @@ func (idx *BlockerIndexer) indexEvents(batch store.Batch, events []abci.Event, t // index iff the event specified index:true and it's not a reserved event compositeKey := fmt.Sprintf("%s.%s", event.Type, string(attr.Key)) - if compositeKey == types.BlockHeightKey { + if compositeKey == tmtypes.BlockHeightKey { return fmt.Errorf("event type and attribute key \"%s\" is reserved; please use a different key", compositeKey) } diff --git a/state/indexer/block/kv/kv_test.go b/indexers/blockindexer/kv/kv_test.go similarity index 97% rename from state/indexer/block/kv/kv_test.go rename to indexers/blockindexer/kv/kv_test.go index a44abff88..55bb88539 100644 --- a/state/indexer/block/kv/kv_test.go +++ b/indexers/blockindexer/kv/kv_test.go @@ -10,7 +10,7 @@ import ( "github.com/tendermint/tendermint/libs/pubsub/query" "github.com/tendermint/tendermint/types" - blockidxkv "github.com/dymensionxyz/dymint/state/indexer/block/kv" + blockidxkv "github.com/dymensionxyz/dymint/indexers/blockindexer/kv" "github.com/dymensionxyz/dymint/store" ) diff --git a/state/indexer/block/kv/util.go b/indexers/blockindexer/kv/util.go similarity index 100% rename from state/indexer/block/kv/util.go rename to indexers/blockindexer/kv/util.go diff --git a/state/indexer/block/null/null.go b/indexers/blockindexer/null/null.go similarity index 90% rename from state/indexer/block/null/null.go rename to indexers/blockindexer/null/null.go index 3f4f65e6f..62658e00e 100644 --- a/state/indexer/block/null/null.go +++ b/indexers/blockindexer/null/null.go @@ -4,7 +4,7 @@ import ( "context" "errors" - "github.com/dymensionxyz/dymint/state/indexer" + indexer "github.com/dymensionxyz/dymint/indexers/blockindexer" "github.com/tendermint/tendermint/libs/pubsub/query" "github.com/tendermint/tendermint/types" ) diff --git a/state/indexer/query_range.go b/indexers/blockindexer/query_range.go similarity index 100% rename from state/indexer/query_range.go rename to indexers/blockindexer/query_range.go diff --git a/state/txindex/indexer.go b/indexers/txindex/indexer.go similarity index 95% rename from state/txindex/indexer.go rename to indexers/txindex/indexer.go index 388d47c18..6d9f6807d 100644 --- a/state/txindex/indexer.go +++ b/indexers/txindex/indexer.go @@ -8,8 +8,6 @@ import ( "github.com/tendermint/tendermint/libs/pubsub/query" ) -// XXX/TODO: These types should be moved to the indexer package. - // TxIndexer interface defines methods to index and search transactions. type TxIndexer interface { // AddBatch analyzes, indexes and stores a batch of transactions. diff --git a/state/txindex/indexer_service.go b/indexers/txindex/indexer_service.go similarity index 95% rename from state/txindex/indexer_service.go rename to indexers/txindex/indexer_service.go index b54efdcf9..0a619e758 100644 --- a/state/txindex/indexer_service.go +++ b/indexers/txindex/indexer_service.go @@ -3,7 +3,7 @@ package txindex import ( "context" - "github.com/dymensionxyz/dymint/state/indexer" + indexer "github.com/dymensionxyz/dymint/indexers/blockindexer" "github.com/tendermint/tendermint/libs/service" "github.com/tendermint/tendermint/types" ) @@ -57,7 +57,7 @@ func (is *IndexerService) OnStart() error { go func() { for { msg := <-blockHeadersSub.Out() - eventDataHeader := msg.Data().(types.EventDataNewBlockHeader) + eventDataHeader, _ := msg.Data().(types.EventDataNewBlockHeader) height := eventDataHeader.Header.Height batch := NewBatch(eventDataHeader.NumTxs) diff --git a/state/txindex/indexer_service_test.go b/indexers/txindex/indexer_service_test.go similarity index 91% rename from state/txindex/indexer_service_test.go rename to indexers/txindex/indexer_service_test.go index dcac5fb99..3f68eb23b 100644 --- a/state/txindex/indexer_service_test.go +++ b/indexers/txindex/indexer_service_test.go @@ -9,9 +9,9 @@ import ( "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/types" - blockidxkv "github.com/dymensionxyz/dymint/state/indexer/block/kv" - "github.com/dymensionxyz/dymint/state/txindex" - "github.com/dymensionxyz/dymint/state/txindex/kv" + blockidxkv "github.com/dymensionxyz/dymint/indexers/blockindexer/kv" + "github.com/dymensionxyz/dymint/indexers/txindex" + "github.com/dymensionxyz/dymint/indexers/txindex/kv" "github.com/dymensionxyz/dymint/store" ) diff --git a/state/txindex/kv/kv.go b/indexers/txindex/kv/kv.go similarity index 97% rename from state/txindex/kv/kv.go rename to indexers/txindex/kv/kv.go index 85ddf8169..03c926ede 100644 --- a/state/txindex/kv/kv.go +++ b/indexers/txindex/kv/kv.go @@ -12,11 +12,12 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/pubsub/query" - "github.com/tendermint/tendermint/types" + tmtypes "github.com/tendermint/tendermint/types" - "github.com/dymensionxyz/dymint/state/indexer" - "github.com/dymensionxyz/dymint/state/txindex" + indexer "github.com/dymensionxyz/dymint/indexers/blockindexer" + "github.com/dymensionxyz/dymint/indexers/txindex" "github.com/dymensionxyz/dymint/store" + "github.com/dymensionxyz/dymint/types" ) const ( @@ -282,7 +283,7 @@ func (txi *TxIndex) Search(ctx context.Context, q *query.Query) ([]*abci.TxResul func lookForHash(conditions []query.Condition) (hash []byte, ok bool, err error) { for _, c := range conditions { - if c.CompositeKey == types.TxHashKey { + if c.CompositeKey == tmtypes.TxHashKey { decoded, err := hex.DecodeString(c.Operand.(string)) return decoded, true, err } @@ -293,7 +294,7 @@ func lookForHash(conditions []query.Condition) (hash []byte, ok bool, err error) // lookForHeight returns a height if there is an "height=X" condition. func lookForHeight(conditions []query.Condition) (height int64) { for _, c := range conditions { - if c.CompositeKey == types.TxHeightKey && c.Op == query.OpEqual { + if c.CompositeKey == tmtypes.TxHeightKey && c.Op == query.OpEqual { return c.Operand.(int64) } } @@ -574,7 +575,7 @@ func keyForEvent(key string, value []byte, result *abci.TxResult) []byte { func keyForHeight(result *abci.TxResult) []byte { return []byte(fmt.Sprintf("%s/%d/%d/%d", - types.TxHeightKey, + tmtypes.TxHeightKey, result.Height, result.Height, result.Index, diff --git a/state/txindex/kv/kv_bench_test.go b/indexers/txindex/kv/kv_bench_test.go similarity index 100% rename from state/txindex/kv/kv_bench_test.go rename to indexers/txindex/kv/kv_bench_test.go diff --git a/state/txindex/kv/kv_test.go b/indexers/txindex/kv/kv_test.go similarity index 99% rename from state/txindex/kv/kv_test.go rename to indexers/txindex/kv/kv_test.go index ae8d18853..023bb1f84 100644 --- a/state/txindex/kv/kv_test.go +++ b/indexers/txindex/kv/kv_test.go @@ -15,7 +15,7 @@ import ( tmrand "github.com/tendermint/tendermint/libs/rand" "github.com/tendermint/tendermint/types" - "github.com/dymensionxyz/dymint/state/txindex" + "github.com/dymensionxyz/dymint/indexers/txindex" "github.com/dymensionxyz/dymint/store" ) diff --git a/state/txindex/kv/utils.go b/indexers/txindex/kv/utils.go similarity index 100% rename from state/txindex/kv/utils.go rename to indexers/txindex/kv/utils.go diff --git a/state/txindex/kv/utils_test.go b/indexers/txindex/kv/utils_test.go similarity index 100% rename from state/txindex/kv/utils_test.go rename to indexers/txindex/kv/utils_test.go diff --git a/state/txindex/null/null.go b/indexers/txindex/null/null.go similarity index 94% rename from state/txindex/null/null.go rename to indexers/txindex/null/null.go index f8f8cba3e..4cf66cbbf 100644 --- a/state/txindex/null/null.go +++ b/indexers/txindex/null/null.go @@ -4,7 +4,7 @@ import ( "context" "errors" - "github.com/dymensionxyz/dymint/state/txindex" + "github.com/dymensionxyz/dymint/indexers/txindex" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/pubsub/query" ) diff --git a/mempool/cache.go b/mempool/cache.go index 3986cd585..78aefa3c4 100644 --- a/mempool/cache.go +++ b/mempool/cache.go @@ -76,7 +76,7 @@ func (c *LRUTxCache) Push(tx types.Tx) bool { if c.list.Len() >= c.size { front := c.list.Front() if front != nil { - frontKey := front.Value.(types.TxKey) + frontKey, _ := front.Value.(types.TxKey) delete(c.cacheMap, frontKey) c.list.Remove(front) } diff --git a/mempool/v1/mempool.go b/mempool/v1/mempool.go index f59b7fbdf..308390b3b 100644 --- a/mempool/v1/mempool.go +++ b/mempool/v1/mempool.go @@ -206,7 +206,7 @@ func (txmp *TxMempool) CheckTx(tx types.Tx, cb func(*abci.Response), txInfo memp if !txmp.cache.Push(tx) { // If the cached transaction is also in the pool, record its sender. if elt, ok := txmp.txByKey[txKey]; ok { - w := elt.Value.(*WrappedTx) + w, _ := elt.Value.(*WrappedTx) w.SetPeer(txInfo.SenderID) } return 0, mempool.ErrTxInCache diff --git a/mockery.go b/mockery.go deleted file mode 100644 index a1b259417..000000000 --- a/mockery.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package mockery .. this is required by mockery, see https://vektra.github.io/mockery/latest/notes/#error-no-go-files-found-in-root-search-path -package mockery diff --git a/node/node.go b/node/node.go index 7d29c0b41..a77c4c376 100644 --- a/node/node.go +++ b/node/node.go @@ -22,16 +22,16 @@ import ( "github.com/dymensionxyz/dymint/config" "github.com/dymensionxyz/dymint/da" daregistry "github.com/dymensionxyz/dymint/da/registry" + indexer "github.com/dymensionxyz/dymint/indexers/blockindexer" + blockidxkv "github.com/dymensionxyz/dymint/indexers/blockindexer/kv" + "github.com/dymensionxyz/dymint/indexers/txindex" + "github.com/dymensionxyz/dymint/indexers/txindex/kv" "github.com/dymensionxyz/dymint/mempool" mempoolv1 "github.com/dymensionxyz/dymint/mempool/v1" nodemempool "github.com/dymensionxyz/dymint/node/mempool" "github.com/dymensionxyz/dymint/p2p" "github.com/dymensionxyz/dymint/settlement" slregistry "github.com/dymensionxyz/dymint/settlement/registry" - "github.com/dymensionxyz/dymint/state/indexer" - blockidxkv "github.com/dymensionxyz/dymint/state/indexer/block/kv" - "github.com/dymensionxyz/dymint/state/txindex" - "github.com/dymensionxyz/dymint/state/txindex/kv" "github.com/dymensionxyz/dymint/store" ) @@ -69,7 +69,7 @@ type Node struct { incomingTxCh chan *p2p.GossipMessage Store store.Store - blockManager *block.Manager + BlockManager *block.Manager dalc da.DataAvailabilityLayerClient settlementlc settlement.LayerI @@ -158,7 +158,7 @@ func NewNode( height := max(genesis.InitialHeight, info.LastBlockHeight) - mp := mempoolv1.NewTxMempool(logger, &conf.MempoolConfig, proxyApp.Mempool(), height) + mp := mempoolv1.NewTxMempool(logger, &conf.MempoolConfig, proxyApp.Mempool(), height, mempoolv1.WithMetrics(metrics)) mpIDs := nodemempool.NewMempoolIDs() // Set p2p client and it's validators @@ -198,7 +198,7 @@ func NewNode( genesis: genesis, conf: conf, P2P: p2pClient, - blockManager: blockManager, + BlockManager: blockManager, dalc: dalc, settlementlc: settlementlc, Mempool: mp, @@ -271,7 +271,7 @@ func (n *Node) OnStart() error { }() // start the block manager - err = n.blockManager.Start(n.ctx) + err = n.BlockManager.Start(n.ctx) if err != nil { return fmt.Errorf("while starting block manager: %w", err) } @@ -380,3 +380,7 @@ func (n *Node) startPrometheusServer() error { } return nil } + +func (n *Node) GetBlockManagerHeight() uint64 { + return n.BlockManager.State.Height() +} diff --git a/node/node_test.go b/node/node_test.go index ae061c244..229e9d69f 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -32,7 +32,7 @@ func TestStartup(t *testing.T) { assert := assert.New(t) require := require.New(t) - // TODO(omritoptix): Test with and without aggregator mode. + // TODO(omritoptix): Test with and without sequencer mode. node, err := testutil.CreateNode(false, nil) require.NoError(err) require.NotNil(node) diff --git a/p2p/client.go b/p2p/client.go index 07a617594..ac84fcd72 100644 --- a/p2p/client.go +++ b/p2p/client.go @@ -320,14 +320,14 @@ func (c *Client) tryConnect(ctx context.Context, peer peer.AddrInfo) { func (c *Client) setupGossiping(ctx context.Context) error { pubsub.GossipSubHistoryGossip = c.conf.GossipCacheSize pubsub.GossipSubHistoryLength = c.conf.GossipCacheSize - pubsub.GossipSubMaxIHaveMessages = c.conf.GossipCacheSize + // We add WithSeenMessagesTTL (with 1 year time) option to avoid ever requesting already seen blocks ps, err := pubsub.NewGossipSub(ctx, c.Host) if err != nil { return err } - //tx gossiper receives the tx to add to the mempool through validation process, since it is a joint process + // tx gossiper receives the tx to add to the mempool through validation process, since it is a joint process c.txGossiper, err = NewGossiper(c.Host, ps, c.getTxTopic(), nil, c.logger, WithValidator(c.txValidator)) if err != nil { return err diff --git a/p2p/validator_test.go b/p2p/validator_test.go index 2c90b44a9..31da0b947 100644 --- a/p2p/validator_test.go +++ b/p2p/validator_test.go @@ -95,10 +95,9 @@ func TestValidator_TxValidator(t *testing.T) { } func TestValidator_BlockValidator(t *testing.T) { - - //Create proposer for the block + // Create proposer for the block proposerKey := ed25519.GenPrivKey() - //Create another key + // Create another key attackerKey := ed25519.GenPrivKey() tests := []struct { @@ -120,7 +119,7 @@ func TestValidator_BlockValidator(t *testing.T) { t.Run(tt.name, func(t *testing.T) { logger := log.TestingLogger() - //Create Block executor + // Create Block executor app := &tmmocks.MockApplication{} clientCreator := proxy.NewLocalClientCreator(app) @@ -133,17 +132,17 @@ func TestValidator_BlockValidator(t *testing.T) { executor, err := block.NewExecutor([]byte("test address"), namespaceId, "test", mpool, proxy.NewAppConns(clientCreator), nil, logger) assert.NoError(t, err) - //Create state + // Create state maxBytes := uint64(100) state := types.State{} state.ConsensusParams.Block.MaxBytes = int64(maxBytes) state.ConsensusParams.Block.MaxGas = 100000 state.Validators = tmtypes.NewValidatorSet(nil) - //Create empty block - block := executor.CreateBlock(1, &types.Commit{}, [32]byte{}, state, maxBytes) + // Create empty block + block := executor.CreateBlock(1, &types.Commit{}, [32]byte{}, &state, maxBytes) - //Create slclient + // Create slclient client := registry.GetClient(registry.Local) pubsubServer := pubsub.NewServer() err = pubsubServer.Start() @@ -169,16 +168,16 @@ func TestValidator_BlockValidator(t *testing.T) { Signatures: []types.Signature{signature}, } - //Create gossiped block + // Create gossiped block gossipedBlock := p2p.GossipedBlock{Block: *block, Commit: *commit} gossipedBlockBytes, err := gossipedBlock.MarshalBinary() require.NoError(t, err) - var blockMsg = &p2p.GossipMessage{ + blockMsg := &p2p.GossipMessage{ Data: gossipedBlockBytes, From: peer.ID("from"), } - //Check block validity + // Check block validity validateBlock := p2p.NewValidator(logger, client).BlockValidator() valid := validateBlock(blockMsg) require.Equal(t, tt.valid, valid) diff --git a/proto/types/dymint/dymint.proto b/proto/types/dymint/dymint.proto index 509cc4157..625f63d95 100755 --- a/proto/types/dymint/dymint.proto +++ b/proto/types/dymint/dymint.proto @@ -28,7 +28,7 @@ message Header { // Previous block info bytes last_header_hash = 5; - // Commit from aggregator(s) from the last block + // Commit from sequencers(s) from the last block bytes last_commit_hash = 6; // Block.Data root aka Transactions @@ -52,8 +52,8 @@ message Header { // pubkey can't be recovered by the signature (e.g. ed25519). bytes proposer_address = 11; - // Hash of block aggregator set, at a time of block creation - bytes aggregators_hash = 12; + // Hash of block sequencer set, at a time of block creation + bytes sequencers_hash = 12; // Chain ID the block belongs to string chain_id = 13; diff --git a/rpc/client/client.go b/rpc/client/client.go index 17d3c42d5..246109564 100644 --- a/rpc/client/client.go +++ b/rpc/client/client.go @@ -65,7 +65,7 @@ func NewClient(node *node.Node) *Client { // ABCIInfo returns basic information about application state. func (c *Client) ABCIInfo(ctx context.Context) (*ctypes.ResultABCIInfo, error) { - resInfo, err := c.query().InfoSync(proxy.RequestInfo) + resInfo, err := c.Query().InfoSync(proxy.RequestInfo) if err != nil { return nil, err } @@ -79,7 +79,7 @@ func (c *Client) ABCIQuery(ctx context.Context, path string, data tmbytes.HexByt // ABCIQueryWithOptions queries for data from application. func (c *Client) ABCIQueryWithOptions(ctx context.Context, path string, data tmbytes.HexBytes, opts rpcclient.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) { - resQuery, err := c.query().QuerySync(abci.RequestQuery{ + resQuery, err := c.Query().QuerySync(abci.RequestQuery{ Path: path, Data: data, Height: opts.Height, @@ -154,7 +154,7 @@ func (c *Client) BroadcastTxCommit(ctx context.Context, tx tmtypes.Tx) (*ctypes. // Wait for the tx to be included in a block or timeout. select { case msg := <-deliverTxSub.Out(): // The tx was included in a block. - deliverTxRes := msg.Data().(tmtypes.EventDataTx) + deliverTxRes, _ := msg.Data().(tmtypes.EventDataTx) return &ctypes.ResultBroadcastTxCommit{ CheckTx: *checkTxRes, DeliverTx: deliverTxRes.Result, @@ -313,10 +313,9 @@ func (c *Client) GenesisChunked(context context.Context, id uint) (*ctypes.Resul func (c *Client) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) { const limit int64 = 20 - // Currently blocks are not pruned and are synced linearly so the base height is 0 minHeight, maxHeight, err := filterMinMax( - 0, - int64(c.node.Store.Height()), + 0, // FIXME: we might be pruned + int64(c.node.GetBlockManagerHeight()), minHeight, maxHeight, limit) @@ -341,7 +340,7 @@ func (c *Client) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) } return &ctypes.ResultBlockchainInfo{ - LastHeight: int64(c.node.Store.Height()), + LastHeight: int64(c.node.GetBlockManagerHeight()), BlockMetas: blocks, }, nil } @@ -468,7 +467,7 @@ func (c *Client) BlockByHash(ctx context.Context, hash []byte) (*ctypes.ResultBl func (c *Client) BlockResults(ctx context.Context, height *int64) (*ctypes.ResultBlockResults, error) { var h uint64 if height == nil { - h = c.node.Store.Height() + h = c.node.GetBlockManagerHeight() } else { h = uint64(*height) } @@ -698,7 +697,7 @@ func (c *Client) BlockSearch(ctx context.Context, query string, page, perPage *i // Status returns detailed information about current status of the node. func (c *Client) Status(ctx context.Context) (*ctypes.ResultStatus, error) { - latest, err := c.node.Store.LoadBlock(c.node.Store.Height()) + latest, err := c.node.Store.LoadBlock(c.node.GetBlockManagerHeight()) if err != nil { // TODO(tzdybal): extract error return nil, fmt.Errorf("find latest block: %w", err) @@ -802,7 +801,7 @@ func (c *Client) UnconfirmedTxs(ctx context.Context, limitPtr *int) (*ctypes.Res // // If valid, the tx is automatically added to the mempool. func (c *Client) CheckTx(ctx context.Context, tx tmtypes.Tx) (*ctypes.ResultCheckTx, error) { - res, err := c.mempool().CheckTxSync(abci.RequestCheckTx{Tx: tx}) + res, err := c.Mempool().CheckTxSync(abci.RequestCheckTx{Tx: tx}) if err != nil { return nil, err } @@ -858,26 +857,26 @@ func (c *Client) resubscribe(subscriber string, q tmpubsub.Query) tmtypes.Subscr } } -func (c *Client) consensus() proxy.AppConnConsensus { +func (c *Client) Consensus() proxy.AppConnConsensus { return c.node.ProxyApp().Consensus() } -func (c *Client) mempool() proxy.AppConnMempool { +func (c *Client) Mempool() proxy.AppConnMempool { return c.node.ProxyApp().Mempool() } -func (c *Client) query() proxy.AppConnQuery { +func (c *Client) Query() proxy.AppConnQuery { return c.node.ProxyApp().Query() } -func (c *Client) snapshot() proxy.AppConnSnapshot { +func (c *Client) Snapshot() proxy.AppConnSnapshot { return c.node.ProxyApp().Snapshot() } func (c *Client) normalizeHeight(height *int64) uint64 { var heightValue uint64 if height == nil || *height == 0 { - heightValue = c.node.Store.Height() + heightValue = c.node.GetBlockManagerHeight() } else { heightValue = uint64(*height) } diff --git a/rpc/client/client_test.go b/rpc/client/client_test.go index 2e42e7a42..81dc1fc4a 100644 --- a/rpc/client/client_test.go +++ b/rpc/client/client_test.go @@ -1,4 +1,4 @@ -package client +package client_test import ( "context" @@ -31,7 +31,9 @@ import ( "github.com/dymensionxyz/dymint/mempool" tmmocks "github.com/dymensionxyz/dymint/mocks/github.com/tendermint/tendermint/abci/types" "github.com/dymensionxyz/dymint/node" + "github.com/dymensionxyz/dymint/rpc/client" "github.com/dymensionxyz/dymint/settlement" + "github.com/dymensionxyz/dymint/testutil" "github.com/dymensionxyz/dymint/types" ) @@ -47,10 +49,10 @@ func TestConnectionGetters(t *testing.T) { assert := assert.New(t) _, rpc := getRPC(t) - assert.NotNil(rpc.consensus()) - assert.NotNil(rpc.mempool()) - assert.NotNil(rpc.snapshot()) - assert.NotNil(rpc.query()) + assert.NotNil(rpc.Consensus()) + assert.NotNil(rpc.Mempool()) + assert.NotNil(rpc.Snapshot()) + assert.NotNil(rpc.Query()) } func TestInfo(t *testing.T) { @@ -129,14 +131,14 @@ func TestGenesisChunked(t *testing.T) { ) require.NoError(t, err) - rpc := NewClient(n) + rpc := client.NewClient(n) var expectedID uint = 2 gc, err := rpc.GenesisChunked(context.Background(), expectedID) assert.Error(err) assert.Nil(gc) - err = rpc.node.Start() + err = n.Start() require.NoError(t, err) expectedID = 0 @@ -156,11 +158,11 @@ func TestBroadcastTxAsync(t *testing.T) { expectedTx := []byte("tx data") - mockApp, rpc := getRPC(t) + mockApp, rpc, node := getRPCAndNode(t) mockApp.On("CheckTx", abci.RequestCheckTx{Tx: expectedTx}).Return(abci.ResponseCheckTx{}) mockApp.On("InitChain", mock.Anything).Return(abci.ResponseInitChain{}) - err := rpc.node.Start() + err := node.Start() require.NoError(t, err) res, err := rpc.BroadcastTxAsync(context.Background(), expectedTx) @@ -173,7 +175,7 @@ func TestBroadcastTxAsync(t *testing.T) { assert.NotEmpty(res.Hash) mockApp.AssertExpectations(t) - err = rpc.node.Stop() + err = node.Stop() require.NoError(t, err) } @@ -192,10 +194,10 @@ func TestBroadcastTxSync(t *testing.T) { Codespace: "space", } - mockApp, rpc := getRPC(t) + mockApp, rpc, node := getRPCAndNode(t) mockApp.On("InitChain", mock.Anything).Return(abci.ResponseInitChain{}) - err := rpc.node.Start() + err := node.Start() require.NoError(t, err) mockApp.On("CheckTx", abci.RequestCheckTx{Tx: expectedTx}).Return(expectedResponse) @@ -210,7 +212,7 @@ func TestBroadcastTxSync(t *testing.T) { assert.NotEmpty(res.Hash) mockApp.AssertExpectations(t) - err = rpc.node.Stop() + err = node.Stop() require.NoError(t, err) } @@ -240,18 +242,18 @@ func TestBroadcastTxCommit(t *testing.T) { Codespace: "space", } - mockApp, rpc := getRPC(t) + mockApp, rpc, node := getRPCAndNode(t) mockApp.On("BeginBlock", mock.Anything).Return(abci.ResponseBeginBlock{}) mockApp.BeginBlock(abci.RequestBeginBlock{}) mockApp.On("CheckTx", abci.RequestCheckTx{Tx: expectedTx}).Return(expectedCheckResp) mockApp.On("InitChain", mock.Anything).Return(abci.ResponseInitChain{}) // in order to broadcast, the node must be started - err := rpc.node.Start() + err := node.Start() require.NoError(err) go func() { time.Sleep(mockTxProcessingTime) - err := rpc.node.EventBus().PublishEventTx(tmtypes.EventDataTx{TxResult: abci.TxResult{ + err := node.EventBus().PublishEventTx(tmtypes.EventDataTx{TxResult: abci.TxResult{ Height: 1, Index: 0, Tx: expectedTx, @@ -267,7 +269,7 @@ func TestBroadcastTxCommit(t *testing.T) { assert.Equal(expectedDeliverResp, res.DeliverTx) mockApp.AssertExpectations(t) - err = rpc.node.Stop() + err = node.Stop() require.NoError(err) } @@ -275,47 +277,47 @@ func TestGetBlock(t *testing.T) { assert := assert.New(t) require := require.New(t) - mockApp, rpc := getRPC(t) + mockApp, rpc, node := getRPCAndNode(t) mockApp.On("BeginBlock", mock.Anything).Return(abci.ResponseBeginBlock{}) mockApp.On("CheckTx", mock.Anything).Return(abci.ResponseCheckTx{}) mockApp.On("EndBlock", mock.Anything).Return(abci.ResponseEndBlock{}) mockApp.On("Commit", mock.Anything).Return(abci.ResponseCommit{}) mockApp.On("InitChain", mock.Anything).Return(abci.ResponseInitChain{}) - err := rpc.node.Start() + err := node.Start() require.NoError(err) block := getRandomBlock(1, 10) - _, err = rpc.node.Store.SaveBlock(block, &types.Commit{}, nil) - rpc.node.Store.SetHeight(block.Header.Height) + _, err = node.Store.SaveBlock(block, &types.Commit{}, nil) + node.BlockManager.State.SetHeight(block.Header.Height) require.NoError(err) blockResp, err := rpc.Block(context.Background(), nil) require.NoError(err) require.NotNil(blockResp) - assert.NotNil(blockResp.Block) - err = rpc.node.Stop() + err = node.Stop() require.NoError(err) } func TestGetCommit(t *testing.T) { require := require.New(t) assert := assert.New(t) - mockApp, rpc := getRPC(t) + mockApp, rpc, node := getRPCAndNode(t) + mockApp.On("BeginBlock", mock.Anything).Return(abci.ResponseBeginBlock{}) mockApp.On("Commit", mock.Anything).Return(abci.ResponseCommit{}) mockApp.On("InitChain", mock.Anything).Return(abci.ResponseInitChain{}) blocks := []*types.Block{getRandomBlock(1, 5), getRandomBlock(2, 6), getRandomBlock(3, 8), getRandomBlock(4, 10)} - err := rpc.node.Start() + err := node.Start() require.NoError(err) for _, b := range blocks { - _, err = rpc.node.Store.SaveBlock(b, &types.Commit{Height: b.Header.Height}, nil) - rpc.node.Store.SetHeight(b.Header.Height) + _, err = node.Store.SaveBlock(b, &types.Commit{Height: b.Header.Height}, nil) + node.BlockManager.State.SetHeight(b.Header.Height) require.NoError(err) } t.Run("Fetch all commits", func(t *testing.T) { @@ -335,27 +337,28 @@ func TestGetCommit(t *testing.T) { assert.Equal(blocks[3].Header.Height, uint64(commit.Height)) }) - err = rpc.node.Stop() + err = node.Stop() require.NoError(err) } func TestBlockSearch(t *testing.T) { require := require.New(t) assert := assert.New(t) - mockApp, rpc := getRPC(t) + mockApp, rpc, node := getRPCAndNode(t) + mockApp.On("BeginBlock", mock.Anything).Return(abci.ResponseBeginBlock{}) mockApp.On("Commit", mock.Anything).Return(abci.ResponseCommit{}) heights := []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} for _, h := range heights { block := getRandomBlock(uint64(h), 5) - _, err := rpc.node.Store.SaveBlock(block, &types.Commit{ + _, err := node.Store.SaveBlock(block, &types.Commit{ Height: uint64(h), HeaderHash: block.Header.Hash(), }, nil) require.NoError(err) } - indexBlocks(t, rpc, heights) + indexBlocks(t, node, heights) tests := []struct { query string @@ -403,7 +406,7 @@ func TestGetBlockByHash(t *testing.T) { assert := assert.New(t) require := require.New(t) - mockApp, rpc := getRPC(t) + mockApp, rpc, node := getRPCAndNode(t) mockApp.On("BeginBlock", mock.Anything).Return(abci.ResponseBeginBlock{}) mockApp.On("CheckTx", mock.Anything).Return(abci.ResponseCheckTx{}) mockApp.On("EndBlock", mock.Anything).Return(abci.ResponseEndBlock{}) @@ -411,11 +414,11 @@ func TestGetBlockByHash(t *testing.T) { mockApp.On("Info", mock.Anything).Return(abci.ResponseInfo{LastBlockHeight: 0, LastBlockAppHash: []byte{0}}) mockApp.On("InitChain", mock.Anything).Return(abci.ResponseInitChain{}) - err := rpc.node.Start() + err := node.Start() require.NoError(err) block := getRandomBlock(1, 10) - _, err = rpc.node.Store.SaveBlock(block, &types.Commit{}, nil) + _, err = node.Store.SaveBlock(block, &types.Commit{}, nil) require.NoError(err) abciBlock, err := types.ToABCIBlock(block) require.NoError(err) @@ -434,7 +437,7 @@ func TestGetBlockByHash(t *testing.T) { assert.NotNil(blockResp.Block) - err = rpc.node.Stop() + err = node.Stop() require.NoError(err) } @@ -442,7 +445,7 @@ func TestTx(t *testing.T) { assert := assert.New(t) require := require.New(t) - mockApp, rpc := getRPCAggregator(t) + mockApp, rpc, node := getRPCAndNodeSequencer(t) require.NotNil(rpc) mockApp.On("BeginBlock", mock.Anything).Return(abci.ResponseBeginBlock{}) @@ -453,7 +456,7 @@ func TestTx(t *testing.T) { mockApp.On("Info", mock.Anything).Return(abci.ResponseInfo{LastBlockHeight: 0, LastBlockAppHash: []byte{0}}) mockApp.On("InitChain", mock.Anything).Return(abci.ResponseInitChain{}) - err := rpc.node.Start() + err := node.Start() require.NoError(err) tx1 := tmtypes.Tx("tx1") @@ -496,12 +499,12 @@ func TestUnconfirmedTxs(t *testing.T) { assert := assert.New(t) require := require.New(t) - mockApp, rpc := getRPC(t) + mockApp, rpc, node := getRPCAndNode(t) mockApp.On("BeginBlock", mock.Anything).Return(abci.ResponseBeginBlock{}) mockApp.On("CheckTx", mock.Anything).Return(abci.ResponseCheckTx{}) mockApp.On("InitChain", mock.Anything).Return(abci.ResponseInitChain{}) - err := rpc.node.Start() + err := node.Start() require.NoError(err) for _, tx := range c.txs { @@ -537,11 +540,11 @@ func TestUnconfirmedTxsLimit(t *testing.T) { assert := assert.New(t) require := require.New(t) - mockApp, rpc := getRPC(t) + mockApp, rpc, node := getRPCAndNode(t) mockApp.On("BeginBlock", mock.Anything).Return(abci.ResponseBeginBlock{}) mockApp.On("CheckTx", mock.Anything).Return(abci.ResponseCheckTx{}) - err := rpc.node.Start() + err := node.Start() require.NoError(err) tx1 := tmtypes.Tx("tx1") @@ -576,29 +579,29 @@ func TestConsensusState(t *testing.T) { resp1, err := rpc.ConsensusState(context.Background()) assert.Nil(resp1) - assert.ErrorIs(err, ErrConsensusStateNotAvailable) + assert.ErrorIs(err, client.ErrConsensusStateNotAvailable) resp2, err := rpc.DumpConsensusState(context.Background()) assert.Nil(resp2) - assert.ErrorIs(err, ErrConsensusStateNotAvailable) + assert.ErrorIs(err, client.ErrConsensusStateNotAvailable) } func TestBlockchainInfo(t *testing.T) { require := require.New(t) assert := assert.New(t) - mockApp, rpc := getRPC(t) + mockApp, rpc, node := getRPCAndNode(t) mockApp.On("BeginBlock", mock.Anything).Return(abci.ResponseBeginBlock{}) mockApp.On("Commit", mock.Anything).Return(abci.ResponseCommit{}) heights := []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} for _, h := range heights { block := getRandomBlock(uint64(h), 5) - _, err := rpc.node.Store.SaveBlock(block, &types.Commit{ + _, err := node.Store.SaveBlock(block, &types.Commit{ Height: uint64(h), HeaderHash: block.Header.Hash(), }, nil) - rpc.node.Store.SetHeight(block.Header.Height) require.NoError(err) + node.BlockManager.State.SetHeight(block.Header.Height) } tests := []struct { @@ -612,19 +615,19 @@ func TestBlockchainInfo(t *testing.T) { desc: "min = 1 and max = 5", min: 1, max: 5, - exp: []*tmtypes.BlockMeta{getBlockMeta(rpc, 1), getBlockMeta(rpc, 5)}, + exp: []*tmtypes.BlockMeta{getBlockMeta(node, 1), getBlockMeta(node, 5)}, err: false, }, { desc: "min height is 0", min: 0, max: 10, - exp: []*tmtypes.BlockMeta{getBlockMeta(rpc, 1), getBlockMeta(rpc, 10)}, + exp: []*tmtypes.BlockMeta{getBlockMeta(node, 1), getBlockMeta(node, 10)}, err: false, }, { desc: "max height is out of range", min: 0, max: 15, - exp: []*tmtypes.BlockMeta{getBlockMeta(rpc, 1), getBlockMeta(rpc, 10)}, + exp: []*tmtypes.BlockMeta{getBlockMeta(node, 1), getBlockMeta(node, 10)}, err: false, }, { desc: "negative min height", @@ -724,7 +727,7 @@ func TestValidatorSetHandling(t *testing.T) { require.NoError(err) require.NotNil(node) - rpc := NewClient(node) + rpc := client.NewClient(node) require.NotNil(rpc) err = node.Start() @@ -756,7 +759,7 @@ func getRandomBlock(height uint64, nTxs int) *types.Block { block := &types.Block{ Header: types.Header{ Height: height, - Version: types.Version{Block: types.InitStateVersion.Consensus.Block}, + Version: types.Version{Block: testutil.BlockVersion}, ProposerAddress: getRandomBytes(20), }, Data: types.Data{ @@ -799,8 +802,8 @@ func getRandomBytes(n int) []byte { return data } -func getBlockMeta(rpc *Client, n int64) *tmtypes.BlockMeta { - b, err := rpc.node.Store.LoadBlock(uint64(n)) +func getBlockMeta(node *node.Node, n int64) *tmtypes.BlockMeta { + b, err := node.Store.LoadBlock(uint64(n)) if err != nil { return nil } @@ -812,17 +815,22 @@ func getBlockMeta(rpc *Client, n int64) *tmtypes.BlockMeta { return bmeta } -// getRPC returns a mock application and a new RPC client (non-aggregator mode) -func getRPC(t *testing.T) (*tmmocks.MockApplication, *Client) { +// getRPC returns a mock application and a new RPC client (non-sequencer mode) +func getRPC(t *testing.T) (*tmmocks.MockApplication, *client.Client) { + app, rpc, _ := getRPCAndNode(t) + return app, rpc +} + +func getRPCAndNode(t *testing.T) (*tmmocks.MockApplication, *client.Client, *node.Node) { return getRPCInternal(t, false) } -func getRPCAggregator(t *testing.T) (*tmmocks.MockApplication, *Client) { +func getRPCAndNodeSequencer(t *testing.T) (*tmmocks.MockApplication, *client.Client, *node.Node) { return getRPCInternal(t, true) } -// getRPC returns a mock application and a new RPC client (non-aggregator mode) -func getRPCInternal(t *testing.T, aggregator bool) (*tmmocks.MockApplication, *Client) { +// getRPC returns a mock application and a new RPC client (non-sequencer mode) +func getRPCInternal(t *testing.T, sequencer bool) (*tmmocks.MockApplication, *client.Client, *node.Node) { t.Helper() require := require.New(t) app := &tmmocks.MockApplication{} @@ -836,7 +844,7 @@ func getRPCInternal(t *testing.T, aggregator bool) (*tmmocks.MockApplication, *C proposerKey := hex.EncodeToString(pubkeyBytes) require.NoError(err) - if aggregator { + if sequencer { localKey = slSeqKey } @@ -868,7 +876,7 @@ func getRPCInternal(t *testing.T, aggregator bool) (*tmmocks.MockApplication, *C context.Background(), config, key, - localKey, // this is where aggregator mode is set. if same key as in settlement.Config, it's aggregator + localKey, // this is where sequencer mode is set. if same key as in settlement.Config, it's sequencer proxy.NewLocalClientCreator(app), &tmtypes.GenesisDoc{ChainID: rollappID}, log.TestingLogger(), @@ -877,18 +885,18 @@ func getRPCInternal(t *testing.T, aggregator bool) (*tmmocks.MockApplication, *C require.NoError(err) require.NotNil(node) - rpc := NewClient(node) + rpc := client.NewClient(node) require.NotNil(rpc) - return app, rpc + return app, rpc, node } // From state/indexer/block/kv/kv_test -func indexBlocks(t *testing.T, rpc *Client, heights []int64) { +func indexBlocks(t *testing.T, node *node.Node, heights []int64) { t.Helper() for _, h := range heights { - require.NoError(t, rpc.node.BlockIndexer.Index(tmtypes.EventDataNewBlockHeader{ + require.NoError(t, node.BlockIndexer.Index(tmtypes.EventDataNewBlockHeader{ Header: tmtypes.Header{Height: h}, ResultBeginBlock: abci.ResponseBeginBlock{ Events: []abci.Event{ @@ -1004,7 +1012,7 @@ func TestMempool2Nodes(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() - local := NewClient(node1) + local := client.NewClient(node1) require.NotNil(local) // broadcast the bad Tx, this should not be propagated or added to the local mempool diff --git a/rpc/json/handler.go b/rpc/json/handler.go index 164b1f329..af33eed97 100644 --- a/rpc/json/handler.go +++ b/rpc/json/handler.go @@ -104,7 +104,7 @@ func (h *handler) serveJSONRPCforWS(w http.ResponseWriter, r *http.Request, wsCo errInter := rets[1].Interface() if errInter != nil { statusCode = http.StatusBadRequest - errResult = errInter.(error) + errResult, _ = errInter.(error) } // Prevents Internet Explorer from MIME-sniffing a response away @@ -177,7 +177,7 @@ func (h *handler) newHandler(methodSpec *method) func(http.ResponseWriter, *http errInter := rets[1].Interface() if errInter != nil { statusCode = int(json2.E_INTERNAL) - err = errInter.(error) + err, _ = errInter.(error) } h.encodeAndWriteResponse(w, rets[0].Interface(), err, statusCode) @@ -200,7 +200,7 @@ func (h *handler) encodeAndWriteResponse(w http.ResponseWriter, result interface } else { bytes, err := tmjson.Marshal(result) if err != nil { - resp.Error = &json2.Error{Code: json2.ErrorCode(json2.E_INTERNAL), Data: err.Error()} + resp.Error = &json2.Error{Code: json2.E_INTERNAL, Data: err.Error()} } else { resp.Result = bytes } diff --git a/rpc/json/service_test.go b/rpc/json/service_test.go index 1a9215454..30152bdb6 100644 --- a/rpc/json/service_test.go +++ b/rpc/json/service_test.go @@ -272,7 +272,7 @@ func TestSubscription(t *testing.T) { assert.Contains(jsonResp.Error.Message, "subscription not found") } -// getRPC returns a mock ABCI application and a local client. (aggregator-mode) +// getRPC returns a mock ABCI application and a local client. (sequencer-mode) func getRPC(t *testing.T) (*tmmocks.MockApplication, *client.Client) { t.Helper() require := require.New(t) diff --git a/rpc/server.go b/rpc/server.go index feea78a00..6368d4ff1 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -106,7 +106,7 @@ func (s *Server) startEventListener() { // onNodeHealthUpdate is a callback function that handles health status events from the node. func (s *Server) onNodeHealthUpdate(event pubsub.Message) { - eventData := event.Data().(*events.DataHealthStatus) + eventData, _ := event.Data().(*events.DataHealthStatus) if eventData.Error != nil { s.Logger.Error("node is unhealthy", "error", eventData.Error) } diff --git a/settlement/base.go b/settlement/base.go index 1e82c3846..562f4369c 100644 --- a/settlement/base.go +++ b/settlement/base.go @@ -43,9 +43,9 @@ func (b *BaseLayerClient) Init(config Config, pubsub *pubsub.Server, logger type apply(b) } - //TODO(srene): For a correct validation, sequencer list would need to be updated after a sequencer list change on the Hub. - //e.g. after receiving an event from the Hub. Right now, node will need to be restarted after a sequencer change, since it is - //only getting the sequencers list during Init. + // TODO(srene): For a correct validation, sequencer list would need to be updated after a sequencer list change on the Hub. + // e.g. after receiving an event from the Hub. Right now, node will need to be restarted after a sequencer change, since it is + // only getting the sequencers list during Init. b.sequencersList, err = b.fetchSequencersList() if err != nil { return err diff --git a/settlement/events.go b/settlement/events.go index b2fa7b691..41447184e 100644 --- a/settlement/events.go +++ b/settlement/events.go @@ -24,9 +24,7 @@ const ( // Convenience objects -var ( - EventNewBatchAcceptedList = map[string][]string{EventTypeKey: {EventNewBatchAccepted}} -) +var EventNewBatchAcceptedList = map[string][]string{EventTypeKey: {EventNewBatchAccepted}} // Data diff --git a/store/kv.go b/store/kv.go index e118d2c0c..7dcab1a4f 100644 --- a/store/kv.go +++ b/store/kv.go @@ -6,35 +6,6 @@ import ( "github.com/dgraph-io/badger/v3" ) -// KVStore encapsulates key-value store abstraction, in minimalistic interface. -// -// KVStore MUST be thread safe. -type KVStore interface { - Get(key []byte) ([]byte, error) // Get gets the value for a key. - Set(key []byte, value []byte) error // Set updates the value for a key. - Delete(key []byte) error // Delete deletes a key. - NewBatch() Batch // NewBatch creates a new batch. - PrefixIterator(prefix []byte) Iterator // PrefixIterator creates iterator to traverse given prefix. -} - -// Batch enables batching of transactions. -type Batch interface { - Set(key, value []byte) error // Accumulates KV entries in a transaction. - Delete(key []byte) error // Deletes the given key. - Commit() error // Commits the transaction. - Discard() // Discards the transaction. -} - -// Iterator enables traversal over a given prefix. -type Iterator interface { - Valid() bool - Next() - Key() []byte - Value() []byte - Error() error - Discard() -} - // NewDefaultInMemoryKVStore builds KVStore that works in-memory (without accessing disk). func NewDefaultInMemoryKVStore() KVStore { db, err := badger.Open(badger.DefaultOptions("").WithInMemory(true)) diff --git a/store/pruning.go b/store/pruning.go index 09908ec5a..cebec016e 100644 --- a/store/pruning.go +++ b/store/pruning.go @@ -1,39 +1,32 @@ package store -import "fmt" +import ( + "fmt" +) // PruneBlocks removes block up to (but not including) a height. It returns number of blocks pruned. -func (s *DefaultStore) PruneBlocks(heightInt int64) (uint64, error) { - if heightInt <= 0 { - return 0, fmt.Errorf("height must be greater than 0") +func (s *DefaultStore) PruneBlocks(from, to uint64) (uint64, error) { + if from <= 0 { + return 0, fmt.Errorf("from height must be greater than 0") } - height := uint64(heightInt) - if height > s.Height() { - return 0, fmt.Errorf("cannot prune beyond the latest height %v", s.height) - } - base := s.Base() - if height < base { - return 0, fmt.Errorf("cannot prune to height %v, it is lower than base height %v", - height, base) + if to <= from { + return 0, fmt.Errorf("to height (%d) must be greater than from height (%d)", to, from) } pruned := uint64(0) batch := s.db.NewBatch() defer batch.Discard() - flush := func(batch Batch, base uint64) error { + flush := func(batch Batch, height uint64) error { err := batch.Commit() if err != nil { - return fmt.Errorf("prune up to height %v: %w", base, err) - } - if ok := s.SetBase(base); !ok { - return fmt.Errorf("set base height: %v", base) + return fmt.Errorf("flush batch to disk: height %d: %w", height, err) } return nil } - for h := base; h < height; h++ { + for h := from; h < to; h++ { hash, err := s.loadHashFromIndex(h) if err != nil { continue @@ -67,7 +60,7 @@ func (s *DefaultStore) PruneBlocks(heightInt int64) (uint64, error) { } } - err := flush(batch, height) + err := flush(batch, to) if err != nil { return 0, err } diff --git a/store/pruning_test.go b/store/pruning_test.go index dc719efd7..43dcd774e 100644 --- a/store/pruning_test.go +++ b/store/pruning_test.go @@ -12,15 +12,12 @@ import ( func TestStorePruning(t *testing.T) { t.Parallel() - pruningHeight := uint64(3) - cases := []struct { - name string - blocks []*types.Block - pruningHeight uint64 - expectedBase uint64 - expectedHeight uint64 - shouldError bool + name string + blocks []*types.Block + from uint64 + to uint64 + shouldError bool }{ {"blocks with pruning", []*types.Block{ testutil.GetRandomBlock(1, 0), @@ -28,59 +25,71 @@ func TestStorePruning(t *testing.T) { testutil.GetRandomBlock(3, 0), testutil.GetRandomBlock(4, 0), testutil.GetRandomBlock(5, 0), - }, pruningHeight, pruningHeight, 5, false}, + }, 3, 5, false}, {"blocks out of order", []*types.Block{ testutil.GetRandomBlock(2, 0), testutil.GetRandomBlock(3, 0), testutil.GetRandomBlock(1, 0), - }, pruningHeight, pruningHeight, 3, false}, + testutil.GetRandomBlock(5, 0), + }, 3, 5, false}, {"with a gap", []*types.Block{ testutil.GetRandomBlock(1, 0), testutil.GetRandomBlock(9, 0), testutil.GetRandomBlock(10, 0), - }, pruningHeight, pruningHeight, 10, false}, - {"pruning beyond latest height", []*types.Block{ + }, 3, 5, false}, + {"pruning height 0", []*types.Block{ testutil.GetRandomBlock(1, 0), testutil.GetRandomBlock(2, 0), - }, pruningHeight, 1, 2, true}, // should error because pruning height > latest height - {"pruning height 0", []*types.Block{ + testutil.GetRandomBlock(3, 0), + }, 0, 1, true}, + {"pruning same height", []*types.Block{ testutil.GetRandomBlock(1, 0), testutil.GetRandomBlock(2, 0), testutil.GetRandomBlock(3, 0), - }, 0, 1, 3, true}, + }, 3, 3, true}, } - for _, c := range cases { t.Run(c.name, func(t *testing.T) { assert := assert.New(t) bstore := store.New(store.NewDefaultInMemoryKVStore()) - assert.Equal(uint64(0), bstore.Height()) + savedHeights := make(map[uint64]bool) for _, block := range c.blocks { _, err := bstore.SaveBlock(block, &types.Commit{}, nil) - _ = bstore.SetHeight(block.Header.Height) assert.NoError(err) + savedHeights[block.Header.Height] = true + + // TODO: add block responses and commits } - _, err := bstore.PruneBlocks(int64(c.pruningHeight)) + // Validate all blocks are saved + for k := range savedHeights { + _, err := bstore.LoadBlock(k) + assert.NoError(err) + } + + _, err := bstore.PruneBlocks(c.from, c.to) if c.shouldError { assert.Error(err) - } else { - assert.NoError(err) - assert.Equal(pruningHeight, bstore.Base()) - assert.Equal(c.expectedHeight, bstore.Height()) - assert.Equal(c.expectedBase, bstore.Base()) + return + } + + assert.NoError(err) - // Check if pruned blocks are really removed from the store - for h := uint64(1); h < pruningHeight; h++ { - _, err := bstore.LoadBlock(h) - assert.Error(err, "Block at height %d should be pruned", h) + // Validate only blocks in the range are pruned + for k := range savedHeights { + if k >= c.from && k < c.to { // k < c.to is the exclusion test + _, err := bstore.LoadBlock(k) + assert.Error(err, "Block at height %d should be pruned", k) - _, err = bstore.LoadBlockResponses(h) - assert.Error(err, "BlockResponse at height %d should be pruned", h) + _, err = bstore.LoadBlockResponses(k) + assert.Error(err, "BlockResponse at height %d should be pruned", k) - _, err = bstore.LoadCommit(h) - assert.Error(err, "Commit at height %d should be pruned", h) + _, err = bstore.LoadCommit(k) + assert.Error(err, "Commit at height %d should be pruned", k) + } else { + _, err := bstore.LoadBlock(k) + assert.NoError(err) } } }) diff --git a/store/store.go b/store/store.go index 154369bba..3c206957e 100644 --- a/store/store.go +++ b/store/store.go @@ -4,7 +4,6 @@ import ( "encoding/binary" "errors" "fmt" - "sync/atomic" tmstate "github.com/tendermint/tendermint/proto/tendermint/state" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -24,12 +23,9 @@ var ( validatorsPrefix = [1]byte{6} ) -// DefaultStore is a default store implmementation. +// DefaultStore is a default store implementation. type DefaultStore struct { db KVStore - - height uint64 // the highest block saved - baseHeight uint64 // the lowest block saved } var _ Store = &DefaultStore{} @@ -46,43 +42,6 @@ func (s *DefaultStore) NewBatch() Batch { return s.db.NewBatch() } -// SetHeight sets the height saved in the Store if it is higher than the existing height -// returns OK if the value was updated successfully or did not need to be updated -func (s *DefaultStore) SetHeight(height uint64) bool { - ok := true - storeHeight := s.Height() - if height > storeHeight { - ok = atomic.CompareAndSwapUint64(&s.height, storeHeight, height) - } - return ok -} - -// Height returns height of the highest block saved in the Store. -func (s *DefaultStore) Height() uint64 { - return atomic.LoadUint64(&s.height) -} - -// NextHeight returns the next height that expected to be stored in store. -func (s *DefaultStore) NextHeight() uint64 { - return s.Height() + 1 -} - -// SetBase sets the base height if it is higher than the existing base height -// returns OK if the value was updated successfully or did not need to be updated -func (s *DefaultStore) SetBase(height uint64) bool { - ok := true - baseHeight := s.Base() - if height > baseHeight { - ok = atomic.CompareAndSwapUint64(&s.baseHeight, baseHeight, height) - } - return ok -} - -// Base returns height of the earliest block saved in the Store. -func (s *DefaultStore) Base() uint64 { - return atomic.LoadUint64(&s.baseHeight) -} - // SaveBlock adds block to the store along with corresponding commit. // Stored height is updated if block height is greater than stored value. // In case a batch is provided, the block and commit are added to the batch and not saved. @@ -202,7 +161,7 @@ func (s *DefaultStore) LoadCommitByHash(hash [32]byte) (*types.Commit, error) { // UpdateState updates state saved in Store. Only one State is stored. // If there is no State in Store, state will be saved. -func (s *DefaultStore) UpdateState(state types.State, batch Batch) (Batch, error) { +func (s *DefaultStore) SaveState(state *types.State, batch Batch) (Batch, error) { pbState, err := state.ToProto() if err != nil { return batch, fmt.Errorf("marshal state to JSON: %w", err) @@ -220,26 +179,24 @@ func (s *DefaultStore) UpdateState(state types.State, batch Batch) (Batch, error } // LoadState returns last state saved with UpdateState. -func (s *DefaultStore) LoadState() (types.State, error) { +func (s *DefaultStore) LoadState() (*types.State, error) { blob, err := s.db.Get(getStateKey()) if err != nil { - return types.State{}, types.ErrNoStateFound + return nil, types.ErrNoStateFound } var pbState pb.State err = pbState.Unmarshal(blob) if err != nil { - return types.State{}, fmt.Errorf("unmarshal state from store: %w", err) + return nil, fmt.Errorf("unmarshal state from store: %w", err) } var state types.State err = state.FromProto(&pbState) if err != nil { - return types.State{}, fmt.Errorf("unmarshal state from proto: %w", err) + return nil, fmt.Errorf("unmarshal state from proto: %w", err) } - atomic.StoreUint64(&s.height, state.LastStoreHeight) - atomic.StoreUint64(&s.baseHeight, state.BaseHeight) - return state, nil + return &state, nil } // SaveValidators stores validator set for given block height in store. diff --git a/store/types.go b/store/storeIface.go similarity index 60% rename from store/types.go rename to store/storeIface.go index 2a531eaaa..3acb988e6 100644 --- a/store/types.go +++ b/store/storeIface.go @@ -1,31 +1,44 @@ package store import ( + "github.com/dymensionxyz/dymint/types" tmstate "github.com/tendermint/tendermint/proto/tendermint/state" tmtypes "github.com/tendermint/tendermint/types" - - "github.com/dymensionxyz/dymint/types" ) -// Store is minimal interface for storing and retrieving blocks, commits and state. -type Store interface { - // NewBatch creates a new db batch. - NewBatch() Batch - - // Height returns height of the highest block in store. - Height() uint64 - - // NextHeight returns the next height that expected to be stored in store. - NextHeight() uint64 +// KVStore encapsulates key-value store abstraction, in minimalistic interface. +// +// KVStore MUST be thread safe. +type KVStore interface { + Get(key []byte) ([]byte, error) // Get gets the value for a key. + Set(key []byte, value []byte) error // Set updates the value for a key. + Delete(key []byte) error // Delete deletes a key. + NewBatch() Batch // NewBatch creates a new batch. + PrefixIterator(prefix []byte) Iterator // PrefixIterator creates iterator to traverse given prefix. +} - // SetHeight sets the height saved in the Store if it is higher than the existing height. - SetHeight(height uint64) bool +// Batch enables batching of transactions. +type Batch interface { + Set(key, value []byte) error // Accumulates KV entries in a transaction. + Delete(key []byte) error // Deletes the given key. + Commit() error // Commits the transaction. + Discard() // Discards the transaction. +} - // Base returns height of the lowest block in store. - Base() uint64 +// Iterator enables traversal over a given prefix. +type Iterator interface { + Valid() bool + Next() + Key() []byte + Value() []byte + Error() error + Discard() +} - // SetBase sets the height saved in the Store for the lowest block - SetBase(height uint64) bool +// Store is minimal interface for storing and retrieving blocks, commits and state. +type Store interface { + // NewStoreBatch creates a new db batch. + NewBatch() Batch // SaveBlock saves block along with its seen commit (which will be included in the next block). SaveBlock(block *types.Block, commit *types.Commit, batch Batch) (Batch, error) @@ -48,15 +61,15 @@ type Store interface { // UpdateState updates state saved in Store. Only one State is stored. // If there is no State in Store, state will be saved. - UpdateState(state types.State, batch Batch) (Batch, error) + SaveState(state *types.State, batch Batch) (Batch, error) // LoadState returns last state saved with UpdateState. - LoadState() (types.State, error) + LoadState() (*types.State, error) SaveValidators(height uint64, validatorSet *tmtypes.ValidatorSet, batch Batch) (Batch, error) LoadValidators(height uint64) (*tmtypes.ValidatorSet, error) // Pruning functions - PruneBlocks(height int64) (uint64, error) + PruneBlocks(from, to uint64) (uint64, error) } diff --git a/store/store_test.go b/store/store_test.go index 3241f47f2..40f272391 100644 --- a/store/store_test.go +++ b/store/store_test.go @@ -8,53 +8,13 @@ import ( tmstate "github.com/tendermint/tendermint/proto/tendermint/state" "github.com/dymensionxyz/dymint/store" + "github.com/dymensionxyz/dymint/testutil" "github.com/dymensionxyz/dymint/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -func TestStoreHeight(t *testing.T) { - t.Parallel() - cases := []struct { - name string - blocks []*types.Block - expected uint64 - }{ - {"single block", []*types.Block{testutil.GetRandomBlock(1, 0)}, 1}, - {"two consecutive blocks", []*types.Block{ - testutil.GetRandomBlock(1, 0), - testutil.GetRandomBlock(2, 0), - }, 2}, - {"blocks out of order", []*types.Block{ - testutil.GetRandomBlock(2, 0), - testutil.GetRandomBlock(3, 0), - testutil.GetRandomBlock(1, 0), - }, 3}, - {"with a gap", []*types.Block{ - testutil.GetRandomBlock(1, 0), - testutil.GetRandomBlock(9, 0), - testutil.GetRandomBlock(10, 0), - }, 10}, - } - - for _, c := range cases { - t.Run(c.name, func(t *testing.T) { - assert := assert.New(t) - bstore := store.New(store.NewDefaultInMemoryKVStore()) - assert.Equal(uint64(0), bstore.Height()) - - for _, block := range c.blocks { - _, err := bstore.SaveBlock(block, &types.Commit{}, nil) - _ = bstore.SetHeight(block.Header.Height) - assert.NoError(err) - } - - assert.Equal(c.expected, bstore.Height()) - }) - } -} - func TestStoreLoad(t *testing.T) { t.Parallel() cases := []struct { @@ -123,7 +83,7 @@ func TestStoreLoad(t *testing.T) { } } -func TestRestart(t *testing.T) { +func TestLoadState(t *testing.T) { t.Parallel() assert := assert.New(t) @@ -133,20 +93,19 @@ func TestRestart(t *testing.T) { kv := store.NewDefaultInMemoryKVStore() s1 := store.New(kv) expectedHeight := uint64(10) - _, err := s1.UpdateState(types.State{ - LastBlockHeight: int64(expectedHeight), - LastStoreHeight: uint64(expectedHeight), - NextValidators: validatorSet, - Validators: validatorSet, - LastValidators: validatorSet, - }, nil) + s := &types.State{ + NextValidators: validatorSet, + Validators: validatorSet, + } + s.LastBlockHeight.Store(expectedHeight) + _, err := s1.SaveState(s, nil) assert.NoError(err) s2 := store.New(kv) - _, err = s2.LoadState() + state, err := s2.LoadState() assert.NoError(err) - assert.Equal(expectedHeight, s2.Height()) + assert.Equal(expectedHeight, state.LastBlockHeight.Load()) } func TestBlockResponses(t *testing.T) { diff --git a/test/loadtime/cmd/report/main.go b/test/loadtime/cmd/report/main.go index 0bc1ae98e..2756c9095 100644 --- a/test/loadtime/cmd/report/main.go +++ b/test/loadtime/cmd/report/main.go @@ -22,7 +22,13 @@ var mainPrefix = [1]byte{0} // BlockStore is a thin wrapper around the DefaultStore which will be used for inspecting the blocks type BlockStore struct { *store.DefaultStore - base uint64 + base uint64 + height uint64 +} + +// Height implements report.BlockStore. +func (b *BlockStore) Height() uint64 { + return b.height } // Base will be used to get the block height of the first block we want to generate the report for @@ -39,14 +45,15 @@ func getStore(directory string) *store.PrefixKV { } func newBlockStore(kvstore store.KVStore, baseHeight uint64) *BlockStore { - store := store.New(kvstore).(*store.DefaultStore) - _, err := store.LoadState() + store, _ := store.New(kvstore).(*store.DefaultStore) + state, err := store.LoadState() if err != nil { log.Fatalf("loading state %s", err) } return &BlockStore{ DefaultStore: store, - base: baseHeight, + base: state.BaseHeight, + height: state.LastBlockHeight.Load(), } } diff --git a/testutil/block.go b/testutil/block.go index b809b0181..195faa6c0 100644 --- a/testutil/block.go +++ b/testutil/block.go @@ -32,7 +32,7 @@ const ( /* -------------------------------------------------------------------------- */ /* utils */ /* -------------------------------------------------------------------------- */ -func GetManagerWithProposerKey(conf config.BlockManagerConfig, proposerKey crypto.PrivKey, settlementlc settlement.LayerI, dalc da.DataAvailabilityLayerClient, genesisHeight int64, storeInitialHeight int64, storeLastBlockHeight int64, proxyAppConns proxy.AppConns, mockStore store.Store) (*block.Manager, error) { +func GetManagerWithProposerKey(conf config.BlockManagerConfig, proposerKey crypto.PrivKey, settlementlc settlement.LayerI, dalc da.DataAvailabilityLayerClient, genesisHeight, storeInitialHeight, storeLastBlockHeight int64, proxyAppConns proxy.AppConns, mockStore store.Store) (*block.Manager, error) { genesis := GenerateGenesis(genesisHeight) // Change the LastBlockHeight to avoid calling InitChainSync within the manager // And updating the state according to the genesis. @@ -43,7 +43,7 @@ func GetManagerWithProposerKey(conf config.BlockManagerConfig, proposerKey crypt } else { managerStore = mockStore } - if _, err := managerStore.UpdateState(state, nil); err != nil { + if _, err := managerStore.SaveState(state, nil); err != nil { return nil, err } @@ -113,7 +113,7 @@ func GetManagerWithProposerKey(conf config.BlockManagerConfig, proposerKey crypt return manager, nil } -func GetManager(conf config.BlockManagerConfig, settlementlc settlement.LayerI, dalc da.DataAvailabilityLayerClient, genesisHeight int64, storeInitialHeight int64, storeLastBlockHeight int64, proxyAppConns proxy.AppConns, mockStore store.Store) (*block.Manager, error) { +func GetManager(conf config.BlockManagerConfig, settlementlc settlement.LayerI, dalc da.DataAvailabilityLayerClient, genesisHeight, storeInitialHeight, storeLastBlockHeight int64, proxyAppConns proxy.AppConns, mockStore store.Store) (*block.Manager, error) { proposerKey, _, err := crypto.GenerateEd25519Key(rand.Reader) if err != nil { return nil, err diff --git a/testutil/mocks.go b/testutil/mocks.go index 5f97ee0e3..b4cb09967 100644 --- a/testutil/mocks.go +++ b/testutil/mocks.go @@ -90,8 +90,7 @@ func CountMockCalls(totalCalls []mock.Call, methodName string) int { // MockStore is a mock store for testing type MockStore struct { - ShouldFailSetHeight bool - ShoudFailUpdateState bool + ShoudFailSaveState bool ShouldFailUpdateStateWithBatch bool *store.DefaultStore height uint64 @@ -99,12 +98,8 @@ type MockStore struct { // SetHeight sets the height of the mock store // Don't set the height to mock failure in setting the height -func (m *MockStore) SetHeight(height uint64) bool { - if m.ShouldFailSetHeight { - return false - } +func (m *MockStore) SetHeight(height uint64) { m.height = height - return true } func (m *MockStore) Height() uint64 { @@ -116,21 +111,20 @@ func (m *MockStore) NextHeight() uint64 { } // UpdateState updates the state of the mock store -func (m *MockStore) UpdateState(state types.State, batch store.Batch) (store.Batch, error) { - if batch != nil && m.ShouldFailUpdateStateWithBatch || m.ShoudFailUpdateState && batch == nil { +func (m *MockStore) SaveState(state *types.State, batch store.Batch) (store.Batch, error) { + if batch != nil && m.ShouldFailUpdateStateWithBatch || m.ShoudFailSaveState && batch == nil { return nil, errors.New("failed to update state") } - return m.DefaultStore.UpdateState(state, batch) + return m.DefaultStore.SaveState(state, batch) } // NewMockStore returns a new mock store func NewMockStore() *MockStore { defaultStore := store.New(store.NewDefaultInMemoryKVStore()) return &MockStore{ - DefaultStore: defaultStore.(*store.DefaultStore), - height: 0, - ShouldFailSetHeight: false, - ShoudFailUpdateState: false, + DefaultStore: defaultStore.(*store.DefaultStore), + height: 0, + ShoudFailSaveState: false, } } diff --git a/testutil/node.go b/testutil/node.go index faf51a444..f99559b00 100644 --- a/testutil/node.go +++ b/testutil/node.go @@ -17,7 +17,7 @@ import ( "github.com/dymensionxyz/dymint/settlement" ) -func CreateNode(isAggregator bool, blockManagerConfig *config.BlockManagerConfig) (*node.Node, error) { +func CreateNode(isSequencer bool, blockManagerConfig *config.BlockManagerConfig) (*node.Node, error) { app := GetAppMock() key, _, _ := crypto.GenerateEd25519Key(rand.Reader) signingKey, pubkey, _ := crypto.GenerateEd25519Key(rand.Reader) diff --git a/testutil/types.go b/testutil/types.go index 4a00e24d2..511636ea3 100644 --- a/testutil/types.go +++ b/testutil/types.go @@ -66,9 +66,9 @@ func generateBlock(height uint64) *types.Block { ConsensusHash: h[3], // AppHash: h[4], AppHash: [32]byte{}, - LastResultsHash: getEmptyLastResultsHash(), + LastResultsHash: GetEmptyLastResultsHash(), ProposerAddress: []byte{4, 3, 2, 1}, - AggregatorsHash: h[6], + SequencersHash: h[6], }, Data: types.Data{ Txs: nil, @@ -193,23 +193,23 @@ func GenerateRandomValidatorSet() *tmtypes.ValidatorSet { } // GenerateState generates an initial state for testing. -func GenerateState(initialHeight int64, lastBlockHeight int64) types.State { - return types.State{ +func GenerateState(initialHeight int64, lastBlockHeight int64) *types.State { + s := &types.State{ ChainID: "test-chain", - InitialHeight: initialHeight, + InitialHeight: uint64(initialHeight), AppHash: [32]byte{}, - LastResultsHash: getEmptyLastResultsHash(), + LastResultsHash: GetEmptyLastResultsHash(), Version: tmstate.Version{ Consensus: version.Consensus{ Block: BlockVersion, App: AppVersion, }, }, - LastBlockHeight: lastBlockHeight, - LastValidators: GenerateRandomValidatorSet(), - Validators: GenerateRandomValidatorSet(), - NextValidators: GenerateRandomValidatorSet(), + Validators: GenerateRandomValidatorSet(), + NextValidators: GenerateRandomValidatorSet(), } + s.LastBlockHeight.Store(uint64(lastBlockHeight)) + return s } // GenerateGenesis generates a genesis for testing. @@ -237,7 +237,7 @@ func GenerateGenesis(initialHeight int64) *tmtypes.GenesisDoc { } } -func getEmptyLastResultsHash() [32]byte { +func GetEmptyLastResultsHash() [32]byte { lastResults := []*abci.ResponseDeliverTx{} return *(*[32]byte)(tmtypes.NewResults(lastResults).Hash()) } diff --git a/types/block.go b/types/block.go index 79ac2b5cf..a87c5512b 100644 --- a/types/block.go +++ b/types/block.go @@ -22,7 +22,7 @@ type Header struct { LastHeaderHash [32]byte // hashes of block data - LastCommitHash [32]byte // commit from aggregator(s) from the last block + LastCommitHash [32]byte // commit from sequencer(s) from the last block DataHash [32]byte // Block.Data root aka Transactions ConsensusHash [32]byte // consensus params for current block AppHash [32]byte // state after applying txs from the current block @@ -38,8 +38,8 @@ type Header struct { // pubkey can't be recovered by the signature (e.g. ed25519). ProposerAddress []byte // original proposer of the block - // Hash of block aggregator set, at a time of block creation - AggregatorsHash [32]byte + // Hash of block sequencer set, at a time of block creation + SequencersHash [32]byte // The Chain ID ChainID string diff --git a/types/conv.go b/types/conv.go index 84c94ffef..0efd04b98 100644 --- a/types/conv.go +++ b/types/conv.go @@ -27,8 +27,8 @@ func ToABCIHeaderPB(header *Header) types.Header { }, LastCommitHash: header.LastCommitHash[:], DataHash: header.DataHash[:], - ValidatorsHash: header.AggregatorsHash[:], - NextValidatorsHash: header.AggregatorsHash[:], + ValidatorsHash: header.SequencersHash[:], + NextValidatorsHash: header.SequencersHash[:], ConsensusHash: header.ConsensusHash[:], AppHash: header.AppHash[:], LastResultsHash: header.LastResultsHash[:], @@ -57,8 +57,8 @@ func ToABCIHeader(header *Header) tmtypes.Header { }, LastCommitHash: header.LastCommitHash[:], DataHash: header.DataHash[:], - ValidatorsHash: header.AggregatorsHash[:], - NextValidatorsHash: header.AggregatorsHash[:], + ValidatorsHash: header.SequencersHash[:], + NextValidatorsHash: header.SequencersHash[:], ConsensusHash: header.ConsensusHash[:], AppHash: header.AppHash[:], LastResultsHash: header.LastResultsHash[:], diff --git a/types/hashing.go b/types/hashing.go index 870301c03..1500658e8 100644 --- a/types/hashing.go +++ b/types/hashing.go @@ -25,8 +25,8 @@ func (h *Header) Hash() [32]byte { }, LastCommitHash: h.LastCommitHash[:], DataHash: h.DataHash[:], - ValidatorsHash: h.AggregatorsHash[:], - NextValidatorsHash: h.AggregatorsHash[:], + ValidatorsHash: h.SequencersHash[:], + NextValidatorsHash: h.SequencersHash[:], ConsensusHash: h.ConsensusHash[:], AppHash: h.AppHash[:], LastResultsHash: h.LastResultsHash[:], diff --git a/types/pb/dymint/dymint.pb.go b/types/pb/dymint/dymint.pb.go index 3200e6bb6..b40004d72 100644 --- a/types/pb/dymint/dymint.pb.go +++ b/types/pb/dymint/dymint.pb.go @@ -91,7 +91,7 @@ type Header struct { Time uint64 `protobuf:"varint,4,opt,name=time,proto3" json:"time,omitempty"` // Previous block info LastHeaderHash []byte `protobuf:"bytes,5,opt,name=last_header_hash,json=lastHeaderHash,proto3" json:"last_header_hash,omitempty"` - // Commit from aggregator(s) from the last block + // Commit from sequencers(s) from the last block LastCommitHash []byte `protobuf:"bytes,6,opt,name=last_commit_hash,json=lastCommitHash,proto3" json:"last_commit_hash,omitempty"` // Block.Data root aka Transactions DataHash []byte `protobuf:"bytes,7,opt,name=data_hash,json=dataHash,proto3" json:"data_hash,omitempty"` @@ -109,8 +109,8 @@ type Header struct { // We keep this in case users choose another signature format where the // pubkey can't be recovered by the signature (e.g. ed25519). ProposerAddress []byte `protobuf:"bytes,11,opt,name=proposer_address,json=proposerAddress,proto3" json:"proposer_address,omitempty"` - // Hash of block aggregator set, at a time of block creation - AggregatorsHash []byte `protobuf:"bytes,12,opt,name=aggregators_hash,json=aggregatorsHash,proto3" json:"aggregators_hash,omitempty"` + // Hash of block sequencer set, at a time of block creation + SequencersHash []byte `protobuf:"bytes,12,opt,name=sequencers_hash,json=sequencersHash,proto3" json:"sequencers_hash,omitempty"` // Chain ID the block belongs to ChainId string `protobuf:"bytes,13,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` } @@ -225,9 +225,9 @@ func (m *Header) GetProposerAddress() []byte { return nil } -func (m *Header) GetAggregatorsHash() []byte { +func (m *Header) GetSequencersHash() []byte { if m != nil { - return m.AggregatorsHash + return m.SequencersHash } return nil } @@ -508,50 +508,50 @@ func init() { func init() { proto.RegisterFile("types/dymint/dymint.proto", fileDescriptor_fe69c538ded4b87f) } var fileDescriptor_fe69c538ded4b87f = []byte{ - // 684 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x94, 0x3d, 0x6f, 0xd3, 0x40, - 0x18, 0xc7, 0xeb, 0x26, 0x75, 0x92, 0xc7, 0xe9, 0x0b, 0x27, 0x54, 0xb9, 0xad, 0x30, 0xa9, 0xa5, - 0xa2, 0x94, 0xc1, 0x15, 0x41, 0x48, 0x4c, 0x48, 0x14, 0x90, 0xd2, 0xd5, 0x95, 0x18, 0x58, 0xa2, - 0x8b, 0x7d, 0xb2, 0x4f, 0xd4, 0x2f, 0xba, 0xbb, 0x54, 0x2d, 0x23, 0x1b, 0x1b, 0x33, 0x1b, 0xdf, - 0x86, 0xb1, 0x62, 0x62, 0x44, 0xcd, 0x17, 0x41, 0xf7, 0xdc, 0x39, 0x31, 0xb0, 0x24, 0xbe, 0xff, - 0xff, 0xe7, 0xbb, 0xc7, 0xcf, 0xcb, 0xc1, 0x81, 0xba, 0xad, 0x99, 0x3c, 0x4b, 0x6f, 0x0b, 0x5e, - 0x2a, 0xfb, 0x17, 0xd5, 0xa2, 0x52, 0x15, 0x71, 0xcd, 0xea, 0xf0, 0xd8, 0x20, 0x8a, 0x95, 0x29, - 0x13, 0x88, 0xd1, 0x79, 0xc2, 0xcf, 0x50, 0x35, 0xe8, 0x61, 0xf8, 0x1f, 0x62, 0x85, 0x35, 0x13, - 0x3e, 0x83, 0xde, 0x7b, 0x26, 0x24, 0xaf, 0x4a, 0xf2, 0x10, 0xb6, 0xe6, 0x57, 0x55, 0xf2, 0xd1, - 0x77, 0x46, 0xce, 0xb8, 0x1b, 0x9b, 0x05, 0xd9, 0x83, 0x0e, 0xad, 0x6b, 0x7f, 0x13, 0x35, 0xfd, - 0x18, 0xfe, 0xec, 0x80, 0x3b, 0x65, 0x34, 0x65, 0x82, 0x9c, 0x42, 0xef, 0xda, 0xbc, 0x8d, 0x2f, - 0x79, 0x93, 0xdd, 0xc8, 0x06, 0x6b, 0x37, 0x8d, 0x1b, 0x9f, 0x1c, 0xc3, 0xb0, 0xa4, 0x05, 0x93, - 0x35, 0x4d, 0xd8, 0x8c, 0xa7, 0xb8, 0xe1, 0x30, 0xf6, 0x56, 0xda, 0x45, 0x4a, 0xf6, 0xc1, 0xcd, - 0x19, 0xcf, 0x72, 0xe5, 0x77, 0xf0, 0x34, 0xbb, 0x22, 0x04, 0xba, 0x8a, 0x17, 0xcc, 0xef, 0xa2, - 0x8a, 0xcf, 0x64, 0x0c, 0x7b, 0x57, 0x54, 0xaa, 0x59, 0x8e, 0x81, 0xcc, 0x72, 0x2a, 0x73, 0x7f, - 0x0b, 0xb7, 0xdc, 0xd1, 0xba, 0x89, 0x6f, 0x4a, 0x65, 0xbe, 0x22, 0x93, 0xaa, 0x28, 0xb8, 0x32, - 0xa4, 0xbb, 0x26, 0xdf, 0xa0, 0x8c, 0xe4, 0x11, 0x0c, 0x52, 0xaa, 0xa8, 0x41, 0x7a, 0x88, 0xf4, - 0xb5, 0x80, 0xe6, 0x09, 0xec, 0x24, 0x55, 0x29, 0x59, 0x29, 0x17, 0xd2, 0x10, 0x7d, 0x24, 0xb6, - 0x57, 0x2a, 0x62, 0x07, 0xd0, 0xa7, 0x75, 0x6d, 0x80, 0x01, 0x02, 0x3d, 0x5a, 0xd7, 0x68, 0x3d, - 0x85, 0x07, 0x18, 0x88, 0x60, 0x72, 0x71, 0xa5, 0xec, 0x26, 0x80, 0xcc, 0xae, 0x36, 0x62, 0xa3, - 0x23, 0x7b, 0x0a, 0x7b, 0xb5, 0xa8, 0xea, 0x4a, 0x32, 0x31, 0xa3, 0x69, 0x2a, 0x98, 0x94, 0xbe, - 0x67, 0xd0, 0x46, 0x7f, 0x6d, 0x64, 0x8d, 0xd2, 0x2c, 0x13, 0x2c, 0xa3, 0xaa, 0x12, 0x76, 0xd7, - 0xa1, 0x41, 0x5b, 0x7a, 0x13, 0x5c, 0x92, 0x53, 0x5e, 0xea, 0xfc, 0x6f, 0x8f, 0x9c, 0xf1, 0x20, - 0xee, 0xe1, 0xfa, 0x22, 0x0d, 0xbf, 0x3b, 0xe0, 0x9a, 0x54, 0xb4, 0xca, 0xe0, 0xfc, 0x55, 0x86, - 0xc7, 0xe0, 0xb5, 0xb3, 0x6d, 0x0a, 0x08, 0xf9, 0x3a, 0xd3, 0x01, 0x80, 0xe4, 0x59, 0x49, 0xd5, - 0x42, 0x30, 0xe9, 0x77, 0x46, 0x1d, 0xed, 0xaf, 0x15, 0xf2, 0x0a, 0x86, 0xaa, 0x98, 0xad, 0x04, - 0xac, 0xa7, 0x37, 0x39, 0x8a, 0xd6, 0x0d, 0x1a, 0x99, 0xd6, 0x34, 0x81, 0x5c, 0xf2, 0x2c, 0xf6, - 0x54, 0x71, 0xd9, 0xf0, 0xe1, 0x17, 0x07, 0xba, 0x6f, 0xa9, 0xa2, 0xba, 0x27, 0xd5, 0x8d, 0xf4, - 0x1d, 0x3c, 0x41, 0x3f, 0x92, 0x97, 0xe0, 0xf3, 0x52, 0x31, 0x51, 0xb0, 0x94, 0x53, 0xc5, 0x66, - 0x52, 0xe9, 0x5f, 0x51, 0x55, 0x4a, 0xfa, 0x9b, 0x88, 0xed, 0xb7, 0xfd, 0x4b, 0x6d, 0xc7, 0xda, - 0x25, 0x2f, 0xa0, 0xcf, 0xae, 0x79, 0xca, 0xca, 0x84, 0x61, 0xc8, 0xde, 0xe4, 0xa0, 0x1d, 0x90, - 0x1e, 0xaa, 0xe8, 0x9d, 0x05, 0xe2, 0x15, 0x1a, 0x7e, 0x76, 0x60, 0xeb, 0x1c, 0x07, 0xe4, 0x89, - 0x4e, 0x97, 0xce, 0x81, 0x1d, 0x81, 0x9d, 0x66, 0x04, 0x4c, 0x0f, 0xc6, 0xd6, 0x25, 0x23, 0xe8, - 0xea, 0x66, 0xc2, 0xbc, 0x79, 0x93, 0x61, 0x43, 0xe9, 0x0f, 0x8a, 0xd1, 0x21, 0x67, 0xe0, 0xb5, - 0x3a, 0x15, 0x87, 0xa0, 0xb5, 0x9d, 0x49, 0x4a, 0x0c, 0xeb, 0xa6, 0x0d, 0xbf, 0xe9, 0x20, 0xa8, - 0x4a, 0x72, 0x3d, 0x5d, 0x52, 0x51, 0xa1, 0xe7, 0xa1, 0x55, 0x39, 0x0f, 0xb5, 0xa9, 0x29, 0xdf, - 0x23, 0x00, 0x56, 0xa6, 0x0d, 0x60, 0xe6, 0x79, 0xc0, 0xca, 0xd4, 0xda, 0x27, 0xe0, 0xe2, 0xc0, - 0x4b, 0x9b, 0x85, 0xed, 0xe6, 0x5c, 0xfc, 0xca, 0xd8, 0x9a, 0x64, 0x0c, 0x3d, 0x13, 0x9e, 0xf4, - 0xbb, 0xc8, 0xfd, 0x1b, 0x5f, 0x63, 0x9f, 0x4f, 0x7f, 0xdc, 0x07, 0xce, 0xdd, 0x7d, 0xe0, 0xfc, - 0xbe, 0x0f, 0x9c, 0xaf, 0xcb, 0x60, 0xe3, 0x6e, 0x19, 0x6c, 0xfc, 0x5a, 0x06, 0x1b, 0x1f, 0xa2, - 0x8c, 0xab, 0x7c, 0x31, 0x8f, 0x92, 0xaa, 0xd0, 0x77, 0x1b, 0x2b, 0xf5, 0x05, 0x71, 0x73, 0xfb, - 0xa9, 0xb9, 0xef, 0xcc, 0x2d, 0x55, 0xcf, 0xed, 0x7a, 0xee, 0xe2, 0x55, 0xf5, 0xfc, 0x4f, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x04, 0xda, 0x66, 0xdf, 0x16, 0x05, 0x00, 0x00, + // 686 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x94, 0xbd, 0x6f, 0xd3, 0x4e, + 0x18, 0xc7, 0xeb, 0x26, 0x75, 0x92, 0xc7, 0xe9, 0xcb, 0xef, 0xf4, 0x53, 0xe5, 0xb6, 0xc2, 0xa4, + 0x96, 0x0a, 0x29, 0x83, 0x2b, 0x82, 0x90, 0x98, 0x90, 0x28, 0x20, 0xa5, 0xab, 0x2b, 0x31, 0xb0, + 0x44, 0x17, 0xfb, 0x14, 0x9f, 0xa8, 0x5f, 0xb8, 0xbb, 0x54, 0x2d, 0x23, 0x1b, 0x1b, 0x33, 0x1b, + 0xff, 0x0d, 0x63, 0x47, 0x46, 0xd4, 0xfc, 0x23, 0xe8, 0x9e, 0x3b, 0xc7, 0x06, 0x96, 0xc4, 0xf7, + 0xfd, 0x7e, 0x7c, 0x7e, 0xee, 0x79, 0x39, 0x38, 0x50, 0xb7, 0x15, 0x93, 0x67, 0xe9, 0x6d, 0xce, + 0x0b, 0x65, 0xff, 0xa2, 0x4a, 0x94, 0xaa, 0x24, 0xae, 0x59, 0x1d, 0x1e, 0x1b, 0x44, 0xb1, 0x22, + 0x65, 0x02, 0x31, 0x3a, 0x4f, 0xf8, 0x19, 0xaa, 0x06, 0x3d, 0x0c, 0xff, 0x41, 0xac, 0xd0, 0x30, + 0xe1, 0x53, 0xe8, 0xbd, 0x63, 0x42, 0xf2, 0xb2, 0x20, 0xff, 0xc3, 0xd6, 0xfc, 0xaa, 0x4c, 0x3e, + 0xf8, 0xce, 0xc8, 0x19, 0x77, 0x63, 0xb3, 0x20, 0x7b, 0xd0, 0xa1, 0x55, 0xe5, 0x6f, 0xa2, 0xa6, + 0x1f, 0xc3, 0xbb, 0x0e, 0xb8, 0x53, 0x46, 0x53, 0x26, 0xc8, 0x29, 0xf4, 0xae, 0xcd, 0xdb, 0xf8, + 0x92, 0x37, 0xd9, 0x8d, 0x6c, 0xb0, 0x76, 0xd3, 0xb8, 0xf6, 0xc9, 0x31, 0x0c, 0x0b, 0x9a, 0x33, + 0x59, 0xd1, 0x84, 0xcd, 0x78, 0x8a, 0x1b, 0x0e, 0x63, 0x6f, 0xad, 0x5d, 0xa4, 0x64, 0x1f, 0xdc, + 0x8c, 0xf1, 0x45, 0xa6, 0xfc, 0x0e, 0x7e, 0xcd, 0xae, 0x08, 0x81, 0xae, 0xe2, 0x39, 0xf3, 0xbb, + 0xa8, 0xe2, 0x33, 0x19, 0xc3, 0xde, 0x15, 0x95, 0x6a, 0x96, 0x61, 0x20, 0xb3, 0x8c, 0xca, 0xcc, + 0xdf, 0xc2, 0x2d, 0x77, 0xb4, 0x6e, 0xe2, 0x9b, 0x52, 0x99, 0xad, 0xc9, 0xa4, 0xcc, 0x73, 0xae, + 0x0c, 0xe9, 0x36, 0xe4, 0x6b, 0x94, 0x91, 0x3c, 0x82, 0x41, 0x4a, 0x15, 0x35, 0x48, 0x0f, 0x91, + 0xbe, 0x16, 0xd0, 0x3c, 0x81, 0x9d, 0xa4, 0x2c, 0x24, 0x2b, 0xe4, 0x52, 0x1a, 0xa2, 0x8f, 0xc4, + 0xf6, 0x5a, 0x45, 0xec, 0x00, 0xfa, 0xb4, 0xaa, 0x0c, 0x30, 0x40, 0xa0, 0x47, 0xab, 0x0a, 0xad, + 0x27, 0xf0, 0x1f, 0x06, 0x22, 0x98, 0x5c, 0x5e, 0x29, 0xbb, 0x09, 0x20, 0xb3, 0xab, 0x8d, 0xd8, + 0xe8, 0xc8, 0x9e, 0xc2, 0x5e, 0x25, 0xca, 0xaa, 0x94, 0x4c, 0xcc, 0x68, 0x9a, 0x0a, 0x26, 0xa5, + 0xef, 0x19, 0xb4, 0xd6, 0x5f, 0x19, 0x99, 0x3c, 0x86, 0x5d, 0xc9, 0x3e, 0x2e, 0x59, 0x91, 0x30, + 0x61, 0x37, 0x1d, 0x9a, 0xe3, 0x35, 0x72, 0x1d, 0x5a, 0x92, 0x51, 0x5e, 0xe8, 0xec, 0x6f, 0x8f, + 0x9c, 0xf1, 0x20, 0xee, 0xe1, 0xfa, 0x22, 0x0d, 0xbf, 0x3b, 0xe0, 0x9a, 0x44, 0xb4, 0x8a, 0xe0, + 0xfc, 0x51, 0x84, 0x87, 0xe0, 0xb5, 0x73, 0x6d, 0xca, 0x07, 0x59, 0x93, 0xe7, 0x00, 0x40, 0xf2, + 0x45, 0x41, 0xd5, 0x52, 0x30, 0xe9, 0x77, 0x46, 0x1d, 0xed, 0x37, 0x0a, 0x79, 0x09, 0x43, 0x95, + 0xcf, 0xd6, 0x02, 0x56, 0xd3, 0x9b, 0x1c, 0x45, 0x4d, 0x7b, 0x46, 0xa6, 0x31, 0x4d, 0x20, 0x97, + 0x7c, 0x11, 0x7b, 0x2a, 0xbf, 0xac, 0xf9, 0xf0, 0x8b, 0x03, 0xdd, 0x37, 0x54, 0x51, 0xdd, 0x91, + 0xea, 0x46, 0xfa, 0x0e, 0x7e, 0x41, 0x3f, 0x92, 0x17, 0xe0, 0xf3, 0x42, 0x31, 0x91, 0xb3, 0x94, + 0x53, 0xc5, 0x66, 0x52, 0xe9, 0x5f, 0x51, 0x96, 0x4a, 0xfa, 0x9b, 0x88, 0xed, 0xb7, 0xfd, 0x4b, + 0x6d, 0xc7, 0xda, 0x25, 0xcf, 0xa1, 0xcf, 0xae, 0x79, 0xaa, 0xb3, 0x84, 0x21, 0x7b, 0x93, 0x83, + 0x76, 0x40, 0x7a, 0xa4, 0xa2, 0xb7, 0x16, 0x88, 0xd7, 0x68, 0xf8, 0xd9, 0x81, 0xad, 0x73, 0x1c, + 0x8f, 0x47, 0x3a, 0x5d, 0x3a, 0x07, 0x76, 0x00, 0x76, 0xea, 0x01, 0x30, 0x1d, 0x18, 0x5b, 0x97, + 0x8c, 0xa0, 0xab, 0x5b, 0x09, 0xf3, 0xe6, 0x4d, 0x86, 0x35, 0xa5, 0x0f, 0x14, 0xa3, 0x43, 0xce, + 0xc0, 0x6b, 0xf5, 0x29, 0x8e, 0x40, 0x6b, 0x3b, 0x93, 0x94, 0x18, 0x9a, 0x96, 0x0d, 0xbf, 0xe9, + 0x20, 0xa8, 0x4a, 0x32, 0x3d, 0x5b, 0x52, 0x51, 0xa1, 0xa7, 0xa1, 0x55, 0x39, 0x0f, 0xb5, 0xa9, + 0x29, 0xdf, 0x03, 0x00, 0x56, 0xa4, 0x35, 0x60, 0xa6, 0x79, 0xc0, 0x8a, 0xd4, 0xda, 0x27, 0xe0, + 0xe2, 0xb8, 0x4b, 0x9b, 0x85, 0xed, 0xfa, 0xbb, 0x78, 0xca, 0xd8, 0x9a, 0x64, 0x0c, 0x3d, 0x13, + 0x9e, 0xf4, 0xbb, 0xc8, 0xfd, 0x1d, 0x5f, 0x6d, 0x9f, 0x4f, 0x7f, 0xdc, 0x07, 0xce, 0xdd, 0x7d, + 0xe0, 0xfc, 0xba, 0x0f, 0x9c, 0xaf, 0xab, 0x60, 0xe3, 0x6e, 0x15, 0x6c, 0xfc, 0x5c, 0x05, 0x1b, + 0xef, 0xa3, 0x05, 0x57, 0xd9, 0x72, 0x1e, 0x25, 0x65, 0xae, 0x6f, 0x36, 0x56, 0xe8, 0xeb, 0xe1, + 0xe6, 0xf6, 0x53, 0x7d, 0xdb, 0x99, 0x3b, 0xaa, 0x9a, 0xdb, 0xf5, 0xdc, 0xc5, 0x8b, 0xea, 0xd9, + 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0d, 0x81, 0x13, 0x49, 0x14, 0x05, 0x00, 0x00, } func (m *Version) Marshal() (dAtA []byte, err error) { @@ -614,10 +614,10 @@ func (m *Header) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x6a } - if len(m.AggregatorsHash) > 0 { - i -= len(m.AggregatorsHash) - copy(dAtA[i:], m.AggregatorsHash) - i = encodeVarintDymint(dAtA, i, uint64(len(m.AggregatorsHash))) + if len(m.SequencersHash) > 0 { + i -= len(m.SequencersHash) + copy(dAtA[i:], m.SequencersHash) + i = encodeVarintDymint(dAtA, i, uint64(len(m.SequencersHash))) i-- dAtA[i] = 0x62 } @@ -1007,7 +1007,7 @@ func (m *Header) Size() (n int) { if l > 0 { n += 1 + l + sovDymint(uint64(l)) } - l = len(m.AggregatorsHash) + l = len(m.SequencersHash) if l > 0 { n += 1 + l + sovDymint(uint64(l)) } @@ -1590,7 +1590,7 @@ func (m *Header) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 12: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AggregatorsHash", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SequencersHash", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -1617,9 +1617,9 @@ func (m *Header) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.AggregatorsHash = append(m.AggregatorsHash[:0], dAtA[iNdEx:postIndex]...) - if m.AggregatorsHash == nil { - m.AggregatorsHash = []byte{} + m.SequencersHash = append(m.SequencersHash[:0], dAtA[iNdEx:postIndex]...) + if m.SequencersHash == nil { + m.SequencersHash = []byte{} } iNdEx = postIndex case 13: diff --git a/types/serialization.go b/types/serialization.go index 814dd3ea5..0892c946b 100644 --- a/types/serialization.go +++ b/types/serialization.go @@ -97,7 +97,7 @@ func (h *Header) ToProto() *pb.Header { AppHash: h.AppHash[:], LastResultsHash: h.LastResultsHash[:], ProposerAddress: h.ProposerAddress[:], - AggregatorsHash: h.AggregatorsHash[:], + SequencersHash: h.SequencersHash[:], } } @@ -129,8 +129,8 @@ func (h *Header) FromProto(other *pb.Header) error { if !safeCopy(h.LastResultsHash[:], other.LastResultsHash) { return errors.New("invalid length of 'LastResultsHash'") } - if !safeCopy(h.AggregatorsHash[:], other.AggregatorsHash) { - return errors.New("invalid length of 'AggregatorsHash'") + if !safeCopy(h.SequencersHash[:], other.SequencersHash) { + return errors.New("invalid length of 'SequencersHash'") } if len(other.ProposerAddress) > 0 { h.ProposerAddress = make([]byte, len(other.ProposerAddress)) @@ -251,22 +251,14 @@ func (s *State) ToProto() (*pb.State, error) { if err != nil { return nil, err } - lastValidators, err := s.LastValidators.ToProto() - if err != nil { - return nil, err - } return &pb.State{ Version: &s.Version, ChainId: s.ChainID, - InitialHeight: s.InitialHeight, - LastBlockHeight: s.LastBlockHeight, - LastBlockID: s.LastBlockID.ToProto(), - LastBlockTime: s.LastBlockTime, + InitialHeight: int64(s.InitialHeight), + LastBlockHeight: int64(s.LastBlockHeight.Load()), NextValidators: nextValidators, Validators: validators, - LastValidators: lastValidators, - LastStoreHeight: s.LastStoreHeight, BaseHeight: s.BaseHeight, LastHeightValidatorsChanged: s.LastHeightValidatorsChanged, ConsensusParams: s.ConsensusParams, @@ -281,22 +273,10 @@ func (s *State) FromProto(other *pb.State) error { var err error s.Version = *other.Version s.ChainID = other.ChainId - s.InitialHeight = other.InitialHeight - s.LastBlockHeight = other.LastBlockHeight - // TODO(omritoptix): remove this as this is only for backwards compatibility - // with old state files that don't have this field. - if other.LastStoreHeight == 0 && other.LastBlockHeight > 1 { - s.LastStoreHeight = uint64(other.LastBlockHeight) - } else { - s.LastStoreHeight = other.LastStoreHeight - } + s.InitialHeight = uint64(other.InitialHeight) + s.LastBlockHeight.Store(uint64(other.LastBlockHeight)) s.BaseHeight = other.BaseHeight - lastBlockID, err := types.BlockIDFromProto(&other.LastBlockID) - if err != nil { - return err - } - s.LastBlockID = *lastBlockID - s.LastBlockTime = other.LastBlockTime + s.NextValidators, err = types.ValidatorSetFromProto(other.NextValidators) if err != nil { return err @@ -305,10 +285,6 @@ func (s *State) FromProto(other *pb.State) error { if err != nil { return err } - s.LastValidators, err = types.ValidatorSetFromProto(other.LastValidators) - if err != nil { - return err - } s.LastHeightValidatorsChanged = other.LastHeightValidatorsChanged s.ConsensusParams = other.ConsensusParams s.LastHeightConsensusParamsChanged = other.LastHeightConsensusParamsChanged diff --git a/types/serialization_test.go b/types/serialization_test.go index 3fff1b0ba..355aaa95c 100644 --- a/types/serialization_test.go +++ b/types/serialization_test.go @@ -3,7 +3,6 @@ package types_test import ( "crypto/rand" "testing" - "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -54,7 +53,7 @@ func TestBlockSerializationRoundTrip(t *testing.T) { AppHash: h[4], LastResultsHash: h[5], ProposerAddress: []byte{4, 3, 2, 1}, - AggregatorsHash: h[6], + SequencersHash: h[6], }, Data: types.Data{ Txs: nil, @@ -98,7 +97,6 @@ func TestStateRoundTrip(t *testing.T) { { "with max bytes", types.State{ - LastValidators: valSet, Validators: valSet, NextValidators: valSet, ConsensusParams: tmproto.ConsensusParams{ @@ -120,21 +118,10 @@ func TestStateRoundTrip(t *testing.T) { }, Software: "dymint", }, - ChainID: "testchain", - InitialHeight: 987, - LastBlockHeight: 987654321, - LastStoreHeight: 987654321, - LastBlockID: tmtypes.BlockID{ - Hash: nil, - PartSetHeader: tmtypes.PartSetHeader{ - Total: 0, - Hash: nil, - }, - }, - LastBlockTime: time.Date(2022, 6, 6, 12, 12, 33, 44, time.UTC), + ChainID: "testchain", + InitialHeight: 987, NextValidators: valSet, Validators: valSet, - LastValidators: valSet, LastHeightValidatorsChanged: 8272, ConsensusParams: tmproto.ConsensusParams{ Block: tmproto.BlockParams{ @@ -165,6 +152,11 @@ func TestStateRoundTrip(t *testing.T) { t.Run(c.name, func(t *testing.T) { require := require.New(t) assert := assert.New(t) + + if c.state.InitialHeight != 0 { + c.state.LastBlockHeight.Store(986321) + } + pState, err := c.state.ToProto() require.NoError(err) require.NotNil(pState) diff --git a/types/state.go b/types/state.go index 4715bf034..8e7afc2d0 100644 --- a/types/state.go +++ b/types/state.go @@ -2,7 +2,7 @@ package types import ( "fmt" - "time" + "sync/atomic" // TODO(tzdybal): copy to local project? tmstate "github.com/tendermint/tendermint/proto/tendermint/state" @@ -12,35 +12,22 @@ import ( "github.com/tendermint/tendermint/version" ) -// InitStateVersion sets the Consensus.Block and Software versions, -// but leaves the Consensus.App version blank. -// The Consensus.App version will be set during the Handshake, once -// we hear from the app what protocol version it is running. -var InitStateVersion = tmstate.Version{ - Consensus: tmversion.Consensus{ - Block: version.BlockProtocol, - App: 0, - }, - Software: version.TMCoreSemVer, -} - // State contains information about current state of the blockchain. type State struct { Version tmstate.Version // immutable ChainID string - InitialHeight int64 // should be 1, not 0, when starting from height 1 + InitialHeight uint64 // should be 1, not 0, when starting from height 1 // LastBlockHeight=0 at genesis (ie. block(H=0) does not exist) - LastBlockHeight int64 - LastBlockID types.BlockID - LastBlockTime time.Time + LastBlockHeight atomic.Uint64 + + // BaseHeight is the height of the first block we have in store after pruning. + BaseHeight uint64 - // In the MVP implementation, there will be only one Validator NextValidators *types.ValidatorSet Validators *types.ValidatorSet - LastValidators *types.ValidatorSet LastHeightValidatorsChanged int64 // Consensus parameters used for validating blocks. @@ -51,51 +38,68 @@ type State struct { // Merkle root of the results from executing prev block LastResultsHash [32]byte - // LastStore height is the last height we've saved to the store. - LastStoreHeight uint64 - - // BaseHeight is the height of the first block we have in store after pruning. - BaseHeight uint64 - // the latest AppHash we've received from calling abci.Commit() AppHash [32]byte } -// NewFromGenesisDoc reads blockchain State from genesis. -func NewFromGenesisDoc(genDoc *types.GenesisDoc) (State, error) { +// NewStateFromGenesis reads blockchain State from genesis. +func NewStateFromGenesis(genDoc *types.GenesisDoc) (*State, error) { err := genDoc.ValidateAndComplete() if err != nil { - return State{}, fmt.Errorf("in genesis doc: %w", err) + return nil, fmt.Errorf("in genesis doc: %w", err) } - var validatorSet, nextValidatorSet *types.ValidatorSet - validatorSet = types.NewValidatorSet(nil) - nextValidatorSet = types.NewValidatorSet(nil) + // InitStateVersion sets the Consensus.Block and Software versions, + // but leaves the Consensus.App version blank. + // The Consensus.App version will be set during the Handshake, once + // we hear from the app what protocol version it is running. + InitStateVersion := tmstate.Version{ + Consensus: tmversion.Consensus{ + Block: version.BlockProtocol, + App: 0, + }, + Software: version.TMCoreSemVer, + } s := State{ Version: InitStateVersion, ChainID: genDoc.ChainID, - InitialHeight: genDoc.InitialHeight, + InitialHeight: uint64(genDoc.InitialHeight), - LastBlockHeight: 0, - LastBlockID: types.BlockID{}, - LastBlockTime: genDoc.GenesisTime, + BaseHeight: uint64(genDoc.InitialHeight), - NextValidators: nextValidatorSet, - Validators: validatorSet, - LastValidators: types.NewValidatorSet(nil), + NextValidators: types.NewValidatorSet(nil), + Validators: types.NewValidatorSet(nil), LastHeightValidatorsChanged: genDoc.InitialHeight, ConsensusParams: *genDoc.ConsensusParams, LastHeightConsensusParamsChanged: genDoc.InitialHeight, - - BaseHeight: 0, } + s.LastBlockHeight.Store(0) copy(s.AppHash[:], genDoc.AppHash) - return s, nil + return &s, nil } func (s *State) IsGenesis() bool { - return s.LastBlockHeight == 0 + return s.Height() == 0 +} + +// SetHeight sets the height saved in the Store if it is higher than the existing height +// returns OK if the value was updated successfully or did not need to be updated +func (s *State) SetHeight(height uint64) { + s.LastBlockHeight.Store(height) +} + +// Height returns height of the highest block saved in the Store. +func (s *State) Height() uint64 { + return s.LastBlockHeight.Load() +} + +// NextHeight returns the next height that expected to be stored in store. +func (s *State) NextHeight() uint64 { + if s.IsGenesis() { + return s.InitialHeight + } + return s.Height() + 1 } diff --git a/types/validation.go b/types/validation.go index 9533d7e7b..8e84f68e1 100644 --- a/types/validation.go +++ b/types/validation.go @@ -8,7 +8,7 @@ import ( tmtypes "github.com/tendermint/tendermint/types" ) -func ValidateProposedTransition(state State, block *Block, commit *Commit, proposer *Sequencer) error { +func ValidateProposedTransition(state *State, block *Block, commit *Commit, proposer *Sequencer) error { if err := block.ValidateWithState(state); err != nil { return fmt.Errorf("block: %w", err) } @@ -39,7 +39,7 @@ func (b *Block) ValidateBasic() error { return nil } -func (b *Block) ValidateWithState(state State) error { +func (b *Block) ValidateWithState(state *State) error { err := b.ValidateBasic() if err != nil { return err @@ -48,12 +48,11 @@ func (b *Block) ValidateWithState(state State) error { b.Header.Version.Block != state.Version.Consensus.Block { return errors.New("b version mismatch") } - if state.LastBlockHeight <= 0 && b.Header.Height != uint64(state.InitialHeight) { - return errors.New("initial b height mismatch") - } - if state.LastBlockHeight > 0 && b.Header.Height != uint64(state.LastStoreHeight)+1 { - return errors.New("b height mismatch") + + if b.Header.Height != state.NextHeight() { + return errors.New("height mismatch") } + if !bytes.Equal(b.Header.AppHash[:], state.AppHash[:]) { return errors.New("AppHash mismatch") } diff --git a/utils/event/funcs.go b/utils/event/funcs.go index 85a8be224..0bfe9c965 100644 --- a/utils/event/funcs.go +++ b/utils/event/funcs.go @@ -34,7 +34,7 @@ func MustSubscribe( case event := <-subscription.Out(): callback(event) case <-subscription.Cancelled(): - logger.Info(clientID + " subscription canceled") + logger.Error("subscription cancelled", "clientID", clientID) return } }