Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
120 changes: 120 additions & 0 deletions bridge/setu/processor/checkpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"math"
"math/big"
"strconv"
"strings"
"sync"
"time"

Expand Down Expand Up @@ -499,6 +500,10 @@ func (cp *CheckpointProcessor) nextExpectedCheckpoint(checkpointContext *Checkpo
)
}

if !cp.filterEthCrossChain(start, end, rootChain, checkpointParams.MaxCheckpointLength) {
end = start
}

// Handle when block producers go down
if end == 0 || end == start || (0 < diff && diff < checkpointParams.AvgCheckpointLength) {
cp.Logger.Debug("Fetching last header block to calculate time")
Expand Down Expand Up @@ -528,6 +533,33 @@ func (cp *CheckpointProcessor) nextExpectedCheckpoint(checkpointContext *Checkpo
}), nil
}

func (cp *CheckpointProcessor) filterEthCrossChain(start uint64, end uint64, rootChain string,
maxCheckpointLengthParam uint64,
) bool {
isOpen, rootChainIsOpen, maxLength := cp.getDynamicCheckpointProposal(rootChain)

if !isOpen || !rootChainIsOpen {
return true
}

if maxCheckpointLengthParam < uint64(maxLength) {
cp.Logger.Error("proposal feature-dynamic-checkpoint maxlength is too long",
"maxLength", maxLength, "MaxCheckpointLength", maxCheckpointLengthParam)

return true
}

if end-start+1 >= uint64(maxLength) {
return true
}

if cp.checkHasCrossChain(start, end, rootChain) {
return true
}

return false
}

// sendCheckpointToHeimdall - creates checkpoint msg and broadcasts to heimdall
func (cp *CheckpointProcessor) createAndSendCheckpointToHeimdall(checkpointContext *CheckpointContext, start, end uint64, rootChain string) error {
cp.Logger.Debug("Initiating checkpoint to Heimdall", "root", rootChain, "start", start, "end", end)
Expand Down Expand Up @@ -985,3 +1017,91 @@ func (cp *CheckpointProcessor) getCheckpointContext(rootChain string) (*Checkpoi
CheckpointParams: checkpointParams,
}, nil
}

func (cp *CheckpointProcessor) checkHasCrossChain(start uint64, end uint64, rootChain string) bool {
addrs, canUse := cp.getAddress(rootChain)
if !canUse {
cp.Logger.Error("mapToken address can't use")

return true
}

if len(addrs) == 0 {
cp.Logger.Error("mapToken address can't use: len=0")

return true
}

topics := util.GetWithDrawToTopics()

if len(topics) == 0 {
cp.Logger.Error("topics can't use: len=0")

return true
}

logs, err := cp.contractConnector.GetLogs(big.NewInt(int64(start)), big.NewInt(int64(end)), addrs, topics)
if err != nil {
cp.Logger.Error("Error while GetLogs", "error", err)

return true
}

cp.Logger.Info("checkHasCrossChain", "start", start, "end", end, "addrLen", len(addrs), "logsLen", len(logs))

return len(logs) != 0
}

func (cp *CheckpointProcessor) getAddress(rootChain string) ([]common.Address, bool) {
eventProcessor := util.NewTokenMapProcessor(cp.cliCtx, cp.storageClient)

nodeStatus, err := helper.GetNodeStatus(cp.cliCtx)
if err != nil {
cp.Logger.Error("Error while fetching heimdall node status", "error", err)

return nil, false
}

toBlock := nodeStatus.SyncInfo.LatestBlockHeight

done, err := eventProcessor.IsInitializationDoneWithBlock(toBlock)
if err != nil {
cp.Logger.Error("Error while fetching token map in IsInitializationDoneWithBlock", "toBlock", toBlock, "error", err)

return nil, false
}

if !done {
cp.Logger.Error("Not done while fetching token map in IsInitializationDoneWithBlock ", "toBlock", toBlock)

return nil, false
}

mlist, err := eventProcessor.GetTokenMapByRootType(rootChain)
if err != nil {
cp.Logger.Error("Error while fetching token map in GetTokenMapByRootType", "rootChain", rootChain, "error", err)

return nil, false
}

cp.Logger.Info("getAddress", "rootChain", rootChain, "mlistLen", len(mlist), "toBlock", toBlock)

retSlice := make([]common.Address, 0, len(mlist))

for _, item := range mlist {
retSlice = append(retSlice, common.HexToAddress(item.ChildToken))
}

return retSlice, true
}

