密码学隐私计算区块链后端【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址https://gitcode.com/GitHub_Trending/fh/fhevm点击查看免费下载本文以仓库 listener/crates/listener_core/CLAUDE.md 为核心骨架结合 AGENTS.md 的指引说明与对应源码展开。AGENTS.md 本身是仓库的 Agent 导航约定它通过CLAUDE.md指令将完整的 Agent 指导指向同目录下的 CLAUDE.md以避免重复维护——因此本文实际的技术主体来自 CLAUDE.md并逐项对应到listener_core的真实实现。在 fhEVM 全栈框架中listener_core是承担「链上数据到业务事件」的关键中间件它是一个面向生产环境的 EVM 区块监听器Production EVM block listener从 RPC 节点拉取区块、校验链连续性、检测重组reorg、按消费者过滤交易并把事件发布到消息代理Redis Streams 或 RabbitMQ最终将规范链canonical区块写入 PostgreSQL。读完本文你将掌握它的完整数据流水线、AsyncSlotBuffer并行抓取与顺序消费模型、五种 RPC 抓取策略、三阶段崩溃安全的 Reorg 回溯算法、FilterIndex倒排索引、Finality / Catchup 辅助流程以及「零事件丢失」的发布保障机制与 HPA 兼容设计。一、组件定位AGENTS.md 与 CLAUDE.md 的导航约定listener_core目录下存在两个 Agent 指导文件AGENTS.md全文仅说明「本仓库将 Agent 指导统一放在 CLAUDE.md 以避免重复」并通过CLAUDE.md引入正文CLAUDE.md完整的 Claude Code Context覆盖该 crate 的职责、流水线、核心算法、文件地图、硬性不变量、错误处理与已知限制。按照该约定所有 Agent 与开发者都应直接阅读 CLAUDE.md 获取完整说明。下文各章节即围绕 CLAUDE.md 的目录结构逐项展开并下沉到源码佐证。二、总体流水线从 RPC 区块到 Broker 事件CLAUDE.md 给出了listener_core的端到端流水线RPC Node → SemEvmRpcProvider (semaphore rate-limited) → EvmBlockFetcher (5 strategies, parallel) → AsyncSlotBuffer (out-of-order insert → in-order read) → Cursor (parent-hash chain validation, sequential) → Publisher (FilterIndex matching → per-consumer payloads) → Broker (Redis | AMQP, with ensure_publish) → DB insert (PostgreSQL, canonical block)每一环在源码中都有对应实现流水线环节实现文件信号量限流 RPC Providersem_evm_rpc_provider.rs五种策略的区块抓取器evm_block_fetcher.rs乱序写入 / 顺序读取缓冲slot_buffer.rs游标父哈希校验 顺序消费evm_listener.rs倒排索引与事件发布publisher.rsBroker 消息处理FetchHandler 等workers.rsPostgreSQL 规范区块写入block_repo.rs核心设计哲学可以概括为并行抓取换取吞吐顺序消费换取一致性。抓取阶段完全并行每个区块一个 tokio 任务而校验与入库阶段严格按块号顺序执行保证「同一 (chain_id, block_number) 至多一个 canonical 区块」这一不变量。三、AsyncSlotBuffer乱序插入、顺序读取的并发协调器CLAUDE.md 指出AsyncSlotBufferT是「fixed-size vec ofMutexOptionTNotify」专门为「并行随机序插入 → 顺序有序读取」这一访问模式优化。实现位于 slot_buffer.rsset_once(index, value)严格写仅当槽位为空时写入否则返回BufferError::AlreadyFilled。写入后调用Notify::notify_waiters()唤醒等待中的消费者。这保证了每个槽位恰好被写一次——重复写被视为逻辑 bug生产者代码中对AlreadyFilled会记录Buffer slot already filled — this is a logic bug错误日志。set(index, value)覆盖写无条件覆盖槽位用于「抓到更新版本区块」或纠错场景。get(index)消费若槽位为空则挂起等待Notify::notified()否则立即返回越界返回None。注意其loop模式确保不会因通知竞态而错过唤醒。该结构的单元测试覆盖了五种典型场景见 slot_buffer.rs顺序填充与读取并行生产者随机延迟乱序填充消费者仍能按序读出且父哈希链正确test_parallel_fill_random_latency直接模拟了真实抓取的乱序到达越界与严格写的边界行为覆盖写 / 替换能力「外部前驱交接」——用数据库 tip 哈希作为槽位 0 的校验基准test_external_predecessor_handover这正是游标算法的微型复刻。四、Cursor生产者-消费者模型与父哈希链校验CLAUDE.md 描述的 Cursor 是AsyncSlotBuffer上的生产者-消费者模式生产者为范围内每个区块tokio::spawn一个任务并行抓取消费者顺序读取并校验block.parent_hash expected_hash不匹配即返回CursorResult::ReorgDetected并取消生产者。4.1 主入口fetch_blocks_and_run_cursorevm_listener.rs 中的fetch_blocks_and_run_cursor是 V2 游标算法的一次迭代编排步骤包括从 DB 读取最新 canonical 区块tip记录其block_number与block_hash从 RPC 获取当前链高若链高未超过 DB tip则sleep(loop_delay_ms)后返回CursorResult::UpToDate计算闭区间[range_start, range_end]range_end min(chain_height, db_tip range_size)创建共享AsyncSlotBuffer与CancellationToken并行tokio::spawn消费者cursor_processing与生产者fetch_blocks_in_paralleltokio::join!等待两者任何一方先失败都不会遗弃另一方按优先级分析结果Reorg 优先不 sleep立即处理→ 成功sleep 后返回→ 错误不 sleep快速传播给重试逻辑。每次迭代使用全新的CancellationToken由生产者与消费者共享实现双向 fail-fast消费者发现重组或 DB 失败时取消 token 以停止剩余 RPC 请求生产者任一抓取失败时取消 token消费者侧的buffer.get立即被唤醒退出。4.2 消费者cursor_processing的关键路径消费者循环evm_listener.rs对每个槽位执行tokio::select! { biased; _ cancel_token.cancelled() 返回 Cancelled block_opt buffer.get(i) 取到区块 }随后校验父哈希fetched_block.block.header.parent_hash current_expected_hash。首个区块的期望值是 DB tip 哈希之后每个区块的期望值更新为前一个已校验区块的哈希。校验失败即cancel_token.cancel()并返回CursorResult::ReorgDetected { block_number, block_hash, parent_hash }。校验通过后遵循publish-before-commit原则先发布区块事件BlockFlow::Live再以BlockStatus::Canonical写入 DB。若发布失败区块不入库、DB tip 不变游标在下一次迭代重试同一区块——这是「零事件丢失」的核心保障详见第七节。4.3 去重设计CLAUDE.md 明确「Lock flow is handling the dedup by design, it will be able to discard message if there is some processing and duplicated tasks」。即去重由 FlowLock 与消息 Ack 机制承担Cursor 本身不做消息级去重见第十节的 FlowLock 详解。五、五种 RPC 抓取策略与错误分类CLAUDE.md 列出的五种策略在 evm_block_fetcher.rs 中均有对应方法get_block_by_number/get_block_by_hash经fetch_blocks_in_parallel调用见 evm_listener.rs策略配置值实现特点block_receipts默认fetch_block_with_block_receipts_by_number2 个并行任务区块 eth_getBlockReceipts节点支持时效率最高batch_receipts_fullfetch_block_with_batch_receipts_by_number单次批量 JSON-RPC 获取全部收据batch_receipts_rangefetch_block_by_number_with_parallel_batched_receipts分块并行批量块大小由batch_receipts_size_range控制transaction_receipts_parallelfetch_block_with_individual_receipts_by_number每个收据一个任务最大并行度transaction_receipts_sequentialfetch_block_with_sequential_receipts_by_number逐个获取对限流最友好5.1 错误重试分类抓取器将 RPC 错误分为三类见 evm_block_fetcher.rsUnrecoverable不可恢复UnsupportedMethod、BatchUnsupported、DeserializationError—— 立即失败RateLimited限流HTTP 429 —— 指数退避重试500ms → 1s → 2s → …上限max_exponential_backoff_ms默认 20000msRecoverable可恢复TransportError、NotFound等 —— 固定间隔重试。所有可恢复错误内置无限重试只有不可恢复错误或取消才会向上冒泡。FetchConfig::default()给出重试间隔 500ms、verify_blockfalse、verify_block_allow_skippingtrue的默认值evm_block_fetcher.rs。5.2 启动策略校验服务启动时会执行validate_strategy_and_init_blockevm_listener.rs先抓取最新区块验证所选策略与 RPC 节点兼容任何失败RPC 不可达、策略不兼容、DB 不可达、起始区块抓取失败都直接panic!走崩溃重启crash-loop-backoff 模式。唯一例外是区块校验失败CouldNotComputeBlock这属于节点正常应答但重算根不一致稳态流水线将其归类为 transient 重试因此启动时只记 ERROR 日志而不崩溃。首次启动且 DB 为空时block_start_on_first_start支持current解析为latest_block_number - 1为首个区块的重组留出安全余量或具体区块号起始区块只作种子、不发布事件首个发布区块是seed 1。六、Block Computer可选密码学校验evm_block_computer.rs 提供可选compute_block: true的区块完整性验证重算transaction root、receipt root与block hash任一不匹配抛出对应的BlockVerificationErrorTransactionRootMismatch、ReceiptRootMismatch、BlockHashMismatch等。该模块特别处理了 L2 的特殊编码Optimism 存款交易类型 126deposit txArbitrum 内部类型 106internal tx。verify_block_allow_skipping为 true 时不支持的交易类型以 WARN 日志跳过而非硬失败FetchConfig中默认 true见 evm_block_fetcher.rs。因此对 L2 链建议保持compute_block_allow_skipping: true避免因未知交易类型阻塞整条流水线。七、Publisher 与 FilterIndexO(1) 交易匹配 发布即保证7.1 FilterIndex 倒排索引publisher.rs 中的FilterIndex是从某 chain_id 全部过滤器构建的倒排索引实现 O(1) 交易匹配而非 O(filters) 全量扫描consumers注册了至少一个过滤器的所有消费者保证每人都会收到 payload哪怕是空 payload以便下游跟踪区块进度unfiltered通配过滤器(None, None, None)的消费者子集——他们接收全部交易与全部日志直接跳过匹配by_from/by_to/by_pair/by_log分别按 from 地址、to 地址、(from,to) 精确对、日志地址建立哈希索引。过滤器地址解析失败时按None处理并记录 WARN例如非法from地址会被降级保证索引构建永不因单条脏数据失败。7.2 Publish-before-commit零事件丢失的核心保障CLAUDE.md 硬性不变量第 1 条ZERO EVENTS MISSED可接受重复at-least-once但每个匹配事件必须到达消费者。其实现机制在 Cursor 与 Finality/Catchup 消费者中完全一致事件先于DB 写入发布若发布失败 → DB 不变 → 游标或 finality tip回退到同一区块重试 → 该区块的事件被重新发布发布为每个消费者无限重试直至 Broker ACK。也就是说丢失事件在协议层面被排除了代价是可能重复投递由下游按(block_number, block_hash)去重。这正是 at-least-once 语义的标准工程取舍。八、Reorg Backtrack三阶段崩溃安全算法CLAUDE.md 描述的 V2 重组回溯算法是本文最值得深挖的部分实现在 evm_listener.rs 的reorg_backtrack。它的核心思想是「走查只读、提交原子、恢复安全」Phase 1 — Walk PublishDB 只读1a按event.block_hash从 RPC 抓取区块 N重组点发布其事件BlockFlow::Live因为它来自实时流收集NewDatabaseBlock元数据。这一步骤弥补了 V1 不发布区块 N 事件的缺口CLAUDE.md 称之为关闭 R2 缺口。1b从 N-1 开始沿parent_hash逐块回溯每个高度按父哈希抓取 → 立即发布事件BlockFlow::Reorged→ 仅保留 72 字节的轻量元数据完整FetchedBlock用完即弃。每个高度都会对 DB 做一次只读比较若该高度 DB canonical 区块哈希与当前区块的parent_hash一致 →分叉点fork-point找到停止若 DB 无该高度区块超出索引边界→ 继续但仅当已收集区块数 ≥finality_depth时停止finality 极限保护到达创世区块height 0也停止。整个 Phase 1 绝不修改 DB——若进程在此阶段崩溃DB 保持原状重试从零重新走查并重新发布at-least-once。Phase 2 — Batch Commit单事务原子提交将收集的区块反转为升序fork1, …, N-1, N通过batch_upsert_blocks_canonical在单个 DB 事务中批量 upsert全部置为 CANONICAL之前的分叉区块在相同事务中被置为 UNCLE。事务任一失败即整体回滚DB 保持原状Broker 重试消息 → 干净重启。UpsertResult分为Inserted/Updated/NoOp三种结果见 block_model.rs其中Updated与NoOp合计大于 0 表示「部分区块来自已知分叉分支」。Phase 3 — Resume发布FETCH_NEW_BLOCKS重新启动游标。此步从reorg_backtrack移到了 ReorgHandler 中、在释放锁之后执行workers.rs以消除与其它 handler 的竞争。崩溃安全矩阵崩溃时机DB 状态重试行为Phase 1 期间未触碰从头重新走查 重新发布at-least-oncePhase 2 期间事务回滚未触碰同上Phase 2 提交后已正确更新走查约 1 个区块即结束重发约 1 个事件at-least-oncereorg_depth 定义被替换的区块数包含区块 N。例如高度 100 重组、分叉点在 97 → depth 3100、99、98 被替换97 是公共祖先。九、Finality 流程已定稿区块的独立消费线由于 finalized 区块永不重组Finality 流程是 Cursor 的镜像简化版无父哈希校验、无 reorg 分支、无回溯发布。validate_and_init_final_blockevm_listener.rsDB 中final_blocks表为空时以「最新 final 区块」为锚点种子同样不发布首个发布的 final 区块是 anchor 1fetch_final_blocksevm_listener.rs读取 final tip → 获取当前 final 高度 → 计算范围 → 同一套生产者-消费者并行模型但消费者final_processing只做「发布 final 事件 → 插入final_blocks」两步finality 判定策略finality_tag: true时使用节点的finalized区块标签false时使用head - finality_depth实现在 sem_evm_rpc_provider.rs 的get_final_block_number。Finality 流使用独立的、加盐的 FlowLock 键FINALITYsalt与实时游标锁完全独立——Finality 流程卡住不会影响实时流反之亦然见 flow_lock.rs。十、Consumer Routing、FlowLock 与 HPA 兼容10.1 消息主题CLAUDE.md 列出了全部路由内部主题FETCH_NEW_BLOCKS、FETCH_FINAL_BLOCK、BACKTRACK_REORG、WATCH、UNWATCH、CLEAN_BLOCKS、CLEAN_FINAL_BLOCKS、FINAL_CATCHUP、RANGE_FINAL_CATCHUP外部主题{consumer_id}.new-event、{consumer_id}.catchup-event、{consumer_id}.final-event、{consumer_id}.final-catchup-event—— 动态生成自 filters DB所有主题按chain_id_to_namespace(chain_id)命名空间隔离。10.2 FlowLockPostgreSQL 咨询锁实现分布式互斥flow_lock.rs 用pg_try_advisory_lock实现非阻塞分布式锁Fetch/Reorg 流的锁键就是chain_idCleaner、Finality、Final-Cleaner 流分别用CLEANER!、FINALITY、FNCLEAN!盐值异或派生独立键四条流互不争抢锁由独立PoolConnection持有RAII guardrelease()或连接关闭PG 自动释放都会解锁Handler 拿到锁后处理先释放锁再发布续作消息消除与其他 handler 的竞争见 workers.rs 的 FetchHandler。10.3 HPA 兼容CLAUDE.md 硬性不变量第 3 条HPA compatible——多副本水平扩容时主流程消息不得被重复处理。机制组合所有处理都先尝试获取 FlowLock若锁被其它 Pod 持有则Ack 并跳过而非 requeue避免无限重排队prefetch1保证每个消费者同时最多在途一条消息防止并发游标运行Cleaner 的锁覆盖其 cron sleep 全程防止重投递的重复消息衍生出第二条自续环。DB 连接池下限也因此有硬约束MIN_POOL_MIN_CONNECTIONS 2、MIN_POOL_MAX_CONNECTIONS 84 个咨询锁会话 4 个并发 handler 查询见 config.rs。十一、Catchup 与 Final Catchup范围补数dispatch_catchup_rangeevm_listener.rs是把任意大的用户补数请求切成有界子范围的编排器只做一次 RPC 调用获取当前链高若block_start chain_height→ 返回空用户要的块还不存在可稍后重发否则把block_end钳制到链高并按catchup.catchup_max_sub_range切成若干CatchupPayload子块实现见split_catchup_range含u64::MAX溢出的防御性处理与完整单测evm_listener.rs子块经range-catchup队列下发由run_range_catchup执行复用实时游标的并行生产者 纯顺序发布消费者catchup_processing无 DB 写入、无父哈希校验、无 reorg 处理纯重放发布到{consumer_id}.catchup-event注意上界是原始链高无 finality 余量——未定稿窗口内的 catchup 允许用户自担重组风险实时游标仍是 canonical 状态的权威。Final Catchupdispatch_final_catchup_range/run_final_range_catchup是同一模式但上界是finalized head 而非原始链高未定稿窗口的重放属于 live catchup 的职责final catchup 绝不重放未定稿区块发布到{consumer_id}.final-catchup-event。十二、错误处理Transient 与 Permanent 的两分法CLAUDE.md 规定 handler 对 Broker 的错误分类Transient瞬时HandlerError::Transient—— DB 错误、RPC 失败、Broker 发布失败、payload 构建错误 → Broker无限重试不递增 delivery countPermanent永久HandlerError::Permanent—— 不变量违例InvariantViolation、反序列化失败 → 超过max_retries后进入死信队列。classify函数workers.rs采用显式 match 臂、无通配符新增EvmListenerError变体时必须在编译期强制作出分类决策。CouldNotFetchBlock、CouldNotComputeBlock、DatabaseError、ChainHeightError、SlotBufferError、BrokerPublishError、MessageProcessingError、PayloadBuildError归为 transient只有InvariantViolation归为 permanent。完整的故障行为矩阵Postgres/Broker/RPC 宕机、消费者队列缺失、各流程行为见仓库根目录的 listener/docs/error_flows.md。十三、配置全景config.yaml 逐项解读以下配置节选自 config.yaml模板与 config-minimal.yamlPolygon 主网示例并补充了源码中的取值范围与默认值。13.1 基础与 HTTPname: listener http_port: 8080 # 共享 HTTP 服务端口必填无默认当前提供 /livez、/readyz13.2 databasedatabase: db_url: postgres://postgres:postgreslocalhost:5432/listener migration_max_attempts: 5 pool: max_connections: 12 # 硬下限 84 个咨询锁会话 4 个并发 handler 查询 min_connections: 2 # 硬下限 21 个锁会话 1 个并发查询 # acquire_timeout_secs: 5 # idle_timeout_secs: 600 # max_lifetime_secs: 1800db_url必须以postgres://或postgresql://开头若启用 IAM RDS 认证iam-authfeature必须在编译期启用对应 feature否则校验失败config.rs。13.3 brokerbroker: broker_type: redis # redis默认| amqp broker_url: redis://localhost:6379 # broker_url: amqp://user:passlocalhost:5672/%2f # ensure_publish: true # 复制感知发布Redis 每次 XADD 后发 WAIT 1 500AMQP 启用 publisher confirms # circuit_breaker_cooldown_secs: 10 # 熔断后重试前等待秒数 # circuit_breaker_threshold: 3 # 连续发布失败触发熔断的次数 # claim_min_idle: 30 # 消息 claim 可被处理前的最小空闲秒数可选Broker 后端在 config.rs 中统一定义broker_type与 URL 协议必须匹配amqp:///amqps://↔redis:///rediss://。ensure_publish是 CLAUDE.md 硬性不变量第 4 条Broker parity的配置入口Redis 每次XADD后执行WAIT 1 500等待至少 1 个副本确认AMQP 则在 channel 上执行confirm_select开启 publisher confirms实现见 listener/crates/shared/broker/src/amqp/rmq_publisher.rs。13.4 telemetry 与 logtelemetry: enabled: true metrics_port: 9091 log: format: pretty # json | compact | pretty # show_file_line: false # 输出源文件 file:line # show_thread_ids: true # 输出线程 ID # show_timestamp: true # 输出 RFC 3339 时间戳 # show_target: true # 输出模块路径 target # show_constants: true # 在每行日志注入 name、network、chain_id # level: info # 默认级别可被 RUST_LOG 覆盖13.5 blockchainblockchain: type: evm chain_id: 1 rpc_url: https://ethereum-rpc.publicnode.com network: ethereum-mainnet finality_depth: 64 # finality_tagfalse 时 final head - finality_depth finality_tag: true # true 用节点的 finalized 标签判定 final 区块 finality_active: true # 启用 fetch-final-block 循环 cleaner: active: true blocks_to_keep: 1000 # 保留的区块数 cron_secs: 3600 # 清理周期秒 catchup: catchup_max_sub_range: 1000 # 补数子范围上限示例值实际按需配置 strategy: automatic_startup: true block_start_on_first_start: current # 首次启动、DB 为空时current 或具体区块号 range_size: 200 # 每轮游标抓取的区块数范围 [1, 10000] loop_delay_ms: 2000 # 两轮迭代间的休眠 max_parallel_requests: 50 # RPC 并发上限范围 [1, 200] block_fetcher: block_receipts # 见第五节五种策略 batch_receipts_size_range: 10 # 仅 batch_receipts_range 生效范围 [1, 100] compute_block: true # 开启交易根/收据根/区块哈希校验 compute_block_allow_skipping: true # 不支持的交易类型跳过而非硬失败 max_exponential_backoff_ms: 500 # 限流指数退避上限默认 20000 publish: publish_retry_secs: 1 # 发布失败重试间隔 publish_stale: true # 是否允许发布陈旧区块 publish_no_stale_retries: 5 # publish_stalefalse 时陈旧发布的放弃重试次数默认 5配置读取支持APP_SECTION__FIELD风格的环境变量覆盖例如APP_BROKER__BROKER_TYPEredis APP_BROKER__BROKER_URLredis://localhost:6379 cargo run见 config.rs 与 config.yaml 头注。range_size的合法范围是[1, 10000]、max_parallel_requests是[1, 200]、batch_receipts_size_range是[1, 100]常量定义见 config.rs。此外 config-avalanche.yaml 与 config-polygon-compute.yaml 还提供了 Avalanche 与 Polygon 计算链的现成配置参考。十四、文件地图快速导航CLAUDE.md 提供的文件地图本文已逐项验证存在文件职责src/main.rs入口点、装配src/lib.rs公共 API 导出src/core/evm_listener.rsCursor Reorg 算法src/core/slot_buffer.rsAsyncSlotBuffersrc/core/publisher.rsFilterIndex 事件发布src/core/workers.rsBroker 消息处理FetchHandler、ReorgHandler 等src/core/filters.rs过滤器生命周期增/删src/core/cleaner.rs旧区块删除src/blockchain/evm/evm_block_fetcher.rs5 种抓取策略src/blockchain/evm/evm_block_computer.rs区块校验src/blockchain/evm/sem_evm_rpc_provider.rs信号量限流 RPC Providersrc/config/config.rsYAML 环境变量配置 schemasrc/store/repositories/block_repo.rs区块 DB 操作upsert、批量 upsertsrc/store/repositories/filter_repo.rs过滤器 DB 操作src/store/models/block_model.rsBlock、BlockStatus、UpsertResultsrc/store/flow_lock.rsPG 咨询锁分布式互斥依赖方面Cargo.toml基于 alloyEVM 类型与 Provider、tokio、sqlxPostgreSQL内置 migrate、thiserror、tracing、metrics、serdeBroker 与 telemetry 复用 workspace 内的shared/broker与shared/telemetrycrateiam-authfeature 可选引入 aws-config / aws-credential-types / aws-sigv4 支持 IAM RDS 认证。十五、硬性不变量与已知限制CLAUDE.md 总结的 7 条硬性不变量是理解该组件设计意图的关键ZERO EVENTS MISSED—— 允许重复at-least-once但每个匹配事件必须到达消费者publish-before-commit 强制执行原子性与崩溃韧性—— DB、Redis、Broker 故障不得破坏状态Reorg 只读走查 原子批量提交Cursor 先发布后入库HPA 兼容—— 主流程消息不重复处理is_empty_or_pending()去重守卫 prefetch1防止每链并发游标Broker 对等—— Redis Streams 与 RabbitMQ 行为完全一致ensure_publish映射为 RedisWAIT 1 500/ AMQPconfirm_select两者共用同一 handler 接口正确的消费者路由—— 事件只发布给过滤器匹配的消费者FilterIndex 每次游标迭代必须从 DB 重建链 ID 隔离—— 所有主题按 chain_id 命名空间隔离DB 查询按 chain_id 过滤每 (chain_id, block_number) 至多一个 canonical 区块跟上最快链—— 通过 SlotBuffer 并行抓取、可配置批大小、5 种 RPC 策略、信号量控制并发。已知接受的限制RPC 卡住会阻塞游标直到超时可接受指数退避缓解。结语listener_core的价值在于把「并行拉取、顺序校验、先发后写、原子回溯」四件事用一套自洽的工程不变量串起来AsyncSlotBuffer消解乱序、Cursor 保证链连续性、publish-before-commit 保证零丢失、三阶段 Reorg 回溯保证崩溃安全、FlowLock 保证水平扩容互斥。对需要在 fhEVM 生态中自建或二次开发链上事件管道、需要理解重组与补数语义的读者而言这份 CLAUDE.md 与其源码实现是最完整的起点故障场景的完整行为矩阵可进一步查阅 listener/docs/error_flows.md架构总览可参考 listener/docs/listener_core.md。赞分享密码学隐私计算区块链后端【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址https://gitcode.com/GitHub_Trending/fh/fhevm点击查看免费下载相关推荐fhEVM 仓库中的 Listener面向 EVM 链的零事件丢失区块链监听器实战指南fhEVM 仓库中的 Listener面向 EVM 链的零事件丢失区块链监听器实战指南 导读本文以 listener 模块的官方 README 为核心骨架密码学隐私计算区块链后端如何发布 Deno 版本start_release 工作流与 crates 发布流水线的源码级解析如何发布 Deno 版本start_release 工作流与 crates 发布流水线的源码级解析 本文以 Deno 仓库自带的 发布说明 https://l语言运行时SDRPlusPlus流水线动态优先级实时任务保障机制SDRPlusPlus流水线动态优先级实时任务保障机制 还在为SDR软件定义无线电处理中的实时性需求而烦恼SDRPlusPlus通过其精巧的流水线架构和桌面应用通信创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?