Hi, when i read the multiversx doc https://docs.multiversx.com/technology/the-wasm-vm/ about wasm-vm。 I find the official doc about the vm is "In case a contract calls another, and they are both in the same shard, the execution is effectively synchronous, and both contracts are executed without even leaving the VM.";;
I have view the code of the mx-chain-vm-go, and find in func of callSCMethod(), after the "err = runtime.CallFunction(function)" the code will exec ", err = host.processAsyncInfo(runtime.GetAsyncContextInfo())" in the default(the same shard); if the contract A call contract B in the same shard is that mean the ", err = host.processAsyncInfo(runtime.GetAsyncContextInfo())" is exec call the B contract?
The analyse 1 and 2 have a conflict, which is the correct principle of cross contract call in one shard about tehe multiversx?
func (host *vmHost) callSCMethod() error {
runtime := host.Runtime()
log.Trace("call SC method")
// TODO host.verifyAllowedFunctionCall() performs some checks, but then the
// function itself is changed by host.getFunctionByCallType(). Order must be
// reversed, and `getFunctionByCallType()` must be decomposed into smaller functions.
err := host.verifyAllowedFunctionCall()
if err != nil {
log.Trace("call SC method failed", "error", err, "src", "verifyAllowedFunctionCall")
return err
}
callType := runtime.GetVMInput().CallType
function, err := host.getFunctionByCallType(callType)
if err != nil {
if callType == vm.AsynchronousCallBack && errors.Is(err, vmhost.ErrNilCallbackFunction) {
err = host.processCallbackStack()
if err != nil {
log.Trace("call SC method failed", "error", err, "src", "processCallbackStack")
}
return err
}
log.Trace("call SC method failed", "error", err, "src", "getFunctionByCallType")
return err
}
err = runtime.CallFunction(function)
if err != nil {
err = host.handleBreakpointIfAny(err)
log.Trace("breakpoint detected and handled", "err", err)
}
if err == nil {
err = host.checkFinalGasAfterExit()
}
if err != nil {
log.Trace("call SC method failed", "error", err, "src", "sc function")
return err
}
switch callType {
case vm.AsynchronousCall:
_, paiErr := host.processAsyncInfo(runtime.GetAsyncContextInfo())
if paiErr != nil {
log.Trace("call SC method failed", "error", paiErr)
return paiErr
}
err = host.sendCallbackToCurrentCaller()
case vm.AsynchronousCallBack:
err = host.processCallbackStack()
default:
_, err = host.processAsyncInfo(runtime.GetAsyncContextInfo())
}
if err != nil {
log.Trace("call SC method failed", "error", err, "src", "async post-process")
}
return err
}
User calls SC and the call enters into doRunSmartContractCall
It gets into the callSCMethod and the WASM code is getting executed on runtime.CallFunction call.
The SC A calls with async VM Api SC B -ManagedAsyncCall from managedei.go which ends the call for SCA and puts a breakpoint in the SCA execution.
This will trigger "handleAsyncCallBreakpoint" function on asyncCall.go and in this function we call executeSyncDestinationCall and executeSyncCallbackCall
Please write the desired question
I read the code about the mx-chain-vm-go and find that func populateWasmerImports(imports *wasmerImports) error { this import the hook function(or host function) into the wasmer, this mean whether or not when A cross contract call B in one shard, the call will not leave wasmer and just through the hook function about v1_5_executeOnDestContext https://github.com/multiversx/mx-chain-vm-go/blob/master/wasmer/wasmerImportsCgo.go#L1949 call the B contract
I have view the code of the mx-chain-vm-go, and find in func of callSCMethod(), after the "err = runtime.CallFunction(function)" the code will exec ", err = host.processAsyncInfo(runtime.GetAsyncContextInfo())" in the default(the same shard); if the contract A call contract B in the same shard is that mean the ", err = host.processAsyncInfo(runtime.GetAsyncContextInfo())" is exec call the B contract?
The analyse 1 and 2 have a conflict, which is the correct principle of cross contract call in one shard about tehe multiversx?
func (host vmHost) processAsyncInfo(asyncInfo vmhost.AsyncContextInfo) (*vmhost.AsyncContextInfo, error) { if len(asyncInfo.AsyncContextMap) == 0 { return asyncInfo, nil }
.... }