Skip to content

Commit

Permalink
refactor!: update OEV gateway interface (#1931)
Browse files Browse the repository at this point in the history
* refactor!: change OEV gateway interface

1. `api3ServerV1` has replaced `dapiServerAddress`
2. `templateId` has replaced `endpointId` and `encodedParameters`.
  • Loading branch information
dcroote authored Jan 10, 2024
1 parent d3cf108 commit 66f69fe
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 59 deletions.
6 changes: 6 additions & 0 deletions .changeset/soft-sloths-brake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@api3/airnode-deployer': minor
'@api3/airnode-node': minor
---

BREAKING CHANGE: the OEV gateway interface has changed in the following ways: `api3ServerV1` has replaced `dapiServerAddress` and `templateId` has replaced `endpointId` and `encodedParameters`.
19 changes: 7 additions & 12 deletions packages/airnode-deployer/terraform/aws/templates/oevGw.yaml.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ components:
type: object
required:
- chainId
- dapiServerAddress
- api3ServerV1
- oevProxyAddress
- updateId
- bidderAddress
Expand All @@ -29,7 +29,7 @@ components:
type: integer
format: int32
minimum: 1
dapiServerAddress:
api3ServerV1:
type: string
oevProxyAddress:
type: string
Expand All @@ -47,14 +47,11 @@ components:
type: object
required:
- airnodeAddress
- endpointId
- encodedParameters
- templateId
properties:
airnodeAddress:
type: string
endpointId:
type: string
encodedParameters:
templateId:
type: string
signedData:
type: object
Expand Down Expand Up @@ -82,16 +79,15 @@ components:
value: |
{
"chainId": 1,
"dapiServerAddress": "0x...",
"api3ServerV1": "0x...",
"oevProxyAddress": "0x...",
"updateId": "0x...",
"bidderAddress": "0x...",
"bidAmount": "123...",
"beacons": [
{
"airnodeAddress": "0x...",
"endpointId": "0x...",
"encodedParameters": "0x...",
"templateId": "0x...",
"signedData": {
"timestamp": "16...",
"encodedValue": "0x...",
Expand All @@ -100,8 +96,7 @@ components:
},
{
"airnodeAddress": "0x...",
"endpointId": "0x...",
"encodedParameters": "0x..."
"templateId": "0x...",
}
]
}
Expand Down
9 changes: 0 additions & 9 deletions packages/airnode-node/src/handlers/sign-oev-data.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ describe('signOevData', () => {
beaconId: '0x1032c3cbea7692429f3f1bdb72c47b5c61bdd3ca995a763027f8aa511b42b11b',
templateId: '0x64a8f8e70cd1bd4e4621bde25053bf4e22633241effa9f768bf18ff6400dc702',
airnodeAddress: '0x9A2Df85E73851e27044504d72563696E5cE86B95',
endpointId: '0xa473a7ca2d5211e6e5766cc6a27c6e90a4f0270f13565e303c56a629815ed60a',
encodedParameters:
'0x3173000000000000000000000000000000000000000000000000000000000000636f696e49640000000000000000000000000000000000000000000000000000657468657265756d000000000000000000000000000000000000000000000000',
timestamp: '1677747253',
encodedValue: '0x0000000000000000000000000000000000000000000000000000000000000064', // 100
signature:
Expand All @@ -23,9 +20,6 @@ describe('signOevData', () => {
beaconId: '0xd6965b1162b263e4dac3084ff0589614a464ac3e4ca012cb90ebb73094f7204e',
templateId: '0x306c24b3373f82f267e678464c3bbca29ca5657d0cc6fa4e92981ff91e7c97f3',
airnodeAddress: '0x9A2Df85E73851e27044504d72563696E5cE86B95',
endpointId: '0x6c0d51132b51cfca233be8f652189a62d1d9e3d7e0fed3dd2f131ebbf01d31d5',
encodedParameters:
'0x3173000000000000000000000000000000000000000000000000000000000000636f696e49640000000000000000000000000000000000000000000000000000626974636f696e00000000000000000000000000000000000000000000000000',
timestamp: '1677747310',
encodedValue: '0x0000000000000000000000000000000000000000000000000000000000000096', // 150
signature:
Expand All @@ -35,9 +29,6 @@ describe('signOevData', () => {
beaconId: '0xac1054d456689fa9d63e70d6a39b2f3896f494a544865969f1de6d3a61bf10ed',
templateId: '0xf13fcbc7e9b814d6f42ca68793c4c5843950d7d77f4c54105669468efc7bb8a0',
airnodeAddress: '0xc89216a9adFA290354eB5365C3d5de6B6A24296a',
endpointId: '0x0441ead8bafbca489e41d994bdde04d233b88423d93bd789651f2dd60d11f752',
encodedParameters:
'0x3173000000000000000000000000000000000000000000000000000000000000636f696e49640000000000000000000000000000000000000000000000000000646f6765636f696e000000000000000000000000000000000000000000000000',
timestamp: '1677747379',
encodedValue: '0x00000000000000000000000000000000000000000000000000000000000000c8', // 200
signature:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@ const validDecodedBeacons = [
beaconId: '0x1032c3cbea7692429f3f1bdb72c47b5c61bdd3ca995a763027f8aa511b42b11b',
templateId: '0x64a8f8e70cd1bd4e4621bde25053bf4e22633241effa9f768bf18ff6400dc702',
airnodeAddress: '0x9A2Df85E73851e27044504d72563696E5cE86B95',
endpointId: '0xa473a7ca2d5211e6e5766cc6a27c6e90a4f0270f13565e303c56a629815ed60a',
encodedParameters:
'0x3173000000000000000000000000000000000000000000000000000000000000636f696e49640000000000000000000000000000000000000000000000000000657468657265756d000000000000000000000000000000000000000000000000',
signedData: {
timestamp: '1677747253',
encodedValue: '0x00000000000000000000000000000000000000000000000000000000000003e8', // 1000
Expand All @@ -50,9 +47,6 @@ const validDecodedBeacons = [
beaconId: '0xd6965b1162b263e4dac3084ff0589614a464ac3e4ca012cb90ebb73094f7204e',
templateId: '0x306c24b3373f82f267e678464c3bbca29ca5657d0cc6fa4e92981ff91e7c97f3',
airnodeAddress: '0x9A2Df85E73851e27044504d72563696E5cE86B95',
endpointId: '0x6c0d51132b51cfca233be8f652189a62d1d9e3d7e0fed3dd2f131ebbf01d31d5',
encodedParameters:
'0x3173000000000000000000000000000000000000000000000000000000000000636f696e49640000000000000000000000000000000000000000000000000000626974636f696e00000000000000000000000000000000000000000000000000',
signedData: {
timestamp: '1677747310',
encodedValue: '0x00000000000000000000000000000000000000000000000000000000000003e9', // 1001
Expand All @@ -65,9 +59,6 @@ const validDecodedBeacons = [
beaconId: '0xac1054d456689fa9d63e70d6a39b2f3896f494a544865969f1de6d3a61bf10ed',
templateId: '0xf13fcbc7e9b814d6f42ca68793c4c5843950d7d77f4c54105669468efc7bb8a0',
airnodeAddress: '0xc89216a9adFA290354eB5365C3d5de6B6A24296a',
endpointId: '0x0441ead8bafbca489e41d994bdde04d233b88423d93bd789651f2dd60d11f752',
encodedParameters:
'0x3173000000000000000000000000000000000000000000000000000000000000636f696e49640000000000000000000000000000000000000000000000000000646f6765636f696e000000000000000000000000000000000000000000000000',
signedData: {
timestamp: '1677747379',
encodedValue: '0x00000000000000000000000000000000000000000000000000000000000003ea', // 1002
Expand All @@ -82,12 +73,12 @@ const validBeaconsWithIds = validDecodedBeacons.map<Required<BeaconWithIds>>((de
);
const validRequestBody: ProcessSignOevDataRequestBody = {
chainId: 31337,
dapiServerAddress: '0x720D8B97a6B90AB8a53358447Df5cf28A9391Ab4',
api3ServerV1: '0x720D8B97a6B90AB8a53358447Df5cf28A9391Ab4',
oevProxyAddress: '0x9AA42184aFD00c9599CE05748E2199F8f083036b',
updateId: '0x3039656530346630306130383438646138323665616363636538343664303000',
bidderAddress: '0xb5c062D4d799b85B4e29c274F9570Fd8216AED68',
bidAmount: '0x0000000000000000000000000000000000000000000000000000000a571a14c0',
beacons: validBeaconsWithIds.map((beacon) => omit(beacon, ['templateId', 'beaconId'])),
beacons: validBeaconsWithIds.map((beacon) => omit(beacon, ['beaconId'])),
};

describe('verifyHttpRequest', () => {
Expand Down Expand Up @@ -252,10 +243,8 @@ describe('validateBeacons', () => {
expect(validateBeacons([validRequestBody.beacons[0]])).toEqual([beacon]);
});

it('returns null if some beacons have invalid encoded parameters', () => {
expect(
validateBeacons([{ ...validRequestBody.beacons[0], encodedParameters: 'invalid encoded parameters' }])
).toBeNull();
it('returns null if some beacons have invalid template IDs', () => {
expect(validateBeacons([{ ...validRequestBody.beacons[0], templateId: 'invalidTemplate' }])).toBeNull();
});
});

Expand Down Expand Up @@ -310,7 +299,7 @@ describe('verifySignOevDataRequest', () => {
...validBeaconsWithIds[0],
signedData: { ...validBeaconsWithIds[0].signedData, timestamp: '1677740000' },
};
const invalidEncodedParametersBeacon: BeaconWithIds = { ...validBeaconsWithIds[0], encodedParameters: 'invalid' };
const invalidTemplateIdBeacon: BeaconWithIds = { ...validBeaconsWithIds[0], templateId: 'invalid' };
const invalidEncodedValueBeacon: BeaconWithIds = {
...validBeaconsWithIds[0],
signedData: { ...validBeaconsWithIds[0].signedData, encodedValue: 'invalid' },
Expand Down Expand Up @@ -395,10 +384,10 @@ describe('verifySignOevDataRequest', () => {
});
});

it('fails if there are beacons with invalid encoded parameters', () => {
it('fails if there are beacons with invalid template ID', () => {
expect(
verifySignOevDataRequest({
beacons: [...validRequestBody.beacons, invalidEncodedParametersBeacon],
beacons: [...validRequestBody.beacons, invalidTemplateIdBeacon],
} as ProcessSignOevDataRequestBody)
).toEqual({
success: false,
Expand Down
29 changes: 9 additions & 20 deletions packages/airnode-node/src/workers/local-gateways/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ import { ethers } from 'ethers';
import { decode } from '@api3/airnode-abi';
import { logger } from '@api3/airnode-utilities';
import { goSync } from '@api3/promise-utils';
import { ApiCallParameters, ApiCallTemplateWithoutId } from '../../types';
import { ApiCallParameters } from '../../types';
import { Config, endpointIdSchema } from '../../config';
import { apiCallParametersSchema } from '../../validation';
import { getAirnodeWalletFromPrivateKey } from '../../evm';
import { getExpectedTemplateIdV1 } from '../../evm/templates';

const TIMESTAMP_DEVIATION = 2; // in minutes
// Solidity type(int224).min
Expand Down Expand Up @@ -121,8 +120,7 @@ export function verifyHttpSignedDataRequest(

const beaconSchema = z.object({
airnodeAddress: z.string(),
endpointId: z.string(),
encodedParameters: z.string(),
templateId: z.string(),
// Signed data might be missing for some of the beacons (as long as the majority has the data). We still need to know
// all of the beacons to derive the data feed ID.
signedData: z
Expand All @@ -146,7 +144,7 @@ export interface BeaconDecoded extends Required<BeaconWithIds> {

export const signOevDataBodySchema = z.object({
chainId: z.number().positive(),
dapiServerAddress: z.string(),
api3ServerV1: z.string(),
oevProxyAddress: z.string(),
updateId: z.string(),
bidderAddress: z.string(),
Expand Down Expand Up @@ -234,18 +232,9 @@ export const validateBeacons = (beacons: Beacon[]): BeaconWithIds[] | null => {
const goValidateBeacons = goSync(() => {
const beaconsWithIds: BeaconWithIds[] = [];
for (const beacon of beacons) {
const { airnodeAddress, encodedParameters, endpointId } = beacon;

// To check parameters validity, exception is caught by the goSync
decode(encodedParameters);

const template: ApiCallTemplateWithoutId = {
airnodeAddress,
endpointId,
encodedParameters,
};
// Both template ID and beacon ID can fail, but it's OK because we are wrapping the validation in goSync
const templateId = getExpectedTemplateIdV1(template);
const { airnodeAddress, templateId } = beacon;

// Beacon ID derivation can fail, but it's OK because we are wrapping the validation in goSync
const beaconId = deriveBeaconId(airnodeAddress, templateId);

beaconsWithIds.push({ ...beacon, templateId, beaconId });
Expand All @@ -262,7 +251,7 @@ export function verifySignOevDataRequest(requestBody: ProcessSignOevDataRequestB
oevUpdateHash: string;
beacons: BeaconDecoded[];
}> {
const { chainId, dapiServerAddress, oevProxyAddress, updateId, bidderAddress, bidAmount, beacons } = requestBody;
const { chainId, api3ServerV1, oevProxyAddress, updateId, bidderAddress, bidAmount, beacons } = requestBody;

const beaconsWithIds = validateBeacons(beacons);
if (!beaconsWithIds) {
Expand Down Expand Up @@ -326,7 +315,7 @@ export function verifySignOevDataRequest(requestBody: ProcessSignOevDataRequestB
logger.debug(
`Deriving update hash. Params: ${JSON.stringify([
chainId,
dapiServerAddress,
api3ServerV1,
oevProxyAddress,
dataFeedId,
updateId,
Expand All @@ -340,7 +329,7 @@ export function verifySignOevDataRequest(requestBody: ProcessSignOevDataRequestB
['uint256', 'address', 'address', 'bytes32', 'bytes32', 'uint256', 'bytes', 'address', 'uint256'],
[
chainId,
dapiServerAddress,
api3ServerV1,
oevProxyAddress,
dataFeedId,
updateId,
Expand Down

0 comments on commit 66f69fe

Please sign in to comment.