1313using Microsoft . AspNetCore . Http ;
1414using Microsoft . VisualStudio . TestPlatform . ObjectModel . DataCollection ;
1515using Microsoft . VisualStudio . TestTools . UnitTesting ;
16+ using Neo . Cryptography . ECC ;
1617using Neo . IO ;
1718using Neo . Json ;
1819using Neo . Network . P2P . Payloads ;
20+ using Neo . Persistence ;
1921using Neo . SmartContract ;
2022using Neo . SmartContract . Native ;
2123using Neo . UnitTests ;
2527using System . IO ;
2628using System . Linq ;
2729using System . Text ;
30+ using System . Threading ;
2831
2932namespace Neo . Plugins . RpcServer . Tests ;
3033
3134public partial class UT_RpcServer
3235{
33- static readonly string NeoScriptHash = "0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5" ;
34- static readonly string GasScriptHash = "0xd2a4cff31913016155e38e474a2c06d08be276cf" ;
3536 static readonly string NeoTotalSupplyScript = "wh8MC3RvdGFsU3VwcGx5DBT1Y\u002B pAvCg9TQ4FxI6jBbPyoHNA70FifVtS" ;
3637 static readonly string NeoTransferScript = "CxEMFPlu76Cuc\u002B bgteStE4ozsOWTNUdrDBQtYNweHko3YcnMFOes3ceblcI/lRTAHwwIdHJhbnNmZXIMFPVj6kC8KD1NDgXEjqMFs/Kgc0DvQWJ9W1I=" ;
3738 static readonly UInt160 ValidatorScriptHash = Contract
@@ -59,12 +60,12 @@ public void TestInvokeFunction()
5960 {
6061 _rpcServer . wallet = _wallet ;
6162
62- JObject resp = ( JObject ) _rpcServer . InvokeFunction ( new JArray ( NeoScriptHash , "totalSupply" , new JArray ( [ ] ) , validatorSigner , true ) ) ;
63+ JObject resp = ( JObject ) _rpcServer . InvokeFunction ( new JArray ( NeoScriptHash . ToString ( ) , "totalSupply" , new JArray ( [ ] ) , validatorSigner , true ) ) ;
6364 Assert . AreEqual ( resp . Count , 8 ) ;
6465 Assert . AreEqual ( resp [ "script" ] , NeoTotalSupplyScript ) ;
6566 Assert . IsTrue ( resp . ContainsProperty ( "gasconsumed" ) ) ;
6667 Assert . IsTrue ( resp . ContainsProperty ( "diagnostics" ) ) ;
67- Assert . AreEqual ( resp [ "diagnostics" ] [ "invokedcontracts" ] [ "call" ] [ 0 ] [ "hash" ] , NeoScriptHash ) ;
68+ Assert . AreEqual ( resp [ "diagnostics" ] [ "invokedcontracts" ] [ "call" ] [ 0 ] [ "hash" ] , NeoScriptHash . ToString ( ) ) ;
6869 Assert . IsTrue ( ( ( JArray ) resp [ "diagnostics" ] [ "storagechanges" ] ) . Count == 0 ) ;
6970 Assert . AreEqual ( resp [ "state" ] , "HALT" ) ;
7071 Assert . AreEqual ( resp [ "exception" ] , null ) ;
@@ -73,7 +74,7 @@ public void TestInvokeFunction()
7374 Assert . AreEqual ( resp [ "stack" ] [ 0 ] [ "value" ] , "100000000" ) ;
7475 Assert . IsTrue ( resp . ContainsProperty ( "tx" ) ) ;
7576
76- resp = ( JObject ) _rpcServer . InvokeFunction ( new JArray ( NeoScriptHash , "symbol" ) ) ;
77+ resp = ( JObject ) _rpcServer . InvokeFunction ( new JArray ( NeoScriptHash . ToString ( ) , "symbol" ) ) ;
7778 Assert . AreEqual ( resp . Count , 6 ) ;
7879 Assert . IsTrue ( resp . ContainsProperty ( "script" ) ) ;
7980 Assert . IsTrue ( resp . ContainsProperty ( "gasconsumed" ) ) ;
@@ -84,7 +85,7 @@ public void TestInvokeFunction()
8485 Assert . AreEqual ( resp [ "stack" ] [ 0 ] [ "value" ] , Convert . ToBase64String ( Encoding . UTF8 . GetBytes ( "NEO" ) ) ) ;
8586
8687 // This call triggers not only NEO but also unclaimed GAS
87- resp = ( JObject ) _rpcServer . InvokeFunction ( new JArray ( NeoScriptHash , "transfer" , new JArray ( [
88+ resp = ( JObject ) _rpcServer . InvokeFunction ( new JArray ( NeoScriptHash . ToString ( ) , "transfer" , new JArray ( [
8889 new JObject ( ) { [ "type" ] = "Hash160" , [ "value" ] = MultisigScriptHash . ToString ( ) } ,
8990 new JObject ( ) { [ "type" ] = "Hash160" , [ "value" ] = ValidatorScriptHash . ToString ( ) } ,
9091 new JObject ( ) { [ "type" ] = "Integer" , [ "value" ] = "1" } ,
@@ -94,17 +95,17 @@ public void TestInvokeFunction()
9495 Assert . AreEqual ( resp [ "script" ] , NeoTransferScript ) ;
9596 Assert . IsTrue ( resp . ContainsProperty ( "gasconsumed" ) ) ;
9697 Assert . IsTrue ( resp . ContainsProperty ( "diagnostics" ) ) ;
97- Assert . AreEqual ( resp [ "diagnostics" ] [ "invokedcontracts" ] [ "call" ] [ 0 ] [ "hash" ] , NeoScriptHash ) ;
98+ Assert . AreEqual ( resp [ "diagnostics" ] [ "invokedcontracts" ] [ "call" ] [ 0 ] [ "hash" ] , NeoScriptHash . ToString ( ) ) ;
9899 Assert . IsTrue ( ( ( JArray ) resp [ "diagnostics" ] [ "storagechanges" ] ) . Count == 4 ) ;
99100 Assert . AreEqual ( resp [ "state" ] , "HALT" ) ;
100101 Assert . AreEqual ( resp [ "exception" ] , $ "The smart contract or address { MultisigScriptHash . ToString ( ) } is not found") ;
101102 JArray notifications = ( JArray ) resp [ "notifications" ] ;
102103 Assert . AreEqual ( notifications . Count , 2 ) ;
103104 Assert . AreEqual ( notifications [ 0 ] [ "eventname" ] . AsString ( ) , "Transfer" ) ;
104- Assert . AreEqual ( notifications [ 0 ] [ "contract" ] . AsString ( ) , NeoScriptHash ) ;
105+ Assert . AreEqual ( notifications [ 0 ] [ "contract" ] . AsString ( ) , NeoScriptHash . ToString ( ) ) ;
105106 Assert . AreEqual ( notifications [ 0 ] [ "state" ] [ "value" ] [ 2 ] [ "value" ] , "1" ) ;
106107 Assert . AreEqual ( notifications [ 1 ] [ "eventname" ] . AsString ( ) , "Transfer" ) ;
107- Assert . AreEqual ( notifications [ 1 ] [ "contract" ] . AsString ( ) , GasScriptHash ) ;
108+ Assert . AreEqual ( notifications [ 1 ] [ "contract" ] . AsString ( ) , GasScriptHash . ToString ( ) ) ;
108109 Assert . AreEqual ( notifications [ 1 ] [ "state" ] [ "value" ] [ 2 ] [ "value" ] , "50000000" ) ;
109110
110111 _rpcServer . wallet = null ;
@@ -117,7 +118,7 @@ public void TestInvokeScript()
117118 Assert . AreEqual ( resp . Count , 7 ) ;
118119 Assert . IsTrue ( resp . ContainsProperty ( "gasconsumed" ) ) ;
119120 Assert . IsTrue ( resp . ContainsProperty ( "diagnostics" ) ) ;
120- Assert . AreEqual ( resp [ "diagnostics" ] [ "invokedcontracts" ] [ "call" ] [ 0 ] [ "hash" ] , NeoScriptHash ) ;
121+ Assert . AreEqual ( resp [ "diagnostics" ] [ "invokedcontracts" ] [ "call" ] [ 0 ] [ "hash" ] , NeoScriptHash . ToString ( ) ) ;
121122 Assert . AreEqual ( resp [ "state" ] , "HALT" ) ;
122123 Assert . AreEqual ( resp [ "exception" ] , null ) ;
123124 Assert . AreEqual ( ( ( JArray ) resp [ "notifications" ] ) . Count , 0 ) ;
@@ -133,7 +134,8 @@ public void TestInvokeScript()
133134 [ TestMethod ]
134135 public void TestTraverseIterator ( )
135136 {
136- JObject resp = ( JObject ) _rpcServer . InvokeFunction ( new JArray ( NeoScriptHash , "getAllCandidates" , new JArray ( [ ] ) , validatorSigner , true ) ) ;
137+ // GetAllCandidates that should return 0 candidates
138+ JObject resp = ( JObject ) _rpcServer . InvokeFunction ( new JArray ( NeoScriptHash . ToString ( ) , "getAllCandidates" , new JArray ( [ ] ) , validatorSigner , true ) ) ;
137139 string sessionId = resp [ "session" ] . AsString ( ) ;
138140 string iteratorId = resp [ "stack" ] [ 0 ] [ "id" ] . AsString ( ) ;
139141 JArray respArray = ( JArray ) _rpcServer . TraverseIterator ( [ sessionId , iteratorId , 100 ] ) ;
@@ -147,6 +149,79 @@ public void TestTraverseIterator()
147149 {
148150 Assert . AreEqual ( e . Message , "Unknown session" ) ;
149151 }
152+
153+ // register candidate in snapshot
154+ resp = ( JObject ) _rpcServer . InvokeFunction ( new JArray ( NeoScriptHash . ToString ( ) , "registerCandidate" ,
155+ new JArray ( [ new JObject ( ) {
156+ [ "type" ] = "PublicKey" ,
157+ [ "value" ] = TestProtocolSettings . SoleNode . StandbyCommittee [ 0 ] . ToString ( ) ,
158+ } ] ) , validatorSigner , true ) ) ;
159+ Assert . AreEqual ( resp [ "state" ] , "HALT" ) ;
160+ SnapshotCache snapshot = _neoSystem . GetSnapshotCache ( ) ;
161+ Transaction ? tx = new Transaction
162+ {
163+ Nonce = 233 ,
164+ ValidUntilBlock = NativeContract . Ledger . CurrentIndex ( snapshot ) + _neoSystem . Settings . MaxValidUntilBlockIncrement ,
165+ Signers = [ new Signer ( ) { Account = ValidatorScriptHash , Scopes = WitnessScope . CalledByEntry } ] ,
166+ Attributes = Array . Empty < TransactionAttribute > ( ) ,
167+ Script = Convert . FromBase64String ( resp [ "script" ] . AsString ( ) ) ,
168+ Witnesses = null ,
169+ } ;
170+ ApplicationEngine engine = ApplicationEngine . Run ( tx . Script , snapshot , container : tx , settings : _neoSystem . Settings , gas : 1200_0000_0000 ) ;
171+ engine . SnapshotCache . Commit ( ) ;
172+
173+ // GetAllCandidates that should return 1 candidate
174+ resp = ( JObject ) _rpcServer . InvokeFunction ( new JArray ( NeoScriptHash . ToString ( ) , "getAllCandidates" , new JArray ( [ ] ) , validatorSigner , true ) ) ;
175+ sessionId = resp [ "session" ] . AsString ( ) ;
176+ iteratorId = resp [ "stack" ] [ 0 ] [ "id" ] . AsString ( ) ;
177+ respArray = ( JArray ) _rpcServer . TraverseIterator ( [ sessionId , iteratorId , 100 ] ) ;
178+ Assert . AreEqual ( respArray . Count , 1 ) ;
179+ Assert . AreEqual ( respArray [ 0 ] [ "type" ] , "Struct" ) ;
180+ JArray value = ( JArray ) respArray [ 0 ] [ "value" ] ;
181+ Assert . AreEqual ( value . Count , 2 ) ;
182+ Assert . AreEqual ( value [ 0 ] [ "type" ] , "ByteString" ) ;
183+ Assert . AreEqual ( value [ 0 ] [ "value" ] , Convert . ToBase64String ( TestProtocolSettings . SoleNode . StandbyCommittee [ 0 ] . ToArray ( ) ) ) ;
184+ Assert . AreEqual ( value [ 1 ] [ "type" ] , "Integer" ) ;
185+ Assert . AreEqual ( value [ 1 ] [ "value" ] , "0" ) ;
186+
187+ // No result when traversed again
188+ respArray = ( JArray ) _rpcServer . TraverseIterator ( [ sessionId , iteratorId , 100 ] ) ;
189+ Assert . AreEqual ( respArray . Count , 0 ) ;
190+
191+ // GetAllCandidates again
192+ resp = ( JObject ) _rpcServer . InvokeFunction ( new JArray ( NeoScriptHash . ToString ( ) , "getAllCandidates" , new JArray ( [ ] ) , validatorSigner , true ) ) ;
193+ sessionId = resp [ "session" ] . AsString ( ) ;
194+ iteratorId = resp [ "stack" ] [ 0 ] [ "id" ] . AsString ( ) ;
195+
196+ // Insufficient result count limit
197+ respArray = ( JArray ) _rpcServer . TraverseIterator ( [ sessionId , iteratorId , 0 ] ) ;
198+ Assert . AreEqual ( respArray . Count , 0 ) ;
199+
200+ // Mocking session timeout
201+ Thread . Sleep ( _rpcServerSettings . SessionExpirationTime . Milliseconds + 1 ) ;
202+ _rpcServer . OnTimer ( new object ( ) ) ;
203+ try
204+ {
205+ respArray = ( JArray ) _rpcServer . TraverseIterator ( [ sessionId , iteratorId , 100 ] ) ;
206+ }
207+ catch ( RpcException e )
208+ {
209+ Assert . AreEqual ( e . Message , "Unknown session" ) ;
210+ }
211+
212+ // Mocking disposal
213+ resp = ( JObject ) _rpcServer . InvokeFunction ( new JArray ( NeoScriptHash . ToString ( ) , "getAllCandidates" , new JArray ( [ ] ) , validatorSigner , true ) ) ;
214+ sessionId = resp [ "session" ] . AsString ( ) ;
215+ iteratorId = resp [ "stack" ] [ 0 ] [ "id" ] . AsString ( ) ;
216+ _rpcServer . Dispose_SmartContract ( ) ;
217+ try
218+ {
219+ respArray = ( JArray ) _rpcServer . TraverseIterator ( [ sessionId , iteratorId , 100 ] ) ;
220+ }
221+ catch ( RpcException e )
222+ {
223+ Assert . AreEqual ( e . Message , "Unknown session" ) ;
224+ }
150225 }
151226
152227 [ TestMethod ]
0 commit comments