Skip to content

impl/bridge_catchup_watcher.hpp

Header file for the bridge catch-up scan watcher. More...

Namespaces

Name
sgns
sgns::evmwatcher

Classes

Name
class sgns::evmwatcher::BridgeCatchupWatcher
Polling watcher that scans bridge chains for historical burn events and forwards them to the node for parsing + minting.
struct sgns::evmwatcher::BridgeCatchupWatcher::Config
Configuration for the catch-up scan watcher.

Detailed Description

Header file for the bridge catch-up scan watcher.

Date: 2026-07-12 SuperGenius ([email protected]) Copyright 2026 Genius Ventures, Inc. SPDX-License-Identifier: MIT

Polling watcher that scans historical blocks for unprocessed bridge burn events and forwards them to the node for parsing + minting. Follows the BridgeRpcWatcher / MessagingWatcher pattern.

The watcher keeps its dependency surface small: it decodes raw event logs and passes the ABI values to a BurnProcessor callback provided by the node. The node (which already links the full account / transaction stack) handles ParseBurnEventValues + MintTokens. This avoids pulling BridgeRelayer → TransactionManager → ipfs_lite into the watcher target.

Source code

#ifndef BRIDGE_CATCHUP_WATCHER_HPP
#define BRIDGE_CATCHUP_WATCHER_HPP

#include <watcher/messaging_watcher.hpp>

#include <account/ChainContractPair.hpp>
#include <eth/abi_decoder.hpp>

#include <chrono>
#include <cstdint>
#include <functional>
#include <mutex>
#include <optional>
#include <string>
#include <unordered_map>
#include <vector>

namespace sgns::evmwatcher
{

    class BridgeCatchupWatcher final : public watcher::MessagingWatcher
    {
    public:
        struct Config
        {
            std::chrono::seconds poll_interval{ 15 }; 
            uint64_t             scan_depth = 10000;  
        };

        using ChainsProvider = std::function<std::vector<ChainContractPair>()>;

        using RpcUrlResolver = std::function<std::optional<std::string>( const std::string &chain_id_str )>;

        using BurnProcessor = std::function<bool( const std::vector<eth::abi::AbiValue> &decoded_values,
                                                  const std::string                     &tx_hash_hex,
                                                  const std::string                     &chain_id_str )>;

        BridgeCatchupWatcher( const Config   &config,
                              MessageCallback message_callback,
                              ChainsProvider  chains_provider,
                              RpcUrlResolver  rpc_resolver,
                              BurnProcessor   burn_processor );

        void startWatching() override;
        void stopWatching() override;

        [[nodiscard]] uint64_t GetLastProcessedBlock( uint64_t chain_id ) const noexcept;

    protected:
        void watch() override;

    private:
        void poll_once();

        Config            config_;           
        ChainsProvider    chains_provider_;  
        RpcUrlResolver    rpc_resolver_;     
        BurnProcessor     burn_processor_;   

        std::unordered_map<uint64_t, uint64_t> last_block_per_chain_;
        mutable std::mutex                     mutex_;
    };

} // namespace sgns::evmwatcher

#endif // BRIDGE_CATCHUP_WATCHER_HPP

Updated on 2026-07-12 at 22:42:54 -0700