gcx/blockchain/genex-chain/compliance_integration.go

150 lines
4.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Package genexchain — Compliance Ante Handler Integration
//
// 本文件将独立的 ComplianceAnteHandler (x/evm/ante/) 桥接到
// Cosmos SDK ante handler 链中,实现验证节点级交易拦截。
//
// 对应指南: 06-区块链开发指南.md §6 (链级合规能力) 和 §16 (验证节点级交易拦截)
//
// 架构:
//
// TX → ComplianceAnteWrapper (OFAC/TravelRule/Structuring)
// → cosmos/evm AnteHandler (签名/Gas/Nonce/...)
// → Mempool → Block
//
// ComplianceAnteHandler 执行三项检查:
// 1. OFAC 地址拦截 — 制裁名单地址的交易直接拒绝,不进入 mempool
// 2. Structuring 检测 — 24h 内拆分交易规避 $3,000 阈值,标记为可疑
// 3. Travel Rule 预打包检查 — ≥$3,000 转移必须已记录身份哈希
//
// OFAC 名单由链下合规服务通过 ComplianceHandler.UpdateOFACList() 定期同步。
// Travel Rule 数据由 compliance-service 通过 ComplianceHandler.RecordTravelRule() 写入。
package genexchain
import (
"fmt"
"math/big"
sdk "github.com/cosmos/cosmos-sdk/types"
evmtypes "github.com/cosmos/evm/x/vm/types"
"github.com/ethereum/go-ethereum/common"
genexante "github.com/genex/genex-chain/x/evm/ante"
)
// ComplianceAnteWrapper 将独立的 ComplianceAnteHandler 桥接到 Cosmos SDK ante 链。
//
// 工作流程:
// 1. 遍历 tx 中的所有消息
// 2. 对 MsgEthereumTx 类型的消息提取 from/to/value
// 3. 调用 ComplianceAnteHandler.AnteHandle() 执行合规检查
// 4. 如果被拒绝 → 返回错误,交易不会被打包
// 5. 如果可疑 → 记录日志,交易仍可打包
// 6. 记录转移金额用于 Structuring 滑动窗口检测
// 7. 合规通过后委托给标准 cosmos/evm ante handler
type ComplianceAnteWrapper struct {
compliance *genexante.ComplianceAnteHandler
inner sdk.AnteHandler
}
// NewComplianceAnteWrapper 创建包含合规检查的 ante handler。
//
// 参数:
// - inner: 标准 cosmos/evm ante handler (由 evmante.NewAnteHandler 创建)
// - compliance: Genex 合规检查处理器
//
// 用法 (在 app.go 中):
//
// standardHandler := evmante.NewAnteHandler(options)
// complianceHandler := genexante.NewComplianceAnteHandler()
// wrappedHandler := NewComplianceAnteWrapper(standardHandler, complianceHandler)
// app.SetAnteHandler(wrappedHandler)
func NewComplianceAnteWrapper(
inner sdk.AnteHandler,
compliance *genexante.ComplianceAnteHandler,
) sdk.AnteHandler {
w := &ComplianceAnteWrapper{
compliance: compliance,
inner: inner,
}
return w.AnteHandle
}
// AnteHandle 在标准 ante handler 之前执行合规检查。
//
// 对于非 EVM 的 Cosmos SDK 消息(如 staking、gov合规检查被跳过
// 直接委托给内部 handler。
//
// 模拟模式 (simulate=true) 下跳过合规检查,因为 gas 估算不应被合规拒绝。
func (w *ComplianceAnteWrapper) AnteHandle(
ctx sdk.Context, tx sdk.Tx, simulate bool,
) (sdk.Context, error) {
// 模拟模式跳过合规检查gas 估算)
if simulate {
return w.inner(ctx, tx, simulate)
}
for _, msg := range tx.GetMsgs() {
// 仅拦截 EVM 交易Cosmos 原生消息直接放行
ethMsg, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok {
continue
}
// 获取底层 go-ethereum Transaction 对象
ethTx := ethMsg.AsTransaction()
if ethTx == nil {
continue
}
// 提取发送方 (from) — Cosmos AccAddress bytes → Ethereum hex
fromBytes := ethMsg.GetFrom()
fromAddr := common.BytesToAddress(fromBytes)
// 提取接收方 (to) — 合约创建时为 nil
toHex := ""
if ethTx.To() != nil {
toHex = ethTx.To().Hex()
}
// 提取交易金额
value := ethTx.Value()
if value == nil {
value = new(big.Int)
}
// ====== 执行合规检查 ======
result := w.compliance.AnteHandle(fromAddr.Hex(), toHex, value)
// 检查 1: OFAC / Travel Rule 拒绝 → 交易不进入 mempool
if !result.Allowed {
ctx.Logger().Error("Transaction rejected by compliance",
"module", "genex-compliance",
"from", fromAddr.Hex(),
"to", toHex,
"value", value.String(),
"reason", result.Reason,
)
return ctx, fmt.Errorf("genex compliance: %s", result.Reason)
}
// 检查 2: 可疑但允许 → 记录警告日志,交易仍可打包
if result.Suspicious {
ctx.Logger().Warn("Suspicious transaction detected",
"module", "genex-compliance",
"from", fromAddr.Hex(),
"to", toHex,
"value", value.String(),
"reason", result.SuspReason,
)
}
// 检查 3: 记录转移金额用于 Structuring 滑动窗口检测
if value.Sign() > 0 {
w.compliance.RecordTransfer(fromAddr.Hex(), value)
}
}
// 合规通过,委托给标准 cosmos/evm ante handler
return w.inner(ctx, tx, simulate)
}