2025-12-06-杂记-前端图拓扑渲染优化
Last Update:
Page View: loading...
性能优化 (Web Workers): 目前的数据获取、解析和Diff算法都在主线程运行。当拓扑变大时,计算Diff会导致页面卡顿。建议将这部分移至 Web Worker。
D3 渲染优化: 目前的设计倾向于每次更新都全量替换 filteredNodes,这会导致 D3 力导向图重新初始化或位置抖动。应该利用 Diff 结果进行增量渲染 (Enter/Update/Exit)。
状态管理解耦: useTopologyData 承担了太多职责(数据存储、UI状态、标签逻辑)。应该拆分为“数据层”和“视觉层”。
数据结构优化: 数组查找(.find)效率低,应更多使用 Map/Set 索引。
优化后文件结构
采用了 Core (数据核心) + Visual (视觉逻辑) + Worker (后台计算) 的分层结构。
codeText
1 | |
现在的以太坊拓扑渲染架构采用了 “分层响应式架构” (Layered Reactive Architecture),结合了 Web Worker 多线程计算 和 D3 增量渲染 技术。
这是一种高性能、低耦合的现代前端架构,专门为了处理大量节点(数千级)的实时动态拓扑而设计。
以下是该架构的详细层级解析:
1. 架构总览图
数据流向是单向的,状态管理是响应式的:
codeMermaid
1 | |
2. 核心层级详细解析
第一层:数据处理层 (Worker Thread)
文件: workers/topology.worker.ts
这是架构的“发动机”,完全脱离主线程运行。
职责:
数据拉取:直接发起 Fetch 请求,不占用主线程网络资源。
数据清洗:解析复杂的 JSON 结构,标准化为 TopologyNode 和 TopologyLink。
智能 Diff (差异计算):
这是性能优化的关键。它对比新旧数据,计算出新增、删除和更新的节点。
坐标继承:在 Worker 中将旧节点的 x, y 坐标赋值给新节点,防止 D3 在数据更新时重新计算布局导致视图“爆炸”或闪烁。
第二层:状态管理层 (Composables)
这一层利用 Vue 3 的 Composition API 将业务逻辑拆分为独立的模块。
数据持有 (useTopologyCore.ts):
与 Worker 通信的桥梁。
使用 shallowRef 存储庞大的拓扑数据。优化点:shallowRef 不会深度监听节点内部属性的变化(如 x, y 坐标),这极大减轻了 Vue 响应式系统的负担,因为 D3 会直接操作这些原生对象。
视觉逻辑 (useTopologyVisual.ts):
纯粹的计算层。它不关心数据怎么来的,只关心怎么显示。
动态过滤:利用 computed 属性,根据 filters(如隐藏共识节点)实时生成 filteredNodes。
样式映射:集中管理颜色 (getNodeColor) 和标签 (getNodeLabel) 逻辑,实现逻辑与渲染分离。
第三层:渲染驱动层 (Render Engine)
文件: useD3Renderer.ts
这是 D3.js 与 Vue 的结合点。
生命周期接管:它在 onMounted 时初始化 D3 仿真器。
增量渲染 (Incremental Rendering):
使用 Vue 的 watch 监听过滤后的数据。
利用 D3 的 enter(), update(), exit() 模式。
Enter: 新节点淡入。
Exit: 被过滤或删除的节点淡出移除。
Update: 现有节点平滑移动到新位置。
事件桥接:将 D3 的 click、drag 事件转换为 Vue 的回调函数,传递给上层组件。
第四层:视图组装层 (View Integration)
文件: EthereumTopology.vue (父组件)
这是架构的“容器”和“胶水”。
依赖注入 (Dependency Injection):
父组件通过 provide(‘topology-state’, …) 将 mode、filters 等状态下发。
子组件 TopologyVisualization 通过 inject 直接获取并修改这些状态。避免了深层 Prop 传递(Prop Drilling)。
组件编排:
负责布局:左上角悬浮控制面板、中间 D3 画布、右侧详情抽屉。
负责联动:当 D3 点击节点时,控制 showPhysicalDetails 变量来弹出侧边栏。
3. 关键性能优化点总结
非阻塞主线程 (Off-Main-Thread):
旧架构:在组件内 fetch 数据 -> 解析 -> 赋值。数据量大时 UI 会卡顿。
新架构:所有数据处理都在 Worker 中完成,主线程只负责接收“准备好渲染”的数据。
浅层响应式 (Shallow Reactivity):
- 使用 shallowRef 代替 ref 存储节点数组。D3 内部高频修改 node.x 和 node.y 时,不会触发 Vue 的依赖更新系统,显著提升动画帧率。
状态保持 (State Preservation):
- Worker 在处理新数据时,会查找旧数据的 ID,并将 x, y, vx, vy (速度向量) 复制给新数据。这保证了在轮询更新时,节点不会重置位置,实现了“流式”的平滑更新效果。
按需计算 (Computed Filtering):
- 连接 (links) 的过滤依赖于节点 (nodes) 的过滤结果。新架构使用了 Set 来建立索引,将连接过滤的时间复杂度从 O(N*M) 降低到 O(M)(其中 N 是节点数,M 是连接数)。
4. 总结
现在的架构是一个 “重后台、轻前台、数据驱动视图” 的专业可视化架构。
Worker 负责“脏活累活”(数据处理)。
D3 负责“精细活”(物理仿真和绘图)。
Vue 负责“指挥”(状态管理和组件通信)。
这种架构非常适合需要长时间运行、实时监控网络状态的生产级系统。
根据提供的代码(EthereumTopologyHandler 和 RealTopologyService),以太坊网络拓扑的处理流程是一个分层获取、数据融合、格式化输出的过程。核心逻辑依赖于 Neo4j 图数据库(存储P2P关系)和 Docker 守护进程(提供容器运行时信息)。
以下是详细的处理步骤解析:
1. 数据源获取 (Data Acquisition)
系统主要通过两个渠道获取数据:
Neo4j 数据库 (核心数据源):存储了爬虫或客户端上报的节点发现数据,包含节点ID、IP、以及节点间的 P2P 连接关系。
Docker Client (辅助数据源):用于获取运行中容器的实时状态、名称映射和网络设置。
2. 核心处理流程
整个拓扑生成的逻辑主要集中在 _get_real_topology_from_neo4j 和 _convert_topology_format 方法中。
步骤 A:从 Neo4j 提取原始拓扑结构
代码通过 Cypher 查询语句分三步提取数据:
查询执行层 (Execution Layer):
查找所有 ExecNode 标签的节点。
查找 EXEC_PEERS_WITH 关系,获取该节点的对等节点(Peers)。
查询共识层 (Consensus Layer):
查找所有 ConsNode 标签的节点。
查找 CONS_PEERS_WITH 关系。
查询验证者 (Validators):
查找与共识节点通过 MANAGES_VALIDATOR 关系连接的 Validator 节点。
这反映了哪个信标节点(Beacon Node)管理着哪些验证者客户端。
步骤 B:容器身份映射 (Container Mapping)
目的:数据库中只有 IP 地址,但在前端展示时,最好能显示具体的 Docker 容器名称(如 geth-node-1)。
实现:_create_ip_to_container_mapping 方法遍历所有 Docker 容器,提取其网络设置中的 IP 地址,建立 IP -> ContainerName 的映射表。
步骤 C:构建拓扑对象 (Topology Construction)
系统将原始数据转换为前端可视化的 JSON 格式,包含 nodes 和 links。
1. 节点生成 (Nodes):
代码根据逻辑自动计算节点的坐标 (x, y) 以便可视化布局:
执行层节点:
type: execution
位置:固定在 Y=150 的水平线上。
共识层节点:
type: consensus
位置:固定在 Y=350 的水平线上(位于执行层下方)。
验证者节点:
type: validator
位置:簇拥在所属共识节点的下方 (y + 60),通过计算偏移量排成小方阵。
2. 连接生成 (Links):
系统构建了四种类型的连接:
执行层 P2P (exec_peer):基于 Neo4j 中的 EXEC_PEERS_WITH 关系,表示 Geth/Nethermind 节点间的 Gossip 协议连接。
共识层 P2P (cons_peer):基于 CONS_PEERS_WITH 关系,表示 Lighthouse/Prysm 节点间的连接。
管理关系 (manages_validator):连接共识节点和它管理的验证者节点。
跨层连接 (cross_layer):关键逻辑。代码会自动匹配 IP 地址相同的执行层节点和共识层节点,并创建一个垂直连接。这代表了以太坊客户端组合(Engine API 通信,例如 Geth <-> Lighthouse 在同一台机器/Pod内)。
3. 容错与缓存机制
为了保证性能和稳定性,代码中包含了以下机制:
缓存 (Caching):
使用 self.cache 存储计算好的拓扑。
设置 cache_ttl (20-30秒),防止频繁查询 Neo4j 导致数据库过载。
降级模式 (Fallback - 仅在 Service 中):
如果 Neo4j 连接失败或返回空数据,RealTopologyService 会调用 _get_container_based_topology。
Fallback 逻辑:直接扫描 Docker 容器,如果发现名为 ethereum 的容器,就根据容器数量“伪造”一个链式的拓扑结构(非网状),以确保界面上至少能看到节点存在,而不是一片空白。
4. 统计与验证 (Statistics & Validation)
EthereumTopologyHandler 还提供了额外的高级功能:
独立查询:get_nodes 和 get_links 可以不依赖完整拓扑逻辑,直接查询特定层的数据,提高效率。
拓扑验证:validate_topology 检查数据一致性:
节点 ID 是否唯一。
连接的源/目标节点是否存在。
是否存在孤立节点。
IP 地址分布是否异常(例如一个 IP 运行了超过2个主要节点)。
总结
该系统处理以太坊拓扑的核心思想是:“数据库定义逻辑关系,Docker 定义物理属性,代码负责视觉组装”。
逻辑层:谁连谁?由 Neo4j 决定。
物理层:你是谁?由 Docker IP 映射决定。
视觉层:你在哪?由代码中的分层坐标计算逻辑决定(执行层在上,共识层在中,验证者在下)。
目前的实现逻辑虽然功能完整,但在性能上存在几个显著的瓶颈,特别是在节点数量增多或 Docker 容器较多时,响应速度会明显下降。
以下是针对代码的具体性能优化方案,按提升幅度从大到小排序:
1. 痛点分析:目前的性能瓶颈在哪里?
Docker API 调用过于频繁 (主要瓶颈):
_create_ip_to_container_mapping 每次生成拓扑都会被调用。它会遍历所有容器并检查网络设置。Docker API 的响应通常是毫秒级到秒级的,如果不缓存,这会严重阻塞主线程。
在物理拓扑中,_get_link_bandwidth 会对每个连接进入容器执行 tc 命令。如果有 50 个连接,就要串行执行 50 次 docker exec,这是极慢的 IO 操作。
串行数据库查询:
- 在 _get_real_topology_from_neo4j 中,执行层查询及处理完之后,才开始共识层的查询。这两者没有依赖关系,完全可以并行。
计算密集型的重复操作:
- 每次请求都重新计算所有节点的坐标和映射关系,即使数据没有变化。
2. 优化方案一:Docker 数据的独立缓存与后台更新
Docker 的元数据(IP、容器名)变化频率远低于 P2P 网络连接的变化频率。不要在每次请求拓扑时都去查询 Docker。
优化策略: 使用“读写分离”的策略,后台任务更新 Docker 映射,前台请求只读内存变量。
codePython
1 | |
3. 优化方案二:物理拓扑带宽检测的“非阻塞化”
在 RealTopologyService 中,物理连接的带宽检测(tc 命令)是极其耗时的。绝对不能在用户请求 API 时实时去跑 tc 命令。
优化策略: 将带宽数据设为“最终一致性”。主接口只返回拓扑结构,带宽字段先返回缓存值或 “Checking…”,后台任务专门负责轮询更新带宽。
codePython
1 | |
4. 优化方案三:Neo4j 并发查询
Neo4j 的 Python Driver (尤其是 Bolt 协议) 支持并发。执行层和共识层的查询是独立的,可以使用 asyncio.gather 同时发起查询。
注意:这需要你的 database_manager 支持异步操作。如果底层是同步驱动,可以用 run_in_executor 包装。
codePython
1 | |
5. 优化方案四:Cypher 查询语句优化
目前的 Cypher 使用了 OPTIONAL MATCH 和 collect,这在数据量大时比较慢。
原查询:
codeCypher
1 | |
如果在节点很多的情况下,这个查询会扫描整个图。
优化建议:
分批次:如果节点超过 1000 个,不要一次性 collect 所有 Peers。前端通常不需要展示所有几千条连线(会卡死浏览器)。可以限制返回的 Peer 数量,例如 LIMIT 10。
索引:确保 node_id, ip 在 Neo4j 中建立了索引 (CREATE INDEX ON :ExecNode(node_id)).
只查 ID:先查出所有 Node 的基础信息,再查 Relation 表(Links),在内存中组装,通常比 Graph DB 做复杂的聚合(Map/Collect)要快。
6. 综合改进后的代码结构建议
这里给出一个集成优化思路的 EthereumTopologyHandler 核心方法重构示例:
codePython
1 | |
总结
要进行性能优化,最关键的修改是:
Docker 映射:改为后台定时更新或长缓存,不要每秒都去 inspect 容器。
物理带宽 (tc):改为异步/后台获取,不要阻塞 API 响应。
Neo4j:使用并发查询,并限制 Cypher 复杂度。
攻击方式(Attack Strategies)
系统目前支持以下6种攻击方式:
1. 节点断网攻击(Node Disconnection Attack)
通过网络隔离手段切断目标节点与其他节点的连接。支持的方法包括:
interface_down: 禁用网络接口route_flush: 清除路由表firewall_block: 防火墙阻断p2p_block: P2P连接阻断
2. 通信干扰攻击(Communication Interference Attack)
通过大量无效通信干扰目标节点正常通信。支持的方法包括:
json_rpc_flood: JSON-RPC请求泛洪p2p_flood: P2P消息泛洪memory_exhaustion: 内存耗尽攻击
3. 时间攻击(Timestamp Attack)
针对共识机制的时间同步进行攻击。支持的方法包括:
- time_shift: 时间偏移
ntp_block: 阻断NTP时间同步time_drift: 时间漂移
4. 简化Sybil攻击(Simplified Sybil Attack)
创建虚假节点来影响网络。可以配置:
- 虚假节点数量(1-20)
- 节点类型(轻节点、全节点、验证者节点)
- 网络环境(主网、测试网、开发网)
- 连接真实节点选项
5. 存储攻击(Storage Attack)
针对节点存储系统的攻击。支持的方法包括:
disk_fill: 磁盘空间填充database_corruption: 数据库损坏state_pollution: 状态污染chain_data_spam: 链上数据垃圾信息
6. Geth/Lighthouse客户端攻击(Geth/Lighthouse Attack)
针对特定以太坊客户端的攻击。支持的方法包括:
process_kill: 终止进程db_corruption: 数据库损坏port_blocking: 端口阻断config_modification: 配置文件修改
攻击模式(Execution Modes)
系统支持三种攻击执行模式:
1. 一次性攻击(One-shot)
执行一次攻击,持续指定时间后自动清理恢复。 配置参数:
- duration_seconds: 攻击持续时间(秒)
2. 重复攻击(Repeated)
按指定间隔重复执行多次攻击。 配置参数:
- interval_seconds: 攻击间隔时间(秒)
- repeat_count: 重复次数
- duration_seconds: 每次攻击持续时间(秒)
3. 持续攻击(Continuous)
持续不断地执行攻击,直到手动停止。 配置参数:
- interval_seconds: 攻击间隔时间(秒)
- duration_seconds: 每次攻击持续时间(秒)
动态目标攻击
系统还支持一种特殊的动态目标攻击功能,可以根据网络拓扑分析结果自动选择攻击目标。支持的中心性指标包括:
- 度中心性(Degree Centrality)
- 介数中心性(Betweenness Centrality)
- 接近中心性(Closeness Centrality)
- 特征向量中心性(Eigenvector Centrality)
通过这些攻击方式和模式的组合,系统可以模拟各种真实的以太坊网络攻击场景,帮助评估网络的安全性和鲁棒性。
1. 发起普通攻击 (Standard Attack)
此接口用于对明确指定的静态 IP 列表发起攻击。
Prompt / 接口说明:
接口地址: POST /api/simulate
功能: 发起针对特定静态目标(IP/ID列表)的攻击模拟。
逻辑约束:
parameters.target_nodes 必须是字符串数组 [“ip1”, “ip2”]。
支持所有三种执行模式 (one_shot, repeated, continuous)。
请求体构建规则:
Level 1 (执行配置): 决定攻击的时间维度。
若是 one_shot: 仅需 duration_seconds。
若是 repeated: 需额外提供 interval_seconds 和 repeat_count。
Level 2 (策略参数): 决定攻击的具体手段。
必须包含 strategy 字段(枚举值)。
其余字段根据 strategy 变化(如 storage_attack 需要 size_mb,而 node_disconnection 不需要)。
请求示例 (JSON):
codeJSON
1 | |
2. 发起自适应攻击 (Adaptive Attack)
此接口用于动态目标攻击,系统会在每一轮攻击开始前重新计算受害者(例如:总是攻击网络中连接数最多的节点)。
Prompt / 接口说明:
接口地址: POST /api/simulate/adaptive
功能: 发起自适应攻击,目标由后端实时计算。
关键区别:
不支持 one_shot 模式(因为一次性攻击不需要”自适应”变化)。必须是 repeated 或 continuous。
parameters.target_nodes 必须是特定格式的字符串指令,以 dynamic: 开头。
目标指令语法: dynamic:{指标}:{选择策略}
示例: dynamic:degree:top:5 (度中心性最高的前5个)
示例: dynamic:betweenness:highest (介数中心性最高的1个)
请求示例 (JSON):
codeJSON
1 | |
3. 前端分流逻辑 (Frontend Logic)
这是前端 Vue 组件如何决定调用哪个接口的核心逻辑说明。
Prompt / 逻辑说明:
前端在点击”发起攻击”按钮时,必须执行以下判断逻辑:
检查目标类型:
获取用户在表单中输入的目标配置。
如果目标是字符串指令且以 dynamic: 开头 -> 标记为 isDynamic。
如果目标是手动输入的 IP 列表 -> 标记为 isStatic。
检查执行模式:
- 获取用户选择的模式 (one_shot, repeated, continuous)。
路由决策树:
IF (isDynamic == True AND mode == one_shot):
- ❌ 报错: 自适应攻击不支持一次性模式。
IF (isDynamic == True AND mode != one_shot):
✅ 调用接口: POST /api/simulate/adaptive
注意: 此时 target_nodes 字段发送字符串。
ELSE (即静态目标,无论什么模式):
✅ 调用接口: POST /api/simulate
注意: 此时 target_nodes 字段必须转换为数组 [] 发送。
4. 停止攻击 (Stop Attack)
Prompt / 接口说明:
接口地址: DELETE /api/simulations/{attack_id}
功能: 立即终止一个正在运行 (running) 或挂起 (pending) 的攻击任务。
适用场景:
用户点击”紧急停止”按钮。
用于中断 continuous (无限持续) 类型的攻击。
用于中断剩余轮次尚未执行的 repeated 攻击。
后端行为:
取消对应的 asyncio.Task。
执行清理逻辑(如恢复防火墙规则、删除垃圾文件)。
将数据库中的状态更新为 stopped。
5. 状态轮询与监控 (Monitoring)
Prompt / 接口说明:
为了在前端展示”实时状态”和”系统日志”,需要配合使用以下两个接口:
获取活跃列表: GET /api/simulations/active
用途: 判断当前是否有攻击在跑 (isRunning 状态)。
频率: 建议每 3-5 秒轮询一次。
返回: 包含 progress (进度百分比) 和 current_round (当前轮次)。
获取详情/日志: GET /api/simulations/{attack_id}
用途: 获取特定攻击的详细日志流。
返回: 包含 logs 数组 ([“Attack started”, “Round 1 finished”])。
前端展示: 将 logs 渲染到控制台面板中。
总结:数据结构对照表 (Type Mapping)
| 参数字段 | 描述 | 类型限制 | ||
| execution_config | ||||
| mode | 执行模式 | “one_shot” \ | “repeated” \ | “continuous” |
| duration_seconds | 单次持续时长 | Integer (秒) | ||
| interval_seconds | 轮次间隔 | Integer (秒), 仅 repeated/continuous 有效 | ||
| repeat_count | 重复次数 | Integer, 仅 repeated 有效 | ||
| parameters | ||||
| strategy | 攻击策略 | “node_disconnection” \ | “storage_attack” … | |
| target_nodes | 攻击目标 | Array [str] (普通) OR String dynamic:… (自适应) | ||
| method | 具体手段 | 依赖于 strategy (如 firewall_block, disk_fill) | ||
| … | 其他参数 | 依赖于 strategy (如 size_mb, intensity) |
1. 全局枚举定义 (Global Enums)
这些枚举值用于填充请求体中的特定字段。
| 枚举类型 | 字段名 | 可选值 (Value) | 说明 |
| 执行模式 | mode | one_shot | 一次性:执行一次,持续指定时间后恢复。 |
| repeated | 重复执行:按间隔重复执行多次。 | ||
| continuous | 持续执行:按间隔无限执行,直到手动停止。 | ||
| 攻击策略 | strategy | node_disconnection | 节点断连攻击 |
| communication_interference | 通信干扰攻击 | ||
| storage_attack | 存储耗尽攻击 | ||
| timestamp_attack | 时间/NTP攻击 | ||
| simplified_sybil_attack | 简化版女巫攻击 | ||
| geth_lighthouse_attack | 客户端特定攻击 (Geth/Lighthouse) |
2. 执行配置 (execution_config)
根据 mode 的不同,所需字段不同。注意:自适应攻击接口 (/simulate/adaptive) 不支持 one_shot。
| 模式 (Mode) | 字段名 | 类型 | 必填 | 默认值 | 约束/说明 |
| 通用 | duration_seconds | Int | ✅ | 30 | 攻击生效持续时间 (秒),>=1 |
| Repeated | interval_seconds | Int | ✅ | 60 | 轮次间隔时间 (秒),>=1 |
| (重复) | repeat_count | Int | ✅ | - | 重复执行的总轮数,>=1 |
| Continuous | interval_seconds | Int | ✅ | 60 | 轮次间隔时间 (秒),>=1 |
3. 策略参数详情 (parameters)
此部分为多态结构,根据 strategy 字段的值,JSON 结构发生变化。
3.1 节点断连 (node_disconnection)
| 字段名 | 类型 | 必填 | 默认值 | 描述/选项 |
| method | String | ✅ | - | interface_down (网卡下线), route_flush (清空路由), firewall_block (防火墙), p2p_block (P2P阻断) |
| target_nodes | Array/Str | ✅ | - | 静态IP列表 或 动态指令 (见第4节) |
3.2 通信干扰 (communication_interference)
| 字段名 | 类型 | 必填 | 默认值 | 描述/选项 |
| method | String | ✅ | - | json_rpc_flood (RPC泛洪), p2p_flood (P2P泛洪), memory_exhaustion (内存耗尽) |
| intensity | String | ❌ | medium | low, medium, high, extreme |
| target_nodes | Array/Str | ✅ | - | 静态IP列表 或 动态指令 |
3.3 存储攻击 (storage_attack)
| 字段名 | 类型 | 必填 | 默认值 | 描述/选项 |
| method | String | ✅ | - | disk_fill (填充), database_corruption (脏数据), state_pollution (状态污染), chain_data_spam (链上垃圾) |
| size_mb | Int | ❌ | 1000 | 填充大小 (MB),100 - 10000 |
| file_count | Int | ❌ | 100 | 生成文件数量,10 - 1000 |
| target_nodes | Array/Str | ✅ | - | 静态IP列表 或 动态指令 |
3.4 时间攻击 (timestamp_attack)
| 字段名 | 类型 | 必填 | 默认值 | 描述/选项 |
| method | String | ✅ | - | time_shift (平移), ntp_block (NTP阻断), time_drift (漂移) |
| time_shift | String | ❌ | +1 hour | 偏移量 (如 +1 hour, -30 minutes),仅 time_shift 方法有效 |
| drift_seconds | Int | ❌ | 3600 | 漂移秒数,-86400 到 86400,仅 time_drift 方法有效 |
| target_nodes | Array/Str | ✅ | - | 静态IP列表 或 动态指令 |
3.5 女巫攻击 (simplified_sybil_attack)
| 字段名 | 类型 | 必填 | 默认值 | 描述/选项 |
| fake_node_count | Int | ❌ | 5 | 虚假节点数量 (1-20) |
| node_type | String | ❌ | light | light (轻节点), full (全节点), validator (验证者) |
| network | String | ❌ | testnet | mainnet, testnet, devnet |
| connect_to_real | Bool | ❌ | True | 是否连接真实节点 |
| min_connections | Int | ❌ | 3 | 最小连接数 (0-10) |
| target_nodes | - | - | - | 注意:此策略通常不需要指定具体目标节点 |
3.6 客户端攻击 (geth_lighthouse_attack)
| 字段名 | 类型 | 必填 | 默认值 | 描述/选项 |
| method | String | ✅ | - | process_kill, db_corruption, port_blocking, config_modification |
| attack_type | String | ✅ | - | geth, lighthouse (指定攻击的客户端类型) |
| target_nodes | Array/Str | ✅ | - | 静态IP列表 或 动态指令 |
4. 目标节点配置 (target_nodes)
target_nodes 字段在不同接口下有严格的格式要求。
| 接口端点 | 格式类型 | 数据结构示例 | 说明 |
| /api/simulate | 静态列表 | [“192.168.1.10”, “node_id_123”] | 明确指定要攻击的节点列表。 |
| /api/simulate/adaptive | 动态指令 | “dynamic:degree:top:5” | 字符串格式,后端自动计算目标。 |
动态指令语法: dynamic:{指标}:{选择器}
指标 (Metric):
degree (度中心性)
betweenness (介数中心性)
closeness (接近中心性)
eigenvector (特征向量中心性)
选择器 (Selector):
highest (选最高的1个)
top:N (选前 N 个,N为数字)
5. 防护配置 (/defense/enable)
| 字段名 | 类型 | 必填 | 示例 | 说明 |
| enabled | Bool | ❌ | true | 是否启用防护 |
| rules | Object | ✅ | {“rate_limit”: 100} | 防护规则字典,具体Key由后端逻辑决定 |
6. 响应结构概览
所有接口通常遵循统一的响应格式:
codeJSON
1 | |
关键数据字段 (data):
attack_id: (String) 攻击任务的唯一标识符。
status: (Enum) pending, running, completed, failed, stopped, cancelled。
logs: (Array[Str]) 攻击日志列表。
{
“nodes”: [
{
“id”: “0xdAC17F958D2ee523a2206206994597C13D831ec7”,
“name”: “Tether USD (USDT)”,
“type”: “ERC20”,
“ip_address”: “”,
“status”: “active”,
“layer”: “contract”,
“container_name”: null,
“neighbor_count”: 5
},
{
“id”: “0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48”,
“name”: “USD Coin (USDC)”,
“type”: “ERC20”,
“ip_address”: “”,
“status”: “active”,
“layer”: “contract”,
“container_name”: null,
“neighbor_count”: 3
},
{
“id”: “0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984”,
“name”: “Uniswap V3: Router”,
“type”: “Router”,
“ip_address”: “”,
“status”: “active”,
“layer”: “contract”,
“container_name”: null,
“neighbor_count”: 8
},
{
“id”: “0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45”,
“name”: “Uniswap V3: SwapRouter02”,
“type”: “SwapRouter”,
“ip_address”: “”,
“status”: “active”,
“layer”: “contract”,
“container_name”: null,
“neighbor_count”: 6
},
{
“id”: “0xE592427A0AEce92De3Edee1F18E0157C05861564”,
“name”: “Uniswap V3: Quoter”,
“type”: “Quoter”,
“ip_address”: “”,
“status”: “active”,
“layer”: “contract”,
“container_name”: null,
“neighbor_count”: 4
},
{
“id”: “0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D”,
“name”: “Uniswap V2: Router”,
“type”: “Router”,
“ip_address”: “”,
“status”: “active”,
“layer”: “contract”,
“container_name”: null,
“neighbor_count”: 7
},
{
“id”: “0x881D40237659C251811CEC9c364ef91dC08D300C”,
“name”: “Curve: 3pool Controller”,
“type”: “CurvePool”,
“ip_address”: “”,
“status”: “active”,
“layer”: “contract”,
“container_name”: null,
“neighbor_count”: 4
},
{
“id”: “0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7”,
“name”: “Curve: 3pool Gauge”,
“type”: “Gauge”,
“ip_address”: “”,
“status”: “active”,
“layer”: “contract”,
“container_name”: null,
“neighbor_count”: 2
}
],
“links”: [
{ “source”: “0xdAC17F958D2ee523a2206206994597C13D831ec7”, “target”: “0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45”, “type”: “transfer_approve” },
{ “source”: “0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45”, “target”: “0xdAC17F958D2ee523a2206206994597C13D831ec7”, “type”: “swap_out” },
{ “source”: “0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45”, “target”: “0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48”, “type”: “swap_in” },
{ “source”: “0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48”, “target”: “0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984”, “type”: “call” },
{ “source”: “0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984”, “target”: “0xE592427A0AEce92De3Edee1F18E0157C05861564”, “type”: “quote” },
{ “source”: “0xdAC17F958D2ee523a2206206994597C13D831ec7”, “target”: “0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D”, “type”: “approve” },
{ “source”: “0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D”, “target”: “0xdAC17F958D2ee523a2206206994597C13D831ec7”, “type”: “swap” },
{ “source”: “0xdAC17F958D2ee523a2206206994597C13D831ec7”, “target”: “0x881D40237659C251811CEC9c364ef91dC08D300C”, “type”: “deposit” },
{ “source”: “0x881D40237659C251811CEC9c364ef91dC08D300C”, “target”: “0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7”, “type”: “stake” }
],
“timestamp”: 1765095677.891234,
“data_source”: “real_web3”,
“topology_type”: “contract”
}
1 | |