@@ -19,86 +19,122 @@ describe("SortitionTree", () => {
1919
2020 describe ( "setLeaf" , async ( ) => {
2121 context ( "when one leaf is set" , ( ) => {
22- beforeEach ( async ( ) => {
23- const weight1 = 0x1234
24- const position1 = parseInt ( "00123456" , 8 )
25-
26- const leaf = await sortition . toLeaf ( alice . address , weight1 )
27- await sortition . publicSetLeaf ( position1 , leaf , weight1 )
28- } )
29-
3022 it ( "should return correct value for the tree" , async ( ) => {
23+ const weight = 0x1234
24+ const position = 42798
25+
26+ const leaf = await sortition . toLeaf ( alice . address , weight )
27+ await sortition . publicSetLeaf ( position , leaf , weight )
3128 const root = await sortition . getRoot ( )
29+ //
30+ // Since the only leaf in the tree is the one we set, that's the only
31+ // weight that propagates to the root node. The first slot in the root
32+ // covers the sum of the first 8^6 = 262144 leaves. The next slot in
33+ // the root covers the sum of the next 262144, and so on.
3234 expect ( ethers . utils . hexlify ( root ) ) . to . be . equal ( "0x1234" )
35+ // The full output here looks like
36+ // 0x00000000,00000000,00000000,00000000,00000000,00000000,00000000,00001234
37+ // slot 7 slot 6 slot 5 slot 4 slot 3 slot 2 slot 1 slot 0
38+ // without the commas added for readability. All the padding zeros are
39+ // dropped when we hexlify.
3340 } )
3441 } )
3542
43+ it ( "should return correct value for the tree with a leaf in a second slot" , async ( ) => {
44+ const weight = 0x1234
45+ const position = 262145
46+
47+ const leaf = await sortition . toLeaf ( alice . address , weight )
48+ await sortition . publicSetLeaf ( position , leaf , weight )
49+ const root = await sortition . getRoot ( )
50+ //
51+ // Since the only leaf in the tree is the one we set, that's the only
52+ // weight that propagates to the root node. The first slot in the root
53+ // covers the sum of the first 8^6 = 262144 leaves. The next slot in
54+ // the root covers the sum of the next 262144, and so on.
55+ expect ( ethers . utils . hexlify ( root ) ) . to . be . equal ( "0x123400000000" )
56+ // The full output here looks like
57+ // 0x00000000,00000000,00000000,00000000,00000000,00000000,00001234,00000000
58+ // slot 7 slot 6 slot 5 slot 4 slot 3 slot 2 slot 1 slot 0
59+ // without the commas added for readability. All the padding zeros are
60+ // dropped when we hexlify, which simplifies to 0x123400000000.
61+ } )
62+
3663 context ( "when two leaves are set" , ( ) => {
37- beforeEach ( async ( ) => {
64+ it ( "should return correct value for the tree" , async ( ) => {
3865 const weight1 = 0x1234
39- const position1 = parseInt ( "00123456" , 8 )
66+ const position1 = 42798
67+
4068 const weight2 = 0x11
41- const position2 = parseInt ( "01234567" , 8 )
69+ const position2 = 342391
4270
4371 const leaf1 = await sortition . toLeaf ( alice . address , weight1 )
4472 await sortition . publicSetLeaf ( position1 , leaf1 , weight1 )
4573
4674 const leaf2 = await sortition . toLeaf ( bob . address , weight2 )
4775 await sortition . publicSetLeaf ( position2 , leaf2 , weight2 )
48- } )
49-
50- it ( "should return correct value for the tree" , async ( ) => {
5176 const root = await sortition . getRoot ( )
5277 expect ( ethers . utils . hexlify ( root ) ) . to . be . equal ( "0x1100001234" )
78+ // The full output here looks like
79+ // 0x00000000,00000000,00000000,00000000,00000000,00000000,00000011,00001234
80+ // slot 7 slot 6 slot 5 slot 4 slot 3 slot 2 slot 1 slot 0
81+ // without the commas added for readability. All the padding zeros are
82+ // dropped when we hexlify, which simplifies to 0x1100001234.
5383 } )
5484 } )
5585 } )
5686
5787 describe ( "removeLeaf" , ( ) => {
5888 context ( "when leaf is removed" , ( ) => {
59- beforeEach ( async ( ) => {
89+ it ( "should return correct value for the tree" , async ( ) => {
6090 const weight1 = 0x1234
61- const position1 = parseInt ( "00123456" , 8 )
91+ const position1 = 42798
92+
6293 const weight2 = 0x11
63- const position2 = parseInt ( "01234567" , 8 )
94+ const position2 = 342391
6495
6596 const leaf1 = await sortition . toLeaf ( alice . address , weight1 )
6697 await sortition . publicSetLeaf ( position1 , leaf1 , weight1 )
6798
6899 const leaf2 = await sortition . toLeaf ( bob . address , weight2 )
69100 await sortition . publicSetLeaf ( position2 , leaf2 , weight2 )
70101 await sortition . publicRemoveLeaf ( position1 )
71- } )
72-
73- it ( "should return correct value for the tree" , async ( ) => {
74102 const root = await sortition . getRoot ( )
75103 expect ( ethers . utils . hexlify ( root ) ) . to . be . equal ( "0x1100000000" )
104+ // The full output here looks like
105+ // 0x00000000,00000000,00000000,00000000,00000000,00000000,00000011,00000000
106+ // slot 7 slot 6 slot 5 slot 4 slot 3 slot 2 slot 1 slot 0
107+ // without the commas added for readability. All the padding zeros are
108+ // dropped when we hexlify, which simplifies to 0x1100000000.
76109 } )
77110 } )
78111 } )
79112
80113 describe ( "insertOperator" , ( ) => {
81114 const weightA = 0xfff0
82115 const weightB = 0x10000001
116+ // weightA + weightB = 0x1000fff1
83117
84118 context ( "when operators are inserted" , ( ) => {
85- beforeEach ( async ( ) => {
119+ it ( "should return correct value for the tree" , async ( ) => {
120+ // insertion begins left to right, so alice is inserted at position 0,
121+ // and bob is inserted at position 1. Their weights will propagate to
122+ // the root's first slot.
86123 await sortition . publicInsertOperator ( alice . address , weightA )
87124 await sortition . publicInsertOperator ( bob . address , weightB )
88- } )
89-
90- it ( "should return correct value for the tree" , async ( ) => {
91125 const root = await sortition . getRoot ( )
92- expect ( ethers . utils . hexlify ( root ) ) . to . be . equal ( "0x1000fff1" )
126+ expect ( ethers . utils . hexlify ( root ) ) . to . be . equal ( "0x1000fff1" ) // weightA + weightB
127+ // The full output here looks like
128+ // 0x00000000,00000000,00000000,00000000,00000000,00000000,00000000,1000fff1
129+ // slot 7 slot 6 slot 5 slot 4 slot 3 slot 2 slot 1 slot 0
130+ // without the commas added for readability. All the padding zeros are
131+ // dropped when we hexlify, which simplifies to 0x1100000000.
93132 } )
94133 } )
95134
96135 context ( "when operator is already registered" , ( ) => {
97- beforeEach ( async ( ) => {
98- await sortition . publicInsertOperator ( alice . address , weightA )
99- } )
100-
101136 it ( "should revert" , async ( ) => {
137+ await sortition . publicInsertOperator ( alice . address , weightA )
102138 await expect (
103139 sortition . publicInsertOperator ( alice . address , weightB ) ,
104140 ) . to . be . revertedWith ( "Operator is already registered in the pool" )
@@ -108,47 +144,38 @@ describe("SortitionTree", () => {
108144
109145 describe ( "getOperatorID" , ( ) => {
110146 context ( "when operator is inserted" , ( ) => {
111- beforeEach ( async ( ) => {
112- await sortition . publicInsertOperator ( alice . address , 0xfff0 )
113- } )
114-
115147 it ( "should return the id of the operator" , async ( ) => {
148+ await sortition . publicInsertOperator ( alice . address , 0xfff0 )
116149 const aliceID = await sortition . getOperatorID ( alice . address )
117150 expect ( aliceID ) . to . be . equal ( 1 )
118151 } )
152+ } )
119153
120- it ( "should return zero id when the operator is unknown" , async ( ) => {
121- const bobID = await sortition . getOperatorID ( bob . address )
122- expect ( bobID ) . to . be . equal ( 0 )
123- } )
154+ it ( "should return zero id when the operator is unknown" , async ( ) => {
155+ const bobID = await sortition . getOperatorID ( bob . address )
156+ expect ( bobID ) . to . be . equal ( 0 )
124157 } )
125158 } )
126159
127160 describe ( "getIDOperator" , ( ) => {
128161 context ( "when operator is inserted" , ( ) => {
129- beforeEach ( async ( ) => {
130- await sortition . publicInsertOperator ( alice . address , 0xfff0 )
131- } )
132-
133162 it ( "should return the address of the operator by their id" , async ( ) => {
163+ await sortition . publicInsertOperator ( alice . address , 0xfff0 )
134164 const aliceAddress = await sortition . getIDOperator ( 1 )
135165 expect ( aliceAddress ) . to . be . equal ( alice . address )
136166 } )
167+ } )
137168
138- it ( "should return zero address when the id of operator is unknown" , async ( ) => {
139- const aliceAddress = await sortition . getIDOperator ( 2 )
140- expect ( aliceAddress ) . to . be . equal ( ZERO_ADDRESS )
141- } )
169+ it ( "should return zero address when the id of operator is unknown" , async ( ) => {
170+ const aliceAddress = await sortition . getIDOperator ( 2 )
171+ expect ( aliceAddress ) . to . be . equal ( ZERO_ADDRESS )
142172 } )
143173 } )
144174
145175 describe ( "removeOperator" , ( ) => {
146176 context ( "when operator is not registered" , ( ) => {
147- beforeEach ( async ( ) => {
148- await sortition . publicInsertOperator ( alice . address , 0x1234 )
149- } )
150-
151177 it ( "should revert" , async ( ) => {
178+ await sortition . publicInsertOperator ( alice . address , 0x1234 )
152179 await expect (
153180 sortition . publicRemoveOperator ( bob . address ) ,
154181 ) . to . be . revertedWith ( "Operator is not registered in the pool" )
@@ -182,22 +209,16 @@ describe("SortitionTree", () => {
182209
183210 describe ( "isOperatorRegistered" , async ( ) => {
184211 context ( "when operator is not registered" , ( ) => {
185- beforeEach ( async ( ) => {
186- await sortition . publicInsertOperator ( alice . address , 0x1234 )
187- } )
188-
189212 it ( "should return false" , async ( ) => {
213+ await sortition . publicInsertOperator ( alice . address , 0x1234 )
190214 expect ( await sortition . publicIsOperatorRegistered ( bob . address ) ) . to . be
191215 . false
192216 } )
193217 } )
194218
195219 context ( "when operator is registered" , ( ) => {
196- beforeEach ( async ( ) => {
197- await sortition . publicInsertOperator ( alice . address , 0x1234 )
198- } )
199-
200220 it ( "should return false" , async ( ) => {
221+ await sortition . publicInsertOperator ( alice . address , 0x1234 )
201222 expect ( await sortition . publicIsOperatorRegistered ( alice . address ) ) . to . be
202223 . true
203224 } )
@@ -206,12 +227,9 @@ describe("SortitionTree", () => {
206227
207228 describe ( "updateLeaf" , async ( ) => {
208229 context ( "when leaf is updated" , ( ) => {
209- beforeEach ( async ( ) => {
230+ it ( "should return the correct value for the root" , async ( ) => {
210231 await sortition . publicInsertOperator ( alice . address , 0x1234 )
211232 await sortition . publicUpdateLeaf ( 0x00000 , 0x9876 )
212- } )
213-
214- it ( "should return the correct value for the root" , async ( ) => {
215233 const root = await sortition . getRoot ( )
216234 expect ( ethers . utils . hexlify ( root ) ) . to . be . equal ( "0x9876" )
217235 } )
@@ -220,19 +238,24 @@ describe("SortitionTree", () => {
220238
221239 describe ( "trunk stacks" , async ( ) => {
222240 it ( "works as expected" , async ( ) => {
241+ // inserted in the first position
223242 await sortition . publicInsertOperator ( alice . address , 0x1234 )
243+ // inserted in the second position
224244 await sortition . publicInsertOperator ( bob . address , 0x9876 )
225245
226246 await sortition . publicRemoveOperator ( alice . address )
227247 const deletedLeaf = await sortition . getLeaf ( 0x00000 )
228248 expect ( deletedLeaf ) . to . be . equal ( 0 )
229249
250+ // the first position isn't reused until we've inserted 8^7 = 2097152
251+ // operators. Alice is inserted in the third position.
230252 await sortition . publicInsertOperator ( alice . address , 0xdead )
231253
232254 const stillDeletedLeaf = await sortition . getLeaf ( 0x00000 )
233255 expect ( stillDeletedLeaf ) . to . be . equal ( 0 )
234256
235257 const root = await sortition . getRoot ( )
258+ // 0x9876 + 0xdead = 0x17723
236259 expect ( ethers . utils . hexlify ( root ) ) . to . be . equal ( "0x017723" )
237260 } )
238261 } )
@@ -244,6 +267,8 @@ describe("SortitionTree", () => {
244267 const index1 = 450
245268 const index2 = 451
246269
270+ // alice is assigned weights [0-450] (451 values) and bob has weight
271+ // [451-2434] (1984 values).
247272 const position1 = await sortition . publicPickWeightedLeaf ( index1 )
248273 expect ( position1 ) . to . be . equal ( 0 )
249274
@@ -261,15 +286,14 @@ describe("SortitionTree", () => {
261286 } )
262287
263288 describe ( "operatorsInPool" , async ( ) => {
264- context ( "when the operator is in the pool" , ( ) => {
265- beforeEach ( async ( ) => {
266- await sortition . publicInsertOperator ( alice . address , 1 )
267- } )
268-
269- it ( "should return true" , async ( ) => {
270- const nOperators = await sortition . operatorsInPool ( )
271- expect ( nOperators ) . to . be . equal ( 1 )
272- } )
289+ it ( "counts the number of operators in the pool" , async ( ) => {
290+ await sortition . publicInsertOperator ( alice . address , 1 )
291+ const justAlice = await sortition . operatorsInPool ( )
292+ expect ( justAlice ) . to . be . equal ( 1 )
293+
294+ await sortition . publicInsertOperator ( bob . address , 1 )
295+ const aliceAndBob = await sortition . operatorsInPool ( )
296+ expect ( aliceAndBob ) . to . be . equal ( 2 )
273297 } )
274298 } )
275299
0 commit comments