-
Notifications
You must be signed in to change notification settings - Fork 4.1k
feat: Upstream BlockSTM Fork #25483
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
feat: Upstream BlockSTM Fork #25483
Changes from all commits
Commits
Show all changes
65 commits
Select commit
Hold shift + click to select a range
cc6c67b
Support object store (#206)
17043e4
cleanup
mmsqe 78e3a48
Merge remote-tracking branch 'origin/release/v0.53.x' into release/v0…
mmsqe f44f06b
fix test
mmsqe e1ee61f
lint
mmsqe b75bb98
Merge remote-tracking branch 'origin/main' into release/v0.53.x_obj_s…
mmsqe e64ccc0
resolve
mmsqe d2c1c3b
fix test
mmsqe 8892029
fix test
mmsqe 83f4859
Problem: store key type assertion is incorrect (#244)
mmsqe d97d3d1
Merge remote-tracking branch 'origin/main' into release/v0.53.x_obj_s…
mmsqe 3c03b87
Merge remote-tracking branch 'origin/main' into release/v0.53.x_obj_s…
mmsqe a06944f
Merge remote-tracking branch 'origin/main' into release/v0.53.x_obj_s…
mmsqe f2fcf30
fix clientv2
mmsqe e328edf
init
technicallyty 58b6c43
Merge remote-tracking branch 'origin' into technicallyty/object-stores
Eric-Warehime a8655d6
Fix gofumpt
Eric-Warehime 78e339e
Add codecov
Eric-Warehime 6dd547c
Remove flags from codecov upload
Eric-Warehime c19b17b
Fix e2e, integration paths
Eric-Warehime 47eac84
Merge remote-tracking branch 'origin' into technicallyty/object-stores
Eric-Warehime 6e24572
Tidy client v2
Eric-Warehime d285145
Add validity test
Eric-Warehime 12a2cc8
Add length validity test
Eric-Warehime 613a3fa
Add baseapp stores test
Eric-Warehime ba1607b
Update codecov to ignore mock dirs
Eric-Warehime 9baec7f
Add rootmulti obj store getter test
Eric-Warehime 1a3f99e
Add prefix objstore test
Eric-Warehime 3cfcbab
Add domain to prefix iter test
Eric-Warehime a1f2db1
Add general prefix obj store tests
Eric-Warehime f90ccd5
Merge remote-tracking branch 'origin' into technicallyty/object-stores
Eric-Warehime 98df6d1
Fix test
Eric-Warehime 269226d
Fix hashing
Eric-Warehime e955c32
Upload all test coverage data
Eric-Warehime 2850c8f
Extend baseapp testing
Eric-Warehime 52a92b1
Add context test
Eric-Warehime f1969b5
Fix lint
Eric-Warehime b37ab1f
Test store types
Eric-Warehime 3859325
Update changelog entry
Eric-Warehime 96dff47
Use var for zeroValue
Eric-Warehime bdb5e3d
Cleanup
Eric-Warehime f39718f
Merge branch 'main' into technicallyty/object-stores
Eric-Warehime 905e1e4
Go mod tidy
Eric-Warehime a450cff
Port blockstm
Eric-Warehime a4c8d30
Add constructor changes
Eric-Warehime 9eeae04
Merge branch 'technicallyty/object-stores' into eric/bstm-upstream
Eric-Warehime 4ddb03a
Lint fix
Eric-Warehime f60a9a0
Go mod tidy
Eric-Warehime b2e29dd
Add blockstm coverage
Eric-Warehime bdd5a60
Add txnrunner test
Eric-Warehime a82c725
Go mod tidy all
Eric-Warehime e0dc364
Remove blockstm separate package, use common store types
Eric-Warehime fad7177
Add comments for type assertion in trace store branching
Eric-Warehime c47a40a
Merge branch 'technicallyty/object-stores' into eric/bstm-upstream
Eric-Warehime 604402a
Merge branch 'main' into technicallyty/object-stores
Eric-Warehime 40059a8
Merge branch 'technicallyty/object-stores' into eric/bstm-upstream
Eric-Warehime 3438141
PR comments
Eric-Warehime 3c81c6c
Fix lint
Eric-Warehime f0bfe48
Refactor
Eric-Warehime fe98b78
Change executor to use errgroup
Eric-Warehime 47d2388
Add comments
Eric-Warehime ed74d82
Fix lints
Eric-Warehime 8565005
Merge remote-tracking branch 'origin' into eric/bstm-upstream
Eric-Warehime e694322
Fix race condition
Eric-Warehime 55cb76b
Add coverage data back for new package
Eric-Warehime File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -234,6 +234,11 @@ jobs: | |
| with: | ||
| name: "${{ github.sha }}-store-coverage" | ||
| continue-on-error: true | ||
| - uses: actions/download-artifact@v4 | ||
| if: env.GIT_DIFF | ||
| with: | ||
| name: "${{ github.sha }}-blockstm-coverage" | ||
| continue-on-error: true | ||
| - uses: actions/download-artifact@v4 | ||
| if: env.GIT_DIFF | ||
| with: | ||
|
|
@@ -253,7 +258,7 @@ jobs: | |
| if: env.GIT_DIFF | ||
| uses: codecov/codecov-action@v5 | ||
| with: | ||
| files: ./00profile.out,./01profile.out,./02profile.out,./03profile.out,./integration-profile.out,./e2e-profile.out,./client/v2/coverage.out,./core/coverage.out,./depinject/coverage.out,./errors/coverage.out,./math/coverage.out,./schema/coverage.out,./collections/coverage.out,./tools/cosmovisor/coverage.out,./tools/confix/coverage.out,./store/coverage.out,./log/coverage.out,./x/tx/coverage.out,./tools/benchmark/coverage.out | ||
| files: ./00profile.out,./01profile.out,./02profile.out,./03profile.out,./integration-profile.out,./e2e-profile.out,./client/v2/coverage.out,./core/coverage.out,./depinject/coverage.out,./errors/coverage.out,./math/coverage.out,./schema/coverage.out,./collections/coverage.out,./tools/cosmovisor/coverage.out,./tools/confix/coverage.out,./store/coverage.out,./log/coverage.out,./x/tx/coverage.out,./tools/benchmark/coverage.out,./blockstm/coverage.out | ||
| fail_ci_if_error: false | ||
| verbose: true | ||
| token: ${{ secrets.CODECOV_TOKEN }} | ||
|
|
@@ -570,6 +575,33 @@ jobs: | |
| with: | ||
| name: "${{ github.sha }}-store-coverage" | ||
| path: ./store/coverage.out | ||
| test-blockstm: | ||
| runs-on: depot-ubuntu-22.04-4 | ||
| steps: | ||
| - uses: actions/checkout@v5 | ||
| - uses: actions/setup-go@v6 | ||
| with: | ||
| go-version: "1.25" | ||
| check-latest: true | ||
| cache: true | ||
| cache-dependency-path: store/go.sum | ||
| - uses: technote-space/[email protected] | ||
| id: git_diff | ||
| with: | ||
| PATTERNS: | | ||
| blockstm/**/*.go | ||
| blockstm/go.mod | ||
| blockstm/go.sum | ||
| - name: tests | ||
| if: env.GIT_DIFF | ||
| run: | | ||
| cd blockstm | ||
| go test -mod=readonly -timeout 30m -coverprofile=coverage.out -covermode=atomic -coverpkg=./,./tree -tags='norace ledger test_ledger_mock' ./... | ||
| - uses: actions/upload-artifact@v4 | ||
| if: env.GIT_DIFF | ||
| with: | ||
| name: "${{ github.sha }}-blockstm-coverage" | ||
| path: ./blockstm/coverage.out | ||
|
|
||
| test-log: | ||
| runs-on: depot-ubuntu-22.04-4 | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| `blockstm` implements the [block-stm algorithm](https://arxiv.org/abs/2203.06871), it follows the paper pseudocode pretty closely. | ||
|
|
||
| The main API is a simple function call `ExecuteBlock`: | ||
|
|
||
| ```golang | ||
| type ExecuteFn func(TxnIndex, MultiStore) | ||
| func ExecuteBlock( | ||
| ctx context.Context, // context for cancellation | ||
| blockSize int, // the number of the transactions to be executed | ||
| stores []storetypes.StoreKey, // the list of store keys to support | ||
| storage MultiStore, // the parent storage, after all transactions are executed, the whole change sets are written into parent storage at once | ||
| executors int, // how many concurrent executors to spawn | ||
| executeFn ExecuteFn, // callback function to actually execute a transaction with a wrapped `MultiStore`. | ||
| ) error | ||
| ``` | ||
|
|
||
| The main deviations from the paper are: | ||
|
|
||
| ### Optimisation | ||
|
|
||
| We applied the optimization described in section 4 of the paper: | ||
|
|
||
| ``` | ||
| Block-STM calls add_dependency from the VM itself, and can thus re-read and continue execution when false is returned. | ||
| ``` | ||
|
|
||
| When the VM execution reads an `ESTIMATE` mark, it'll hang on a `CondVar`, so it can resume execution after the dependency is resolved, | ||
| much more efficient than abortion and rerun. | ||
|
|
||
| ### Support Deletion, Iteration, and MultiStore | ||
|
|
||
| These features are necessary for integration with cosmos-sdk. | ||
|
|
||
| The multi-version data structure is implemented with nested btree for easier iteration support, | ||
| the `WriteSet` is also implemented with a btree, and it takes advantage of ordered property to optimize some logic. | ||
|
|
||
| The internal data structures are also adapted with multiple stores in mind. | ||
|
|
||
| ### Attribution | ||
|
|
||
| This package was originally authored in [go-block-stm](https://github.com/crypto-org-chain/go-block-stm). We have brought the full source tree into the SDK so that we can natively incorporate the library and required changes into the SDK. Over time we expect to incoporate optimizations and deviations from the upstream implementation. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| package blockstm | ||
|
|
||
| import ( | ||
| "context" | ||
| "strconv" | ||
| "testing" | ||
|
|
||
| "github.com/test-go/testify/require" | ||
|
|
||
| storetypes "cosmossdk.io/store/types" | ||
| ) | ||
|
|
||
| func BenchmarkBlockSTM(b *testing.B) { | ||
| stores := map[storetypes.StoreKey]int{StoreKeyAuth: 0, StoreKeyBank: 1} | ||
| for i := 0; i < 26; i++ { | ||
| key := storetypes.NewKVStoreKey(strconv.FormatInt(int64(i), 10)) | ||
| stores[key] = i + 2 | ||
| } | ||
| storage := NewMultiMemDB(stores) | ||
| testCases := []struct { | ||
| name string | ||
| block *MockBlock | ||
| }{ | ||
| {"random-10000/100", testBlock(10000, 100)}, | ||
| {"no-conflict-10000", noConflictBlock(10000)}, | ||
| {"worst-case-10000", worstCaseBlock(10000)}, | ||
| {"iterate-10000/100", iterateBlock(10000, 100)}, | ||
| } | ||
| for _, tc := range testCases { | ||
| b.Run(tc.name+"-sequential", func(b *testing.B) { | ||
| b.ResetTimer() | ||
| for i := 0; i < b.N; i++ { | ||
| runSequential(storage, tc.block) | ||
| } | ||
| }) | ||
| for _, worker := range []int{1, 5, 10, 15, 20} { | ||
| b.Run(tc.name+"-worker-"+strconv.Itoa(worker), func(b *testing.B) { | ||
| b.ResetTimer() | ||
| for i := 0; i < b.N; i++ { | ||
| require.NoError( | ||
| b, | ||
| ExecuteBlock(context.Background(), tc.block.Size(), stores, storage, worker, tc.block.ExecuteTx), | ||
| ) | ||
| } | ||
| }) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| func runSequential(storage MultiStore, block *MockBlock) { | ||
| for i, tx := range block.Txs { | ||
| block.Results[i] = tx(storage) | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| package blockstm | ||
|
|
||
| import "sync" | ||
|
|
||
| type Condvar struct { | ||
| sync.Mutex | ||
| notified bool | ||
| cond sync.Cond | ||
| } | ||
|
|
||
| func NewCondvar() *Condvar { | ||
| c := &Condvar{} | ||
| c.cond = *sync.NewCond(c) | ||
| return c | ||
| } | ||
|
|
||
| func (cv *Condvar) Wait() { | ||
| cv.Lock() | ||
| for !cv.notified { | ||
| cv.cond.Wait() | ||
| } | ||
| cv.Unlock() | ||
| } | ||
|
|
||
| func (cv *Condvar) Notify() { | ||
| cv.Lock() | ||
| cv.notified = true | ||
| cv.Unlock() | ||
swift1337 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| cv.cond.Signal() | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| package blockstm | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
| ) | ||
|
|
||
| // Executor fields are not mutated during execution. | ||
| type Executor struct { | ||
| ctx context.Context // context for cancellation | ||
| scheduler *Scheduler // scheduler for task management | ||
| txExecutor TxExecutor // callback to actually execute a transaction | ||
| mvMemory *MVMemory // multi-version memory for the executor | ||
|
|
||
| // index of the executor, used for debugging output | ||
| i int | ||
| } | ||
|
|
||
| func NewExecutor( | ||
| ctx context.Context, | ||
| scheduler *Scheduler, | ||
| txExecutor TxExecutor, | ||
| mvMemory *MVMemory, | ||
| i int, | ||
| ) *Executor { | ||
| return &Executor{ | ||
| ctx: ctx, | ||
| scheduler: scheduler, | ||
| txExecutor: txExecutor, | ||
| mvMemory: mvMemory, | ||
| i: i, | ||
| } | ||
| } | ||
|
|
||
| // Run executes all tasks until completion | ||
| // Invariant `num_active_tasks`: | ||
| // - `NextTask` increases it if returns a valid task. | ||
| // - `TryExecute` and `NeedsReexecution` don't change it if it returns a new valid task to run, | ||
| // otherwise it decreases it. | ||
| func (e *Executor) Run() error { | ||
| var kind TaskKind | ||
| version := InvalidTxnVersion | ||
| for !e.scheduler.Done() { | ||
| if !version.Valid() { | ||
| // check for cancellation | ||
| select { | ||
| case <-e.ctx.Done(): | ||
| return nil | ||
| default: | ||
| } | ||
|
|
||
| version, kind = e.scheduler.NextTask() | ||
| continue | ||
| } | ||
|
|
||
| switch kind { | ||
| case TaskKindExecution: | ||
| version, kind = e.TryExecute(version) | ||
| case TaskKindValidation: | ||
swift1337 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| version, kind = e.NeedsReexecution(version) | ||
| default: | ||
| return fmt.Errorf("unknown task kind %v", kind) | ||
| } | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| func (e *Executor) TryExecute(version TxnVersion) (TxnVersion, TaskKind) { | ||
| e.scheduler.executedTxns.Add(1) | ||
| view := e.execute(version.Index) | ||
| wroteNewLocation := e.mvMemory.Record(version, view) | ||
| return e.scheduler.FinishExecution(version, wroteNewLocation) | ||
| } | ||
|
|
||
| func (e *Executor) NeedsReexecution(version TxnVersion) (TxnVersion, TaskKind) { | ||
| e.scheduler.validatedTxns.Add(1) | ||
| valid := e.mvMemory.ValidateReadSet(version.Index) | ||
| aborted := !valid && e.scheduler.TryValidationAbort(version) | ||
| if aborted { | ||
| e.mvMemory.ConvertWritesToEstimates(version.Index) | ||
| } | ||
| return e.scheduler.FinishValidation(version.Index, aborted) | ||
| } | ||
|
|
||
| func (e *Executor) execute(txn TxnIndex) *MultiMVMemoryView { | ||
| view := e.mvMemory.View(txn) | ||
| e.txExecutor(txn, view) | ||
| return view | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.