Skip to content

Commit

Permalink
Merge pull request #5801 from multiversx/sandbox-queries
Browse files Browse the repository at this point in the history
Deep VM Queries (for older epochs, as well)
  • Loading branch information
iulianpascalau authored Feb 15, 2024
2 parents 5531e7f + 624413b commit 6faf35a
Show file tree
Hide file tree
Showing 18 changed files with 621 additions and 233 deletions.
78 changes: 37 additions & 41 deletions factory/api/apiResolverFactory.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ func createScQueryService(
list := make([]process.SCQueryService, 0, numConcurrentVms)
for i := 0; i < numConcurrentVms; i++ {
argsQueryElem.index = i
scQueryService, err = createScQueryElement(argsQueryElem)
scQueryService, err = createScQueryElement(*argsQueryElem)
if err != nil {
return nil, err
}
Expand All @@ -340,10 +340,12 @@ func createScQueryService(
}

func createScQueryElement(
args *scQueryElementArgs,
args scQueryElementArgs,
) (process.SCQueryService, error) {
var err error

selfShardID := args.processComponents.ShardCoordinator().SelfId()

pkConverter := args.coreComponents.AddressPubKeyConverter()
automaticCrawlerAddressesStrings := args.generalConfig.BuiltInFunctions.AutomaticCrawlerAddresses
convertedAddresses, errDecode := factory.DecodeAddresses(pkConverter, automaticCrawlerAddressesStrings)
Expand All @@ -357,10 +359,20 @@ func createScQueryElement(
return nil, errDecode
}

apiBlockchain, err := createBlockchainForScQuery(selfShardID)
if err != nil {
return nil, err

Check warning on line 364 in factory/api/apiResolverFactory.go

View check run for this annotation

Codecov / codecov/patch

factory/api/apiResolverFactory.go#L364

Added line #L364 was not covered by tests
}

accountsAdapterApi, err := createNewAccountsAdapterApi(args, apiBlockchain)
if err != nil {
return nil, err
}

builtInFuncFactory, err := createBuiltinFuncs(
args.gasScheduleNotifier,
args.coreComponents.InternalMarshalizer(),
args.stateComponents.AccountsAdapterAPI(),
accountsAdapterApi,
args.processComponents.ShardCoordinator(),
args.coreComponents.EpochNotifier(),
args.coreComponents.EnableEpochsHandler(),
Expand Down Expand Up @@ -400,16 +412,17 @@ func createScQueryElement(
GasSchedule: args.gasScheduleNotifier,
Counter: counters.NewDisabledCounter(),
MissingTrieNodesNotifier: syncer.NewMissingTrieNodesNotifier(),
Accounts: accountsAdapterApi,
BlockChain: apiBlockchain,
}

var apiBlockchain data.ChainHandler
var vmFactory process.VirtualMachinesContainerFactory
maxGasForVmQueries := args.generalConfig.VirtualMachine.GasConfig.ShardMaxGasPerVmQuery
if args.processComponents.ShardCoordinator().SelfId() == core.MetachainShardId {
if selfShardID == core.MetachainShardId {
maxGasForVmQueries = args.generalConfig.VirtualMachine.GasConfig.MetaMaxGasPerVmQuery
apiBlockchain, vmFactory, err = createMetaVmContainerFactory(args, argsHook)
vmFactory, err = createMetaVmContainerFactory(args, argsHook)

Check warning on line 423 in factory/api/apiResolverFactory.go

View check run for this annotation

Codecov / codecov/patch

factory/api/apiResolverFactory.go#L423

Added line #L423 was not covered by tests
} else {
apiBlockchain, vmFactory, err = createShardVmContainerFactory(args, argsHook)
vmFactory, err = createShardVmContainerFactory(args, argsHook)
}
if err != nil {
return nil, err
Expand Down Expand Up @@ -453,23 +466,19 @@ func createScQueryElement(
return smartContract.NewSCQueryService(argsNewSCQueryService)
}

func createMetaVmContainerFactory(args *scQueryElementArgs, argsHook hooks.ArgBlockChainHook) (data.ChainHandler, process.VirtualMachinesContainerFactory, error) {
apiBlockchain, err := blockchain.NewMetaChain(disabled.NewAppStatusHandler())
if err != nil {
return nil, nil, err
}

accountsAdapterApi, err := createNewAccountsAdapterApi(args, apiBlockchain)
if err != nil {
return nil, nil, err
func createBlockchainForScQuery(selfShardID uint32) (data.ChainHandler, error) {
isMetachain := selfShardID == core.MetachainShardId
if isMetachain {
return blockchain.NewMetaChain(disabled.NewAppStatusHandler())
}

argsHook.BlockChain = apiBlockchain
argsHook.Accounts = accountsAdapterApi
return blockchain.NewBlockChain(disabled.NewAppStatusHandler())
}

func createMetaVmContainerFactory(args scQueryElementArgs, argsHook hooks.ArgBlockChainHook) (process.VirtualMachinesContainerFactory, error) {

Check warning on line 478 in factory/api/apiResolverFactory.go

View check run for this annotation

Codecov / codecov/patch

factory/api/apiResolverFactory.go#L478

Added line #L478 was not covered by tests
blockChainHookImpl, errBlockChainHook := hooks.NewBlockChainHookImpl(argsHook)
if errBlockChainHook != nil {
return nil, nil, errBlockChainHook
return nil, errBlockChainHook

Check warning on line 481 in factory/api/apiResolverFactory.go

View check run for this annotation

Codecov / codecov/patch

factory/api/apiResolverFactory.go#L481

Added line #L481 was not covered by tests
}

argsNewVmFactory := metachain.ArgsNewVMContainerFactory{
Expand All @@ -490,35 +499,22 @@ func createMetaVmContainerFactory(args *scQueryElementArgs, argsHook hooks.ArgBl
}
vmFactory, err := metachain.NewVMContainerFactory(argsNewVmFactory)
if err != nil {
return nil, nil, err
return nil, err

Check warning on line 502 in factory/api/apiResolverFactory.go

View check run for this annotation

Codecov / codecov/patch

factory/api/apiResolverFactory.go#L502

Added line #L502 was not covered by tests
}

return apiBlockchain, vmFactory, nil
return vmFactory, nil

Check warning on line 505 in factory/api/apiResolverFactory.go

View check run for this annotation

Codecov / codecov/patch

factory/api/apiResolverFactory.go#L505

Added line #L505 was not covered by tests
}

func createShardVmContainerFactory(args *scQueryElementArgs, argsHook hooks.ArgBlockChainHook) (data.ChainHandler, process.VirtualMachinesContainerFactory, error) {
apiBlockchain, err := blockchain.NewBlockChain(disabled.NewAppStatusHandler())
if err != nil {
return nil, nil, err
}

accountsAdapterApi, err := createNewAccountsAdapterApi(args, apiBlockchain)
if err != nil {
return nil, nil, err
}

argsHook.BlockChain = apiBlockchain
argsHook.Accounts = accountsAdapterApi

func createShardVmContainerFactory(args scQueryElementArgs, argsHook hooks.ArgBlockChainHook) (process.VirtualMachinesContainerFactory, error) {
queryVirtualMachineConfig := args.generalConfig.VirtualMachine.Querying.VirtualMachineConfig
esdtTransferParser, errParser := parsers.NewESDTTransferParser(args.coreComponents.InternalMarshalizer())
if errParser != nil {
return nil, nil, errParser
return nil, errParser
}

blockChainHookImpl, errBlockChainHook := hooks.NewBlockChainHookImpl(argsHook)
if errBlockChainHook != nil {
return nil, nil, errBlockChainHook
return nil, errBlockChainHook

Check warning on line 517 in factory/api/apiResolverFactory.go

View check run for this annotation

Codecov / codecov/patch

factory/api/apiResolverFactory.go#L517

Added line #L517 was not covered by tests
}

argsNewVMFactory := shard.ArgVMContainerFactory{
Expand All @@ -540,13 +536,13 @@ func createShardVmContainerFactory(args *scQueryElementArgs, argsHook hooks.ArgB

vmFactory, err := shard.NewVMContainerFactory(argsNewVMFactory)
if err != nil {
return nil, nil, err
return nil, err
}

return apiBlockchain, vmFactory, nil
return vmFactory, nil
}

func createNewAccountsAdapterApi(args *scQueryElementArgs, chainHandler data.ChainHandler) (state.AccountsAdapterAPI, error) {
func createNewAccountsAdapterApi(args scQueryElementArgs, chainHandler data.ChainHandler) (state.AccountsAdapterAPI, error) {
argsAccCreator := factoryState.ArgsAccountCreator{
Hasher: args.coreComponents.Hasher(),
Marshaller: args.coreComponents.InternalMarshalizer(),
Expand Down Expand Up @@ -623,7 +619,7 @@ func createNewAccountsAdapterApi(args *scQueryElementArgs, chainHandler data.Cha
return state.NewAccountsDBApi(accounts, provider)
}

func newStoragePruningManager(args *scQueryElementArgs) (state.StoragePruningManager, error) {
func newStoragePruningManager(args scQueryElementArgs) (state.StoragePruningManager, error) {
argsMemEviction := evictionWaitingList.MemoryEvictionWaitingListArgs{
RootHashesSize: args.generalConfig.EvictionWaitingList.RootHashesSize,
HashesSize: args.generalConfig.EvictionWaitingList.HashesSize,
Expand Down
20 changes: 20 additions & 0 deletions factory/api/apiResolverFactory_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package api_test

import (
"fmt"
"strings"
"sync"
"testing"
Expand Down Expand Up @@ -448,5 +449,24 @@ func TestCreateApiResolver_createScQueryElement(t *testing.T) {
require.True(t, strings.Contains(strings.ToLower(err.Error()), "hasher"))
require.Nil(t, scQueryService)
})
}

func TestCreateApiResolver_createBlockchainForScQuery(t *testing.T) {
t.Parallel()

t.Run("for metachain", func(t *testing.T) {
t.Parallel()

apiBlockchain, err := api.CreateBlockchainForScQuery(core.MetachainShardId)
require.NoError(t, err)
require.Equal(t, "*blockchain.metaChain", fmt.Sprintf("%T", apiBlockchain))
})

t.Run("for shard", func(t *testing.T) {
t.Parallel()

apiBlockchain, err := api.CreateBlockchainForScQuery(0)
require.NoError(t, err)
require.Equal(t, "*blockchain.blockChain", fmt.Sprintf("%T", apiBlockchain))
})
}
8 changes: 7 additions & 1 deletion factory/api/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package api

import (
"github.com/multiversx/mx-chain-core-go/core"
"github.com/multiversx/mx-chain-core-go/data"
"github.com/multiversx/mx-chain-go/config"
"github.com/multiversx/mx-chain-go/factory"
"github.com/multiversx/mx-chain-go/process"
Expand Down Expand Up @@ -29,7 +30,7 @@ type SCQueryElementArgs struct {

// CreateScQueryElement -
func CreateScQueryElement(args SCQueryElementArgs) (process.SCQueryService, error) {
return createScQueryElement(&scQueryElementArgs{
return createScQueryElement(scQueryElementArgs{
generalConfig: args.GeneralConfig,
epochConfig: args.EpochConfig,
coreComponents: args.CoreComponents,
Expand All @@ -47,3 +48,8 @@ func CreateScQueryElement(args SCQueryElementArgs) (process.SCQueryService, erro
guardedAccountHandler: args.GuardedAccountHandler,
})
}

// CreateBlockchainForScQuery -
func CreateBlockchainForScQuery(selfShardID uint32) (data.ChainHandler, error) {
return createBlockchainForScQuery(selfShardID)
}
113 changes: 113 additions & 0 deletions integrationTests/miniNetwork.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package integrationTests

import (
"encoding/hex"
"fmt"
"math/big"
"testing"

"github.com/multiversx/mx-chain-core-go/data/transaction"
)

// MiniNetwork is a mini network, useful for some integration tests
type MiniNetwork struct {
Round uint64
Nonce uint64

Nodes []*TestProcessorNode
ShardNode *TestProcessorNode
MetachainNode *TestProcessorNode
Users map[string]*TestWalletAccount
}

// NewMiniNetwork creates a MiniNetwork
func NewMiniNetwork() *MiniNetwork {
n := &MiniNetwork{}

nodes := CreateNodes(
1,
1,
1,
)

n.Nodes = nodes
n.ShardNode = nodes[0]
n.MetachainNode = nodes[1]
n.Users = make(map[string]*TestWalletAccount)

return n
}

// Stop stops the mini network
func (n *MiniNetwork) Stop() {
n.ShardNode.Close()
n.MetachainNode.Close()
}

// FundAccount funds an account
func (n *MiniNetwork) FundAccount(address []byte, value *big.Int) {
shard := n.MetachainNode.ShardCoordinator.ComputeId(address)

if shard == n.MetachainNode.ShardCoordinator.SelfId() {
MintAddress(n.MetachainNode.AccntState, address, value)
} else {
MintAddress(n.ShardNode.AccntState, address, value)
}
}

// AddUser adds a user (account) to the mini network
func (n *MiniNetwork) AddUser(balance *big.Int) *TestWalletAccount {
user := CreateTestWalletAccount(n.ShardNode.ShardCoordinator, 0)
n.Users[string(user.Address)] = user
n.FundAccount(user.Address, balance)
return user
}

// Start starts the mini network
func (n *MiniNetwork) Start() {
n.Round = 1
n.Nonce = 1
}

// Continue advances processing with a number of rounds
func (n *MiniNetwork) Continue(t *testing.T, numRounds int) {
idxProposers := []int{0, 1}

for i := int64(0); i < int64(numRounds); i++ {
n.Nonce, n.Round = ProposeAndSyncOneBlock(t, n.Nodes, idxProposers, n.Round, n.Nonce)
}
}

// SendTransaction sends a transaction
func (n *MiniNetwork) SendTransaction(
senderPubkey []byte,
receiverPubkey []byte,
value *big.Int,
data string,
additionalGasLimit uint64,
) (string, error) {
sender, ok := n.Users[string(senderPubkey)]
if !ok {
return "", fmt.Errorf("unknown sender: %s", hex.EncodeToString(senderPubkey))
}

tx := &transaction.Transaction{
Nonce: sender.Nonce,
Value: new(big.Int).Set(value),
SndAddr: sender.Address,
RcvAddr: receiverPubkey,
Data: []byte(data),
GasPrice: MinTxGasPrice,
GasLimit: MinTxGasLimit + uint64(len(data)) + additionalGasLimit,
ChainID: ChainID,
Version: MinTransactionVersion,
}

txBuff, _ := tx.GetDataForSigning(TestAddressPubkeyConverter, TestTxSignMarshalizer, TestTxSignHasher)
tx.Signature, _ = sender.SingleSigner.Sign(sender.SkTxSign, txBuff)
txHash, err := n.ShardNode.SendTransaction(tx)

sender.Nonce++

return txHash, err
}
Loading

0 comments on commit 6faf35a

Please sign in to comment.