1
- import { ethereum , dataSource , BigInt , Bytes , DataSourceContext } from '@graphprotocol/graph-ts'
2
- import { TestEvent } from '../generated/Contract/Contract'
3
- import { IpfsFile , IpfsFile1 } from '../generated/schema'
1
+ import {
2
+ ethereum ,
3
+ dataSource ,
4
+ BigInt ,
5
+ Bytes ,
6
+ DataSourceContext ,
7
+ } from "@graphprotocol/graph-ts" ;
8
+ import { TestEvent } from "../generated/Contract/Contract" ;
9
+ import { IpfsFile , IpfsFile1 , SpawnTestEntity } from "../generated/schema" ;
4
10
5
11
// CID of `file-data-sources/abis/Contract.abi` after being processed by graph-cli.
6
- const KNOWN_CID = "QmQ2REmceVtzawp7yrnxLQXgNNCtFHEnig6fL9aqE1kcWq"
12
+ const KNOWN_CID = "QmQ2REmceVtzawp7yrnxLQXgNNCtFHEnig6fL9aqE1kcWq" ;
7
13
8
14
export function handleBlock ( block : ethereum . Block ) : void {
9
- let entity = new IpfsFile ( "onchain" )
10
- entity . content = "onchain"
11
- entity . save ( )
15
+ let entity = new IpfsFile ( "onchain" ) ;
16
+ entity . content = "onchain" ;
17
+ entity . save ( ) ;
12
18
13
19
// This will create the same data source twice, once at block 0 and another at block 2.
14
20
// The creation at block 2 should be detected as a duplicate and therefore a noop.
15
21
if ( block . number == BigInt . fromI32 ( 0 ) || block . number == BigInt . fromI32 ( 2 ) ) {
16
- dataSource . create ( "File" , [ KNOWN_CID ] )
22
+ dataSource . create ( "File" , [ KNOWN_CID ] ) ;
17
23
}
18
24
19
25
if ( block . number == BigInt . fromI32 ( 1 ) ) {
20
- let entity = IpfsFile . load ( "onchain" ) !
21
- assert ( entity . content == "onchain" )
26
+ let entity = IpfsFile . load ( "onchain" ) ! ;
27
+ assert ( entity . content == "onchain" ) ;
22
28
23
29
// The test assumes file data sources are processed in the block in which they are created.
24
30
// So the ds created at block 0 will have been processed.
@@ -27,17 +33,16 @@ export function handleBlock(block: ethereum.Block): void {
27
33
assert ( IpfsFile . load ( KNOWN_CID ) == null ) ;
28
34
29
35
// Test that using an invalid CID will be ignored
30
- dataSource . create ( "File" , [ "hi, I'm not valid" ] )
36
+ dataSource . create ( "File" , [ "hi, I'm not valid" ] ) ;
31
37
}
32
38
33
-
34
- // This will invoke File1 data source with same CID, which will be used
39
+ // This will invoke File1 data source with same CID, which will be used
35
40
// to test whether same cid is triggered across different data source.
36
41
if ( block . number == BigInt . fromI32 ( 3 ) ) {
37
42
// Test that onchain data sources cannot read offchain data (again, but this time more likely to hit the DB than the write queue).
38
43
assert ( IpfsFile . load ( KNOWN_CID ) == null ) ;
39
44
40
- dataSource . create ( "File1" , [ KNOWN_CID ] )
45
+ dataSource . create ( "File1" , [ KNOWN_CID ] ) ;
41
46
}
42
47
}
43
48
@@ -46,17 +51,32 @@ export function handleTestEvent(event: TestEvent): void {
46
51
47
52
if ( command == "createFile2" ) {
48
53
// Will fail the subgraph when processed due to mismatch in the entity type and 'entities'.
49
- dataSource . create ( "File2" , [ KNOWN_CID ] )
54
+ dataSource . create ( "File2" , [ KNOWN_CID ] ) ;
50
55
} else if ( command == "saveConflictingEntity" ) {
51
56
// Will fail the subgraph because the same entity has been created in a file data source.
52
- let entity = new IpfsFile ( KNOWN_CID )
53
- entity . content = "empty"
54
- entity . save ( )
57
+ let entity = new IpfsFile ( KNOWN_CID ) ;
58
+ entity . content = "empty" ;
59
+ entity . save ( ) ;
55
60
} else if ( command == "createFile1" ) {
56
61
// Will fail the subgraph with a conflict between two entities created by offchain data sources.
57
62
let context = new DataSourceContext ( ) ;
58
63
context . setBytes ( "hash" , event . block . hash ) ;
59
- dataSource . createWithContext ( "File1" , [ KNOWN_CID ] , context )
64
+ dataSource . createWithContext ( "File1" , [ KNOWN_CID ] , context ) ;
65
+ } else if ( command == "spawnOffChainHandlerTest" ) {
66
+ // Used to test the spawning of a file data source from another file data source handler.
67
+ // `SpawnTestHandler` will spawn a file data source that will be handled by `spawnOffChainHandlerTest`,
68
+ // which creates another file data source `OffChainDataSource`, which will be handled by `handleSpawnedTest`.
69
+ let context = new DataSourceContext ( ) ;
70
+ context . setString ( "command" , command ) ;
71
+ dataSource . createWithContext ( "SpawnTestHandler" , [ KNOWN_CID ] , context ) ;
72
+ } else if ( command == "spawnOnChainHandlerTest" ) {
73
+ // Used to test the failure of spawning of on-chain data source from a file data source handler.
74
+ // `SpawnTestHandler` will spawn a file data source that will be handled by `spawnTestHandler`,
75
+ // which creates an `OnChainDataSource`, which should fail since spawning onchain datasources
76
+ // from offchain handlers is not allowed.
77
+ let context = new DataSourceContext ( ) ;
78
+ context . setString ( "command" , command ) ;
79
+ dataSource . createWithContext ( "SpawnTestHandler" , [ KNOWN_CID ] , context ) ;
60
80
} else {
61
81
assert ( false , "Unknown command: " + command ) ;
62
82
}
@@ -66,22 +86,48 @@ export function handleFile(data: Bytes): void {
66
86
// Test that offchain data sources cannot read onchain data.
67
87
assert ( IpfsFile . load ( "onchain" ) == null ) ;
68
88
69
- if ( dataSource . stringParam ( ) != "QmVkvoPGi9jvvuxsHDVJDgzPEzagBaWSZRYoRDzU244HjZ" ) {
89
+ if (
90
+ dataSource . stringParam ( ) != "QmVkvoPGi9jvvuxsHDVJDgzPEzagBaWSZRYoRDzU244HjZ"
91
+ ) {
70
92
// Test that an offchain data source cannot read from another offchain data source.
71
- assert ( IpfsFile . load ( "QmVkvoPGi9jvvuxsHDVJDgzPEzagBaWSZRYoRDzU244HjZ" ) == null ) ;
93
+ assert (
94
+ IpfsFile . load ( "QmVkvoPGi9jvvuxsHDVJDgzPEzagBaWSZRYoRDzU244HjZ" ) == null
95
+ ) ;
72
96
}
73
97
74
- let entity = new IpfsFile ( dataSource . stringParam ( ) )
75
- entity . content = data . toString ( )
76
- entity . save ( )
98
+ let entity = new IpfsFile ( dataSource . stringParam ( ) ) ;
99
+ entity . content = data . toString ( ) ;
100
+ entity . save ( ) ;
77
101
78
102
// Test that an offchain data source can load its own entities
79
- let loaded_entity = IpfsFile . load ( dataSource . stringParam ( ) ) !
80
- assert ( loaded_entity . content == entity . content )
103
+ let loaded_entity = IpfsFile . load ( dataSource . stringParam ( ) ) ! ;
104
+ assert ( loaded_entity . content == entity . content ) ;
81
105
}
82
106
83
107
export function handleFile1 ( data : Bytes ) : void {
84
- let entity = new IpfsFile1 ( dataSource . stringParam ( ) )
85
- entity . content = data . toString ( )
86
- entity . save ( )
108
+ let entity = new IpfsFile1 ( dataSource . stringParam ( ) ) ;
109
+ entity . content = data . toString ( ) ;
110
+ entity . save ( ) ;
111
+ }
112
+
113
+ // Used to test spawning a file data source from another file data source handler.
114
+ // This function spawns a file data source that will be handled by `handleSpawnedTest`.
115
+ export function spawnTestHandler ( data : Bytes ) : void {
116
+ let context = new DataSourceContext ( ) ;
117
+ context . setString ( "file" , "fromSpawnTestHandler" ) ;
118
+ let command = dataSource . context ( ) . getString ( "command" ) ;
119
+ if ( command == "spawnOffChainHandlerTest" ) {
120
+ dataSource . createWithContext ( "OffChainDataSource" , [ KNOWN_CID ] , context ) ;
121
+ } else if ( command == "spawnOnChainHandlerTest" ) {
122
+ dataSource . createWithContext ( "OnChainDataSource" , [ KNOWN_CID ] , context ) ;
123
+ }
124
+ }
125
+
126
+ // This is the handler for the data source spawned by `spawnOffChainHandlerTest`.
127
+ export function handleSpawnedTest ( data : Bytes ) : void {
128
+ let entity = new SpawnTestEntity ( dataSource . stringParam ( ) ) ;
129
+ let context = dataSource . context ( ) . getString ( "file" ) ;
130
+ entity . content = data . toString ( ) ;
131
+ entity . context = context ;
132
+ entity . save ( ) ;
87
133
}
0 commit comments