1
+ package gnosis_test
2
+
3
+ import (
4
+ "context"
5
+ "github.com/rs/zerolog/log"
6
+ "github.com/shutter-network/rolling-shutter/rolling-shutter/keyper/database"
7
+ "github.com/shutter-network/rolling-shutter/rolling-shutter/keyperimpl/gnosis"
8
+ "github.com/shutter-network/rolling-shutter/rolling-shutter/medley/service"
9
+ "github.com/shutter-network/rolling-shutter/rolling-shutter/medley/testsetup"
10
+ "gotest.tools/assert"
11
+ "testing"
12
+ "time"
13
+ )
14
+
15
+ func TestSyncMonitor_ThrowsErrorWhenBlockNotIncreasing (t * testing.T ) {
16
+ ctx , cancel := context .WithCancel (context .Background ())
17
+ defer cancel ()
18
+
19
+ dbpool , closeDB := testsetup .NewTestDBPool (ctx , t , database .Definition )
20
+ defer closeDB ()
21
+
22
+ _ , err := dbpool .Exec (ctx , `
23
+ CREATE TABLE IF NOT EXISTS transaction_submitted_events_synced_until(
24
+ enforce_one_row bool PRIMARY KEY DEFAULT true,
25
+ block_hash bytea NOT NULL,
26
+ block_number bigint NOT NULL CHECK (block_number >= 0),
27
+ slot bigint NOT NULL CHECK (slot >= 0)
28
+ );
29
+ ` )
30
+ if err != nil {
31
+ t .Fatalf ("failed to create table: %v" , err )
32
+ }
33
+
34
+ initialBlockNumber := int64 (100 )
35
+ _ , err = dbpool .Exec (ctx , `
36
+ INSERT INTO transaction_submitted_events_synced_until (block_hash, block_number, slot)
37
+ VALUES ($1, $2, $3);
38
+ ` , []byte {0x01 , 0x02 , 0x03 }, initialBlockNumber , 1 )
39
+ if err != nil {
40
+ t .Fatalf ("failed to insert initial data: %v" , err )
41
+ }
42
+
43
+ monitor := & gnosis.SyncMonitor {
44
+ DBPool : dbpool ,
45
+ }
46
+
47
+ errCh := make (chan error , 1 )
48
+
49
+ go func () {
50
+ err := service .RunWithSighandler (ctx , monitor )
51
+ if err != nil {
52
+ errCh <- err
53
+ }
54
+ }()
55
+
56
+ time .Sleep (80 * time .Second )
57
+
58
+ select {
59
+ case err := <- errCh :
60
+ assert .ErrorContains (t , err , "block number has not increased between checks" )
61
+ case <- time .After (5 * time .Second ):
62
+ t .Fatal ("expected an error, but none was returned" )
63
+ }
64
+
65
+ }
66
+
67
+ func TestSyncMonitor_HandlesBlockNumberIncreasing (t * testing.T ) {
68
+ ctx , cancel := context .WithCancel (context .Background ())
69
+ defer cancel ()
70
+
71
+ dbpool , closeDB := testsetup .NewTestDBPool (ctx , t , database .Definition )
72
+ defer closeDB ()
73
+
74
+ _ , err := dbpool .Exec (ctx , `
75
+ CREATE TABLE IF NOT EXISTS transaction_submitted_events_synced_until(
76
+ enforce_one_row bool PRIMARY KEY DEFAULT true,
77
+ block_hash bytea NOT NULL,
78
+ block_number bigint NOT NULL CHECK (block_number >= 0),
79
+ slot bigint NOT NULL CHECK (slot >= 0)
80
+ );
81
+ ` )
82
+ if err != nil {
83
+ t .Fatalf ("failed to create table: %v" , err )
84
+ }
85
+
86
+ initialBlockNumber := int64 (100 )
87
+ _ , err = dbpool .Exec (ctx , `
88
+ INSERT INTO transaction_submitted_events_synced_until (block_hash, block_number, slot)
89
+ VALUES ($1, $2, $3);
90
+ ` , []byte {0x01 , 0x02 , 0x03 }, initialBlockNumber , 1 )
91
+ if err != nil {
92
+ t .Fatalf ("failed to insert initial data: %v" , err )
93
+ }
94
+
95
+ var count int
96
+ err = dbpool .QueryRow (ctx , `
97
+ SELECT count(*) FROM transaction_submitted_events_synced_until
98
+ WHERE block_number = $1;
99
+ ` , initialBlockNumber ).Scan (& count )
100
+ if err != nil {
101
+ t .Fatalf ("failed to verify initial data: %v" , err )
102
+ }
103
+
104
+ assert .Equal (t , 1 , count , "initial data should be inserted" )
105
+
106
+ monitor := & gnosis.SyncMonitor {
107
+ DBPool : dbpool ,
108
+ }
109
+
110
+ _ , deferFn := service .RunBackground (ctx , monitor )
111
+ defer deferFn ()
112
+
113
+ doneCh := make (chan struct {})
114
+ go func () {
115
+ for i := 0 ; i < 5 ; i ++ {
116
+ // Simulate block number increment by updating the database
117
+ newBlockNumber := initialBlockNumber + int64 (i + 1 )
118
+ log .Info ().
119
+ Int64 ("previous-block-number" , initialBlockNumber + int64 (i )).
120
+ Int64 ("new-block-number" , newBlockNumber ).
121
+ Msg ("comparing blocks" )
122
+
123
+ _ , err := dbpool .Exec (ctx , `
124
+ UPDATE transaction_submitted_events_synced_until
125
+ SET block_number = $1
126
+ WHERE block_number = $2;
127
+ ` , newBlockNumber , initialBlockNumber + int64 (i ))
128
+ if err != nil {
129
+ t .Fatalf ("failed to update block number: %v" , err )
130
+ }
131
+
132
+ time .Sleep (30 * time .Second )
133
+ }
134
+
135
+ doneCh <- struct {}{}
136
+ }()
137
+
138
+ select {
139
+ case <- doneCh :
140
+ var finalBlockNumber int64
141
+ err = dbpool .QueryRow (ctx , `SELECT block_number FROM transaction_submitted_events_synced_until LIMIT 1;` ).Scan (& finalBlockNumber )
142
+ if err != nil {
143
+ t .Fatalf ("failed to retrieve final block number: %v" , err )
144
+ }
145
+
146
+ assert .Equal (t , initialBlockNumber + 5 , finalBlockNumber , "block number should have been incremented correctly" )
147
+ }
148
+ }
0 commit comments