Skip to content
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

Compute root validation #1465

Closed
wants to merge 11 commits into from
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@
"integration-tests/contract-v0.10/Cargo.toml",
"cosmwasm/contracts/v1/compute-tests/random-test/Cargo.toml",
"go-cosmwasm/Cargo.toml",
"integration-tests/contract-v0.10/Cargo.toml",
"check-hw/Cargo.toml",
"./cosmwasm/enclaves/shared/block-verifier/Cargo.toml",
"cosmwasm/enclaves/shared/cosmos-proto/Cargo.toml",
"cosmwasm/enclaves/shared/contract-engine/Cargo.toml",
"cosmwasm/enclaves/shared/utils/Cargo.toml",
"cosmwasm/enclaves/shared/block-verifier/Cargo.toml"
],
"rust-analyzer.diagnostics.experimental.enable": true,
"rust-analyzer.rustfmt.rangeFormatting.enable": true,
Expand Down
68 changes: 68 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package app

import (
"encoding/binary"
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"sort"

packetforwardtypes "github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v4/router/types"
ibcfeetypes "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types"
gocosmwasm "github.com/scrtlabs/SecretNetwork/go-cosmwasm/api"
ibcswitchtypes "github.com/scrtlabs/SecretNetwork/x/emergencybutton/types"

"github.com/cosmos/cosmos-sdk/baseapp"
Expand All @@ -22,7 +25,9 @@ import (
"github.com/cosmos/cosmos-sdk/server/config"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/store/rootmulti"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/kv"
"github.com/cosmos/cosmos-sdk/types/module"
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
"github.com/cosmos/cosmos-sdk/x/authz"
Expand Down Expand Up @@ -72,6 +77,7 @@ import (
reg "github.com/scrtlabs/SecretNetwork/x/registration"
"github.com/spf13/cast"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto/tmhash"
tmjson "github.com/tendermint/tendermint/libs/json"
tmlog "github.com/tendermint/tendermint/libs/log"
tmos "github.com/tendermint/tendermint/libs/os"
Expand Down Expand Up @@ -316,9 +322,71 @@ func (app *SecretNetworkApp) Name() string { return app.BaseApp.Name() }

// BeginBlocker application updates every begin block
func (app *SecretNetworkApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
multiStore := app.BaseApp.CommitMultiStore()
rootMulti, ok := multiStore.(*rootmulti.Store)
if !ok {
panic("app's multi store is not of type *rootmulti.Store")
} else {
storeRoots := storesRootsFromMultiStore(rootMulti)
rootsBytes, err := storeRoots.Marshal()
if err != nil {
panic(err)
}

computeKv := rootMulti.GetCommitKVStore(sdk.NewKVStoreKey(compute.StoreKey))
computeRoot := computeKv.LastCommitID().Hash

err = gocosmwasm.SubmitModulesStoreRoots(rootsBytes, computeRoot)
if err != nil {
panic(err)
}
}

return app.mm.BeginBlock(ctx, req)
}

func storesRootsFromMultiStore(rootMulti *rootmulti.Store) kv.Pairs { //[][]byte {
stores := rootMulti.GetStores()
kvs := kv.Pairs{}

for k, v := range stores {
// Stores of type StoreTypeTransient don't participate in AppHash calculation
if v.GetStoreType() == sdk.StoreTypeTransient {
continue
}

kvs.Pairs = append(kvs.Pairs, kv.Pair{Key: []byte(k.Name()), Value: tmhash.Sum(v.LastCommitID().Hash)})
}

// Have to sort in order to calculate the correct AppHash
sort.Sort(kvs)

return kvs
}

// This is a copy of an internal cosmos-sdk function: https://github.com/scrtlabs/cosmos-sdk/blob/1b9278476b3ac897d8ebb90241008476850bf212/store/internal/maps/maps.go#LL152C1-L152C1
// pairBytes returns key || value, with both the
// key and value length prefixed.
func pairBytes(kv kv.Pair) []byte {
// In the worst case:
// * 8 bytes to Uvarint encode the length of the key
// * 8 bytes to Uvarint encode the length of the value
// So preallocate for the worst case, which will in total
// be a maximum of 14 bytes wasted, if len(key)=1, len(value)=1,
// but that's going to rare.
buf := make([]byte, 8+len(kv.Key)+8+len(kv.Value))

// Encode the key, prefixed with its length.
nlk := binary.PutUvarint(buf, uint64(len(kv.Key)))
nk := copy(buf[nlk:], kv.Key)

// Encode the value, prefixing with its length.
nlv := binary.PutUvarint(buf[nlk+nk:], uint64(len(kv.Value)))
nv := copy(buf[nlk+nk+nlv:], kv.Value)

return buf[:nlk+nk+nlv+nv]
}

// EndBlocker application updates every end block
func (app *SecretNetworkApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
return app.mm.EndBlock(ctx, req)
Expand Down
Loading