This package implements the watcher for the NEAR blockchain.
Responsibility: Observe finalized publishMessage event emissions from the Wormhole Core account on the NEAR blockchain.
There are multiple supervised runners:
transactionProcessingJob, going through all receipt outcomes, searching for Wormhole messages, and checking that they have been finalized. If there are Wormhole messages in any receipts from this transaction but those receipts are not in finalized blocks, the transactionProcessingJob will be put in the back of the queue.ObsvReqProcessor: Process observation requests. An observation request is a way of kindly asking the Guardian to go back in time and look at a particular transaction and try to identify wormhole events in it. Observation requests are received from other Guardians or injected through the admin API. Even though they are signed, they should not be trusted.
chunkProcessingQueue gets new chunk hashes. These are processed once we think that the transactions in it are likely to be completed.
transactionProcessingQueue is a priority queue and gets all the transactions from the chunks. These are constantly processed and put back to the end of the queue if processing fails. If processing a transaction fails, most likely because not all receipts have been finalized, it is retried with an exponential backoff and eventually it is dropped.
multiple workers process both types of jobs from these two queues
Determining finality of blocks:
Do we really have to parse every single NEAR transaction?
Unfortunately NEAR does not (yet?) provide a mechanism to subscribe to a particular contract. There is a RPC API EXPERIMENTAL_changes_in_block which would tell you if the block contained any receipts that touch your account, but there is no way of knowing in which block the transaction started. Even if there was, you'd still need to process all transactions in the block and we are expecting there to be a Wormhole transaction in most blocks.
txProcRetry retries and was droppedchunk_id is the ID of the chunk from which all or some transactions have been dropped.tx_hash.height.height.previous_height (the height of the previously highest block that we polled) and newest_final_height (the height of the latest block that is final).initialTxProcDelay ^ (txProcRetry+2) time after the block containing the start of the transaction has been observed. Otherwise they will be missed. Strong network congestion or gaps/delays in block production could violate this.The testing strategy is to run the watcher with a mock RPC server. The mock RPC server mostly forwards requests to the mainnet RPC and caches them. Cached response are committed to the repository such that the tests don't actually depend on the mainnet RPC server. For negative tests, there are folders with synthetic RPC responses. The synthetic data is generated with a bash script: createDerivatives.sh.
Run tilt without optional networks:
tilt up -- --evm2=false --solana=false --terra_classic=false --terra2=false
If you have everything built and setup:
cd wormhole/near/
npm ci
ts-node test/sdk.ts
If it doesn't work, this dockerfile may be a good starting point:
RUN dnf update && dnf install -y python3 npm curl
RUN dnf install -y gcc gcc-c++ make git
RUN npm install -g typescript ts-node n
RUN n stable
RUN git clone https://github.com/wormhole-foundation/wormhole.git
WORKDIR /wormhole/ethereum
RUN npm ci
RUN npm run build
WORKDIR /wormhole/sdk/js
RUN npm ci
RUN npm run build-all
WORKDIR /wormhole/near
RUN npm ci
RUN ts-node test/sdk.ts