Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor!: update OEV gateway interface #1931

Merged
merged 2 commits into from
Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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', () => {
dcroote marked this conversation as resolved.
Show resolved Hide resolved
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