wormhole/staging/algorand/test/pkeeper-sc-test.js

140 lines
8.6 KiB
JavaScript

const PricecasterLib = require('../lib/pricecaster')
const tools = require('../tools/app-tools')
const algosdk = require('algosdk')
const { expect } = require('chai')
const chai = require('chai')
chai.use(require('chai-as-promised'))
// Test general configuration for Betanet
const VALIDATOR_ADDR = 'OPDM7ACAW64Q4VBWAL77Z5SHSJVZZ44V3BAN7W44U43SUXEOUENZMZYOQU'
const VALIDATOR_MNEMO = 'assault approve result rare float sugar power float soul kind galaxy edit unusual pretty tone tilt net range pelican avoid unhappy amused recycle abstract master'
const OTHER_ADDR = 'DMTBK62XZ6KNI7L5E6TRBTPB4B3YNVB4WYGSWR42SEV4XKV4LYHGBW4O34'
const OTHER_MNEMO = 'old agree harbor cost pink fog chunk hope vital used rural soccer model acquire clown host friend bring marriage surge dirt surge slab absent punch'
const SIGNATURES = {}
SIGNATURES[VALIDATOR_ADDR] = algosdk.mnemonicToSecretKey(VALIDATOR_MNEMO)
SIGNATURES[OTHER_ADDR] = algosdk.mnemonicToSecretKey(OTHER_MNEMO)
const VALID_SYMBOL = 'BTC/USD '
const VALID_PRICE = BigInt(485265555)
const VALID_EXPONENT = BigInt(4)
const VALID_CONF = BigInt(1400000)
const VALID_SLOT = BigInt(104566700)
function signCallback (sender, tx) {
const txSigned = tx.signTxn(SIGNATURES[sender].sk)
return txSigned
}
describe('Price-Keeper contract tests', function () {
let pclib
let algodClient
let appId
let lastTs
before(async function () {
algodClient = new algosdk.Algodv2('', 'https://api.betanet.algoexplorer.io', '')
pclib = new PricecasterLib.PricecasterLib(algodClient)
console.log('Clearing accounts of all previous apps...')
const appsTo = await tools.readCreatedApps(algodClient, VALIDATOR_ADDR)
for (let i = 0; i < appsTo.length; i++) {
console.log('Clearing ' + appsTo[i].id)
try {
const txId = await pclib.deleteApp(VALIDATOR_ADDR, signCallback, appsTo[i].id)
await pclib.waitForConfirmation(txId)
} catch (e) {
console.error('Could not delete application! Reason: ' + e)
}
}
console.log('Creating new app...')
const txId = await pclib.createApp(VALIDATOR_ADDR, VALIDATOR_ADDR, VALID_SYMBOL, signCallback)
const txResponse = await pclib.waitForTransactionResponse(txId)
appId = pclib.appIdFromCreateAppResponse(txResponse)
pclib.setAppId(appId)
console.log('App Id: %d', appId)
})
it('Must create app with proper initial global state', async function () {
const stVAddr = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'vaddr')
const stSym = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'sym')
expect(Buffer.from(stSym, 'base64').toString()).to.equal(VALID_SYMBOL)
expect(stVAddr.toString()).to.equal(VALIDATOR_ADDR)
})
it('Must accept valid message and store data', async function () {
const msgBuffer = pclib.createMessage(VALID_SYMBOL, VALID_PRICE, VALID_EXPONENT, VALID_CONF, VALID_SLOT, SIGNATURES[VALIDATOR_ADDR].sk)
const txid = await pclib.submitMessage(VALIDATOR_ADDR, msgBuffer, signCallback)
expect(txid).to.have.length(52)
await pclib.waitForTransactionResponse(txid)
// console.log(await tools.printAppGlobalState(algodClient, appId, VALIDATOR_ADDR))
const stPrice = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'price')
const stExp = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'exp')
const stConf = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'conf')
const stSlot = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'slot')
expect(stPrice.toString()).to.equal(VALID_PRICE.toString())
expect((Buffer.from(stExp, 'base64')).readBigInt64BE()).to.equal(VALID_EXPONENT)
expect(stSlot.toString()).to.equal(VALID_SLOT.toString())
expect(stConf.toString()).to.equal(VALID_CONF.toString())
})
it('Must accept second message with different price', async function () {
const msgBuffer = pclib.createMessage(VALID_SYMBOL, VALID_PRICE + BigInt(400), VALID_EXPONENT + BigInt(3), VALID_CONF + BigInt(2), VALID_SLOT + BigInt(100), SIGNATURES[VALIDATOR_ADDR].sk)
const txid = await pclib.submitMessage(VALIDATOR_ADDR, msgBuffer, signCallback)
expect(txid).to.have.length(52)
await pclib.waitForTransactionResponse(txid)
const stPrice = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'price')
const stExp = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'exp')
const stConf = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'conf')
const stSlot = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'slot')
expect(stPrice.toString()).to.equal((VALID_PRICE + BigInt(400)).toString())
expect((Buffer.from(stExp, 'base64')).readBigInt64BE()).to.equal(VALID_EXPONENT + BigInt(3))
expect(stSlot.toString()).to.equal((VALID_SLOT + BigInt(100)).toString())
expect(stConf.toString()).to.equal((VALID_CONF + BigInt(2)).toString())
lastTs = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'ts')
})
it('Must accept negative exponent, stored as 2-complement 64bit', async function () {
const msgBuffer = pclib.createMessage(VALID_SYMBOL, VALID_PRICE, BigInt(-9), VALID_CONF, VALID_SLOT, SIGNATURES[VALIDATOR_ADDR].sk)
const txid = await pclib.submitMessage(VALIDATOR_ADDR, msgBuffer, signCallback)
expect(txid).to.have.length(52)
await pclib.waitForTransactionResponse(txid)
const stExp = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'exp')
const bufExp = Buffer.from(stExp, 'base64')
const val = bufExp.readBigInt64BE()
expect(val.toString()).to.equal('-9')
})
it('Must reject non-validator as signer', async function () {
const msgBuffer = pclib.createMessage(VALID_SYMBOL, VALID_PRICE, VALID_EXPONENT, VALID_CONF, VALID_SLOT, SIGNATURES[OTHER_ADDR].sk)
await expect(pclib.submitMessage(VALIDATOR_ADDR, msgBuffer, signCallback)).to.be.rejectedWith('Bad Request')
})
it('Must reject non-validator as sender', async function () {
const msgBuffer = pclib.createMessage(VALID_SYMBOL, VALID_PRICE, VALID_EXPONENT, VALID_CONF, VALID_SLOT, SIGNATURES[VALIDATOR_ADDR].sk)
await expect(pclib.submitMessage(OTHER_ADDR, msgBuffer, signCallback)).to.be.rejectedWith('Bad Request')
})
it('Must reject future timestamp', async function () {
const msgBuffer = pclib.createMessage(VALID_SYMBOL, VALID_PRICE, VALID_EXPONENT, VALID_CONF, VALID_SLOT, SIGNATURES[VALIDATOR_ADDR].sk, undefined, undefined, undefined, BigInt(lastTs + 200))
await expect(pclib.submitMessage(VALIDATOR_ADDR, msgBuffer, signCallback)).to.be.rejectedWith('Bad Request')
})
it('Must reject old timestamp', async function () {
const msgBuffer = pclib.createMessage(VALID_SYMBOL, VALID_PRICE, VALID_EXPONENT, VALID_CONF, VALID_SLOT, SIGNATURES[VALIDATOR_ADDR].sk, undefined, undefined, undefined, BigInt(lastTs - 999999))
await expect(pclib.submitMessage(VALIDATOR_ADDR, msgBuffer, signCallback)).to.be.rejectedWith('Bad Request')
})
it('Must reject zero-priced message', async function () {
const msgBuffer = pclib.createMessage(VALID_SYMBOL, BigInt(0), VALID_EXPONENT, VALID_CONF, VALID_SLOT, SIGNATURES[VALIDATOR_ADDR].sk)
await expect(pclib.submitMessage(VALIDATOR_ADDR, msgBuffer, signCallback)).to.be.rejectedWith('Bad Request')
})
it('Must reject zero slot', async function () {
const msgBuffer = pclib.createMessage(VALID_SYMBOL, VALID_PRICE, VALID_EXPONENT, VALID_CONF, BigInt(0), SIGNATURES[VALIDATOR_ADDR].sk)
await expect(pclib.submitMessage(VALIDATOR_ADDR, msgBuffer, signCallback)).to.be.rejectedWith('Bad Request')
})
it('Must reject bad header', async function () {
const msgBuffer = pclib.createMessage(VALID_SYMBOL, VALID_PRICE, VALID_EXPONENT, VALID_CONF, BigInt(0), SIGNATURES[VALIDATOR_ADDR].sk, 'BADHEADER')
await expect(pclib.submitMessage(VALIDATOR_ADDR, msgBuffer, signCallback)).to.be.rejectedWith('Bad Request')
})
it('Must reject bad destination appId', async function () {
const msgBuffer = pclib.createMessage(VALID_SYMBOL, VALID_PRICE, VALID_EXPONENT, VALID_CONF, BigInt(0), SIGNATURES[VALIDATOR_ADDR].sk, undefined, BigInt(100))
await expect(pclib.submitMessage(VALIDATOR_ADDR, msgBuffer, signCallback)).to.be.rejectedWith('Bad Request')
})
it('Must reject bad message version', async function () {
const msgBuffer = pclib.createMessage(VALID_SYMBOL, VALID_PRICE, VALID_EXPONENT, VALID_CONF, BigInt(0), SIGNATURES[VALIDATOR_ADDR].sk, undefined, undefined, 0)
await expect(pclib.submitMessage(VALIDATOR_ADDR, msgBuffer, signCallback)).to.be.rejectedWith('Bad Request')
})
})