Skip to content

Commit

Permalink
Merge pull request #6564 from multiversx/esdt-safe-callback-problem
Browse files Browse the repository at this point in the history
Esdt safe callback test on fail case
  • Loading branch information
axenteoctavian authored Nov 7, 2024
2 parents 4e4724a + 587a74b commit 91c8f13
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 2 deletions.
165 changes: 164 additions & 1 deletion integrationTests/chainSimulator/bridge/esdtSafe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,167 @@ func TestChainSimulator_DepositAndExecuteOperations(t *testing.T) {
}
}

// transfer from sovereign chain to main chain with transfer data
// tokens are originated from sovereign chain
// the execution is always expected to fail because of transfer data arguments
// we also check that tokens are burned if the execution fails
func TestChainSimulator_ExecuteWithTransferDataFails(t *testing.T) {
if testing.Short() {
t.Skip("this is not a short test")
}

roundsPerEpoch := core.OptionalUint64{
HasValue: true,
Value: 20,
}
cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{
BypassTxSignatureCheck: true,
TempDir: t.TempDir(),
PathToInitialConfig: defaultPathToInitialConfig,
NumOfShards: 3,
GenesisTimestamp: time.Now().Unix(),
RoundDurationInMillis: uint64(6000),
RoundsPerEpoch: roundsPerEpoch,
ApiInterface: api.NewNoApiInterface(),
MinNodesPerShard: 3,
MetaChainMinNodes: 3,
NumNodesWaitingListMeta: 0,
NumNodesWaitingListShard: 0,
AlterConfigsFunction: func(cfg *config.Configs) {
cfg.SystemSCConfig.ESDTSystemSCConfig.BaseIssuingCost = issuePaymentCost
},
})
require.Nil(t, err)
require.NotNil(t, cs)

defer cs.Close()

err = cs.GenerateBlocksUntilEpochIsReached(4)
require.Nil(t, err)

// deploy bridge setup
initialAddress := "erd1l6xt0rqlyzw56a3k8xwwshq2dcjwy3q9cppucvqsmdyw8r98dz3sae0kxl"
chainSim.InitAddressesAndSysAccState(t, cs, initialAddress)
bridgeData := deployBridgeSetup(t, cs, initialAddress, ArgsEsdtSafe{}, esdtSafeContract, esdtSafeWasmPath)
esdtSafeAddr, _ := cs.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Encode(bridgeData.ESDTSafeAddress)
esdtSafeAddrShard := chainSim.GetShardForAddress(cs, esdtSafeAddr)

wallet, err := cs.GenerateAndMintWalletAddress(0, chainSim.InitialAmount)
require.Nil(t, err)
nonce := uint64(0)

err = cs.GenerateBlocks(1)
require.Nil(t, err)

receiverShardId := uint32(0)

// TODO MX-15942 uncomment dynamic tokens, currently there is no issue function in SC framework for dynamic esdts
tokens := make([]chainSim.ArgsDepositToken, 0)
tokens = append(tokens, chainSim.ArgsDepositToken{
Identifier: "ab1-TKN-fasd35",
Nonce: uint64(0),
Amount: big.NewInt(14556666767),
Type: core.Fungible,
})
tokens = append(tokens, chainSim.ArgsDepositToken{
Identifier: "ab1-NFTV2-1ds234",
Nonce: uint64(1),
Amount: big.NewInt(1),
Type: core.NonFungibleV2,
})
//tokens = append(tokens, chainSim.ArgsDepositToken{
// Identifier: "ab2-DNFT-fdfe3r",
// Nonce: uint64(1),
// Amount: big.NewInt(1),
// Type: core.DynamicNFT,
//})
tokens = append(tokens, chainSim.ArgsDepositToken{
Identifier: "ab2-SFT-gw4fw2",
Nonce: uint64(1),
Amount: big.NewInt(1421),
Type: core.SemiFungible,
})
//tokens = append(tokens, chainSim.ArgsDepositToken{
// Identifier: "ab4-DSFT-g43g2s",
// Nonce: uint64(1),
// Amount: big.NewInt(1534),
// Type: core.DynamicSFT,
//})
tokens = append(tokens, chainSim.ArgsDepositToken{
Identifier: "ab5-META-1ds234",
Nonce: uint64(1),
Amount: big.NewInt(6231),
Type: core.MetaFungible,
})
//tokens = append(tokens, chainSim.ArgsDepositToken{
// Identifier: "ab5-DMETA-f23g2f",
// Nonce: uint64(1),
// Amount: big.NewInt(162367),
// Type: core.DynamicMeta,
//})

// generate hello contracts in each shard
// hello contract has one endpoint "hello" which receives a number as argument
// if number is 0 then will throw error, otherwise will do nothing
receiverContracts := deployReceiverContractInAllShards(t, cs)

