0

I’m having troubles with making a local custom adapter to work: my node seems to not react to the logs it receives and the job using my adapter is not triggered.

Some points I have been careful about:

  • My consumer contract and node are funded with both LINK and ETH
  • My adapter name is understood by the node and the .toml job is validated
  • My oracle is deployed and well set in my .toml job definition
  • Fulfillment permissions are set up for the oracle with the correct node address
  • Both oracle address and jobId are correct when making the request from the consumer contract
  • I have ensured that my node has both UNRESTRICTED_NETWORK_ACCESS and ENABLE_EXPERIMENTAL_ADAPTERS variables set to true
  • The fee definition seems correct in the consumer contract definition, as it follows the ATestnetConsumer.sol example.

The exemplary contract ATestnetConsumer.sol works well with the node. Requests are made and responses are returned to the oracle and then the consumer contract.

I also made a webhook job version which uses my custom adapter and it works well. Still, making call from my own consumer contract for a job using my custom adapter triggers no job on the node.

When the chainlink request is made, LINK is being payed by the consumer contract and logs are received by the node:

2022-02-01T14:19:39Z [DEBUG] LogBroadcaster: Received a log log/broadcaster.go:324 address=ORACLE_ADDRESS_IS_CORRECT_HERE blockHash=0x8057122669ab1fc78f44920e1910e9a17f2cbfaa59bf94d2d2a1588eaaeff5db blockNumber=29

No error message pops up. The node seems to process as much logs as there has been request from my consumer (9 here), but does not proceed with any job runs:

2022-02-01T14:39:27Z [INFO] LogBroadcaster: Finished async backfill of 9 logs  log/eth_subscriber.go:155

The adapter is hosted within a container. The url set up for is: http://host.docker.internal:5000/auth (host.docker.internal stands for localhost). I also tried localhost and 0.0.0.0 as hosts. Because my webhook is successful I do not expect troubles for the node to access it. Also, my adapter/webserver logs show no interaction coming from the node (since no job is triggered).

What am I missing here? What additional steps should I take?

My chainlink node version is 0.10.15 (otherwise UI problems with versions 1.0.x). My Oracle contract uses chainlink v0.6 and my chainlink client is v0.8 (for both example ATestnetConsumer.sol and my contract.

Node .env file:

ROOT=/chainlink
LOG_LEVEL=debug
ETH_CHAIN_ID=42
MIN_OUTGOING_CONFIRMATIONS=2
LINK_CONTRACT_ADDRESS=CORRECT_LINK_ADDRESS
CHAINLINK_TLS_PORT=0
SECURE_COOKIES=false
GAS_UPDATER_ENABLED=true
ALLOW_ORIGINS=*
MIN_INCOMING_CONFIRMATIONS=1
FEATURE_WEBHOOK_V2=true
ENABLE_EXPERIMENTAL_ADAPTERS=true
DEFAULT_HTTP_ALLOW_UNRESTRICTED_NETWORK_ACCESS=true
CHAINLINK_DEV=true
BLOCK_BACKFILL_SKIP=true

Bridge info:

Name    adapter-name
URL http://host.docker.internal:5000/auth
Confirmations   0
Minimum Contract Payment    0
Outgoing Token  some_outgoing_token

Job definition:

type = "directrequest"
schemaVersion = 1
name = "some-name"
contractAddress = "ORACLE_ADDRESS_IS_CORRECT_HERE"
maxTaskDuration = "0s"
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="my-adapter" requestData="{\\"data\\": {\\"lichess_token\\": $(decode_cbor.apiToken)}}"]
    parse_acc    [type=jsonparse path="data,verified" data="$(fetch)"]
    parse_accid  [type=jsonparse path="data,url" data="$(fetch)"]
    encode_data  [type=ethabiencode 
                  abi="(uint256 requestIdx, bool accountVerified, bytes accountId)" 
                  data="{ \\"requestIdx\\": $(decode_cbor.requestIdx), \\"accountVerified\\": $(parse_acc), \\"accountId\\": $(parse_accid) }"
                 ]
    encode_tx    [type=ethabiencode
                  abi="fulfillOracleRequest(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes32 data)"
                  data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}"
                 ]
    submit_tx    [type=ethtx to="ORACLE_ADDRESS_IS_CORRECT_HERE" data="$(encode_tx)"]

    decode_log -> decode_cbor -> fetch -> parse_acc -> parse_accid -> encode_data -> encode_tx -> submit_tx
"""
externalJobID = "27cd13da-85cd-44b1-8851-78500663ffa0"

3 Answers 3

0

Hi @pedropedro

Sounds like it could be a something in docker config. The node works, the adapter works on a webhook job, but not through a normal job on the node.

I suggest you to review very carefully the docker config.

1
  • Thanks Solange for this suggestion :) I eventually found the solution to my problem! Commented Feb 3, 2022 at 9:37
0

I eventually found the solution.

The string to bytes conversion I used for the jobId was seemingly erroneous. Strangely, this is the same which is given within the ATestnetConsumer.sol example. Yet, it was not outputting an interpretable jobId for the node.

The stringToBytes32 function:

  function stringToBytes32(string memory source) private pure returns (bytes32 result) {
    bytes memory tempEmptyStringTest = bytes(source);
    if (tempEmptyStringTest.length == 0) {
      return 0x0;
    }

    assembly { // solhint-disable-line no-inline-assembly
      result := mload(add(source, 32))
    }
  }

What I did instead was hardcode the jobId within the contract constructor and with type bytes32, instead of converting the string given in the function call.

0

When calling requestEthereumPrice at the client contract, just make sure you are passing the job id without the dashes (i.e. externalJobID = "27cd13da85cd44b1885178500663ffa0"), otherwise job id will not fit into a bytes32 type.

That is probably why your function stringToBytes32() output was not what you expected

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.