Abehjati/pyth-evm-update-method (#209)

* Add updatePriceFeeds to eth contract

* update gitignore

* Update typos

* Use calldata instead of memory for gas efficiency
This commit is contained in:
Ali Behjati 2022-05-16 16:14:43 +04:30 committed by GitHub
parent c9ef5ec365
commit ce56351c3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 60 additions and 29 deletions

2
.gitignore vendored
View File

@ -10,3 +10,5 @@ venv
.env
bigtable-admin.json
bigtable-writer.json
.vscode
.dccache

View File

@ -45,6 +45,12 @@ contract Pyth is PythGetters, PythSetters, AbstractPyth {
return batch;
}
function updatePriceFeeds(bytes[] calldata updateData) public override {
for(uint i = 0; i < updateData.length; i++) {
updatePriceBatchFromVm(updateData[i]);
}
}
function newPriceInfo(PythInternalStructs.PriceAttestation memory pa) private view returns (PythInternalStructs.PriceInfo memory info) {
info.attestationTime = pa.attestationTime;
info.publishTime = pa.publishTime;

View File

@ -11,7 +11,7 @@
"dependencies": {
"@openzeppelin/contracts": "^4.5.0",
"@openzeppelin/contracts-upgradeable": "^4.5.2",
"@pythnetwork/pyth-sdk-solidity": "0.0.3",
"@pythnetwork/pyth-sdk-solidity": "^0.1.0",
"dotenv": "^10.0.0",
"elliptic": "^6.5.2",
"ganache-cli": "^6.12.1",
@ -3674,9 +3674,9 @@
"dev": true
},
"node_modules/@pythnetwork/pyth-sdk-solidity": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@pythnetwork/pyth-sdk-solidity/-/pyth-sdk-solidity-0.0.3.tgz",
"integrity": "sha512-4FaoGD4Sizvdm0+8KuQsYzARHa+myNwmFE2GBYxmMcw3zMtwvD7PH0RWM8nK9UyExJ+vyAAth7SbVzyLfN4Yow=="
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@pythnetwork/pyth-sdk-solidity/-/pyth-sdk-solidity-0.1.0.tgz",
"integrity": "sha512-tyW8d98pnBHPhd/NS5jwCAzrOn/v+sqxUKseVXNQxohAxmuJ2QSOAypjNgaEFNKwu7DtgKQxoive2PnNJBVnXg=="
},
"node_modules/@redux-saga/core": {
"version": "1.1.3",
@ -39998,9 +39998,9 @@
"dev": true
},
"@pythnetwork/pyth-sdk-solidity": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@pythnetwork/pyth-sdk-solidity/-/pyth-sdk-solidity-0.0.3.tgz",
"integrity": "sha512-4FaoGD4Sizvdm0+8KuQsYzARHa+myNwmFE2GBYxmMcw3zMtwvD7PH0RWM8nK9UyExJ+vyAAth7SbVzyLfN4Yow=="
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@pythnetwork/pyth-sdk-solidity/-/pyth-sdk-solidity-0.1.0.tgz",
"integrity": "sha512-tyW8d98pnBHPhd/NS5jwCAzrOn/v+sqxUKseVXNQxohAxmuJ2QSOAypjNgaEFNKwu7DtgKQxoive2PnNJBVnXg=="
},
"@redux-saga/core": {
"version": "1.1.3",

View File

@ -32,7 +32,7 @@
"dependencies": {
"@openzeppelin/contracts": "^4.5.0",
"@openzeppelin/contracts-upgradeable": "^4.5.2",
"@pythnetwork/pyth-sdk-solidity": "0.0.3",
"@pythnetwork/pyth-sdk-solidity": "^0.1.0",
"dotenv": "^10.0.0",
"elliptic": "^6.5.2",
"ganache-cli": "^6.12.1",

View File

@ -224,32 +224,55 @@ contract("Pyth", function () {
}
});
async function attest(contract, data) {
const vm = await signAndEncodeVM(
1,
1,
testPyth2WormholeChainId,
testPyth2WormholeEmitter,
0,
data,
[testSigner1PK],
0,
0
);
await contract.updatePriceBatchFromVm("0x" + vm);
async function updatePriceFeeds(contract, batches) {
let updateData = []
for (let data of batches) {
const vm = await signAndEncodeVM(
1,
1,
testPyth2WormholeChainId,
testPyth2WormholeEmitter,
0,
data,
[testSigner1PK],
0,
0
);
updateData.push("0x" + vm)
}
await contract.updatePriceFeeds(updateData);
}
it("should attest price updates over wormhole", async function () {
let ts = 1647273460
let rawBatch = generateRawBatchAttestation(ts - 5, ts, 1337);
await attest(this.pythProxy, rawBatch);
let rawBatch = generateRawBatchAttestation(ts - 5, ts, 1337);
await updatePriceFeeds(this.pythProxy, [rawBatch]);
});
it("should attest price updates empty", async function () {
await updatePriceFeeds(this.pythProxy, []);
});
it("should attest price updates with multiple batches of correct order", async function () {
let ts = 1647273460
let rawBatch1 = generateRawBatchAttestation(ts - 5, ts, 1337);
let rawBatch2 = generateRawBatchAttestation(ts + 5, ts + 10, 1338);
await updatePriceFeeds(this.pythProxy, [rawBatch1, rawBatch2]);
});
it("should attest price updates with multiple batches of wrong order", async function () {
let ts = 1647273460
let rawBatch1 = generateRawBatchAttestation(ts - 5, ts, 1337);
let rawBatch2 = generateRawBatchAttestation(ts + 5, ts + 10, 1338);
await updatePriceFeeds(this.pythProxy, [rawBatch2, rawBatch1]);
});
it("should cache price updates", async function () {
let currentTimestamp = (await web3.eth.getBlock("latest")).timestamp;
let priceVal = 521;
let rawBatch = generateRawBatchAttestation(currentTimestamp - 5, currentTimestamp, priceVal);
await attest(this.pythProxy, rawBatch);
await updatePriceFeeds(this.pythProxy, [rawBatch]);
let first_prod_id = "0x" + "01".repeat(32);
let first_price_id = "0x" + "fe".repeat(32);
@ -271,7 +294,7 @@ contract("Pyth", function () {
nextTimestamp,
priceVal + 5
);
await attest(this.pythProxy, rawBatch2);
await updatePriceFeeds(this.pythProxy, [rawBatch2]);
first = await this.pythProxy.queryPriceFeed(first_price_id);
assert.equal(first.price, priceVal + 5);
@ -285,7 +308,7 @@ contract("Pyth", function () {
nextTimestamp,
priceVal + 10
);
await attest(this.pythProxy, rawBatch3);
await updatePriceFeeds(this.pythProxy, [rawBatch3]);
first = await this.pythProxy.queryPriceFeed(first_price_id);
assert.equal(first.price, priceVal + 5);
@ -308,7 +331,7 @@ contract("Pyth", function () {
it("should show stale cached prices as unknown", async function () {
let smallestTimestamp = 1;
let rawBatch = generateRawBatchAttestation(smallestTimestamp, smallestTimestamp + 5, 1337);
await attest(this.pythProxy, rawBatch);
await updatePriceFeeds(this.pythProxy, [rawBatch]);
for (var i = 1; i <= RAW_BATCH_ATTESTATION_COUNT; i++) {
const price_id =
@ -325,7 +348,7 @@ contract("Pyth", function () {
it("should show cached prices too far into the future as unknown", async function () {
let largestTimestamp = 4294967295;
let rawBatch = generateRawBatchAttestation(largestTimestamp - 5, largestTimestamp, 1337);
await attest(this.pythProxy, rawBatch);
await updatePriceFeeds(this.pythProxy, [rawBatch]);
for (var i = 1; i <= RAW_BATCH_ATTESTATION_COUNT; i++) {
const price_id =

View File

@ -46,7 +46,7 @@ export class EvmRelay implements Relay {
: null;
let tx = this.p2wContract
.updatePriceBatchFromVm("0x" + signedVAAs[i], { gasLimit: 1000000 })
.updatePriceFeeds(["0x" + signedVAAs[i]], { gasLimit: 1000000 })
.then(async (pending) => {
let receipt = await pending.wait();
logger.info(