-
-
Notifications
You must be signed in to change notification settings - Fork 86
/
ChainSync.test.ts
120 lines (113 loc) · 4.24 KB
/
ChainSync.test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import { createChainSyncClient } from '@src/ChainSync'
import delay from 'delay'
import {
Block,
BlockAllegra,
BlockByron,
BlockMary,
BlockShelley,
Hash16, Point
} from '@cardano-ogmios/schema'
const connection = { port: 1338 }
describe('ChainSync', () => {
it('returns the interaction context', async () => {
const client = await createChainSyncClient({ connection })
expect(client.context.connectionString).toBe('ws://localhost:1338')
expect(client.context.socket.readyState).toBe(client.context.socket.OPEN)
await client.shutdown()
})
describe('startSync', () => {
it('selects the tip as the intersection if no point provided', async () => {
const client = await createChainSyncClient({ connection })
const intersection = await client.startSync()
if (intersection.point === 'origin' || intersection.tip === 'origin') {
await client.shutdown()
throw new Error('Test network is not syncing')
} else if ('slot' in intersection.point && 'slot' in intersection.tip) {
expect(intersection.point.slot).toEqual(intersection.tip.slot)
expect(intersection.point.hash).toEqual(intersection.tip.hash)
}
await client.shutdown()
})
it('intersects at the genesis if origin provided as point', async () => {
const client = await createChainSyncClient({ connection })
const intersection = await client.startSync(['origin'])
expect(intersection.point).toEqual('origin')
expect(intersection.tip).toBeDefined()
await client.shutdown()
})
it('accepts message handlers for roll back and roll forward messages', async () => {
const rollbackPoints: Point[] = []
const blocks: Block[] = []
const client = await createChainSyncClient({ connection })
client.on({
rollBackward: ({ point }) => {
rollbackPoints.push(point)
client.requestNext()
},
rollForward: async ({ block }) => {
if (blocks.length < 10) {
blocks.push(block)
client.requestNext()
}
}
})
await client.startSync(['origin'], 10)
await delay(1000)
await client.shutdown()
let firstBlockHash: Hash16
if ('byron' in blocks[0]) {
const block = blocks[0] as { byron: BlockByron }
firstBlockHash = block.byron.hash
} else if ('shelley' in blocks[0]) {
const block = blocks[0] as { shelley: BlockShelley }
firstBlockHash = block.shelley.body[0].id
} else if ('allegra' in blocks[0]) {
const block = blocks[0] as { allegra: BlockAllegra }
firstBlockHash = block.allegra.body[0].id
} else if ('mary' in blocks[0]) {
const block = blocks[0] as { mary: BlockMary }
firstBlockHash = block.mary.body[0].id
}
expect(firstBlockHash).toBeDefined()
expect(rollbackPoints.length).toBe(1)
expect(blocks.length).toBe(10)
})
it('implements pipelining to increase sync performance', async () => {
type BlocksPerSecond = number
const run = async (requestBuffer?: number): Promise<BlocksPerSecond> => {
const blocks: Block[] = []
const client = await createChainSyncClient({ connection })
const start = Date.now()
let stop: number
client.on({
rollBackward: () => {
client.requestNext()
},
rollForward: async ({ block }) => {
if (blocks.length < 1000) {
blocks.push(block)
client.requestNext()
} else if (stop === undefined) {
stop = Date.now() - start
}
}
})
await client.startSync(['origin'], requestBuffer)
await delay(800)
await client.shutdown()
expect(blocks.length).toBe(1000)
return 1000 * blocks.length / stop
}
const pipelinedBlocksPerSecond = await run()
const nonPipelinedBlocksPerSecond = await run(1)
expect(pipelinedBlocksPerSecond).toBeGreaterThan(nonPipelinedBlocksPerSecond)
})
})
it('rejects method calls after shutdown', async () => {
const client = await createChainSyncClient({ connection })
await client.shutdown()
const run = () => client.startSync(['origin'])
await expect(run).rejects
})
})