func (cp *CheckpointProcessor) getDynamicCheckpointProposal(rootType string) (bool, bool, int) {
fea, err := util.GetDynamicCheckpointFeature(cp.cliCtx)
if err != nil {
cp.Logger.Error("Error while fetching dynamic checkpoint feature", "error", err)

return false, false, 0
}

return fea.IsOpen, fea.IntConf[strings.ToLower(rootType)] != 0, fea.IntConf["maxLength"]
}
37 changes: 37 additions & 0 deletions bridge/setu/util/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import (
"sync"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"

stakingTypes "github.com/maticnetwork/heimdall/staking/types"

mLog "github.com/RichardKnop/machinery/v1/log"
Expand Down Expand Up @@ -69,8 +72,12 @@ const (

BridgeDBFlag = "bridge-db"
ProposersURLSizeLimit = 100

WithdrawToEventSig = "0x67b714876402c93362735688659e2283b4a37fb21bab24bc759ca759ae851fd8"
)

var withDrawToTopics = [][]string{{WithdrawToEventSig}}

var (
logger log.Logger
loggerOnce sync.Once
Expand Down Expand Up @@ -533,6 +540,36 @@ func GetValidatorNonce(cliCtx cliContext.CLIContext, validatorID uint64) (uint64
return validator.Nonce, result.Height, nil
}

func GetWithDrawToTopics() [][]common.Hash {
return getTopics(withDrawToTopics)
}

func getTopics(topicStr [][]string) [][]common.Hash {
ret := make([][]common.Hash, len(topicStr))

for i, topics := range topicStr {
for _, topic := range topics {
topicByte, err := hexutil.Decode(topic)
if err != nil {
logger.Error("Error while decoding topic", "error", err)

return nil
}

var h common.Hash

copy(h[:], topicByte)
ret[i] = append(ret[i], h)
}
}

return ret
}

func GetDynamicCheckpointFeature(cliCtx cliContext.CLIContext) (*featureManagerTypes.PlainFeatureData, error) {
return GetTargetFeatureConfig(cliCtx, featureManagerTypes.DynamicCheckpoint)
}

// GetTargetFeatureConfig return target feature config.
func GetTargetFeatureConfig(
cliCtx cliContext.CLIContext, feature string,
Expand Down
1 change: 1 addition & 0 deletions featuremanager/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ func (k Keeper) addFeature(feature string) {
func (k Keeper) RegistreFeature() {
// all new type of features should be registered here.
k.addFeature("feature-x")
k.addFeature(types.DynamicCheckpoint)
}

func (k Keeper) HasFeature(feature string) bool {
Expand Down
4 changes: 4 additions & 0 deletions featuremanager/types/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ const (
// DefaultParamspace default name for parameter store.
DefaultParamspace = ModuleName
)

const (
DynamicCheckpoint = "DynamicCheckpoint"
)
18 changes: 18 additions & 0 deletions helper/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"strconv"
"strings"

"github.com/ethereum/go-ethereum"

"github.com/maticnetwork/heimdall/tron"

"github.com/ethereum/go-ethereum/accounts/abi"
Expand Down Expand Up @@ -462,6 +464,22 @@ func (c *ContractCaller) GetBlockNumberFromTxHash(tx common.Hash) (*big.Int, err
return blkNum, nil
}

func (c *ContractCaller) GetLogs(fromBlock *big.Int, toBlock *big.Int, addrs []common.Address,
topics [][]common.Hash,
) ([]ethTypes.Log, error) {
logs, err := c.MaticChainClient.FilterLogs(context.Background(), ethereum.FilterQuery{
FromBlock: fromBlock,
ToBlock: toBlock,
Addresses: addrs,
Topics: topics,
})
if err != nil {
return nil, err
}

return logs, nil
}

// GetConfirmedTxReceipt returns confirmed tx receipt
func (c *ContractCaller) GetConfirmedTxReceipt(tx common.Hash, requiredConfirmations uint64, rootChain string) (*ethTypes.Receipt, error) {

Expand Down