Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e7dad9e
fix the problem trongrid tx fail but has log
sgz13140 Jun 2, 2026
ddfbb25
Merge pull request #141 from sgz13140/hotfix/tronEventResult
sgz13140 Jun 2, 2026
047572c
remove event filter when check transaction receipt
sgz13140 Jun 2, 2026
8575a57
Merge pull request #142 from sgz13140/hotfix/tronEventResult
aaronliu01 Jun 2, 2026
370ee98
getTronConfirmedTxReceipt
sgz13140 Jun 11, 2026
f6e294b
getTronTronscantionReceipt in listener
sgz13140 Jun 11, 2026
fdfc768
Merge branch 'master' into hotfix/tronConfirmedTx
sgz13140 Jun 11, 2026
cee0616
merge master and modify mock function
sgz13140 Jun 11, 2026
83a3b05
add deposit switch
sgz13140 Jun 12, 2026
fdb1653
use CloseOriginTokenDeposit instead of open
sgz13140 Jun 12, 2026
a26cf28
modify unitest
sgz13140 Jun 12, 2026
c279655
Merge pull request #146 from sgz13140/hotfix/tronConfirmedTx
aaronliu01 Jun 12, 2026
bab001e
Merge branch 'develop_tmp' into develop_tronreceipt
sgz13140 Jun 12, 2026
2e669af
Merge pull request #145 from bttcprotocol/develop_tronreceipt
aaronliu01 Jun 12, 2026
dcc9dd5
Merge pull request #144 from sgz13140/feat/depositSwitch
aaronliu01 Jun 12, 2026
7e7609e
solve lint check
sgz13140 Jun 12, 2026
a89f4ec
solve lint check
sgz13140 Jun 12, 2026
b962675
Merge pull request #147 from sgz13140/feat/depositSwitch
aaronliu01 Jun 12, 2026
3e6496c
feat: do not vote for StateSynced event
aaronliu01 Jun 22, 2026
b0676d7
Merge pull request #148 from aaronliu01/feat/decline-mintableerc20
aaronliu01 Jun 22, 2026
7839ba8
feat: clerk side_handler log append txHash field
aaronliu01 Jun 25, 2026
06c99d4
log: Debug -> Info
aaronliu01 Jun 25, 2026
c3a1358
Merge pull request #149 from aaronliu01/feat/decline-mintableerc20
aaronliu01 Jun 25, 2026
e2a3d52
feat: CloseOriginTokenDeposit Test
aaronliu01 Jul 14, 2026
a073918
Merge pull request #153 from aaronliu01/feat/decline-mintableerc20
aaronliu01 Jul 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions bridge/setu/listener/tron.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,18 @@ func (tl *TronListener) queryAndBroadcastEvents(chainManagerParams *chainmanager
logBytes, _ := json.Marshal(vLog)
if selectedEvent != nil {
tl.Logger.Debug("ReceivedTronEvent", "eventname", selectedEvent.Name)

receipt, err := tl.contractConnector.GetTronTransactionReceipt(vLog.TxHash.Hex())
if receipt != nil && !helper.IsTronTransactionReceiptSuccessful(receipt) {
tl.Logger.Error(
"Skip failed tron transaction event",
"eventname", selectedEvent.Name,
"txHash", vLog.TxHash.Hex(),
"error", err,
)
continue
}

switch selectedEvent.Name {
case "NewHeaderBlock":
if isCurrentValidator, delay := util.CalculateTaskDelay(tl.cliCtx); isCurrentValidator {
Expand Down
44 changes: 43 additions & 1 deletion bridge/setu/processor/clerk.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,27 @@ func (cp *ClerkProcessor) sendStateSyncedToHeimdall(eventName string, logBytes s
return nil
}

cp.Logger.Debug(
if helper.GetConfig().CloseOriginTokenDeposit {
shouldBroadcast, err := cp.shouldBroadcastStateSyncedEvent(event.Data, rootChainType)
if err != nil {
cp.Logger.Error("Error while checking state sync token type", "error", err)
return err
}
if !shouldBroadcast {
cp.Logger.Info("Ignoring deposit event for non-mintable ERC20 token",
"event", eventName,
"id", event.Id,
"contract", event.ContractAddress,
"data", hex.EncodeToString(event.Data),
"txHash", hmTypes.BytesToHeimdallHash(vLog.TxHash.Bytes()),
"logIndex", uint64(vLog.Index),
"rootChainType", rootChainType,
)
return nil
}
}

cp.Logger.Info(
"⬜ New event found",
"event", eventName,
"id", event.Id,
Expand Down Expand Up @@ -118,6 +138,28 @@ func (cp *ClerkProcessor) sendStateSyncedToHeimdall(eventName string, logBytes s
return nil
}

func (cp *ClerkProcessor) shouldBroadcastStateSyncedEvent(data []byte, rootChainType string) (bool, error) {
stateData, err := helper.ParseStateSyncData(data)
if err != nil {
return false, err
}
if stateData.EventType != helper.StateSyncEventDeposit {
return true, nil
}

return false, nil
// rootChainManagerProxy, err := helper.GetRootChainManagerProxy(rootChainType)
// if err != nil {
// return false, err
// }
// tokenType, err := cp.contractConnector.GetRootTokenType(rootChainType, rootChainManagerProxy, stateData.RootToken)
// if err != nil {
// return false, err
// }

// return tokenType == helper.MintableERC20TokenHash, nil
}

// isOldTx checks if tx is already processed or not
func (cp *ClerkProcessor) isOldTx(cliCtx cliContext.CLIContext, txHash string, logIndex uint64, rootChainType string) (bool, error) {
queryParam := map[string]interface{}{
Expand Down
6 changes: 5 additions & 1 deletion chainmanager/side_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,14 @@ func SideHandleMsgNewChain(ctx sdk.Context, msg types.MsgNewChain, k Keeper, con
err error
)
// get event log on tron
receipt, err = contractCaller.GetTronTransactionReceipt(msg.TxHash.Hex())
receipt, err = contractCaller.GetTronConfirmedTxReceipt(msg.TxHash.Hex(), params.TronchainTxConfirmations)
if err != nil || receipt == nil {
return common.ErrorSideTx(k.Codespace(), common.CodeWaitFrConfirmation)
}
if !helper.IsTronTransactionReceiptSuccessful(receipt) {
k.Logger(ctx).Error("Tron transaction failed", "txHash", msg.TxHash.Hex(), "status", receipt.Status)
return common.ErrorSideTx(k.Codespace(), common.CodeInvalidMsg)
}
contractAddress = hmTypes.HexToTronAddress(chainParams.TronChainAddress)
// decode validator join event
eventLog, err := contractCaller.DecodeNewChainEvent(contractAddress, receipt, msg.LogIndex)
Expand Down
8 changes: 7 additions & 1 deletion checkpoint/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,10 +240,16 @@ func SendCheckpointACKTx(cdc *codec.Codec) *cobra.Command {
}
rootChainAddress = chainmanagerParams.ChainParams.RootChainAddress.EthAddress()
case hmTypes.RootChainTypeTron:
receipt, err = contractCallerObj.GetTronTransactionReceipt(txHash.Hex())
receipt, err = contractCallerObj.GetTronConfirmedTxReceipt(
txHash.Hex(),
chainmanagerParams.TronchainTxConfirmations,
)
if err != nil || receipt == nil {
return errors.New("transaction is not confirmed yet. Please wait for sometime and try again")
}
if !helper.IsTronTransactionReceiptSuccessful(receipt) {
return errors.New("tron transaction failed")
}
rootChainAddress = hmTypes.HexToTronAddress(chainmanagerParams.ChainParams.TronChainAddress)
default:
return fmt.Errorf("wrong root chain %v", rootChain)
Expand Down
5 changes: 4 additions & 1 deletion clerk/querier.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,10 @@ func handleQueryRecordSequence(ctx sdk.Context, req abci.RequestQuery, keeper Ke
receipt, err = contractCallerObj.GetConfirmedTxReceipt(hmTypes.HexToHeimdallHash(params.TxHash).EthHash(),
bscChain.TxConfirmations, hmTypes.RootChainTypeBsc, false)
case hmTypes.RootChainTypeTron:
receipt, err = contractCallerObj.GetTronTransactionReceipt(hmTypes.HexToHeimdallHash(params.TxHash).TronHash().Hex())
receipt, err = contractCallerObj.GetTronConfirmedTxReceipt(
hmTypes.HexToHeimdallHash(params.TxHash).TronHash().Hex(),
chainParams.TronchainTxConfirmations,
)
default:
return nil, sdk.ErrInternal(fmt.Sprintf("wrong chain type = " + params.RootChainType + "please pass correct chainType like eth or tron"))
}
Expand Down
2 changes: 1 addition & 1 deletion clerk/querier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ func (suite *QuerierTestSuite) TestHandleQueryRecordSequence() {
// tron
testSeq = helper.CalculateSequence(big.NewInt(1), 1, hmTypes.RootChainTypeTron).String()
ck.SetRecordSequence(ctx, testSeq)
suite.contractCaller.On("GetTronTransactionReceipt", txHash.TronHash().String()).Return(txreceipt, nil)
suite.contractCaller.On("GetTronConfirmedTxReceipt", txHash.TronHash().String(), chainParams.TronchainTxConfirmations).Return(txreceipt, nil)
req = abci.RequestQuery{
Path: route,
Data: app.Codec().MustMarshalJSON(types.NewQueryRecordSequenceParams("12345", logIndex, hmTypes.RootChainTypeTron)),
Expand Down
40 changes: 39 additions & 1 deletion clerk/side_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,14 @@ func SideHandleMsgEventRecord(ctx sdk.Context, k Keeper, msg types.MsgEventRecor
}
contractAddress = bscChain.StateSenderAddress.EthAddress()
case hmTypes.RootChainTypeTron:
receipt, err = contractCaller.GetTronTransactionReceipt(msg.TxHash.Hex())
receipt, err = contractCaller.GetTronConfirmedTxReceipt(msg.TxHash.Hex(), params.TronchainTxConfirmations)
if err != nil || receipt == nil {
return hmCommon.ErrorSideTx(k.Codespace(), common.CodeWaitFrConfirmation)
}
if !helper.IsTronTransactionReceiptSuccessful(receipt) {
k.Logger(ctx).Error("Tron transaction failed", "txHash", msg.TxHash.Hex(), "status", receipt.Status)
return hmCommon.ErrorSideTx(k.Codespace(), common.CodeInvalidMsg)
}
contractAddress = hmTypes.HexToTronAddress(chainParams.TronStateSenderAddress)
default:
k.Logger(ctx).Error("RootChain type: ", msg.RootChainType, " does not match eth or tron")
Expand Down Expand Up @@ -138,6 +142,18 @@ func SideHandleMsgEventRecord(ctx sdk.Context, k Keeper, msg types.MsgEventRecor
return hmCommon.ErrorSideTx(k.Codespace(), common.CodeInvalidMsg)
}

if helper.GetConfig().CloseOriginTokenDeposit {
shouldVote, err := shouldVoteStateSyncedEvent(contractCaller, msg.RootChainType, msg.Data)
if err != nil {
k.Logger(ctx).Error("Error parsing state sync data", "error", err)
return hmCommon.ErrorSideTx(k.Codespace(), common.CodeErrDecodeEvent)
}
if !shouldVote {
k.Logger(ctx).Error("Deposit token type is not mintable ERC20", "rootChainType", msg.RootChainType, "txHash", msg.TxHash.Hex())
return hmCommon.ErrorSideTx(k.Codespace(), common.CodeInvalidMsg)
}
}

result.Result = abci.SideTxResultType_Yes
return
}
Expand Down Expand Up @@ -211,3 +227,25 @@ func PostHandleMsgEventRecord(ctx sdk.Context, k Keeper, msg types.MsgEventRecor
Events: ctx.EventManager().Events(),
}
}

func shouldVoteStateSyncedEvent(contractCaller helper.IContractCaller, rootChainType string, data []byte) (bool, error) {
stateData, err := helper.ParseStateSyncData(data)
if err != nil {
return false, err
}
if stateData.EventType != helper.StateSyncEventDeposit {
return true, nil
}
return false, nil

// rootChainManagerProxy, err := helper.GetRootChainManagerProxy(rootChainType)
// if err != nil {
// return false, err
// }
// tokenType, err := contractCaller.GetRootTokenType(rootChainType, rootChainManagerProxy, stateData.RootToken)
// if err != nil {
// return false, err
// }

// return tokenType == helper.MintableERC20TokenHash, nil
}
101 changes: 98 additions & 3 deletions clerk/side_handler_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package clerk_test

import (
"encoding/hex"
"math/big"
"math/rand"
"strings"
"testing"
"time"

Expand All @@ -14,6 +16,7 @@ import (
"github.com/stretchr/testify/suite"
abci "github.com/tendermint/tendermint/abci/types"

ethCommon "github.com/ethereum/go-ethereum/common"
ethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/maticnetwork/heimdall/app"
"github.com/maticnetwork/heimdall/clerk"
Expand Down Expand Up @@ -62,9 +65,7 @@ func TestSideHandlerTestSuite(t *testing.T) {
suite.Run(t, new(SideHandlerTestSuite))
}

//
// Test cases
//
func (suite *SideHandlerTestSuite) TestSideHandler() {
t, ctx := suite.T(), suite.ctx

Expand All @@ -88,6 +89,7 @@ func (suite *SideHandlerTestSuite) TestSideHandleMsgEventRecord() {
logIndex := uint64(10)
blockNumber := uint64(599)
txReceipt := &ethTypes.Receipt{
Status: ethTypes.ReceiptStatusSuccessful,
BlockNumber: new(big.Int).SetUint64(blockNumber),
}
txHash := hmTypes.HexToHeimdallHash("success hash")
Expand Down Expand Up @@ -131,6 +133,7 @@ func (suite *SideHandlerTestSuite) TestSideHandleMsgEventRecord() {
logIndex := uint64(10)
blockNumber := uint64(599)
txReceipt := &ethTypes.Receipt{
Status: ethTypes.ReceiptStatusSuccessful,
BlockNumber: new(big.Int).SetUint64(blockNumber),
}
txHash := hmTypes.HexToHeimdallHash("hello tron")
Expand All @@ -147,7 +150,7 @@ func (suite *SideHandlerTestSuite) TestSideHandleMsgEventRecord() {
suite.chainID,
hmTypes.RootChainTypeTron,
)
suite.contractCaller.On("GetTronTransactionReceipt", txHash.Hex()).Return(txReceipt, nil)
suite.contractCaller.On("GetTronConfirmedTxReceipt", txHash.Hex(), chainParams.TronchainTxConfirmations).Return(txReceipt, nil)
event := &statesender.StatesenderStateSynced{
Id: new(big.Int).SetUint64(msg.ID),
ContractAddress: msg.ContractAddress.TronAddress(),
Expand All @@ -166,6 +169,95 @@ func (suite *SideHandlerTestSuite) TestSideHandleMsgEventRecord() {
require.Error(t, err)

})

t.Run("CloseOriginTokenDeposit", func(t *testing.T) {
suite.contractCaller = mocks.IContractCaller{}
suite.sideHandler = clerk.NewSideTxHandler(suite.app.ClerkKeeper, &suite.contractCaller)
conf := helper.GetDefaultHeimdallConfig()
conf.CloseOriginTokenDeposit = true
conf.EthRootChainManagerProxy = "0x0000000000000000000000000000000000000001"
helper.SetTestConfig(conf)
defer helper.SetTestConfig(helper.GetDefaultHeimdallConfig())

logIndex := uint64(11)
blockNumber := uint64(600)
txReceipt := &ethTypes.Receipt{
BlockNumber: new(big.Int).SetUint64(blockNumber),
}
txHash := hmTypes.HexToHeimdallHash("mintable deposit")
data, err := hex.DecodeString(strings.TrimPrefix(depositStateSyncData, "0x"))
require.NoError(t, err)
rootToken := ethCommon.HexToAddress("0x032017411f4663b317fe77c257d28d5cd1b26e3d")

msg := types.NewMsgEventRecord(
hmTypes.BytesToHeimdallAddress(addr1.Bytes()),
txHash,
logIndex,
blockNumber,
id,
hmTypes.BytesToHeimdallAddress(addr1.Bytes()),
data,
suite.chainID,
hmTypes.RootChainTypeEth,
)

suite.contractCaller.On("GetConfirmedTxReceipt", txHash.EthHash(), chainParams.MainchainTxConfirmations, hmTypes.RootChainTypeEth).Return(txReceipt, nil)
event := &statesender.StatesenderStateSynced{
Id: new(big.Int).SetUint64(msg.ID),
ContractAddress: msg.ContractAddress.EthAddress(),
Data: msg.Data,
}
suite.contractCaller.On("DecodeStateSyncedEvent", chainParams.ChainParams.StateSenderAddress.EthAddress(), txReceipt, logIndex).Return(event, nil)
suite.contractCaller.On("GetRootTokenType", hmTypes.RootChainTypeEth, conf.EthRootChainManagerProxy, rootToken).Return(helper.MintableERC20TokenHash, nil)

result := suite.sideHandler(ctx, msg)
require.Equal(t, uint32(common.CodeInvalidMsg), result.Code)
require.Equal(t, abci.SideTxResultType_Skip, result.Result)
})
t.Run("CloseOriginTokenDeposit", func(t *testing.T) {
suite.contractCaller = mocks.IContractCaller{}
suite.sideHandler = clerk.NewSideTxHandler(suite.app.ClerkKeeper, &suite.contractCaller)
conf := helper.GetDefaultHeimdallConfig()
conf.CloseOriginTokenDeposit = true
conf.EthRootChainManagerProxy = "0x0000000000000000000000000000000000000001"
helper.SetTestConfig(conf)
defer helper.SetTestConfig(helper.GetDefaultHeimdallConfig())

logIndex := uint64(12)
blockNumber := uint64(601)
txReceipt := &ethTypes.Receipt{
BlockNumber: new(big.Int).SetUint64(blockNumber),
}
txHash := hmTypes.HexToHeimdallHash("non mintable deposit")
data, err := hex.DecodeString(strings.TrimPrefix(depositStateSyncData, "0x"))
require.NoError(t, err)
rootToken := ethCommon.HexToAddress("0x032017411f4663b317fe77c257d28d5cd1b26e3d")

msg := types.NewMsgEventRecord(
hmTypes.BytesToHeimdallAddress(addr1.Bytes()),
txHash,
logIndex,
blockNumber,
id,
hmTypes.BytesToHeimdallAddress(addr1.Bytes()),
data,
suite.chainID,
hmTypes.RootChainTypeEth,
)

suite.contractCaller.On("GetConfirmedTxReceipt", txHash.EthHash(), chainParams.MainchainTxConfirmations, hmTypes.RootChainTypeEth).Return(txReceipt, nil)
event := &statesender.StatesenderStateSynced{
Id: new(big.Int).SetUint64(msg.ID),
ContractAddress: msg.ContractAddress.EthAddress(),
Data: msg.Data,
}
suite.contractCaller.On("DecodeStateSyncedEvent", chainParams.ChainParams.StateSenderAddress.EthAddress(), txReceipt, logIndex).Return(event, nil)
suite.contractCaller.On("GetRootTokenType", hmTypes.RootChainTypeEth, conf.EthRootChainManagerProxy, rootToken).Return(ethCommon.HexToHash("0x01"), nil)

result := suite.sideHandler(ctx, msg)
require.NotEqual(t, uint32(sdk.CodeOK), result.Code)
require.Equal(t, abci.SideTxResultType_Skip, result.Result)
})
t.Run("NoReceipt", func(t *testing.T) {
suite.contractCaller = mocks.IContractCaller{}

Expand Down Expand Up @@ -201,6 +293,7 @@ func (suite *SideHandlerTestSuite) TestSideHandleMsgEventRecord() {
logIndex := uint64(100)
blockNumber := uint64(510)
txReceipt := &ethTypes.Receipt{
Status: ethTypes.ReceiptStatusSuccessful,
BlockNumber: new(big.Int).SetUint64(blockNumber),
}
txHash := hmTypes.HexToHeimdallHash("no log hash")
Expand Down Expand Up @@ -228,6 +321,8 @@ func (suite *SideHandlerTestSuite) TestSideHandleMsgEventRecord() {
})
}

const depositStateSyncData = "0x87a7811f4bfedea3d341ad165680ae306b01aaeacc205d227629cf157dd9f821000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000a9635197462ba512b47d19399017f6857888bc27000000000000000000000000032017411f4663b317fe77c257d28d5cd1b26e3d0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000056bc75e2d63100000"

func (suite *SideHandlerTestSuite) TestPostHandler() {
t, ctx := suite.T(), suite.ctx

Expand Down
Loading
Loading