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

DFI-1026 VM module migration #1

Merged
merged 7 commits into from
Apr 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Tests & CrossBuild & DockerBuild

on: [push]

jobs:
lint:
name: Linter checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
with:
version: v1.32
args: --exclude 'unused' --timeout=10m

test:
name: Unit tests & Integration tests
runs-on: ${{ matrix.os }}

strategy:
fail-fast: true
matrix:
go:
- 1.15.11
os:
- ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Install Go toolchain
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go }}

- name: Get dependencies
run: |
go mod download

- name: Run tests
run: |
go test -v ./...
17 changes: 17 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ LEDGER_ENABLED := false

# Common vars
DOCKER := $(shell which docker)
PROTOC := $(shell which protoc)

# Build version

Expand Down Expand Up @@ -84,6 +85,22 @@ lint:
@echo "--> Running Golang linter (unused variable / function warning are skipped)"
@golangci-lint run --exclude 'unused'

tests:
@echo "--> Running tests"
go test ./... -v

proto-gen:
@echo "--> Generating DVM Protobuf files"
@#mkdir -p $(CURDIR)/pkg/types/dvm_proto/types_grpc
@#mkdir -p $(CURDIR)/pkg/types/dvm_proto/compiler_grpc
@#mkdir -p $(CURDIR)/pkg/types/dvm_proto/ds_grpc
@#mkdir -p $(CURDIR)/pkg/types/dvm_proto/metadata_grpc
@#mkdir -p $(CURDIR)/pkg/types/dvm_proto/vm_grpc
@#$(PROTOC) --proto_path=$(CURDIR)/third_party/proto/dvm_proto --go_out=plugins=grpc:$(CURDIR)/pkg/types/dvm_proto/types_grpc --go_opt=paths=source_relative $(CURDIR)/third_party/proto/dvm_proto/common-types.proto
@#$(PROTOC) --proto_path=$(CURDIR)/third_party/proto/dvm_proto --go_out=plugins=grpc:$(CURDIR)/pkg/types/dvm_proto/compiler_grpc --go_opt=paths=source_relative $(CURDIR)/third_party/proto/dvm_proto/compiler.proto
@#$(PROTOC) --proto_path=$(CURDIR)/third_party/proto/dvm_proto --go_out=plugins=grpc:$(CURDIR)/pkg/types/dvm_proto/ds_grpc --go_opt=paths=source_relative $(CURDIR)/third_party/proto/dvm_proto/data-source.proto
@#$(PROTOC) --proto_path=$(CURDIR)/third_party/proto/dvm_proto --go_out=plugins=grpc:$(CURDIR)/pkg/types/dvm_proto/metadata_grpc --go_opt=paths=source_relative $(CURDIR)/third_party/proto/dvm_proto/metadata.proto
@#$(PROTOC) --proto_path=$(CURDIR)/third_party/proto/dvm_proto --go_out=plugins=grpc:$(CURDIR)/pkg/types/dvm_proto/vm_grpc --go_opt=paths=source_relative $(CURDIR)/third_party/proto/dvm_proto/vm.proto