tokensMapper := make(map[string]string)

// transfer sovereign chain -> main chain -> sovereign chain
// token originated from sovereign chain
for _, token := range tokens {
// register sovereign token identifier
// this will issue a new token on main chain and create a mapper between the identifiers
registerTokens(t, cs, wallet, &nonce, bridgeData.ESDTSafeAddress, token)
tokensMapper[token.Identifier] = chainSim.GetIssuedEsdtIdentifier(t, cs.GetNodeHandler(core.MetachainShardId), getTokenTicker(token.Identifier), token.Type.String())

// get contract from next shard
receiver := receiverContracts[receiverShardId]

// execute operations received from sovereign chain
// expecting the token to be minted in esdt-safe contract with the same properties and transferred with SC call to hello contract
// for (dynamic) SFT/MetaESDT the contract will create one more token and keep it forever
trnsData := &transferData{
GasLimit: uint64(10000000),
Function: []byte("hello"),
Args: [][]byte{{0x00}},
}
// the executed operation in hello contract is expected to fail, tokens will be minted and then burned
txResult := executeOperation(t, cs, bridgeData.OwnerAccount.Wallet, receiver.Bytes, &bridgeData.OwnerAccount.Nonce, bridgeData.ESDTSafeAddress, []chainSim.ArgsDepositToken{token}, wallet.Bytes, trnsData)
chainSim.RequireSuccessfulTransaction(t, txResult)
receivedToken := chainSim.ArgsDepositToken{
Identifier: tokensMapper[token.Identifier],
Nonce: token.Nonce,
Amount: token.Amount,
Type: token.Type,
}
if isSftOrMeta(receivedToken.Type) {
chainSim.RequireAccountHasToken(t, cs, getTokenIdentifier(receivedToken), esdtSafeAddr, big.NewInt(1))
} else {
chainSim.RequireAccountHasToken(t, cs, getTokenIdentifier(receivedToken), esdtSafeAddr, big.NewInt(0))
}

// no tokens should be in hello contract
waitIfCrossShardProcessing(cs, esdtSafeAddrShard, receiverShardId)
chainSim.RequireAccountHasToken(t, cs, getTokenIdentifier(receivedToken), receiver.Bech32, big.NewInt(0))

// wait for tokens to be sent back if cross shard
waitIfCrossShardProcessing(cs, esdtSafeAddrShard, receiverShardId)
// still no tokens in esdt-safe, tokens should be burned
if isSftOrMeta(receivedToken.Type) {
chainSim.RequireAccountHasToken(t, cs, getTokenIdentifier(receivedToken), esdtSafeAddr, big.NewInt(1))
} else {
chainSim.RequireAccountHasToken(t, cs, getTokenIdentifier(receivedToken), esdtSafeAddr, big.NewInt(0))
}
tokenSupply, err := cs.GetNodeHandler(esdtSafeAddrShard).GetFacadeHandler().GetTokenSupply(getTokenIdentifier(receivedToken))
require.Nil(t, err)
require.NotNil(t, tokenSupply)
require.Equal(t, receivedToken.Amount.String(), tokenSupply.Burned)

nextShardId(&receiverShardId)
}
}

func waitIfCrossShardProcessing(cs chainSim.ChainSimulator, senderShard uint32, receivedShard uint32) {
if senderShard != receivedShard {
_ = cs.GenerateBlocks(3)
Expand Down Expand Up @@ -518,7 +679,9 @@ func deployReceiverContractInAllShards(t *testing.T, cs chainSim.ChainSimulator)
}

func isNft(esdtType core.ESDTType) bool {
return esdtType == core.NonFungible || esdtType == core.NonFungibleV2
return esdtType == core.NonFungible ||
esdtType == core.NonFungibleV2 ||
esdtType == core.DynamicNFT
}

func isSftOrMeta(esdtType core.ESDTType) bool {
Expand Down
Binary file modified integrationTests/chainSimulator/bridge/testdata/esdt-safe.wasm
Binary file not shown.
2 changes: 1 addition & 1 deletion integrationTests/chainSimulator/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ func IssueFungible(
func GetIssuedEsdtIdentifier(t *testing.T, nodeHandler process.NodeHandler, ticker string, tokenType string) string {
issuedTokens, err := nodeHandler.GetFacadeHandler().GetAllIssuedESDTs(tokenType)
require.Nil(t, err)
require.GreaterOrEqual(t, len(issuedTokens), 1)
require.GreaterOrEqual(t, len(issuedTokens), 1, "no issued tokens found of type %s", tokenType)

for _, issuedToken := range issuedTokens {
if strings.Contains(issuedToken, ticker) {
Expand Down

0 comments on commit 91c8f13

Please sign in to comment.