Updates
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
require('bare-process/global')
|
||||
const test = require('brittle')
|
||||
const HyperP2PDecentralizedOracle = require('../index.js')
|
||||
const crypto = require('bare-crypto')
|
||||
const b4a = require('b4a')
|
||||
|
||||
test('lifecycle - ready and close', async (t) => {
|
||||
const oracle = new HyperP2PDecentralizedOracle()
|
||||
await oracle.ready()
|
||||
t.ok(oracle._ready, 'should be ready')
|
||||
t.is(oracle.id.length, 16, 'id length correct')
|
||||
await oracle.close()
|
||||
t.is(oracle._closed, true, 'closed flag set')
|
||||
})
|
||||
|
||||
test('submitReport and query basic flow', async (t) => {
|
||||
const oracle = new HyperP2PDecentralizedOracle({ quorumSize: 2 })
|
||||
await oracle.ready()
|
||||
|
||||
const feedId = 'price-feed-btc'
|
||||
const res = await oracle.submitReport(feedId, '65000', { source: 'coingecko' })
|
||||
t.ok(res.reportId, 'report id returned')
|
||||
|
||||
// Simulate receiving from peers to reach quorum
|
||||
const kp2 = require('hypercore-crypto').keyPair()
|
||||
const report2 = {
|
||||
id: b4a.toString(crypto.randomBytes(16), 'hex'),
|
||||
feedId,
|
||||
data: '65000',
|
||||
metadata: { source: 'binance' },
|
||||
timestamp: Date.now(),
|
||||
publicKey: b4a.toString(kp2.publicKey, 'hex'),
|
||||
signature: null
|
||||
}
|
||||
const dataToSign = b4a.from(`${feedId}:${report2.id}:${report2.data}:${report2.timestamp}`)
|
||||
report2.signature = b4a.toString(require('hypercore-crypto').sign(dataToSign, kp2.secretKey), 'hex')
|
||||
|
||||
await oracle.receiveReport(report2)
|
||||
|
||||
const result = await oracle.query(feedId)
|
||||
t.ok(result.value, 'query should return value')
|
||||
t.ok(result.quorum >= 1, 'quorum reached or partial')
|
||||
|
||||
await oracle.close()
|
||||
})
|
||||
|
||||
test('receiveReport with signature verification', async (t) => {
|
||||
const oracle = new HyperP2PDecentralizedOracle()
|
||||
await oracle.ready()
|
||||
|
||||
const feedId = 'test-feed'
|
||||
const kp = require('hypercore-crypto').keyPair()
|
||||
const report = {
|
||||
id: b4a.toString(crypto.randomBytes(16), 'hex'),
|
||||
feedId,
|
||||
data: JSON.stringify({ temp: 42 }),
|
||||
metadata: {},
|
||||
timestamp: Date.now(),
|
||||
publicKey: b4a.toString(kp.publicKey, 'hex'),
|
||||
signature: null
|
||||
}
|
||||
const dataToSign = b4a.from(`${feedId}:${report.id}:${report.data}:${report.timestamp}`)
|
||||
report.signature = b4a.toString(require('hypercore-crypto').sign(dataToSign, kp.secretKey), 'hex')
|
||||
|
||||
const ok = await oracle.receiveReport(report)
|
||||
t.is(ok, true, 'valid report accepted')
|
||||
|
||||
// Tampered report
|
||||
const badReport = { ...report, data: 'tampered' }
|
||||
const badOk = await oracle.receiveReport(badReport)
|
||||
t.is(badOk, false, 'tampered report rejected')
|
||||
|
||||
await oracle.close()
|
||||
})
|
||||
|
||||
test('raiseDispute and vote flow', async (t) => {
|
||||
const oracle = new HyperP2PDecentralizedOracle({ quorumSize: 2 })
|
||||
await oracle.ready()
|
||||
|
||||
const feedId = 'dispute-feed'
|
||||
const { reportId } = await oracle.submitReport(feedId, 'invalid-value')
|
||||
|
||||
const disputeId = await oracle.raiseDispute(feedId, reportId, 'data-inconsistency')
|
||||
t.ok(disputeId, 'dispute created')
|
||||
|
||||
const voterKp = require('hypercore-crypto').keyPair()
|
||||
await oracle.voteOnDispute(disputeId, feedId, 'reject', voterKp.publicKey)
|
||||
|
||||
const metrics = await oracle.getMetrics()
|
||||
t.ok(metrics.disputesRaised >= 1, 'dispute metric tracked')
|
||||
|
||||
await oracle.close()
|
||||
})
|
||||
|
||||
test('metrics and persistence roundtrip', async (t) => {
|
||||
const oracle = new HyperP2PDecentralizedOracle()
|
||||
await oracle.ready()
|
||||
|
||||
await oracle.submitReport('metrics-feed', 123)
|
||||
const m1 = await oracle.getMetrics()
|
||||
t.ok(m1.reportsSubmitted >= 1, 'submission metric')
|
||||
|
||||
await oracle.close()
|
||||
t.pass('close without error')
|
||||
})
|
||||
|
||||
test('error handling and closed state', async (t) => {
|
||||
const oracle = new HyperP2PDecentralizedOracle()
|
||||
await oracle.ready()
|
||||
await oracle.close()
|
||||
|
||||
try {
|
||||
await oracle.submitReport('closed-feed', 'x')
|
||||
t.fail('should throw on closed')
|
||||
} catch (err) {
|
||||
t.ok(err.message.includes('closed'), 'correct error on closed submit')
|
||||
}
|
||||
})
|
||||
test('hyper-p2p-decentralized-oracle: validation rejects invalid input', async (t) => {
|
||||
const m = new HyperP2PDecentralizedOracle()
|
||||
try {
|
||||
if (typeof m.addNeighbor === 'function') m.addNeighbor(null)
|
||||
else if (typeof m.buildCircuit === 'function') m.buildCircuit([])
|
||||
else if (typeof m.grant === 'function') m.grant(null, -1)
|
||||
else if (typeof m.enqueue === 'function') m.enqueue('bad', null)
|
||||
else if (typeof m.reportSample === 'function') m.reportSample(null, -1, -1)
|
||||
else if (typeof m.fanout === 'function') m.fanout(null, 0)
|
||||
else if (typeof m.probe === 'function') m.probe(null)
|
||||
else if (typeof m.resolve === 'function') m.resolve(null)
|
||||
else if (typeof m.acquire === 'function') m.acquire(null)
|
||||
else throw new Error('no validation hook')
|
||||
t.fail('expected throw')
|
||||
} catch (err) {
|
||||
t.ok(err instanceof Error)
|
||||
}
|
||||
await m.close()
|
||||
})
|
||||
Reference in New Issue
Block a user