@echo "--> Generating Protobuf files"
$(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace tendermintdev/sdk-proto-gen sh ./scripts/protocgen.sh
140 changes: 126 additions & 14 deletions app/app.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package app

import (
"fmt"
"io"
"math/big"
"net"
"net/http"
"time"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/gorilla/mux"
"github.com/rakyll/statik/fs"
"google.golang.org/grpc"

abci "github.com/tendermint/tendermint/abci/types"
tmJson "github.com/tendermint/tendermint/libs/json"
Expand Down Expand Up @@ -83,6 +88,12 @@ import (
upgradeKeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
upgradeTypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"

"github.com/dfinance/dstation/pkg"
"github.com/dfinance/dstation/x/vm"
vmConfig "github.com/dfinance/dstation/x/vm/config"
vmKeeper "github.com/dfinance/dstation/x/vm/keeper"
vmTypes "github.com/dfinance/dstation/x/vm/types"

// unnamed import of statik for swagger UI support
_ "github.com/cosmos/cosmos-sdk/client/docs/statik"
)
Expand Down Expand Up @@ -112,6 +123,7 @@ var (
evidence.AppModuleBasic{},
transfer.AppModuleBasic{},
vesting.AppModuleBasic{},
vm.AppModuleBasic{},
)

// module account permissions
Expand All @@ -123,6 +135,7 @@ var (
stakingTypes.NotBondedPoolName: {authTypes.Burner, authTypes.Staking},
govTypes.ModuleName: {authTypes.Burner},
ibcTransferTypes.ModuleName: {authTypes.Minter, authTypes.Burner},
vmTypes.DelPoolName: {authTypes.Staking},
}
)

Expand Down Expand Up @@ -162,6 +175,7 @@ type DnApp struct { // nolint: golint
IBCKeeper *ibcKeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly
EvidenceKeeper evidenceKeeper.Keeper
TransferKeeper ibcTransferKeeper.Keeper
VmKeeper vmKeeper.Keeper

// make scoped keepers public for test purposes
ScopedIBCKeeper capabilityKeeper.ScopedKeeper
Expand All @@ -172,6 +186,11 @@ type DnApp struct { // nolint: golint

// simulation manager
sm *module.SimulationManager

// vm connections
vmConfig *vmConfig.VMConfig
vmConn *grpc.ClientConn
dsListener net.Listener
}

// Name returns the name of the App.
Expand Down Expand Up @@ -297,10 +316,66 @@ func (app *DnApp) RegisterTendermintService(clientCtx client.Context) {
tmservice.RegisterTendermintService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.interfaceRegistry)
}

// Initialize connection to VM server.
func (app *DnApp) InitializeVMConnection(addr string, appOpts serverTypes.AppOptions) {
// Custom (used for mock connection)
if obj := appOpts.Get(FlagCustomVMConnection); obj != nil {
conn, ok := obj.(*grpc.ClientConn)
if !ok {
panic(fmt.Errorf("%s appOpt: type assertion failed: %T", FlagCustomVMConnection, obj))
}
app.vmConn = conn
return
}

// gRPC connection
app.Logger().Info(fmt.Sprintf("Creating VM connection, address: %s", addr))
conn, err := pkg.GetGRpcClientConnection(addr, 1*time.Second)
if err != nil {
panic(err)
}
app.vmConn = conn

app.Logger().Info(fmt.Sprintf("Non-blocking connection initialized, status: %s", app.vmConn.GetState()))
}

// Initialize listener to listen for connections from VM for data server.
func (app *DnApp) InitializeVMDataServer(addr string, appOpts serverTypes.AppOptions) {
// Custom (used for mock connection)
if obj := appOpts.Get(FlagCustomDSListener); obj != nil {
listener, ok := obj.(net.Listener)
if !ok {
panic(fmt.Errorf("%s appOpt: type assertion failed: %T", FlagCustomDSListener, obj))
}
app.dsListener = listener
return
}

app.Logger().Info(fmt.Sprintf("Starting VM data server listener, address: %s", addr))
listener, err := pkg.GetGRpcNetListener(addr)
if err != nil {
panic(err)
}
app.dsListener = listener

app.Logger().Info("VM data server is running")
}

// CloseConnections closes VM connection and stops DS server.
func (app DnApp) CloseConnections() {
app.VmKeeper.StopDSServer()
if app.dsListener != nil {
app.dsListener.Close()
}
if app.vmConn != nil {
app.vmConn.Close()
}
}

// NewDnApp returns a reference to an initialized Dnode service.
func NewDnApp(
logger log.Logger, db tmDb.DB, traceStore io.Writer, loadLatest bool, skipUpgradeHeights map[int64]bool,
homePath string, invCheckPeriod uint, encodingConfig EncodingConfig, appOpts serverTypes.AppOptions, baseAppOptions ...func(*baseapp.BaseApp),
homePath string, invCheckPeriod uint, encodingConfig EncodingConfig, vmConfig *vmConfig.VMConfig, appOpts serverTypes.AppOptions, baseAppOptions ...func(*baseapp.BaseApp),
) *DnApp {

appCodec := encodingConfig.Marshaler
Expand All @@ -317,6 +392,7 @@ func NewDnApp(
mintTypes.StoreKey, distrTypes.StoreKey, slashingTypes.StoreKey,
govTypes.StoreKey, paramsTypes.StoreKey, ibcHost.StoreKey, upgradeTypes.StoreKey,
evidenceTypes.StoreKey, ibcTransferTypes.StoreKey, capabilityTypes.StoreKey,
vmTypes.StoreKey,
)
tkeys := sdk.NewTransientStoreKeys(paramsTypes.TStoreKey)
memKeys := sdk.NewMemoryStoreKeys(capabilityTypes.MemStoreKey)
Expand All @@ -330,8 +406,17 @@ func NewDnApp(
keys: keys,
tkeys: tkeys,
memKeys: memKeys,
vmConfig: vmConfig,
}

// Initialize VM connections
app.InitializeVMDataServer(vmConfig.DataListen, appOpts)
app.InitializeVMConnection(vmConfig.Address, appOpts)

// Reduce ConsensusPower reduction coefficient (1 xfi == 1 power unit)
// 1 xfi == 1000000000000000000 (exp == 18)
sdk.PowerReduction = sdk.NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil))

