本地Chainlink节点请求无法触发fulfill函数问题求助
Chainlink本地节点任务执行故障排查:fulfill函数未触发
请求已正常发起,但fulfillReEncryption函数未被调用,导致获取的数据无法保存。相关现象:
- 任务列表最后一步标记为
suspended,再次执行代码后变为completed - 尝试将
minIncomingConfirmations设为0,但始终被覆盖为1
已提供的代码与配置
智能合约代码片段
function reEncryptData( string memory reEncryptionKey, string memory _encryptedData ) public returns (bytes32) { Chainlink.Request memory request = buildOperatorRequest( jobId, this.fulfillReEncryption.selector ); request.add("reEncryptionKey", reEncryptionKey); request.add("encryptedData", _encryptedData); return sendOperatorRequest(request, fee); } function fulfillReEncryption( bytes32 requestId, bytes memory _data ) public recordChainlinkFulfillment(requestId) { reEncryptedData = string(_data); }
任务配置文件(.toml)
type = "directrequest" schemaVersion = 1 name = "Re-Encrypt Data" contractAddress = "0xC1CD77E8cd5FB78898815952117Aca334fe573cd" maxTaskDuration = "0s" minIncomingConfirmations = "0" observationSource = """ decode_log [type=ethabidecodelog abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)" data="$(jobRun.logData)" topics="$(jobRun.logTopics)"] decode_cbor [type=cborparse data="$(decode_log.data)"] fetch [type=bridge name="re-encrypt" requestData="{\"id\": $(jobSpec.externalJobID), \"data\": { \"encryptedData\": $(decode_cbor.encryptedData), \"reEncryptionKey\": $(decode_cbor.reEncryptionKey)}}"] parse [type=jsonparse path="data,reEncryptedData" data="$(fetch)"] encode_large [type=ethabiencode abi="(bytes32 requestId, bytes _data)" data="{\"requestId\": $(decode_log.requestId), \"_data\": $(parse) }"] encode_tx [type=ethabiencode abi="fulfillOracleRequest2(bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 expiration, bytes calldata data)" data="{\"requestId\": $(decode_log.requestId), \"payment\": $(decode_log.payment), \"callbackAddr\": $(decode_log.callbackAddr), \"callbackFunctionId\": $(decode_log.callbackFunctionId), \"expiration\": $(decode_log.cancelExpiration), \"data\": $(encode_large)}" ] submit_tx [type=ethtx to="0xC1CD77E8cd5FB78898815952117Aca334fe573cd" data="$(encode_tx)"] decode_log -> decode_cbor -> fetch -> parse -> encode_large -> encode_tx -> submit_tx """
合约调用代码
await ( await reEncryption .connect(dataSubject) .reEncryptData( "d48065aceb01496e1e4f8f74c7b68422ba16e1de7c80a9e927683f30c42b150804d505e4835912f719e96fd27f8e42345aa757070f5fa083974f5fb82fd384b4bdc74dbd75b6a60c68108d97e4c8dcd02c12a7d5552e28df3a7af366bb05b86ace", "eyJrZXkiOiIwNGU5MjcwMzhiMjFjMDJhZDI2MmUxZmMwNmY4YmU0NTFiYmUyODU0Y2FmZGNmMDg4YzY5NDBjNTUzMjI4M2E3OTE5NTY1NDU0N2ZjZmQ2Yzg1OWJiZWQ2NmNlZmNlN2FkOTUyMDhkNmI5MjNkNjVkYjRmNTQyYWEwYTI3M2VmY2U1MDRmMTE4NmRkYzMxMjZhYWMwNGJhZWNlN2I5NDA4YzkwMDVkY2Q2MjJhYTlkY2E4YjU4NDg1MmI0NjU0MzAyNzMwM2U4NjA2MWRlNTNmYjcxNzk1NTAzZjNiYzRiNDMyNTJhNWFiODRiZDE2YmZkN2M4ZjYzZWRmMWM1ODIzZjVlZDNlYzg3OGJmNGY0ZTAzMmYxN2NiNWI5Y2RlOWU1YzMwN2U5NzI4ZjJmYzBhMWUwNGM2NzA2MDRjM2MyM2Q1NWIiLCJjaXBoZXIiOiJlcGtLVU1abEU1Q29Ucm1RbUUydkFRPT0ifQ==" ) ).wait();
已完成的前置配置:
- 使用Operator.sol部署合约
- 为目标合约和Operator合约充值LINK
- 为Oracle节点账户充值ETH和LINK
- 将Oracle节点地址添加至
setAuthorizedSenders列表
排查步骤
1. 定位minIncomingConfirmations被覆盖的原因
- Operator.sol默认
minIncomingConfirmations值为1,若任务配置无法生效,需检查节点是否加载了最新的任务文件:重启Chainlink节点,查看启动日志中是否有任务加载成功的提示。 - 确认Operator合约是否支持动态读取任务配置中的
minIncomingConfirmations,部分版本的Operator可能强制使用合约内配置值。
2. 核查自定义Bridge的可用性
- 任务中使用了
re-encryptbridge,需确认该bridge的配置文件已放置在节点的bridges目录下,且对应服务正常运行。 - 查看节点日志中
fetch步骤的输出,确认是否成功从外部服务获取到reEncryptedData。若bridge调用失败,会直接中断后续流程。
3. 验证fulfillOracleRequest2的参数正确性
- 核对
encode_tx步骤中的callbackAddr是否为目标合约地址,而非Operator地址。 - 计算
fulfillReEncryption函数的选择器(web3.eth.abi.encodeFunctionSignature("fulfillReEncryption(bytes32,bytes)")取前4字节),与任务日志中的callbackFunctionId对比,确保两者一致。
4. 分析节点日志中的错误信息
- 重点查看任务进入
suspended状态时的日志:- 是否有ETH余额不足的提示(
submit_tx需支付gas)? - 是否存在CBOR解码、JSON解析失败的报错?
- 是否有LINK支付验证不通过的信息?
- 是否有ETH余额不足的提示(
5. 确认权限配置完整性
- 检查Operator合约是否被授权调用目标合约的
fulfillReEncryption函数,部分场景下需显式给Operator合约授权。 - 验证
recordChainlinkFulfillment修饰器是否正确校验了请求发起方的权限,可通过日志确认请求ID的合法性。
6. 简化任务流程做测试
- 暂时移除
fetch和parse步骤,修改任务流程为decode_log -> encode_large -> encode_tx -> submit_tx,将encode_large中的_data设为固定bytes值。若此简化流程能触发fulfillReEncryption,则问题出在外部bridge服务或数据解析环节。
内容的提问来源于stack exchange,提问作者ozaher
相关产品推荐
相关产品推荐

