您正在查看: Surou 发布的文章

error getting sequences: error no leaves on L1InfoTree yet and GetInitL1InfoRootMap

错误

启动sequence-sender时报以下错误

2024-11-15T11:11:46.117Z        ERROR   sequencesender/sequencesender.go:312    error getting sequences: error no leaves on L1InfoTree yet and GetInitL1InfoRootMap fails: %!w(<nil>)   {"pid": 39, "version": "v0.4.0-beta5", "module": "sequence-sender"}
github.com/0xPolygon/cdk/sequencesender.(*SequenceSender).tryToSendSequence
        /go/src/github.com/0xPolygon/cdk/sequencesender/sequencesender.go:312
github.com/0xPolygon/cdk/sequencesender.(*SequenceSender).sequenceSending
        /go/src/github.com/0xPolygon/cdk/sequencesender/sequencesender.go:243

相关代码

// Returns CounterL1InfoRoot to use for this batch
func (t *TxBuilderBananaBase) GetCounterL1InfoRoot(ctx context.Context, highestL1IndexInBatch uint32) (uint32, error) {
    header, err := t.ethClient.HeaderByNumber(ctx, t.blockFinality)
    if err != nil {
        return 0, fmt.Errorf("error calling HeaderByNumber, with block finality %d: %w", t.blockFinality.Int64(), err)
    }
    var resL1InfoCounter uint32

    info, err := t.l1InfoTree.GetLatestInfoUntilBlock(ctx, header.Number.Uint64())
    if err == nil {
        resL1InfoCounter = info.L1InfoTreeIndex + 1
    }
    if errors.Is(err, l1infotreesync.ErrNotFound) {
        // There are no L1 Info tree leaves yet, so we can try to use L1InfoRootMap event
        l1infotreeInitial, err := t.l1InfoTree.GetInitL1InfoRootMap(ctx)
        if l1infotreeInitial == nil || err != nil {
            return 0, fmt.Errorf("error no leaves on L1InfoTree yet and GetInitL1InfoRootMap fails: %w", err)
        }
        // We use this leaf as first one
        resL1InfoCounter = l1infotreeInitial.LeafCount
    } else if err != nil {
        return 0, fmt.Errorf("error calling GetLatestInfoUntilBlock with block num %d: %w", header.Number.Uint64(), err)
    }

分析

l1InfoTree.GetInitL1InfoRootMap 没有获取到数据
GetInitL1InfoRootMap 通过事件InitL1InfoRootMap进行写入的

if event.InitL1InfoRootMap != nil {
            log.Debugf("handle InitL1InfoRootMap event %s", event.InitL1InfoRootMap.String())
            err = processEventInitL1InfoRootMap(tx, block.Num, event.InitL1InfoRootMap)
            if err != nil {
                err = fmt.Errorf("initL1InfoRootMap. Err: %w", err)
                log.Errorf("error processing InitL1InfoRootMap: %v", err)
                return err
            }
        }

对应合约PolygonZkEVMGlobalExitRootV2.sol->emit InitL1InfoRootMap

 function initialize() external virtual initializer {
        // Get the current historic root
        bytes32 currentL1InfoRoot = getRoot();

        // Store L1InfoRoot
        l1InfoRootMap[uint32(depositCount)] = currentL1InfoRoot;

        emit InitL1InfoRootMap(uint32(depositCount), currentL1InfoRoot);
    }

继续排查,看链是否代码没有执行对应逻辑
l1infotreesync/processor.go

func (p *processor) ProcessBlock(ctx context.Context, block sync.Block) error {
    ...
        if event.InitL1InfoRootMap != nil {
            log.Debugf("handle InitL1InfoRootMap event %s", event.InitL1InfoRootMap.String())
            err = processEventInitL1InfoRootMap(tx, block.Num, event.InitL1InfoRootMap)
            if err != nil {
                err = fmt.Errorf("initL1InfoRootMap. Err: %w", err)
                log.Errorf("error processing InitL1InfoRootMap: %v", err)
                return err
            }
        }
func (d *EVMDriver) handleNewBlock(ctx context.Context, b EVMBlock) {
    ...
    err := d.processor.ProcessBlock(ctx, blockToProcess)
2024-11-16T01:17:02.244Z        DEBUG   sync/evmdriver.go:100   handleNewBlock blockNum: 7085616 blockHash: 0x72c30608c656bfd164e1e5836db12d6b36ad2f7ddbd5e26557ea18fcdce98d94  {"pid": 40, "version": "v0.4.0-beta5", "syncer": "l1infotreesync"}
2024-11-16T01:17:02.244Z        INFO    l1infotreesync/processor.go:343 block 7085616 processed with 0 events   {"pid": 40, "version": "v0.4.0-beta5"}

执行逻辑中已经包含 event.InitL1InfoRootMap

继续排查

排查两个角度

  1. 合约中并未发出
  2. 区块高度有错误
    由于事件是由合约PolygonZkEVMGlobalExitRootV2.sol发出,对应的合约地址为deploy_output.json->polygonZkEVMGlobalExitRootAddress
    查看当前地址
    https://sepolia.etherscan.io/tx/0xc3b16bdaa7054689230e976e20badcb65c92ad2a623ea89b1b33147a1fc0f227#eventlog

    高度:7085224
    合约event.InitL1InfoRootMap已发出,排除问题1

继续看下配置的高度deploy_output.json->deploymentRollupManagerBlockNumber
https://sepolia.etherscan.io/tx/0x03f41442db2e20f2551436df6ec607be307c89e7b05fe32fc462fceb225ce24a
高度:7085226

问题汇总

当前高度没有包含PolygonZkEVMGlobalExitRootV2->initialize 高度,所以导致事件event.InitL1InfoRootMap没有扫描到,从而导致GetInitL1InfoRootMap数据没有本地存储,最终导致sequence-sender报错

解决方式

查询deploy_output.json->polygonZkEVMGlobalExitRootAddress合约地址交易对应的高度,并更新到sequence-sender配置
L1InfoTreeSync->InitialBlock

https://sepolia.etherscan.io/address/0xEEc7988853B40B65FaBB3E9A3393E093D5710515

polygon cdk fork12各服务版本对应关系

fork版本 服务名称 tag 官方镜像
fork12 zkevm-contracts v8.0.0-fork.12
zkevm-prover-stateless-executor v8.0.0-RC14-fork.12 hermeznetwork/zkevm-prover:v8.0.0-RC14-fork.12
zkevm-prover-state-executor v8.0.0-RC14-fork.12 hermeznetwork/zkevm-prover:v8.0.0-RC14-fork.12
cdk-erigon-sequencer v2.1.2 hermeznetwork/cdk-erigon:v2.1.2
cdk-erigon-rpc v2.1.2 hermeznetwork/cdk-erigon:v2.1.2
zkevm-pool-manager v0.1.2 hermeznetwork/zkevm-pool-manager:v0.1.2
Sequence sender&Aggregator v0.4.0-beta5 ghcr.io/0xpolygon/cdk:0.4.0-beta5
cdk-data-availability v0.0.10 0xpolygon/cdk-data-availability:0.0.10
bridge-service v0.6.0-RC1 hermeznetwork/zkevm-bridge-service:v0.6.0-RC1

调研polygon cdk-fork12是否支持在polygon pos测试网amoy部署

背景

调研polygon cdk-fork12是否支持在polygon pos测试网amoy部署

前置结论

结论:polygon cdk-fork12依赖于以太坊PoS状态检查,polygon pos测试网amoy RPC未实现该逻辑导致不兼容,无法支持部署polygon网络

概述

在推荐配置下,da,sequencer,sync,pool-manager,bridge 各个核心服务正常运行,交易正常处理
但sequence-sender运行报错,跟进代码,由于交易状态检查逻辑中,会依次检查各个状态的过度:LatestBlock->SafeBlock->PendingBlock->FinalizedBlock,由于polygon pos测试网amoy没有像以太坊PoS完整实现,所以导致报错

2024-11-14T12:21:48.112Z        ERROR   l1_check_block/l1_block_by_name.go:171  checkL1block:: Error getting L1 block %!d(string=safe/0). err: safe block not found     {"pid": 40}
github.com/0xPolygonHermez/zkevm-synchronizer-l1/synchronizer/l1_check_block.(*L1BlockNumberByNameFetch).BlockNumber
        /go/pkg/mod/github.com/0x!polygon!hermez/zkevm-synchronizer-l1@v1.0.5/synchronizer/l1_check_block/l1_block_by_name.go:171
github.com/0xPolygon/zkevm-ethtx-manager/ethtxmanager.(*Client).waitMinedTxToBeSafe
        /go/pkg/mod/github.com/0x!polygon/zkevm-ethtx-manager@v0.2.1/ethtxmanager/ethtxmanager.go:525
github.com/0xPolygon/zkevm-ethtx-manager/ethtxmanager.(*Client).Start
        /go/pkg/mod/github.com/0x!polygon/zkevm-ethtx-manager@v0.2.1/ethtxmanager/ethtxmanager.go:458
2024-11-14T12:21:48.112Z        ERROR   ethtxmanager/ethtxmanager.go:927        failed to wait safe tx to be finalized: failed to get safe block number: safe block not found%!(EXTRA string=
/go/pkg/mod/github.com/0x!polygon/zkevm-ethtx-manager@v0.2.1/log/log.go:140 github.com/0xPolygon/zkevm-ethtx-manager/log.appendStackTraceMaybeArgs()
/go/pkg/mod/github.com/0x!polygon/zkevm-ethtx-manager@v0.2.1/log/log.go:249 github.com/0xPolygon/zkevm-ethtx-manager/log.Errorf()
/go/pkg/mod/github.com/0x!polygon/zkevm-ethtx-manager@v0.2.1/ethtxmanager/ethtxmanager.go:927 github.com/0xPolygon/zkevm-ethtx-manager/ethtxmanager.(*Client).logErrorAndWait()
/go/pkg/mod/github.com/0x!polygon/zkevm-ethtx-manager@v0.2.1/ethtxmanager/ethtxmanager.go:460 github.com/0xPolygon/zkevm-ethtx-manager/ethtxmanager.(*Client).Start()
// BlockFinality indicates the status of the blocks that will be queried in order to sync
    BlockFinality string `jsonschema:"enum=LatestBlock, enum=SafeBlock, enum=PendingBlock, enum=FinalizedBlock, enum=EarliestBlock" mapstructure:"BlockFinality"` //nolint:lll

polygon cdk变更TrustedSequencerURL

背景

特殊场景需要变更合约PolygonZkEVM.sol中的TrustedSequencerURL

合约代码

/**
     * @notice Allow the admin to set the trusted sequencer URL
     * @param newTrustedSequencerURL URL of trusted sequencer
     */
    function setTrustedSequencerURL(
        string memory newTrustedSequencerURL
    ) external onlyAdmin {
        trustedSequencerURL = newTrustedSequencerURL;

        emit SetTrustedSequencerURL(newTrustedSequencerURL);
    }

ABI

[{
      "inputs": [
        {
          "internalType": "string",
          "name": "newTrustedSequencerURL",
          "type": "string"
        }
      ],
      "name": "setTrustedSequencerURL",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    }]

测试

当前合约内TrustedSequencerURL:http://172.18.36.173:8123
期望变更为:http://172.18.39.162:8123
直接使用在线工具:https://www.smartcontractgui.xyz/
PolygonZkEVM合约地址在create_rollup_output.json->rollupAddress: 0x584eF34da0d700082d3c29cD3844d9524e656950

import { ethers } from 'hardhat';
import path from 'path';
import fs from 'fs';
require('dotenv').config({ path: path.resolve(__dirname, '../.env') });
import createRollupParameters from './create_rollup_output.json';

async function main() {
    const privateKey = path.join(__dirname, 'keystore', './admin.privateKey');
    const data = fs.readFileSync(privateKey, 'UTF-8');
    const wa = new ethers.Wallet(data, ethers.provider);
    console.log(`Use ${wa.address}`);
    const polygonZkEVM = (await ethers.getContractFactory('PolygonZkEVM', wa)).attach(createRollupParameters.rollupAddress);
    console.log(await polygonZkEVM.trustedSequencerURL());
    const tx = await polygonZkEVM.setTrustedSequencerURL("http://172.18.39.162:8123");
    await tx.wait(1);
    console.log(await polygonZkEVM.trustedSequencerURL());
}

main().catch((error) => {
    console.error(error);
    process.exit(1);
});

cdk-erigon - ChainDB name is not recognized

https://github.com/0xPolygonHermez/cdk-erigon/blob/06e93d49704726977297cf1d5055f43185e313bd/cmd/utils/flags.go#L2253-L2295

    chain = ctx.String(ChainFlag.Name)
    if strings.HasPrefix(chain, "dynamic") {
        configFilePath := ctx.String(ConfigFlag.Name)
        if configFilePath == "" {
            Fatalf("Config file is required for dynamic chain")
        }

        // Be sure to set this first
        params.DynamicChainConfigPath = filepath.Dir(configFilePath)
        filename := path.Join(params.DynamicChainConfigPath, chain+"-conf.json")

        genesis := core.GenesisBlockByChainName(chain)

        dConf := DynamicConfig{}

        if _, err := os.Stat(filename); err == nil {
            dConfBytes, err := os.ReadFile(filename)
            if err != nil {
                panic(err)
            }
            if err := json.Unmarshal(dConfBytes, &dConf); err != nil {
                panic(err)
            }
        }

        genesis.Timestamp = dConf.Timestamp
        genesis.GasLimit = dConf.GasLimit
        genesis.Difficulty = big.NewInt(dConf.Difficulty)

        cfg.Genesis = genesis

        genesisHash := libcommon.HexToHash(dConf.Root)
        if !ctx.IsSet(NetworkIdFlag.Name) {
            cfg.NetworkID = params.NetworkIDByChainName(chain)
        }
        SetDNSDiscoveryDefaults(cfg, genesisHash)
    } else {
        switch chain {
        default:
            genesis := core.GenesisBlockByChainName(chain)
            genesisHash := params.GenesisHashByChainName(chain)
            if (genesis == nil) || (genesisHash == nil) {
                Fatalf("ChainDB name is not recognized: %s", chain)

新建的自定义链,名称需要以dynamic关键词,例如dynamic-bcskill-testnet, 否则会获取对应的hash进行比对