app.ParamsKeeper = initParamsKeeper(appCodec, legacyAmino, keys[paramsTypes.StoreKey], tkeys[paramsTypes.TStoreKey])
// set the BaseApp's parameter store
bApp.SetParamStore(app.ParamsKeeper.Subspace(baseapp.Paramspace).WithKeyTable(paramsKeeper.ConsensusParamsKeyTable()))
Expand All @@ -341,7 +426,7 @@ func NewDnApp(
scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibcHost.ModuleName)
scopedTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibcTransferTypes.ModuleName)

// add keepers
// Add keepers
app.AccountKeeper = authKeeper.NewAccountKeeper(
appCodec, keys[authTypes.StoreKey], app.GetSubspace(authTypes.ModuleName), authTypes.ProtoBaseAccount, maccPerms,
)
Expand All @@ -367,7 +452,7 @@ func NewDnApp(
)
app.UpgradeKeeper = upgradeKeeper.NewKeeper(skipUpgradeHeights, keys[upgradeTypes.StoreKey], appCodec, homePath)

// register the staking hooks
// Register the staking hooks
// NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
app.StakingKeeper = *stakingKeeper.SetHooks(
stakingTypes.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()),
Expand All @@ -378,13 +463,18 @@ func NewDnApp(
appCodec, keys[ibcHost.StoreKey], app.GetSubspace(ibcHost.ModuleName), app.StakingKeeper, scopedIBCKeeper,
)

// register the proposal types
app.VmKeeper = vmKeeper.NewKeeper(
appCodec, keys[vmTypes.StoreKey], app.vmConn, app.dsListener, app.vmConfig, app.AccountKeeper, app.BankKeeper,
)

