From e8099997afd3c6bb6682c2df5dcd6f80596507c5 Mon Sep 17 00:00:00 2001 From: beer-1 Date: Thu, 26 Sep 2024 16:48:30 +0900 Subject: [PATCH 1/4] introduce vmpool to make each vm run on single thread --- x/move/keeper/genesis.go | 9 ++++++--- x/move/keeper/handler.go | 18 +++++++++++++++--- x/move/keeper/keeper.go | 31 ++++++++++++++++++++++--------- x/move/keeper/vmpool.go | 25 +++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 15 deletions(-) create mode 100644 x/move/keeper/vmpool.go diff --git a/x/move/keeper/genesis.go b/x/move/keeper/genesis.go index 2eecc067..af65af49 100644 --- a/x/move/keeper/genesis.go +++ b/x/move/keeper/genesis.go @@ -46,10 +46,13 @@ func (k Keeper) Initialize( _allowedPublishers[i] = addr } - // The default upgrade policy is compatible when it's not set, - // so skip the registration at initialize. + // TODO - remove this after loader v2 is installed + vm := k.acquireVM(ctx) + defer k.releaseVM(vm) + + // The default upgrade policy is compatible when it's not set. vmStore := types.NewVMStore(ctx, k.VMStore) - execRes, err := k.moveVM.Initialize(vmStore, api, env, vmtypes.NewModuleBundle(modules...), _allowedPublishers) + execRes, err := vm.Initialize(vmStore, api, env, vmtypes.NewModuleBundle(modules...), _allowedPublishers) if err != nil { return err } diff --git a/x/move/keeper/handler.go b/x/move/keeper/handler.go index fe9fa9f2..7ce3f04c 100644 --- a/x/move/keeper/handler.go +++ b/x/move/keeper/handler.go @@ -164,6 +164,10 @@ func (k Keeper) executeEntryFunction( args [][]byte, isJSON bool, ) error { + // TODO - remove this after loader v2 is installed + vm := k.acquireVM(ctx) + defer k.releaseVM(vm) + payload, err := types.BuildExecuteEntryFunctionPayload( moduleAddr, moduleName, @@ -200,7 +204,7 @@ func (k Keeper) executeEntryFunction( // run vm gasBalance := gasForRuntime - execRes, err := k.moveVM.ExecuteEntryFunction( + execRes, err := vm.ExecuteEntryFunction( &gasBalance, types.NewVMStore(sdkCtx, k.VMStore), NewApi(k, sdkCtx), @@ -280,6 +284,10 @@ func (k Keeper) executeScript( args [][]byte, isJSON bool, ) error { + // TODO - remove this after loader v2 is installed + vm := k.acquireVM(ctx) + defer k.releaseVM(vm) + // prepare payload payload, err := types.BuildExecuteScriptPayload( byteCodes, @@ -315,7 +323,7 @@ func (k Keeper) executeScript( // run vm gasBalance := gasForRuntime - execRes, err := k.moveVM.ExecuteScript( + execRes, err := vm.ExecuteScript( &gasBalance, types.NewVMStore(sdkCtx, k.VMStore), NewApi(k, sdkCtx), @@ -557,6 +565,10 @@ func (k Keeper) executeViewFunction( args [][]byte, isJSON bool, ) (vmtypes.ViewOutput, uint64, error) { + // TODO - remove this after loader v2 is installed + vm := k.acquireVM(ctx) + defer k.releaseVM(vm) + payload, err := types.BuildExecuteViewFunctionPayload( moduleAddr, moduleName, @@ -586,7 +598,7 @@ func (k Keeper) executeViewFunction( gasForRuntime := gasMeter.Limit() - gasMeter.GasConsumedToLimit() gasBalance := gasForRuntime - viewRes, err := k.moveVM.ExecuteViewFunction( + viewRes, err := vm.ExecuteViewFunction( &gasBalance, types.NewVMStore(ctx, k.VMStore), api, diff --git a/x/move/keeper/keeper.go b/x/move/keeper/keeper.go index 3cf5ba3f..1ac17de1 100644 --- a/x/move/keeper/keeper.go +++ b/x/move/keeper/keeper.go @@ -3,6 +3,9 @@ package keeper import ( "context" "errors" + "sync" + + "golang.org/x/sync/semaphore" "cosmossdk.io/collections" "cosmossdk.io/core/address" @@ -41,8 +44,10 @@ type Keeper struct { config moveconfig.MoveConfig - // moveVM instance - moveVM types.VMEngine + // TODO - remove after loader v2 + moveVMs *[]types.VMEngine + moveVMMutx *sync.Mutex + moveVMSemaphore *semaphore.Weighted feeCollector string authority string @@ -85,12 +90,18 @@ func NewKeeper( moveConfig.ContractSimulationGasLimit = moveconfig.DefaultContractSimulationGasLimit } - moveVM, err := vm.NewVM(vmtypes.InitiaVMConfig{ - // TODO: check this before mainnet - AllowUnstable: true, - }) - if err != nil { - panic(err) + vmCount := 10 + vms := make([]types.VMEngine, vmCount) + for i := 0; i < vmCount; i++ { + moveVM, err := vm.NewVM(vmtypes.InitiaVMConfig{ + // TODO: check this before mainnet + AllowUnstable: true, + }) + if err != nil { + panic(err) + } + + vms[i] = &moveVM } sb := collections.NewSchemaBuilder(storeService) @@ -103,7 +114,9 @@ func NewKeeper( msgRouter: msgRouter, grpcRouter: grpcRouter, config: moveConfig, - moveVM: &moveVM, + moveVMs: &vms, + moveVMMutx: new(sync.Mutex), + moveVMSemaphore: semaphore.NewWeighted(int64(vmCount)), distrKeeper: distrKeeper, StakingKeeper: stakingKeeper, RewardKeeper: rewardKeeper, diff --git a/x/move/keeper/vmpool.go b/x/move/keeper/vmpool.go new file mode 100644 index 00000000..167c3b11 --- /dev/null +++ b/x/move/keeper/vmpool.go @@ -0,0 +1,25 @@ +package keeper + +import ( + "context" + + "github.com/initia-labs/initia/x/move/types" +) + +func (k Keeper) acquireVM(ctx context.Context) (vm types.VMEngine) { + k.moveVMSemaphore.Acquire(ctx, 1) + + k.moveVMMutx.Lock() + vm, *k.moveVMs = (*k.moveVMs)[0], (*k.moveVMs)[1:] + k.moveVMMutx.Unlock() + + return +} + +func (k Keeper) releaseVM(vm types.VMEngine) { + k.moveVMMutx.Lock() + *k.moveVMs = append(*k.moveVMs, vm) + k.moveVMMutx.Unlock() + + k.moveVMSemaphore.Release(1) +} From b3dd21170e158aa081ca912d0d3b54daf1a4c616 Mon Sep 17 00:00:00 2001 From: beer-1 Date: Thu, 26 Sep 2024 17:15:03 +0900 Subject: [PATCH 2/4] fix lint --- x/move/keeper/vmpool.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/x/move/keeper/vmpool.go b/x/move/keeper/vmpool.go index 167c3b11..5d014448 100644 --- a/x/move/keeper/vmpool.go +++ b/x/move/keeper/vmpool.go @@ -7,7 +7,10 @@ import ( ) func (k Keeper) acquireVM(ctx context.Context) (vm types.VMEngine) { - k.moveVMSemaphore.Acquire(ctx, 1) + err := k.moveVMSemaphore.Acquire(ctx, 1) + if err != nil { + panic(err) + } k.moveVMMutx.Lock() vm, *k.moveVMs = (*k.moveVMs)[0], (*k.moveVMs)[1:] From 73f31d2b949c489d0a7d0bed6388c3606b187442 Mon Sep 17 00:00:00 2001 From: beer-1 Date: Thu, 26 Sep 2024 18:10:46 +0900 Subject: [PATCH 3/4] use index to rotate --- x/move/keeper/genesis.go | 2 +- x/move/keeper/handler.go | 6 +++--- x/move/keeper/keeper.go | 7 +++++-- x/move/keeper/vmpool.go | 10 ++++------ 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/x/move/keeper/genesis.go b/x/move/keeper/genesis.go index af65af49..5df0c36e 100644 --- a/x/move/keeper/genesis.go +++ b/x/move/keeper/genesis.go @@ -48,7 +48,7 @@ func (k Keeper) Initialize( // TODO - remove this after loader v2 is installed vm := k.acquireVM(ctx) - defer k.releaseVM(vm) + defer k.releaseVM() // The default upgrade policy is compatible when it's not set. vmStore := types.NewVMStore(ctx, k.VMStore) diff --git a/x/move/keeper/handler.go b/x/move/keeper/handler.go index 7ce3f04c..d12a1f58 100644 --- a/x/move/keeper/handler.go +++ b/x/move/keeper/handler.go @@ -166,7 +166,7 @@ func (k Keeper) executeEntryFunction( ) error { // TODO - remove this after loader v2 is installed vm := k.acquireVM(ctx) - defer k.releaseVM(vm) + defer k.releaseVM() payload, err := types.BuildExecuteEntryFunctionPayload( moduleAddr, @@ -286,7 +286,7 @@ func (k Keeper) executeScript( ) error { // TODO - remove this after loader v2 is installed vm := k.acquireVM(ctx) - defer k.releaseVM(vm) + defer k.releaseVM() // prepare payload payload, err := types.BuildExecuteScriptPayload( @@ -567,7 +567,7 @@ func (k Keeper) executeViewFunction( ) (vmtypes.ViewOutput, uint64, error) { // TODO - remove this after loader v2 is installed vm := k.acquireVM(ctx) - defer k.releaseVM(vm) + defer k.releaseVM() payload, err := types.BuildExecuteViewFunctionPayload( moduleAddr, diff --git a/x/move/keeper/keeper.go b/x/move/keeper/keeper.go index 1ac17de1..0498babc 100644 --- a/x/move/keeper/keeper.go +++ b/x/move/keeper/keeper.go @@ -45,9 +45,10 @@ type Keeper struct { config moveconfig.MoveConfig // TODO - remove after loader v2 - moveVMs *[]types.VMEngine + moveVMs []types.VMEngine moveVMMutx *sync.Mutex moveVMSemaphore *semaphore.Weighted + moveVMIdx *int feeCollector string authority string @@ -91,6 +92,7 @@ func NewKeeper( } vmCount := 10 + moveVMIdx := int(0) vms := make([]types.VMEngine, vmCount) for i := 0; i < vmCount; i++ { moveVM, err := vm.NewVM(vmtypes.InitiaVMConfig{ @@ -114,9 +116,10 @@ func NewKeeper( msgRouter: msgRouter, grpcRouter: grpcRouter, config: moveConfig, - moveVMs: &vms, + moveVMs: vms, moveVMMutx: new(sync.Mutex), moveVMSemaphore: semaphore.NewWeighted(int64(vmCount)), + moveVMIdx: &moveVMIdx, distrKeeper: distrKeeper, StakingKeeper: stakingKeeper, RewardKeeper: rewardKeeper, diff --git a/x/move/keeper/vmpool.go b/x/move/keeper/vmpool.go index 5d014448..d4675a41 100644 --- a/x/move/keeper/vmpool.go +++ b/x/move/keeper/vmpool.go @@ -13,16 +13,14 @@ func (k Keeper) acquireVM(ctx context.Context) (vm types.VMEngine) { } k.moveVMMutx.Lock() - vm, *k.moveVMs = (*k.moveVMs)[0], (*k.moveVMs)[1:] + idx := *k.moveVMIdx + *k.moveVMIdx = (idx + 1) % len(k.moveVMs) + vm = k.moveVMs[idx] k.moveVMMutx.Unlock() return } -func (k Keeper) releaseVM(vm types.VMEngine) { - k.moveVMMutx.Lock() - *k.moveVMs = append(*k.moveVMs, vm) - k.moveVMMutx.Unlock() - +func (k Keeper) releaseVM() { k.moveVMSemaphore.Release(1) } From 62309d340492567f4f02f8cefddcdacf6a237828 Mon Sep 17 00:00:00 2001 From: beer-1 Date: Thu, 26 Sep 2024 18:17:26 +0900 Subject: [PATCH 4/4] use atomic --- x/move/keeper/keeper.go | 9 +++------ x/move/keeper/vmpool.go | 8 +++----- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/x/move/keeper/keeper.go b/x/move/keeper/keeper.go index 0498babc..652fd31b 100644 --- a/x/move/keeper/keeper.go +++ b/x/move/keeper/keeper.go @@ -3,7 +3,6 @@ package keeper import ( "context" "errors" - "sync" "golang.org/x/sync/semaphore" @@ -46,9 +45,8 @@ type Keeper struct { // TODO - remove after loader v2 moveVMs []types.VMEngine - moveVMMutx *sync.Mutex + moveVMIdx *uint64 moveVMSemaphore *semaphore.Weighted - moveVMIdx *int feeCollector string authority string @@ -92,7 +90,7 @@ func NewKeeper( } vmCount := 10 - moveVMIdx := int(0) + moveVMIdx := uint64(0) vms := make([]types.VMEngine, vmCount) for i := 0; i < vmCount; i++ { moveVM, err := vm.NewVM(vmtypes.InitiaVMConfig{ @@ -117,9 +115,8 @@ func NewKeeper( grpcRouter: grpcRouter, config: moveConfig, moveVMs: vms, - moveVMMutx: new(sync.Mutex), - moveVMSemaphore: semaphore.NewWeighted(int64(vmCount)), moveVMIdx: &moveVMIdx, + moveVMSemaphore: semaphore.NewWeighted(int64(vmCount)), distrKeeper: distrKeeper, StakingKeeper: stakingKeeper, RewardKeeper: rewardKeeper, diff --git a/x/move/keeper/vmpool.go b/x/move/keeper/vmpool.go index d4675a41..a5425486 100644 --- a/x/move/keeper/vmpool.go +++ b/x/move/keeper/vmpool.go @@ -2,6 +2,7 @@ package keeper import ( "context" + "sync/atomic" "github.com/initia-labs/initia/x/move/types" ) @@ -12,11 +13,8 @@ func (k Keeper) acquireVM(ctx context.Context) (vm types.VMEngine) { panic(err) } - k.moveVMMutx.Lock() - idx := *k.moveVMIdx - *k.moveVMIdx = (idx + 1) % len(k.moveVMs) - vm = k.moveVMs[idx] - k.moveVMMutx.Unlock() + idx := atomic.AddUint64(k.moveVMIdx, 1) + vm = k.moveVMs[idx%uint64(len(k.moveVMs))] return }