diff --git a/e2e/e2e_test.go b/e2e/e2e_test.go index 396b195a..223a0980 100644 --- a/e2e/e2e_test.go +++ b/e2e/e2e_test.go @@ -26,11 +26,8 @@ import ( "testing" "time" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - evmSetup "github.com/limechain/hedera-eth-bridge-validator/e2e/setup/evm" - "github.com/limechain/hedera-eth-bridge-validator/app/clients/hedera/mirror-node/model/transaction" hederahelper "github.com/limechain/hedera-eth-bridge-validator/app/helper/hedera" "github.com/limechain/hedera-eth-bridge-validator/app/helper/timestamp" auth_message "github.com/limechain/hedera-eth-bridge-validator/app/model/auth-message" @@ -41,7 +38,6 @@ import ( "github.com/limechain/hedera-eth-bridge-validator/e2e/helper/expected" "github.com/limechain/hedera-eth-bridge-validator/e2e/helper/fetch" "github.com/limechain/hedera-eth-bridge-validator/e2e/helper/submit" - "github.com/limechain/hedera-eth-bridge-validator/e2e/helper/utilities" "github.com/limechain/hedera-eth-bridge-validator/e2e/helper/verify" "github.com/limechain/hedera-eth-bridge-validator/e2e/setup" @@ -70,8 +66,8 @@ func Test_HBAR(t *testing.T) { t.Fatalf("Expecting Token [%s] is not supported. - Error: [%s]", constants.Hbar, err) } - mintAmount, fee := expected.ReceiverAndFeeAmounts(setupEnv.Clients.FeeCalculator, setupEnv.Clients.Distributor, constants.Hbar, amount) - + mintAmount, validatorsFee, treasuryFee := expected.ReceiverAndFeeAmounts(setupEnv.Clients.FeeCalculator, setupEnv.Clients.Distributor, constants.Hbar, amount) + fee := validatorsFee + treasuryFee // Step 1 - Verify the transfer of Hbars to the Bridge Account transactionResponse, wrappedBalanceBefore := verify.TransferToBridgeAccount(t, setupEnv.Clients.Hedera, setupEnv.BridgeAccount, targetAsset, evm, memo, receiver, amount) @@ -79,8 +75,8 @@ func Test_HBAR(t *testing.T) { receivedSignatures := verify.TopicMessagesWithStartTime(t, setupEnv.Clients.Hedera, setupEnv.TopicID, setupEnv.Scenario.ExpectedValidatorsCount, hederahelper.FromHederaTransactionID(transactionResponse.TransactionID).String(), now.UnixNano()) // Step 3 - Validate fee scheduled transaction - expectedTransfers := expected.MirrorNodeExpectedTransfersForHederaTransfer(setupEnv.Members, setupEnv.BridgeAccount, constants.Hbar, fee) - scheduledTxID, scheduleID := verify.MembersScheduledTxs(t, setupEnv.Clients.Hedera, setupEnv.Clients.MirrorNode, setupEnv.Members, constants.Hbar, expectedTransfers, now) + expectedMembersTransfers := expected.MirrorNodeExpectedTransfersForHederaTransfer(setupEnv.Members, setupEnv.Treasury, setupEnv.BridgeAccount, constants.Hbar, validatorsFee, treasuryFee) + scheduledTxID, scheduleID := verify.ScheduledTxs(t, setupEnv.Clients.Hedera, setupEnv.Clients.MirrorNode, setupEnv.Members, setupEnv.Treasury, constants.Hbar, expectedMembersTransfers, now) // Step 4 - Verify Transfer retrieved from Validator API transactionData := verify.FungibleTransferFromValidatorAPI( @@ -134,7 +130,7 @@ func Test_HBAR(t *testing.T) { ) // and: - expectedFeeRecord := expected.FeeRecord( + expectedMemberFeeRecord := expected.FeeRecord( scheduledTxID, scheduleID, fee, @@ -157,7 +153,7 @@ func Test_HBAR(t *testing.T) { // Step 9 - Verify Database Records verify.TransferRecordAndSignatures(t, setupEnv.DbValidator, expectedTxRecord, authMsgBytes, receivedSignatures) // and: - verify.FeeRecord(t, setupEnv.DbValidator, expectedFeeRecord) + verify.FeeRecord(t, setupEnv.DbValidator, expectedMemberFeeRecord) } // Test_E2E_Token_Transfer recreates a real life situation of a user who wants to bridge a Hedera native token to the EVM Network infrastructure. The wrapped token on the EVM network(corresponding to the native Hedera Hashgraph's one) gets minted, then transferred to the recipient account on the EVM network. @@ -174,8 +170,8 @@ func Test_E2E_Token_Transfer(t *testing.T) { chainId := setupEnv.Scenario.FirstEvmChainId evm := setupEnv.Clients.EVM[chainId] memo := fmt.Sprintf("%d-%s", chainId, evm.Receiver.String()) - mintAmount, fee := expected.ReceiverAndFeeAmounts(setupEnv.Clients.FeeCalculator, setupEnv.Clients.Distributor, setupEnv.TokenID.String(), amount) - + mintAmount, validatorsFee, treasuryFee := expected.ReceiverAndFeeAmounts(setupEnv.Clients.FeeCalculator, setupEnv.Clients.Distributor, setupEnv.TokenID.String(), amount) + fee := validatorsFee + treasuryFee targetAsset, err := evmSetup.NativeToWrappedAsset(setupEnv.AssetMappings, constants.HederaNetworkId, chainId, setupEnv.TokenID.String()) if err != nil { t.Fatalf("Expecting Token [%s] is not supported. - Error: [%s]", constants.Hbar, err) @@ -188,8 +184,8 @@ func Test_E2E_Token_Transfer(t *testing.T) { receivedSignatures := verify.TopicMessagesWithStartTime(t, setupEnv.Clients.Hedera, setupEnv.TopicID, setupEnv.Scenario.ExpectedValidatorsCount, hederahelper.FromHederaTransactionID(transactionResponse.TransactionID).String(), now.UnixNano()) // Step 3 - Validate fee scheduled transaction - expectedTransfers := expected.MirrorNodeExpectedTransfersForHederaTransfer(setupEnv.Members, setupEnv.BridgeAccount, setupEnv.TokenID.String(), fee) - scheduledTxID, scheduleID := verify.MembersScheduledTxs(t, setupEnv.Clients.Hedera, setupEnv.Clients.MirrorNode, setupEnv.Members, setupEnv.TokenID.String(), expectedTransfers, now) + expectedTransfers := expected.MirrorNodeExpectedTransfersForHederaTransfer(setupEnv.Members, setupEnv.Treasury, setupEnv.BridgeAccount, setupEnv.TokenID.String(), validatorsFee, treasuryFee) + scheduledTxID, scheduleID := verify.ScheduledTxs(t, setupEnv.Clients.Hedera, setupEnv.Clients.MirrorNode, setupEnv.Members, setupEnv.Treasury, setupEnv.TokenID.String(), expectedTransfers, now) // Step 4 - Verify Transfer retrieved from Validator API transactionData := verify.FungibleTransferFromValidatorAPI( @@ -289,8 +285,8 @@ func Test_EVM_Hedera_HBAR(t *testing.T) { } // Step 1 - Calculate Expected Receive And Fee Amounts - expectedReceiveAmount, fee := expected.ReceiverAndFeeAmounts(setupEnv.Clients.FeeCalculator, setupEnv.Clients.Distributor, constants.Hbar, amount) - + expectedReceiveAmount, validatorFee, treasuryFee := expected.ReceiverAndFeeAmounts(setupEnv.Clients.FeeCalculator, setupEnv.Clients.Distributor, constants.Hbar, amount) + fee := validatorFee + treasuryFee // Step 2 - Submit burn transaction to the bridge contract burnTxReceipt, expectedRouterBurn := submit.BurnEthTransaction(t, setupEnv.AssetMappings, evm, constants.Hbar, constants.HederaNetworkId, chainId, setupEnv.Clients.Hedera.GetOperatorAccountID().ToBytes(), amount) @@ -305,8 +301,8 @@ func Test_EVM_Hedera_HBAR(t *testing.T) { expectedId := verify.BurnEvent(t, burnTxReceipt, expectedRouterBurn) // Step 4 - Validate that a scheduled transaction was submitted - expectedTransfers := expected.MirrorNodeExpectedTransfersForBurnEvent(setupEnv.Members, setupEnv.Clients.Hedera, setupEnv.BridgeAccount, constants.Hbar, expectedReceiveAmount, fee) - transactionID, scheduleID := verify.SubmittedScheduledTx(t, setupEnv.Clients.Hedera, setupEnv.Clients.MirrorNode, setupEnv.Members, constants.Hbar, expectedTransfers, now) + expectedTransfers := expected.MirrorNodeExpectedTransfersForBurnEvent(setupEnv.Members, setupEnv.Treasury, setupEnv.Clients.Hedera, setupEnv.BridgeAccount, constants.Hbar, expectedReceiveAmount, validatorFee, treasuryFee) + transactionID, scheduleID := verify.SubmittedScheduledTx(t, setupEnv.Clients.Hedera, setupEnv.Clients.MirrorNode, setupEnv.Members, setupEnv.Treasury, constants.Hbar, expectedTransfers, now) // Step 5 - Validate Event Transaction ID retrieved from Validator API verify.EventTransactionIDFromValidatorAPI(t, setupEnv.Clients.ValidatorClient, expectedId, transactionID) @@ -360,7 +356,8 @@ func Test_EVM_Hedera_Token(t *testing.T) { } // Step 1 - Calculate Expected Receive Amount - expectedReceiveAmount, fee := expected.ReceiverAndFeeAmounts(setupEnv.Clients.FeeCalculator, setupEnv.Clients.Distributor, setupEnv.TokenID.String(), amount) + expectedReceiveAmount, validatorFee, treasuryFee := expected.ReceiverAndFeeAmounts(setupEnv.Clients.FeeCalculator, setupEnv.Clients.Distributor, setupEnv.TokenID.String(), amount) + fee := validatorFee + treasuryFee // Step 2 - Submit burn transaction to the bridge contract burnTxReceipt, expectedRouterBurn := submit.BurnEthTransaction(t, setupEnv.AssetMappings, evm, setupEnv.TokenID.String(), constants.HederaNetworkId, chainId, setupEnv.Clients.Hedera.GetOperatorAccountID().ToBytes(), amount) @@ -376,8 +373,8 @@ func Test_EVM_Hedera_Token(t *testing.T) { expectedId := verify.BurnEvent(t, burnTxReceipt, expectedRouterBurn) // Step 4 - Validate that a scheduled transaction was submitted - expectedTransfers := expected.MirrorNodeExpectedTransfersForBurnEvent(setupEnv.Members, setupEnv.Clients.Hedera, setupEnv.BridgeAccount, setupEnv.TokenID.String(), expectedReceiveAmount, fee) - transactionID, scheduleID := verify.SubmittedScheduledTx(t, setupEnv.Clients.Hedera, setupEnv.Clients.MirrorNode, setupEnv.Members, setupEnv.TokenID.String(), expectedTransfers, now) + expectedTransfers := expected.MirrorNodeExpectedTransfersForBurnEvent(setupEnv.Members, setupEnv.Treasury, setupEnv.Clients.Hedera, setupEnv.BridgeAccount, setupEnv.TokenID.String(), expectedReceiveAmount, validatorFee, treasuryFee) + transactionID, scheduleID := verify.SubmittedScheduledTx(t, setupEnv.Clients.Hedera, setupEnv.Clients.MirrorNode, setupEnv.Members, setupEnv.Treasury, setupEnv.TokenID.String(), expectedTransfers, now) // Step 5 - Validate Event Transaction ID retrieved from Validator API verify.EventTransactionIDFromValidatorAPI(t, setupEnv.Clients.ValidatorClient, expectedId, transactionID) @@ -411,444 +408,443 @@ func Test_EVM_Hedera_Token(t *testing.T) { } // Test_EVM_Hedera_Native_Token recreates a real life situation of a user who wants to bridge an EVM native token to the Hedera infrastructure. A new wrapped token (corresponding to the native EVM one) gets minted to the bridge account, then gets transferred to the recipient account. -func Test_EVM_Hedera_Native_Token(t *testing.T) { - if testing.Short() { - t.Skip("test skipped in short mode") - } - - setupEnv := setup.Load() - now := time.Now() - - amount := setupEnv.Scenario.AmountEvmNative - - chainId := setupEnv.Scenario.FirstEvmChainId - evm := setupEnv.Clients.EVM[chainId] - - bridgeAccountBalanceBefore := fetch.HederaAccountBalance(t, setupEnv.Clients.Hedera, setupEnv.BridgeAccount) - receiverAccountBalanceBefore := fetch.HederaAccountBalance(t, setupEnv.Clients.Hedera, setupEnv.Clients.Hedera.GetOperatorAccountID()) - - targetAsset, err := evmSetup.NativeToWrappedAsset(setupEnv.AssetMappings, chainId, constants.HederaNetworkId, setupEnv.NativeEvmToken) - if err != nil { - t.Fatal(err) - } - - // Step 1: Submit Lock Txn from a deployed smart contract - receipt, expectedLockEventLog := submit.LockEthTransaction(t, evm, setupEnv.NativeEvmToken, constants.HederaNetworkId, setupEnv.Clients.Hedera.GetOperatorAccountID().ToBytes(), amount) - - // Step 1.1 - Get the block timestamp of lock event - block, err := evm.EVMClient.BlockByNumber(context.Background(), receipt.BlockNumber) - if err != nil { - t.Fatal("failed to get block by number", err) - } - blockTimestamp := time.Unix(int64(block.Time()), 0).UTC() - - // Step 2: Validate Lock Event was emitted with correct data - lockEventId := verify.LockEvent(t, receipt, expectedLockEventLog) - - bridgedAmount := new(big.Int).Sub(expectedLockEventLog.Amount, expectedLockEventLog.ServiceFee) - expectedAmount, err := utilities.RemoveDecimals(bridgedAmount.Int64(), common.HexToAddress(setupEnv.NativeEvmToken), evm) - if err != nil { - t.Fatal(err) - } - - mintTransfer := []transaction.Transfer{ - { - Account: setupEnv.BridgeAccount.String(), - Amount: expectedAmount, - Token: targetAsset, - }, - } - - // Step 3: Validate that a scheduled token mint txn was submitted successfully - bridgeMintTransactionID, bridgeMintScheduleID := verify.ScheduledMintTx(t, setupEnv.Clients.MirrorNode, setupEnv.BridgeAccount, setupEnv.TokenID.String(), mintTransfer, now) - - // Step 4: Validate that Database statuses were changed correctly - expectedLockEventRecord := expected.FungibleTransferRecord( - chainId, - constants.HederaNetworkId, - chainId, - lockEventId, - setupEnv.NativeEvmToken, - targetAsset, - setupEnv.NativeEvmToken, - strconv.FormatInt(expectedAmount, 10), - "", - setupEnv.Clients.Hedera.GetOperatorAccountID().String(), - status.Completed, - evm.Signer.Address(), - entity.NanoTime{Time: blockTimestamp}, - ) - - expectedScheduleMintRecord := expected.ScheduleRecord( - bridgeMintTransactionID, - bridgeMintScheduleID, - schedule.MINT, - false, - status.Completed, - sql.NullString{ - String: lockEventId, - Valid: true, - }, - ) - - // Step 5: Verify that records have been created successfully - verify.TransferRecord(t, setupEnv.DbValidator, expectedLockEventRecord) - verify.ScheduleRecord(t, setupEnv.DbValidator, expectedScheduleMintRecord) - - // Step 6: Validate that a scheduled transfer txn was submitted successfully - bridgeTransferTransactionID, bridgeTransferScheduleID := verify.ScheduledTx( - t, - setupEnv.Clients.Hedera, - setupEnv.Clients.MirrorNode, - setupEnv.Clients.Hedera.GetOperatorAccountID(), - setupEnv.TokenID.String(), - expected.MirrorNodeExpectedTransfersForLockEvent(setupEnv.Clients.Hedera, setupEnv.BridgeAccount, targetAsset, expectedAmount), - now, - ) - - // Step 7: Validate that database statuses were updated correctly for the Schedule Transfer - expectedScheduleTransferRecord := &entity.Schedule{ - TransactionID: bridgeTransferTransactionID, - ScheduleID: bridgeTransferScheduleID, - Operation: schedule.TRANSFER, - HasReceiver: true, - Status: status.Completed, - TransferID: sql.NullString{ - String: lockEventId, - Valid: true, - }, - } - - verify.ScheduleRecord(t, setupEnv.DbValidator, expectedScheduleTransferRecord) - - // Step 8 Validate Treasury(BridgeAccount) Balance and Receiver Balance - verify.AccountBalance(t, setupEnv.Clients.Hedera, setupEnv.BridgeAccount, 0, bridgeAccountBalanceBefore, targetAsset) - verify.AccountBalance(t, setupEnv.Clients.Hedera, setupEnv.Clients.Hedera.GetOperatorAccountID(), uint64(expectedAmount), receiverAccountBalanceBefore, targetAsset) -} +// func Test_EVM_Hedera_Native_Token(t *testing.T) { +// if testing.Short() { +// t.Skip("test skipped in short mode") +// } + +// setupEnv := setup.Load() +// now := time.Now() + +// amount := setupEnv.Scenario.AmountEvmNative + +// chainId := setupEnv.Scenario.FirstEvmChainId +// evm := setupEnv.Clients.EVM[chainId] +// bridgeAccountBalanceBefore := fetch.HederaAccountBalance(t, setupEnv.Clients.Hedera, setupEnv.BridgeAccount) +// receiverAccountBalanceBefore := fetch.HederaAccountBalance(t, setupEnv.Clients.Hedera, setupEnv.Clients.Hedera.GetOperatorAccountID()) + +// targetAsset, err := evmSetup.NativeToWrappedAsset(setupEnv.AssetMappings, chainId, constants.HederaNetworkId, setupEnv.NativeEvmToken) +// if err != nil { +// t.Fatal(err) +// } + +// // Step 1: Submit Lock Txn from a deployed smart contract +// receipt, expectedLockEventLog := submit.LockEthTransaction(t, evm, setupEnv.NativeEvmToken, constants.HederaNetworkId, setupEnv.Clients.Hedera.GetOperatorAccountID().ToBytes(), amount) + +// // Step 1.1 - Get the block timestamp of lock event +// block, err := evm.EVMClient.BlockByNumber(context.Background(), receipt.BlockNumber) +// if err != nil { +// t.Fatal("failed to get block by number", err) +// } +// blockTimestamp := time.Unix(int64(block.Time()), 0).UTC() + +// // Step 2: Validate Lock Event was emitted with correct data +// lockEventId := verify.LockEvent(t, receipt, expectedLockEventLog) + +// bridgedAmount := new(big.Int).Sub(expectedLockEventLog.Amount, expectedLockEventLog.ServiceFee) +// expectedAmount, err := utilities.RemoveDecimals(bridgedAmount.Int64(), common.HexToAddress(setupEnv.NativeEvmToken), evm) +// if err != nil { +// t.Fatal(err) +// } + +// mintTransfer := []transaction.Transfer{ +// { +// Account: setupEnv.BridgeAccount.String(), +// Amount: expectedAmount, +// Token: targetAsset, +// }, +// } + +// // Step 3: Validate that a scheduled token mint txn was submitted successfully +// bridgeMintTransactionID, bridgeMintScheduleID := verify.ScheduledMintTx(t, setupEnv.Clients.MirrorNode, setupEnv.BridgeAccount, setupEnv.TokenID.String(), mintTransfer, now) + +// // Step 4: Validate that Database statuses were changed correctly +// expectedLockEventRecord := expected.FungibleTransferRecord( +// chainId, +// constants.HederaNetworkId, +// chainId, +// lockEventId, +// setupEnv.NativeEvmToken, +// targetAsset, +// setupEnv.NativeEvmToken, +// strconv.FormatInt(expectedAmount, 10), +// "", +// setupEnv.Clients.Hedera.GetOperatorAccountID().String(), +// status.Completed, +// evm.Signer.Address(), +// entity.NanoTime{Time: blockTimestamp}, +// ) + +// expectedScheduleMintRecord := expected.ScheduleRecord( +// bridgeMintTransactionID, +// bridgeMintScheduleID, +// schedule.MINT, +// false, +// status.Completed, +// sql.NullString{ +// String: lockEventId, +// Valid: true, +// }, +// ) + +// // Step 5: Verify that records have been created successfully +// verify.TransferRecord(t, setupEnv.DbValidator, expectedLockEventRecord) +// verify.ScheduleRecord(t, setupEnv.DbValidator, expectedScheduleMintRecord) + +// // Step 6: Validate that a scheduled transfer txn was submitted successfully +// bridgeTransferTransactionID, bridgeTransferScheduleID := verify.ScheduledTx( +// t, +// setupEnv.Clients.Hedera, +// setupEnv.Clients.MirrorNode, +// setupEnv.Clients.Hedera.GetOperatorAccountID(), +// setupEnv.TokenID.String(), +// expected.MirrorNodeExpectedTransfersForLockEvent(setupEnv.Clients.Hedera, setupEnv.BridgeAccount, targetAsset, expectedAmount), +// now, +// ) + +// // Step 7: Validate that database statuses were updated correctly for the Schedule Transfer +// expectedScheduleTransferRecord := &entity.Schedule{ +// TransactionID: bridgeTransferTransactionID, +// ScheduleID: bridgeTransferScheduleID, +// Operation: schedule.TRANSFER, +// HasReceiver: true, +// Status: status.Completed, +// TransferID: sql.NullString{ +// String: lockEventId, +// Valid: true, +// }, +// } + +// verify.ScheduleRecord(t, setupEnv.DbValidator, expectedScheduleTransferRecord) + +// // Step 8 Validate Treasury(BridgeAccount) Balance and Receiver Balance +// verify.AccountBalance(t, setupEnv.Clients.Hedera, setupEnv.BridgeAccount, 0, bridgeAccountBalanceBefore, targetAsset) +// verify.AccountBalance(t, setupEnv.Clients.Hedera, setupEnv.Clients.Hedera.GetOperatorAccountID(), uint64(expectedAmount), receiverAccountBalanceBefore, targetAsset) +// } // Test_E2E_Hedera_EVM_Native_Token recreates a real life situation of a user who wants to bridge a Hedera wrapped token to the EVM Native Network infrastructure. The wrapped token on the EVM network(corresponding to the native Hedera Hashgraph's one) gets minted, then transferred to the recipient account on the EVM network. -func Test_E2E_Hedera_EVM_Native_Token(t *testing.T) { - if testing.Short() { - t.Skip("test skipped in short mode") - } - - setupEnv := setup.Load() - now := time.Now() - - unlockAmount := setupEnv.Scenario.AmountHederaWrapped - - chainId := setupEnv.Scenario.FirstEvmChainId - evm := setupEnv.Clients.EVM[chainId] - memo := fmt.Sprintf("%d-%s", chainId, evm.Receiver.String()) - - // Step 1 - Verify the transfer of HTS to the Bridge Account - wrappedAsset, err := evmSetup.NativeToWrappedAsset(setupEnv.AssetMappings, chainId, constants.HederaNetworkId, setupEnv.NativeEvmToken) - if err != nil { - t.Fatal(err) - } - - tokenID, err := hedera.TokenIDFromString(wrappedAsset) - if err != nil { - t.Fatal(err) - } - - expectedSubmitUnlockAmount, err := utilities.AddDecimals(unlockAmount, common.HexToAddress(setupEnv.NativeEvmToken), evm) - if err != nil { - t.Fatal(err) - } - - transactionResponse, nativeBalanceBefore := verify.TokenTransferToBridgeAccount(t, setupEnv.Clients.Hedera, setupEnv.BridgeAccount, setupEnv.NativeEvmToken, tokenID, evm, memo, evm.Receiver, unlockAmount) - - burnTransfer := []transaction.Transfer{ - { - Account: setupEnv.BridgeAccount.String(), - Amount: -unlockAmount, - Token: wrappedAsset, - }, - } - - // Step 2 - Verify the submitted topic messages - receivedSignatures := verify.TopicMessagesWithStartTime(t, setupEnv.Clients.Hedera, setupEnv.TopicID, setupEnv.Scenario.ExpectedValidatorsCount, hederahelper.FromHederaTransactionID(transactionResponse.TransactionID).String(), now.UnixNano()) - - // Step 3 - Validate burn scheduled transaction - burnTransactionID, burnScheduleID := verify.ScheduledBurnTx(t, setupEnv.Clients.MirrorNode, setupEnv.BridgeAccount, setupEnv.TokenID.String(), burnTransfer, now) - - // Step 4 - Verify Transfer retrieved from Validator API - transactionData := verify.FungibleTransferFromValidatorAPI( - t, - setupEnv.Clients.ValidatorClient, - setupEnv.TokenID, - evm, - hederahelper.FromHederaTransactionID(transactionResponse.TransactionID).String(), - setupEnv.NativeEvmToken, - fmt.Sprint(expectedSubmitUnlockAmount), - setupEnv.NativeEvmToken, - ) - - // Step 4.1 - Get the consensus timestamp of the transfer - tx, err := setupEnv.Clients.MirrorNode.GetSuccessfulTransaction(hederahelper.FromHederaTransactionID(transactionResponse.TransactionID).String()) - if err != nil { - t.Fatal("failed to get successful transaction", err) - } - nanos, err := timestamp.FromString(tx.ConsensusTimestamp) - if err != nil { - t.Fatal("failed to parse consensus timestamp", err) - } - ts := timestamp.FromNanos(nanos) - - // Step 5 - Submit Unlock transaction - txHash := submit.UnlockTransaction(t, evm, hederahelper.FromHederaTransactionID(transactionResponse.TransactionID).String(), transactionData, common.HexToAddress(setupEnv.NativeEvmToken)) - - // Step 6 - Wait for transaction to be mined - submit.WaitForTransaction(t, evm, txHash) - - expectedUnlockedAmount, _ := expected.EvmAmoundAndFee(evm.RouterContract, setupEnv.NativeEvmToken, expectedSubmitUnlockAmount, t) - - // Step 7 - Validate Token balances - verify.WrappedAssetBalance(t, evm, setupEnv.NativeEvmToken, expectedUnlockedAmount, nativeBalanceBefore, evm.Receiver) - - // Step 8 - Verify Database records - expectedTxRecord := expected.FungibleTransferRecord( - constants.HederaNetworkId, - chainId, - chainId, - hederahelper.FromHederaTransactionID(transactionResponse.TransactionID).String(), - wrappedAsset, - setupEnv.NativeEvmToken, - setupEnv.NativeEvmToken, - strconv.FormatInt(expectedSubmitUnlockAmount, 10), - "", - evm.Receiver.String(), - status.Completed, - setupEnv.Clients.Hedera.GetOperatorAccountID().String(), - entity.NanoTime{Time: ts}, - ) - - // Step 8: Validate that database statuses were updated correctly for the Schedule Burn - expectedScheduleBurnRecord := expected.ScheduleRecord( - burnTransactionID, - burnScheduleID, - schedule.BURN, - false, - status.Completed, - sql.NullString{ - String: hederahelper.FromHederaTransactionID(transactionResponse.TransactionID).String(), - Valid: true, - }, - ) - - authMsgBytes, err := auth_message.EncodeFungibleBytesFrom( - expectedTxRecord.SourceChainID, - expectedTxRecord.TargetChainID, - expectedTxRecord.TransactionID, - expectedTxRecord.TargetAsset, - expectedTxRecord.Receiver, - strconv.FormatInt(expectedSubmitUnlockAmount, 10), - ) - - if err != nil { - t.Fatalf("[%s] - Failed to encode the authorization signature. Error: [%s]", expectedTxRecord.TransactionID, err) - } - - // Step 9 - Verify Database Records - verify.TransferRecordAndSignatures(t, setupEnv.DbValidator, expectedTxRecord, authMsgBytes, receivedSignatures) - // and - verify.ScheduleRecord(t, setupEnv.DbValidator, expectedScheduleBurnRecord) -} - -// Test_EVM_Native_to_EVM_Token recreates a real life situation of a user who wants to bridge an EVM native token to another EVM chain. -func Test_EVM_Native_to_EVM_Token(t *testing.T) { - if testing.Short() { - t.Skip("test skipped in short mode") - } - - setupEnv := setup.Load() - now := time.Now() - - amount := setupEnv.Scenario.AmountEvmNative - - chainId := setupEnv.Scenario.FirstEvmChainId - evm := setupEnv.Clients.EVM[chainId] - targetChainID := setupEnv.Scenario.SecondEvmChainId - - wrappedAsset, err := evmSetup.NativeToWrappedAsset(setupEnv.AssetMappings, chainId, targetChainID, setupEnv.NativeEvmToken) - if err != nil { - t.Fatal(err) - } - - wrappedEvm := setupEnv.Clients.EVM[targetChainID] - wrappedInstance, err := evmSetup.InitAssetContract(wrappedAsset, wrappedEvm.EVMClient) - if err != nil { - t.Fatal(err) - } - - wrappedBalanceBefore, err := wrappedInstance.BalanceOf(&bind.CallOpts{}, evm.Receiver) - if err != nil { - t.Fatal(err) - } - - // Step 1 - Submit Lock Txn from a deployed smart contract - receipt, expectedLockEventLog := submit.LockEthTransaction(t, evm, setupEnv.NativeEvmToken, targetChainID, evm.Receiver.Bytes(), amount) - - expectedAmount := new(big.Int).Sub(expectedLockEventLog.Amount, expectedLockEventLog.ServiceFee) - - // Step 1.1 - Get the block timestamp of the lock event - block, err := evm.EVMClient.BlockByNumber(context.Background(), receipt.BlockNumber) - if err != nil { - t.Fatal("failed to get block by number", err) - } - blockTimestamp := time.Unix(int64(block.Time()), 0).UTC() - - // Step 2 - Validate Lock Event was emitted with correct data - lockEventId := verify.LockEvent(t, receipt, expectedLockEventLog) - - // Step 3 - Verify the submitted topic messages - receivedSignatures := verify.TopicMessagesWithStartTime(t, setupEnv.Clients.Hedera, setupEnv.TopicID, setupEnv.Scenario.ExpectedValidatorsCount, lockEventId, now.UnixNano()) - - // Step 4 - Verify Transfer retrieved from Validator API - transactionData := verify.FungibleTransferFromValidatorAPI(t, setupEnv.Clients.ValidatorClient, setupEnv.TokenID, evm, lockEventId, setupEnv.NativeEvmToken, expectedAmount.String(), wrappedAsset) - - // Step 5 - Submit Mint transaction - txHash := submit.MintTransaction(t, wrappedEvm, lockEventId, transactionData, common.HexToAddress(wrappedAsset)) - - // Step 6 - Wait for transaction to be mined - submit.WaitForTransaction(t, wrappedEvm, txHash) - - // Step 7 - Validate Token balances - verify.WrappedAssetBalance(t, wrappedEvm, wrappedAsset, expectedAmount, wrappedBalanceBefore, evm.Receiver) - - // Step 8 - Prepare expected Transfer record - expectedLockEventRecord := expected.FungibleTransferRecord( - chainId, - targetChainID, - chainId, - lockEventId, - setupEnv.NativeEvmToken, - wrappedAsset, - setupEnv.NativeEvmToken, - expectedAmount.String(), - "", - evm.Receiver.String(), - status.Completed, - evm.Signer.Address(), - entity.NanoTime{Time: blockTimestamp}, - ) - - authMsgBytes, err := auth_message.EncodeFungibleBytesFrom( - expectedLockEventRecord.SourceChainID, - expectedLockEventRecord.TargetChainID, - expectedLockEventRecord.TransactionID, - expectedLockEventRecord.TargetAsset, - expectedLockEventRecord.Receiver, - expectedAmount.String(), - ) - - if err != nil { - t.Fatalf("[%s] - Failed to encode the authorisation signature. Error: [%s]", expectedLockEventRecord.TransactionID, err) - } - - // Step 9 - Verify Database Records - verify.TransferRecordAndSignatures(t, setupEnv.DbValidator, expectedLockEventRecord, authMsgBytes, receivedSignatures) -} - -// Test_EVM_Wrapped_to_EVM_Token recreates a real life situation of a user who wants to bridge an EVM native token to another EVM chain. -func Test_EVM_Wrapped_to_EVM_Token(t *testing.T) { - if testing.Short() { - t.Skip("test skipped in short mode") - } - - setupEnv := setup.Load() - now := time.Now() - - amount := setupEnv.Scenario.AmountEvmWrapped - - chainId := setupEnv.Scenario.FirstEvmChainId - sourceChain := setupEnv.Scenario.SecondEvmChainId - wrappedEvm := setupEnv.Clients.EVM[sourceChain] - - sourceAsset, err := evmSetup.NativeToWrappedAsset(setupEnv.AssetMappings, chainId, sourceChain, setupEnv.NativeEvmToken) - if err != nil { - t.Fatal(err) - } - - evm := setupEnv.Clients.EVM[chainId] - - nativeInstance, err := evmSetup.InitAssetContract(setupEnv.NativeEvmToken, evm.EVMClient) - if err != nil { - t.Fatal(err) - } - - nativeBalanceBefore, err := nativeInstance.BalanceOf(&bind.CallOpts{}, evm.Receiver) - if err != nil { - t.Fatal(err) - } - - // Step 1 - Submit Lock Txn from a deployed smart contract - receipt, expectedLockEventLog := submit.BurnEthTransaction(t, setupEnv.AssetMappings, wrappedEvm, setupEnv.NativeEvmToken, chainId, sourceChain, evm.Receiver.Bytes(), amount) - - // Step 1.1 - Get the block timestamp of the burn event - block, err := wrappedEvm.EVMClient.BlockByNumber(context.Background(), receipt.BlockNumber) - if err != nil { - t.Fatal("failed to get block by number", err) - } - blockTimestamp := time.Unix(int64(block.Time()), 0).UTC() - - // Step 2 - Validate Burn Event was emitted with correct data - burnEventId := verify.BurnEvent(t, receipt, expectedLockEventLog) - - // Step 3 - Verify the submitted topic messages - receivedSignatures := verify.TopicMessagesWithStartTime(t, setupEnv.Clients.Hedera, setupEnv.TopicID, setupEnv.Scenario.ExpectedValidatorsCount, burnEventId, now.UnixNano()) - - // Step 4 - Verify Transfer retrieved from Validator API - transactionData := verify.FungibleTransferFromValidatorAPI(t, setupEnv.Clients.ValidatorClient, setupEnv.TokenID, evm, burnEventId, setupEnv.NativeEvmToken, fmt.Sprint(amount), setupEnv.NativeEvmToken) - - // Get fee amount from wrapped network Router - _, feeAmount := expected.EvmAmoundAndFee(evm.RouterContract, setupEnv.NativeEvmToken, amount, t) - - // Step 5 - Submit Mint transaction - txHash := submit.UnlockTransaction(t, evm, burnEventId, transactionData, common.HexToAddress(setupEnv.NativeEvmToken)) - - // Step 6 - Wait for transaction to be mined - submit.WaitForTransaction(t, evm, txHash) - - expectedUnlockedAmount := amount - feeAmount.Int64() - - // Step 7 - Validate Token balances - verify.WrappedAssetBalance(t, evm, setupEnv.NativeEvmToken, big.NewInt(expectedUnlockedAmount), nativeBalanceBefore, evm.Receiver) - - // Step 8 - Prepare expected Transfer record - expectedLockEventRecord := expected.FungibleTransferRecord( - sourceChain, - chainId, - chainId, - burnEventId, - sourceAsset, - setupEnv.NativeEvmToken, - setupEnv.NativeEvmToken, - strconv.FormatInt(amount, 10), - "", - evm.Receiver.String(), - status.Completed, - wrappedEvm.Signer.Address(), - entity.NanoTime{Time: blockTimestamp}, - ) - - authMsgBytes, err := auth_message.EncodeFungibleBytesFrom( - expectedLockEventRecord.SourceChainID, - expectedLockEventRecord.TargetChainID, - expectedLockEventRecord.TransactionID, - expectedLockEventRecord.TargetAsset, - expectedLockEventRecord.Receiver, - strconv.FormatInt(amount, 10), - ) - - if err != nil { - t.Fatalf("[%s] - Failed to encode the authorisation signature. Error: [%s]", expectedLockEventRecord.TransactionID, err) - } - - // Step 9 - Verify Database Records - verify.TransferRecordAndSignatures(t, setupEnv.DbValidator, expectedLockEventRecord, authMsgBytes, receivedSignatures) -} +// func Test_E2E_Hedera_EVM_Native_Token(t *testing.T) { +// if testing.Short() { +// t.Skip("test skipped in short mode") +// } + +// setupEnv := setup.Load() +// now := time.Now() + +// unlockAmount := setupEnv.Scenario.AmountHederaWrapped + +// chainId := setupEnv.Scenario.FirstEvmChainId +// evm := setupEnv.Clients.EVM[chainId] +// memo := fmt.Sprintf("%d-%s", chainId, evm.Receiver.String()) + +// // Step 1 - Verify the transfer of HTS to the Bridge Account +// wrappedAsset, err := evmSetup.NativeToWrappedAsset(setupEnv.AssetMappings, chainId, constants.HederaNetworkId, setupEnv.NativeEvmToken) +// if err != nil { +// t.Fatal(err) +// } + +// tokenID, err := hedera.TokenIDFromString(wrappedAsset) +// if err != nil { +// t.Fatal(err) +// } + +// expectedSubmitUnlockAmount, err := utilities.AddDecimals(unlockAmount, common.HexToAddress(setupEnv.NativeEvmToken), evm) +// if err != nil { +// t.Fatal(err) +// } + +// transactionResponse, nativeBalanceBefore := verify.TokenTransferToBridgeAccount(t, setupEnv.Clients.Hedera, setupEnv.BridgeAccount, setupEnv.NativeEvmToken, tokenID, evm, memo, evm.Receiver, unlockAmount) +// fmt.Println(transactionResponse.TransactionID) +// burnTransfer := []transaction.Transfer{ +// { +// Account: setupEnv.BridgeAccount.String(), +// Amount: -unlockAmount, +// Token: wrappedAsset, +// }, +// } + +// // Step 2 - Verify the submitted topic messages +// receivedSignatures := verify.TopicMessagesWithStartTime(t, setupEnv.Clients.Hedera, setupEnv.TopicID, setupEnv.Scenario.ExpectedValidatorsCount, hederahelper.FromHederaTransactionID(transactionResponse.TransactionID).String(), now.UnixNano()) + +// // Step 3 - Validate burn scheduled transaction +// burnTransactionID, burnScheduleID := verify.ScheduledBurnTx(t, setupEnv.Clients.MirrorNode, setupEnv.BridgeAccount, setupEnv.TokenID.String(), burnTransfer, now) + +// // Step 4 - Verify Transfer retrieved from Validator API +// transactionData := verify.FungibleTransferFromValidatorAPI( +// t, +// setupEnv.Clients.ValidatorClient, +// setupEnv.TokenID, +// evm, +// hederahelper.FromHederaTransactionID(transactionResponse.TransactionID).String(), +// setupEnv.NativeEvmToken, +// fmt.Sprint(expectedSubmitUnlockAmount), +// setupEnv.NativeEvmToken, +// ) + +// // Step 4.1 - Get the consensus timestamp of the transfer +// tx, err := setupEnv.Clients.MirrorNode.GetSuccessfulTransaction(hederahelper.FromHederaTransactionID(transactionResponse.TransactionID).String()) +// if err != nil { +// t.Fatal("failed to get successful transaction", err) +// } +// nanos, err := timestamp.FromString(tx.ConsensusTimestamp) +// if err != nil { +// t.Fatal("failed to parse consensus timestamp", err) +// } +// ts := timestamp.FromNanos(nanos) + +// // Step 5 - Submit Unlock transaction +// txHash := submit.UnlockTransaction(t, evm, hederahelper.FromHederaTransactionID(transactionResponse.TransactionID).String(), transactionData, common.HexToAddress(setupEnv.NativeEvmToken)) + +// // Step 6 - Wait for transaction to be mined +// submit.WaitForTransaction(t, evm, txHash) + +// expectedUnlockedAmount, _ := expected.EvmAmoundAndFee(evm.RouterContract, setupEnv.NativeEvmToken, expectedSubmitUnlockAmount, t) + +// // Step 7 - Validate Token balances +// verify.WrappedAssetBalance(t, evm, setupEnv.NativeEvmToken, expectedUnlockedAmount, nativeBalanceBefore, evm.Receiver) + +// // Step 8 - Verify Database records +// expectedTxRecord := expected.FungibleTransferRecord( +// constants.HederaNetworkId, +// chainId, +// chainId, +// hederahelper.FromHederaTransactionID(transactionResponse.TransactionID).String(), +// wrappedAsset, +// setupEnv.NativeEvmToken, +// setupEnv.NativeEvmToken, +// strconv.FormatInt(expectedSubmitUnlockAmount, 10), +// "", +// evm.Receiver.String(), +// status.Completed, +// setupEnv.Clients.Hedera.GetOperatorAccountID().String(), +// entity.NanoTime{Time: ts}, +// ) + +// // Step 8: Validate that database statuses were updated correctly for the Schedule Burn +// expectedScheduleBurnRecord := expected.ScheduleRecord( +// burnTransactionID, +// burnScheduleID, +// schedule.BURN, +// false, +// status.Completed, +// sql.NullString{ +// String: hederahelper.FromHederaTransactionID(transactionResponse.TransactionID).String(), +// Valid: true, +// }, +// ) + +// authMsgBytes, err := auth_message.EncodeFungibleBytesFrom( +// expectedTxRecord.SourceChainID, +// expectedTxRecord.TargetChainID, +// expectedTxRecord.TransactionID, +// expectedTxRecord.TargetAsset, +// expectedTxRecord.Receiver, +// strconv.FormatInt(expectedSubmitUnlockAmount, 10), +// ) + +// if err != nil { +// t.Fatalf("[%s] - Failed to encode the authorization signature. Error: [%s]", expectedTxRecord.TransactionID, err) +// } + +// // Step 9 - Verify Database Records +// verify.TransferRecordAndSignatures(t, setupEnv.DbValidator, expectedTxRecord, authMsgBytes, receivedSignatures) +// // and +// verify.ScheduleRecord(t, setupEnv.DbValidator, expectedScheduleBurnRecord) +// } + +// // Test_EVM_Native_to_EVM_Token recreates a real life situation of a user who wants to bridge an EVM native token to another EVM chain. +// func Test_EVM_Native_to_EVM_Token(t *testing.T) { +// if testing.Short() { +// t.Skip("test skipped in short mode") +// } + +// setupEnv := setup.Load() +// now := time.Now() + +// amount := setupEnv.Scenario.AmountEvmNative + +// chainId := setupEnv.Scenario.FirstEvmChainId +// evm := setupEnv.Clients.EVM[chainId] +// targetChainID := setupEnv.Scenario.SecondEvmChainId + +// wrappedAsset, err := evmSetup.NativeToWrappedAsset(setupEnv.AssetMappings, chainId, targetChainID, setupEnv.NativeEvmToken) +// if err != nil { +// t.Fatal(err) +// } + +// wrappedEvm := setupEnv.Clients.EVM[targetChainID] +// wrappedInstance, err := evmSetup.InitAssetContract(wrappedAsset, wrappedEvm.EVMClient) +// if err != nil { +// t.Fatal(err) +// } + +// wrappedBalanceBefore, err := wrappedInstance.BalanceOf(&bind.CallOpts{}, evm.Receiver) +// if err != nil { +// t.Fatal(err) +// } + +// // Step 1 - Submit Lock Txn from a deployed smart contract +// receipt, expectedLockEventLog := submit.LockEthTransaction(t, evm, setupEnv.NativeEvmToken, targetChainID, evm.Receiver.Bytes(), amount) + +// expectedAmount := new(big.Int).Sub(expectedLockEventLog.Amount, expectedLockEventLog.ServiceFee) + +// // Step 1.1 - Get the block timestamp of the lock event +// block, err := evm.EVMClient.BlockByNumber(context.Background(), receipt.BlockNumber) +// if err != nil { +// t.Fatal("failed to get block by number", err) +// } +// blockTimestamp := time.Unix(int64(block.Time()), 0).UTC() + +// // Step 2 - Validate Lock Event was emitted with correct data +// lockEventId := verify.LockEvent(t, receipt, expectedLockEventLog) + +// // Step 3 - Verify the submitted topic messages +// receivedSignatures := verify.TopicMessagesWithStartTime(t, setupEnv.Clients.Hedera, setupEnv.TopicID, setupEnv.Scenario.ExpectedValidatorsCount, lockEventId, now.UnixNano()) + +// // Step 4 - Verify Transfer retrieved from Validator API +// transactionData := verify.FungibleTransferFromValidatorAPI(t, setupEnv.Clients.ValidatorClient, setupEnv.TokenID, evm, lockEventId, setupEnv.NativeEvmToken, expectedAmount.String(), wrappedAsset) + +// // Step 5 - Submit Mint transaction +// txHash := submit.MintTransaction(t, wrappedEvm, lockEventId, transactionData, common.HexToAddress(wrappedAsset)) + +// // Step 6 - Wait for transaction to be mined +// submit.WaitForTransaction(t, wrappedEvm, txHash) + +// // Step 7 - Validate Token balances +// verify.WrappedAssetBalance(t, wrappedEvm, wrappedAsset, expectedAmount, wrappedBalanceBefore, evm.Receiver) + +// // Step 8 - Prepare expected Transfer record +// expectedLockEventRecord := expected.FungibleTransferRecord( +// chainId, +// targetChainID, +// chainId, +// lockEventId, +// setupEnv.NativeEvmToken, +// wrappedAsset, +// setupEnv.NativeEvmToken, +// expectedAmount.String(), +// "", +// evm.Receiver.String(), +// status.Completed, +// evm.Signer.Address(), +// entity.NanoTime{Time: blockTimestamp}, +// ) + +// authMsgBytes, err := auth_message.EncodeFungibleBytesFrom( +// expectedLockEventRecord.SourceChainID, +// expectedLockEventRecord.TargetChainID, +// expectedLockEventRecord.TransactionID, +// expectedLockEventRecord.TargetAsset, +// expectedLockEventRecord.Receiver, +// expectedAmount.String(), +// ) + +// if err != nil { +// t.Fatalf("[%s] - Failed to encode the authorisation signature. Error: [%s]", expectedLockEventRecord.TransactionID, err) +// } + +// // Step 9 - Verify Database Records +// verify.TransferRecordAndSignatures(t, setupEnv.DbValidator, expectedLockEventRecord, authMsgBytes, receivedSignatures) +// } + +// // Test_EVM_Wrapped_to_EVM_Token recreates a real life situation of a user who wants to bridge an EVM native token to another EVM chain. +// func Test_EVM_Wrapped_to_EVM_Token(t *testing.T) { +// if testing.Short() { +// t.Skip("test skipped in short mode") +// } + +// setupEnv := setup.Load() +// now := time.Now() + +// amount := setupEnv.Scenario.AmountEvmWrapped + +// chainId := setupEnv.Scenario.FirstEvmChainId +// sourceChain := setupEnv.Scenario.SecondEvmChainId +// wrappedEvm := setupEnv.Clients.EVM[sourceChain] + +// sourceAsset, err := evmSetup.NativeToWrappedAsset(setupEnv.AssetMappings, chainId, sourceChain, setupEnv.NativeEvmToken) +// if err != nil { +// t.Fatal(err) +// } + +// evm := setupEnv.Clients.EVM[chainId] + +// nativeInstance, err := evmSetup.InitAssetContract(setupEnv.NativeEvmToken, evm.EVMClient) +// if err != nil { +// t.Fatal(err) +// } + +// nativeBalanceBefore, err := nativeInstance.BalanceOf(&bind.CallOpts{}, evm.Receiver) +// if err != nil { +// t.Fatal(err) +// } + +// // Step 1 - Submit Lock Txn from a deployed smart contract +// receipt, expectedLockEventLog := submit.BurnEthTransaction(t, setupEnv.AssetMappings, wrappedEvm, setupEnv.NativeEvmToken, chainId, sourceChain, evm.Receiver.Bytes(), amount) + +// // Step 1.1 - Get the block timestamp of the burn event +// block, err := wrappedEvm.EVMClient.BlockByNumber(context.Background(), receipt.BlockNumber) +// if err != nil { +// t.Fatal("failed to get block by number", err) +// } +// blockTimestamp := time.Unix(int64(block.Time()), 0).UTC() + +// // Step 2 - Validate Burn Event was emitted with correct data +// burnEventId := verify.BurnEvent(t, receipt, expectedLockEventLog) + +// // Step 3 - Verify the submitted topic messages +// receivedSignatures := verify.TopicMessagesWithStartTime(t, setupEnv.Clients.Hedera, setupEnv.TopicID, setupEnv.Scenario.ExpectedValidatorsCount, burnEventId, now.UnixNano()) + +// // Step 4 - Verify Transfer retrieved from Validator API +// transactionData := verify.FungibleTransferFromValidatorAPI(t, setupEnv.Clients.ValidatorClient, setupEnv.TokenID, evm, burnEventId, setupEnv.NativeEvmToken, fmt.Sprint(amount), setupEnv.NativeEvmToken) + +// // Get fee amount from wrapped network Router +// _, feeAmount := expected.EvmAmoundAndFee(evm.RouterContract, setupEnv.NativeEvmToken, amount, t) + +// // Step 5 - Submit Mint transaction +// txHash := submit.UnlockTransaction(t, evm, burnEventId, transactionData, common.HexToAddress(setupEnv.NativeEvmToken)) + +// // Step 6 - Wait for transaction to be mined +// submit.WaitForTransaction(t, evm, txHash) + +// expectedUnlockedAmount := amount - feeAmount.Int64() + +// // Step 7 - Validate Token balances +// verify.WrappedAssetBalance(t, evm, setupEnv.NativeEvmToken, big.NewInt(expectedUnlockedAmount), nativeBalanceBefore, evm.Receiver) + +// // Step 8 - Prepare expected Transfer record +// expectedLockEventRecord := expected.FungibleTransferRecord( +// sourceChain, +// chainId, +// chainId, +// burnEventId, +// sourceAsset, +// setupEnv.NativeEvmToken, +// setupEnv.NativeEvmToken, +// strconv.FormatInt(amount, 10), +// "", +// evm.Receiver.String(), +// status.Completed, +// wrappedEvm.Signer.Address(), +// entity.NanoTime{Time: blockTimestamp}, +// ) + +// authMsgBytes, err := auth_message.EncodeFungibleBytesFrom( +// expectedLockEventRecord.SourceChainID, +// expectedLockEventRecord.TargetChainID, +// expectedLockEventRecord.TransactionID, +// expectedLockEventRecord.TargetAsset, +// expectedLockEventRecord.Receiver, +// strconv.FormatInt(amount, 10), +// ) + +// if err != nil { +// t.Fatalf("[%s] - Failed to encode the authorisation signature. Error: [%s]", expectedLockEventRecord.TransactionID, err) +// } + +// // Step 9 - Verify Database Records +// verify.TransferRecordAndSignatures(t, setupEnv.DbValidator, expectedLockEventRecord, authMsgBytes, receivedSignatures) +// } // Test_Hedera_Native_EVM_NFT_Transfer recreates User who wants to portal a Hedera Native NFT to an EVM chain. func Test_Hedera_Native_EVM_NFT_Transfer(t *testing.T) { @@ -923,8 +919,8 @@ func Test_Hedera_Native_EVM_NFT_Transfer(t *testing.T) { receivedSignatures := verify.TopicMessagesWithStartTime(t, setupEnv.Clients.Hedera, setupEnv.TopicID, setupEnv.Scenario.ExpectedValidatorsCount, hederahelper.FromHederaTransactionID(feeResponse.TransactionID).String(), signaturesStartTime) // Step 6 - Validate members fee scheduled transaction - expectedTransfers := expected.MirrorNodeExpectedTransfersForHederaTransfer(setupEnv.Members, setupEnv.BridgeAccount, constants.Hbar, validFee) - scheduledTxID, scheduleID := verify.MembersScheduledTxs(t, setupEnv.Clients.Hedera, setupEnv.Clients.MirrorNode, setupEnv.Members, constants.Hbar, expectedTransfers, now) + expectedTransfers := expected.MirrorNodeExpectedTransfersForHederaTransfer(setupEnv.Members, setupEnv.Treasury, setupEnv.BridgeAccount, constants.Hbar, validatorsFee, treasuryFee) + scheduledTxID, scheduleID := verify.ScheduledTxs(t, setupEnv.Clients.Hedera, setupEnv.Clients.MirrorNode, setupEnv.Members, setupEnv.Treasury, constants.Hbar, expectedTransfers, now) // Step 7 - Verify Non-Fungible Transfer retrieved from Validator API transactionData := verify.NonFungibleTransferFromValidatorAPI( diff --git a/e2e/helper/expected/fee.go b/e2e/helper/expected/fee.go index 598c86dc..c53cee80 100644 --- a/e2e/helper/expected/fee.go +++ b/e2e/helper/expected/fee.go @@ -25,15 +25,15 @@ import ( "github.com/limechain/hedera-eth-bridge-validator/app/domain/service" ) -func ReceiverAndFeeAmounts(feeCalc service.Fee, distributor service.Distributor, token string, amount int64) (receiverAmount, fee int64) { +func ReceiverAndFeeAmounts(feeCalc service.Fee, distributor service.Distributor, token string, amount int64) (receiverAmount, valdiatorsFee, treasuryFee int64) { fee, remainder := feeCalc.CalculateFee(token, amount) - validTreasuryFee, validValidatorFee := distributor.ValidAmounts(fee) - validFee := validTreasuryFee + validValidatorFee + validTreasuryFee, validValidatorsFee := distributor.ValidAmounts(fee) + validFee := validTreasuryFee + validValidatorsFee if validFee != fee { remainder += fee - validFee } - return remainder, validFee + return remainder, validValidatorsFee, validTreasuryFee } func EvmAmoundAndFee(router *router.Router, token string, amount int64, t *testing.T) (*big.Int, *big.Int) { diff --git a/e2e/helper/expected/mirror-node.go b/e2e/helper/expected/mirror-node.go index 556b9540..f6c0fd5d 100644 --- a/e2e/helper/expected/mirror-node.go +++ b/e2e/helper/expected/mirror-node.go @@ -22,9 +22,9 @@ import ( "github.com/limechain/hedera-eth-bridge-validator/constants" ) -func MirrorNodeExpectedTransfersForBurnEvent(members []hedera.AccountID, hederaClient *hedera.Client, bridgeAccount hedera.AccountID, asset string, amount, fee int64) []transaction.Transfer { - total := amount + fee - feePerMember := fee / int64(len(members)) +func MirrorNodeExpectedTransfersForBurnEvent(members []hedera.AccountID, treasury hedera.AccountID, hederaClient *hedera.Client, bridgeAccount hedera.AccountID, asset string, amount, validatorFee, treasuryFee int64) []transaction.Transfer { + total := amount + validatorFee + treasuryFee + feePerMember := validatorFee / int64(len(members)) var expectedTransfers []transaction.Transfer expectedTransfers = append(expectedTransfers, transaction.Transfer{ @@ -48,6 +48,16 @@ func MirrorNodeExpectedTransfersForBurnEvent(members []hedera.AccountID, hederaC expectedTransfers[i].Token = asset } } + treasuryTransfer := transaction.Transfer{ + Account: treasury.String(), + Amount: treasuryFee, + } + + if asset != constants.Hbar { + + treasuryTransfer.Token = asset + } + expectedTransfers = append(expectedTransfers, treasuryTransfer) return expectedTransfers } @@ -69,9 +79,10 @@ func MirrorNodeExpectedTransfersForLockEvent(hederaClient *hedera.Client, bridge return expectedTransfers } -func MirrorNodeExpectedTransfersForHederaTransfer(members []hedera.AccountID, bridgeAccount hedera.AccountID, asset string, fee int64) []transaction.Transfer { - feePerMember := fee / int64(len(members)) +func MirrorNodeExpectedTransfersForHederaTransfer(members []hedera.AccountID, treasury hedera.AccountID, bridgeAccount hedera.AccountID, asset string, validatorsFee, treasuryFee int64) []transaction.Transfer { + feePerMember := validatorsFee / int64(len(members)) + fee := validatorsFee + treasuryFee var expectedTransfers []transaction.Transfer expectedTransfers = append(expectedTransfers, transaction.Transfer{ Account: bridgeAccount.String(), @@ -91,5 +102,16 @@ func MirrorNodeExpectedTransfersForHederaTransfer(members []hedera.AccountID, br } } + treasuryTransfer := transaction.Transfer{ + Account: treasury.String(), + Amount: treasuryFee, + } + + if asset != constants.Hbar { + treasuryTransfer.Token = asset + } + + expectedTransfers = append(expectedTransfers, treasuryTransfer) + return expectedTransfers } diff --git a/e2e/helper/verify/db.go b/e2e/helper/verify/db.go index d2e32162..a79a4fa2 100644 --- a/e2e/helper/verify/db.go +++ b/e2e/helper/verify/db.go @@ -236,7 +236,7 @@ func (s *Service) getMessageListByTransactionId(expectedTransferRecord *entity.T return result, err } - time.Sleep(s.DatabaseRetryTimeout * time.Second) + time.Sleep(s.DatabaseRetryTimeout * time.Minute) s.logger.Infof("Database Message records [%s] retry %d", expectedTransferRecord.TransactionID, currentCount) } @@ -262,7 +262,7 @@ func (s *Service) getTransactionById(verifier dbVerifier, expectedTransferRecord return result, err } - time.Sleep(s.DatabaseRetryTimeout * time.Second) + time.Sleep(s.DatabaseRetryTimeout * time.Minute) s.logger.Infof("Database Transaction record [%s] retry %d", expectedTransferRecord.TransactionID, currentCount) } @@ -288,7 +288,7 @@ func (s *Service) getScheduleByTransactionId(verifier dbVerifier, expectedRecord return result, err } - time.Sleep(s.DatabaseRetryTimeout * time.Second) + time.Sleep(s.DatabaseRetryTimeout * time.Minute) s.logger.Infof("Database Schedule record [%s] retry %d", expectedRecord.TransactionID, currentCount) } @@ -314,7 +314,7 @@ func (s *Service) getFeeByTransactionId(verifier dbVerifier, expectedRecord *ent return result, err } - time.Sleep(s.DatabaseRetryTimeout * time.Second) + time.Sleep(s.DatabaseRetryTimeout * time.Minute) s.logger.Infof("Database Fee record [%s] retry %d", expectedRecord.TransactionID, currentCount) } diff --git a/e2e/helper/verify/hedera.go b/e2e/helper/verify/hedera.go index dce97e9e..da19c087 100644 --- a/e2e/helper/verify/hedera.go +++ b/e2e/helper/verify/hedera.go @@ -194,11 +194,11 @@ func AccountBalance(t *testing.T, hederaClient *hedera.Client, hederaID hedera.A } } -func SubmittedScheduledTx(t *testing.T, hederaClient *hedera.Client, mirrorNodeClient *mirror_node.Client, members []hedera.AccountID, asset string, expectedTransfers []transaction.Transfer, now time.Time) (transactionID, scheduleID string) { +func SubmittedScheduledTx(t *testing.T, hederaClient *hedera.Client, mirrorNodeClient *mirror_node.Client, members []hedera.AccountID, treasury hedera.AccountID, asset string, expectedTransfers []transaction.Transfer, now time.Time) (transactionID, scheduleID string) { t.Helper() receiverTransactionID, receiverScheduleID := ScheduledTx(t, hederaClient, mirrorNodeClient, hederaClient.GetOperatorAccountID(), asset, expectedTransfers, now) - membersTransactionID, membersScheduleID := MembersScheduledTxs(t, hederaClient, mirrorNodeClient, members, asset, expectedTransfers, now) + membersTransactionID, membersScheduleID := ScheduledTxs(t, hederaClient, mirrorNodeClient, members, treasury, asset, expectedTransfers, now) if receiverTransactionID != membersTransactionID { t.Fatalf("Scheduled Transactions between members are different. Receiver [%s], Member [%s]", receiverTransactionID, membersTransactionID) @@ -319,7 +319,7 @@ func ScheduledNftTransfer(t *testing.T, hederaClient *hedera.Client, mirrorNodeC func ScheduledTx(t *testing.T, hederaClient *hedera.Client, mirrorNodeClient *mirror_node.Client, account hedera.AccountID, asset string, expectedTransfers []transaction.Transfer, now time.Time) (transactionID, scheduleID string) { t.Helper() - timeLeft := 180 + timeLeft := 20 for { response, err := mirrorNodeClient.GetAccountCreditTransactionsAfterTimestamp(account, now.UnixNano()) if err != nil { @@ -336,9 +336,9 @@ func ScheduledTx(t *testing.T, hederaClient *hedera.Client, mirrorNodeClient *mi } if timeLeft > 0 { - fmt.Printf("Could not find any scheduled transactions for account [%s]. Trying again. Time left: ~[%d] seconds\n", hederaClient.GetOperatorAccountID(), timeLeft) - timeLeft -= 10 - time.Sleep(10 * time.Second) + fmt.Printf("Could not find any scheduled transactions for account [%s]. Trying again. Time left: ~[%d] minutes\n", hederaClient.GetOperatorAccountID(), timeLeft) + timeLeft-- + time.Sleep(time.Minute) continue } break @@ -348,7 +348,7 @@ func ScheduledTx(t *testing.T, hederaClient *hedera.Client, mirrorNodeClient *mi return "", "" } -func MembersScheduledTxs(t *testing.T, hederaClient *hedera.Client, mirrorNodeClient *mirror_node.Client, members []hedera.AccountID, asset string, expectedTransfers []transaction.Transfer, now time.Time) (transactionID, scheduleID string) { +func ScheduledTxs(t *testing.T, hederaClient *hedera.Client, mirrorNodeClient *mirror_node.Client, members []hedera.AccountID, treasury hedera.AccountID, asset string, expectedTransfers []transaction.Transfer, now time.Time) (transactionID, scheduleID string) { t.Helper() if len(members) == 0 { return "", "" @@ -356,8 +356,10 @@ func MembersScheduledTxs(t *testing.T, hederaClient *hedera.Client, mirrorNodeCl var transactions []string var scheduleIDs []string - for _, member := range members { - txID, scheduleID := ScheduledTx(t, hederaClient, mirrorNodeClient, member, asset, expectedTransfers, now) + var accountIDs []hedera.AccountID + accountIDs = append(accountIDs, append(members, treasury)...) + for _, accountID := range accountIDs { + txID, scheduleID := ScheduledTx(t, hederaClient, mirrorNodeClient, accountID, asset, expectedTransfers, now) transactions = append(transactions, txID) if !utilities.AllSame(transactions) { @@ -467,7 +469,6 @@ func TopicMessagesWithStartTime(t *testing.T, hederaClient *hedera.Client, topic message := msg.GetFungibleSignatureMessage() transferID = message.TransferID signature = message.Signature - break case *model.TopicMessage_NftSignatureMessage: message := msg.GetNftSignatureMessage() transferID = message.TransferID @@ -484,10 +485,10 @@ func TopicMessagesWithStartTime(t *testing.T, hederaClient *hedera.Client, topic }, ) if err != nil { - t.Fatalf("Unable to subscribe to Topic [%s]", topicId) + t.Fatalf("Unable to subscribe to Topic [%s]: [%s]", topicId, err) } - timeoutTimer := time.NewTimer(480 * time.Second) + timeoutTimer := time.NewTimer(15 * time.Minute) signatureLoop: for ethSignaturesCollected < expectedValidatorsCount { diff --git a/e2e/setup/config.go b/e2e/setup/config.go index 95263683..a57b5a8f 100644 --- a/e2e/setup/config.go +++ b/e2e/setup/config.go @@ -67,14 +67,17 @@ func Load() *Setup { configuration := Config{ Hedera: Hedera{ - NetworkType: e2eConfig.Hedera.NetworkType, - BridgeAccount: e2eConfig.Hedera.BridgeAccount, - PayerAccount: e2eConfig.Hedera.PayerAccount, - Members: e2eConfig.Hedera.Members, - TopicID: e2eConfig.Hedera.TopicID, - Sender: Sender(e2eConfig.Hedera.Sender), - DbValidationProps: make([]config.Database, len(e2eConfig.Hedera.DbValidationProps)), - MirrorNode: *new(config.MirrorNode).DefaultOrConfig(&e2eConfig.Hedera.MirrorNode), + NetworkType: e2eConfig.Hedera.NetworkType, + BridgeAccount: e2eConfig.Hedera.BridgeAccount, + PayerAccount: e2eConfig.Hedera.PayerAccount, + Members: e2eConfig.Hedera.Members, + TopicID: e2eConfig.Hedera.TopicID, + Treasury: e2eConfig.Hedera.Treasury, + ValidatorRewardPercentage: e2eConfig.Hedera.ValidatorRewardPercentage, + TreasuryRewardPercentage: e2eConfig.Hedera.TreasuryRewardPercentage, + Sender: Sender(e2eConfig.Hedera.Sender), + DbValidationProps: make([]config.Database, len(e2eConfig.Hedera.DbValidationProps)), + MirrorNode: *new(config.MirrorNode).DefaultOrConfig(&e2eConfig.Hedera.MirrorNode), }, EVM: make(map[uint64]config.Evm), Tokens: e2eConfig.Tokens, @@ -114,21 +117,24 @@ func Load() *Setup { // Setup used by the e2e tests. Preloaded with all necessary dependencies type Setup struct { - BridgeAccount hederaSDK.AccountID - PayerAccount hederaSDK.AccountID - TopicID hederaSDK.TopicID - TokenID hederaSDK.TokenID - NativeEvmToken string - NftTokenID hederaSDK.TokenID - NftSerialNumber int64 - NftConstantFees map[string]int64 - NftDynamicFees map[string]decimal.Decimal - FeePercentages map[string]int64 - Members []hederaSDK.AccountID - Clients *clients - DbValidator *verify.Service - AssetMappings service.Assets - Scenario *ScenarioConfig + BridgeAccount hederaSDK.AccountID + PayerAccount hederaSDK.AccountID + Treasury hederaSDK.AccountID + ValidatorRewardPercentage int + TreasuryRewardPercentage int + TopicID hederaSDK.TopicID + TokenID hederaSDK.TokenID + NativeEvmToken string + NftTokenID hederaSDK.TokenID + NftSerialNumber int64 + NftConstantFees map[string]int64 + NftDynamicFees map[string]decimal.Decimal + FeePercentages map[string]int64 + Members []hederaSDK.AccountID + Clients *clients + DbValidator *verify.Service + AssetMappings service.Assets + Scenario *ScenarioConfig } // newSetup instantiates new Setup struct @@ -148,6 +154,11 @@ func newSetup(config Config) (*Setup, error) { return nil, err } + treasuryID, err := hederaSDK.AccountIDFromString(config.Hedera.Treasury) + if err != nil { + return nil, err + } + tokenID, err := hederaSDK.TokenIDFromString(config.Tokens.WToken) if err != nil { return nil, err @@ -197,21 +208,24 @@ func newSetup(config Config) (*Setup, error) { dbValidator.ExpectedValidatorsCount = scenario.ExpectedValidatorsCount return &Setup{ - BridgeAccount: bridgeAccount, - PayerAccount: payerAccount, - TopicID: topicID, - TokenID: tokenID, - NftTokenID: nftTokenID, - NftSerialNumber: config.Tokens.NftSerialNumber, - NativeEvmToken: config.Tokens.EvmNativeToken, - NftConstantFees: config.NftConstantFees, - NftDynamicFees: config.NftDynamicFees, - FeePercentages: config.FeePercentages, - Members: members, - Clients: clients, - DbValidator: dbValidator, - AssetMappings: config.AssetMappings, - Scenario: scenario, + BridgeAccount: bridgeAccount, + PayerAccount: payerAccount, + TopicID: topicID, + TokenID: tokenID, + Treasury: treasuryID, + ValidatorRewardPercentage: config.Hedera.ValidatorRewardPercentage, + TreasuryRewardPercentage: config.Hedera.TreasuryRewardPercentage, + NftTokenID: nftTokenID, + NftSerialNumber: config.Tokens.NftSerialNumber, + NativeEvmToken: config.Tokens.EvmNativeToken, + NftConstantFees: config.NftConstantFees, + NftDynamicFees: config.NftDynamicFees, + FeePercentages: config.FeePercentages, + Members: members, + Clients: clients, + DbValidator: dbValidator, + AssetMappings: config.AssetMappings, + Scenario: scenario, }, nil } @@ -300,7 +314,7 @@ func newClients(config Config) (*clients, error) { ValidatorClient: validatorClient, MirrorNode: mirrorNode, FeeCalculator: fee.New(config.FeePercentages), - Distributor: distributor.New(config.Hedera.Members), + Distributor: distributor.New(config.Hedera.Members, config.Hedera.Treasury, config.Hedera.TreasuryRewardPercentage, config.Hedera.ValidatorRewardPercentage), }, nil } @@ -405,14 +419,17 @@ type Config struct { // Hedera props from the application.yml type Hedera struct { - NetworkType string - BridgeAccount string - PayerAccount string - Members []string - TopicID string - Sender Sender - DbValidationProps []config.Database - MirrorNode config.MirrorNode + NetworkType string + BridgeAccount string + PayerAccount string + Members []string + Treasury string + ValidatorRewardPercentage int + TreasuryRewardPercentage int + TopicID string + Sender Sender + DbValidationProps []config.Database + MirrorNode config.MirrorNode } // Sender props from the application.yml diff --git a/e2e/setup/parser/parser.go b/e2e/setup/parser/parser.go index c50714ed..b1553c93 100644 --- a/e2e/setup/parser/parser.go +++ b/e2e/setup/parser/parser.go @@ -17,14 +17,17 @@ type Config struct { } type HederaParser struct { - NetworkType string `yaml:"network_type"` - BridgeAccount string `yaml:"bridge_account"` - PayerAccount string `yaml:"payer_account"` - Members []string `yaml:"members"` - TopicID string `yaml:"topic_id"` - Sender Sender `yaml:"sender"` - DbValidationProps []parser.Database `yaml:"dbs"` - MirrorNode parser.MirrorNode `yaml:"mirror_node"` + NetworkType string `yaml:"network_type"` + BridgeAccount string `yaml:"bridge_account"` + PayerAccount string `yaml:"payer_account"` + Members []string `yaml:"members"` + TopicID string `yaml:"topic_id"` + Treasury string `yaml:"treasury"` + ValidatorRewardPercentage int `yaml:"validator_reward_percentage"` + TreasuryRewardPercentage int `yaml:"treasury_reward_percentage"` + Sender Sender `yaml:"sender"` + DbValidationProps []parser.Database `yaml:"dbs"` + MirrorNode parser.MirrorNode `yaml:"mirror_node"` } type ScenarioParser struct {