// Register the proposal types
govRouter := govTypes.NewRouter()
govRouter.AddRoute(govTypes.RouterKey, govTypes.ProposalHandler).
AddRoute(paramsProposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)).
AddRoute(distrTypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)).
AddRoute(upgradeTypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)).
AddRoute(ibcHost.RouterKey, ibcClient.NewClientUpdateProposalHandler(app.IBCKeeper.ClientKeeper))
AddRoute(ibcHost.RouterKey, ibcClient.NewClientUpdateProposalHandler(app.IBCKeeper.ClientKeeper)).
AddRoute(vmTypes.RouterKey, vm.NewGovHandler(app.VmKeeper))
app.GovKeeper = govKeeper.NewKeeper(
appCodec, keys[govTypes.StoreKey], app.GetSubspace(govTypes.ModuleName), app.AccountKeeper, app.BankKeeper,
&stakingKeeper, govRouter,
Expand Down Expand Up @@ -418,9 +508,6 @@ func NewDnApp(
skipGenesisInvariants = opt
}

// NOTE: Any module instantiated in the module manager that is later modified
// must be passed by reference here.

// NOTE: Any module instantiated in the module manager that is later modified
// must be passed by reference here.
app.mm = module.NewManager(
Expand All @@ -443,27 +530,49 @@ func NewDnApp(
ibc.NewAppModule(app.IBCKeeper),
params.NewAppModule(app.ParamsKeeper),
transferModule,
vm.NewAppModule(appCodec, app.VmKeeper, app.AccountKeeper, app.BankKeeper),
)

// During begin block slashing happens after distr.BeginBlocker so that
// there is nothing left over in the validator fee pool, so as to keep the
// CanWithdrawInvariant invariant.
// NOTE: staking module is required if HistoricalEntries param > 0
app.mm.SetOrderBeginBlockers(
upgradeTypes.ModuleName, mintTypes.ModuleName, distrTypes.ModuleName, slashingTypes.ModuleName,
evidenceTypes.ModuleName, stakingTypes.ModuleName, ibcHost.ModuleName,
upgradeTypes.ModuleName,
mintTypes.ModuleName,
distrTypes.ModuleName,
slashingTypes.ModuleName,
evidenceTypes.ModuleName,
stakingTypes.ModuleName,
ibcHost.ModuleName,
vmTypes.ModuleName,
)
app.mm.SetOrderEndBlockers(
crisisTypes.ModuleName,
govTypes.ModuleName,
stakingTypes.ModuleName,
)
app.mm.SetOrderEndBlockers(crisisTypes.ModuleName, govTypes.ModuleName, stakingTypes.ModuleName)

// NOTE: The genutils module must occur after staking so that pools are
// properly initialized with tokens from genesis accounts.
// NOTE: Capability module must occur first so that it can initialize any capabilities
// so that other modules that want to create or claim capabilities afterwards in InitChain
// can do so safely.
app.mm.SetOrderInitGenesis(
capabilityTypes.ModuleName, authTypes.ModuleName, bankTypes.ModuleName, distrTypes.ModuleName, stakingTypes.ModuleName,
slashingTypes.ModuleName, govTypes.ModuleName, mintTypes.ModuleName, crisisTypes.ModuleName,
ibcHost.ModuleName, genutilTypes.ModuleName, evidenceTypes.ModuleName, ibcTransferTypes.ModuleName,
capabilityTypes.ModuleName,
authTypes.ModuleName,
bankTypes.ModuleName,
distrTypes.ModuleName,
stakingTypes.ModuleName,
slashingTypes.ModuleName,
govTypes.ModuleName,
mintTypes.ModuleName,
crisisTypes.ModuleName,
ibcHost.ModuleName,
genutilTypes.ModuleName,
evidenceTypes.ModuleName,
ibcTransferTypes.ModuleName,
vmTypes.ModuleName,
)

app.mm.RegisterInvariants(&app.CrisisKeeper)
Expand Down Expand Up @@ -525,6 +634,9 @@ func NewDnApp(
app.ScopedIBCKeeper = scopedIBCKeeper
app.ScopedTransferKeeper = scopedTransferKeeper

// Start the VM data source server after all the initialization is done
app.VmKeeper.StartDSServer()

return app
}

Expand Down
26 changes: 26 additions & 0 deletions app/options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package app

import (
"github.com/cosmos/cosmos-sdk/baseapp"

vmTypes "github.com/dfinance/dstation/x/vm/types"
)

const (
FlagCustomVMConnection = "custom-vm-connection"
FlagCustomDSListener = "custom-ds-listener"
)

func VMCrashHandleBaseAppOption() func(*baseapp.BaseApp) {
return func(app *baseapp.BaseApp) {
app.AddRunTxRecoveryHandler(func(recoveryObj interface{}) error {
if err, ok := recoveryObj.(error); ok {
if vmTypes.ErrVMCrashed.Is(err) {
panic(recoveryObj)
}
}

return nil
})
}
}
Loading