@@ -28,7 +28,7 @@ import (
2828var emptyCommitments = core.BlockCommitments {}
2929
3030const (
31- testResponse = `{"jsonrpc":"2.0","method":"starknet_subscriptionNewHeads","params":{"result":{"block_hash":"0x4e1f77f39545afe866ac151ac908bd1a347a2a8a7d58bef1276db4f06fdf2f6","parent_hash":"0x2a70fb03fe363a2d6be843343a1d81ce6abeda1e9bd5cc6ad8fa9f45e30fdeb","block_number":2,"new_root":"0x3ceee867d50b5926bb88c0ec7e0b9c20ae6b537e74aac44b8fcf6bb6da138d9","timestamp":1637084470,"sequencer_address":"0x0","l1_gas_price":{"price_in_fri":"0x0","price_in_wei":"0x0"},"l1_data_gas_price":{"price_in_fri":"0x0","price_in_wei":"0x0"},"l1_da_mode":"CALLDATA","starknet_version":""},"subscription_id":%d}}`
31+ newHeadsResponse = `{"jsonrpc":"2.0","method":"starknet_subscriptionNewHeads","params":{"result":{"block_hash":"0x4e1f77f39545afe866ac151ac908bd1a347a2a8a7d58bef1276db4f06fdf2f6","parent_hash":"0x2a70fb03fe363a2d6be843343a1d81ce6abeda1e9bd5cc6ad8fa9f45e30fdeb","block_number":2,"new_root":"0x3ceee867d50b5926bb88c0ec7e0b9c20ae6b537e74aac44b8fcf6bb6da138d9","timestamp":1637084470,"sequencer_address":"0x0","l1_gas_price":{"price_in_fri":"0x0","price_in_wei":"0x0"},"l1_data_gas_price":{"price_in_fri":"0x0","price_in_wei":"0x0"},"l1_da_mode":"CALLDATA","starknet_version":""},"subscription_id":%d}}`
3232)
3333
3434func TestEvents (t * testing.T ) {
@@ -238,12 +238,24 @@ func (fc *fakeConn) Equal(other jsonrpc.Conn) bool {
238238
239239type fakeSyncer struct {
240240 newHeads * feed.Feed [* core.Header ]
241+ reorgs * feed.Feed [* sync.ReorgData ]
242+ }
243+
244+ func newFakeSyncer () * fakeSyncer {
245+ return & fakeSyncer {
246+ newHeads : feed .New [* core.Header ](),
247+ reorgs : feed .New [* sync.ReorgData ](),
248+ }
241249}
242250
243251func (fs * fakeSyncer ) SubscribeNewHeads () sync.HeaderSubscription {
244252 return sync.HeaderSubscription {Subscription : fs .newHeads .Subscribe ()}
245253}
246254
255+ func (fs * fakeSyncer ) SubscribeReorg () sync.ReorgSubscription {
256+ return sync.ReorgSubscription {Subscription : fs .reorgs .Subscribe ()}
257+ }
258+
247259func (fs * fakeSyncer ) StartingBlockNumber () (uint64 , error ) {
248260 return 0 , nil
249261}
@@ -256,7 +268,7 @@ func TestSubscribeNewHeadsAndUnsubscribe(t *testing.T) {
256268 t .Parallel ()
257269
258270 chain := blockchain .New (pebble .NewMemTest (t ), & utils .Mainnet )
259- syncer := & fakeSyncer { newHeads : feed . New [ * core. Header ]()}
271+ syncer := newFakeSyncer ()
260272 handler := rpc .New (chain , syncer , nil , "" , utils .NewNopZapLogger ())
261273
262274 ctx , cancel := context .WithCancel (context .Background ())
@@ -289,7 +301,7 @@ func TestSubscribeNewHeadsAndUnsubscribe(t *testing.T) {
289301 syncer .newHeads .Send (testHeader (t ))
290302
291303 // Receive a block header.
292- want := fmt .Sprintf (testResponse , id .ID )
304+ want := fmt .Sprintf (newHeadsResponse , id .ID )
293305 got := make ([]byte , len (want ))
294306 _ , err := clientConn .Read (got )
295307 require .NoError (t , err )
@@ -323,7 +335,7 @@ func TestMultipleSubscribeNewHeadsAndUnsubscribe(t *testing.T) {
323335
324336 log := utils .NewNopZapLogger ()
325337 chain := blockchain .New (pebble .NewMemTest (t ), & utils .Mainnet )
326- syncer := & fakeSyncer { newHeads : feed . New [ * core. Header ]()}
338+ syncer := newFakeSyncer ()
327339 handler := rpc .New (chain , syncer , nil , "" , log )
328340
329341 ctx , cancel := context .WithCancel (context .Background ())
@@ -377,11 +389,11 @@ func TestMultipleSubscribeNewHeadsAndUnsubscribe(t *testing.T) {
377389 syncer .newHeads .Send (testHeader (t ))
378390
379391 // Receive a block header.
380- firstWant = fmt .Sprintf (testResponse , firstID )
392+ firstWant = fmt .Sprintf (newHeadsResponse , firstID )
381393 _ , firstGot , err = conn1 .Read (ctx )
382394 require .NoError (t , err )
383395 require .Equal (t , firstWant , string (firstGot ))
384- secondWant = fmt .Sprintf (testResponse , secondID )
396+ secondWant = fmt .Sprintf (newHeadsResponse , secondID )
385397 _ , secondGot , err = conn2 .Read (ctx )
386398 require .NoError (t , err )
387399 require .Equal (t , secondWant , string (secondGot ))
@@ -407,7 +419,7 @@ func TestSubscribeNewHeadsHistorical(t *testing.T) {
407419 assert .NoError (t , chain .Store (block0 , & emptyCommitments , stateUpdate0 , nil ))
408420
409421 chain = blockchain .New (testDB , & utils .Mainnet )
410- syncer := & fakeSyncer { newHeads : feed . New [ * core. Header ]()}
422+ syncer := newFakeSyncer ()
411423 handler := rpc .New (chain , syncer , nil , "" , utils .NewNopZapLogger ())
412424
413425 ctx , cancel := context .WithCancel (context .Background ())
@@ -450,7 +462,7 @@ func TestSubscribeNewHeadsHistorical(t *testing.T) {
450462 syncer .newHeads .Send (testHeader (t ))
451463
452464 // Check new block content
453- want = fmt .Sprintf (testResponse , id .ID )
465+ want = fmt .Sprintf (newHeadsResponse , id .ID )
454466 got = make ([]byte , len (want ))
455467 _ , err = clientConn .Read (got )
456468 require .NoError (t , err )
@@ -478,3 +490,48 @@ func testHeader(t *testing.T) *core.Header {
478490 }
479491 return header
480492}
493+
494+ func TestSubscriptionReorg (t * testing.T ) {
495+ t .Parallel ()
496+
497+ chain := blockchain .New (pebble .NewMemTest (t ), & utils .Mainnet )
498+ syncer := newFakeSyncer ()
499+ handler := rpc .New (chain , syncer , nil , "" , utils .NewNopZapLogger ())
500+
501+ ctx , cancel := context .WithCancel (context .Background ())
502+ t .Cleanup (cancel )
503+
504+ go func () {
505+ require .NoError (t , handler .Run (ctx ))
506+ }()
507+ time .Sleep (50 * time .Millisecond )
508+
509+ serverConn , clientConn := net .Pipe ()
510+ t .Cleanup (func () {
511+ require .NoError (t , serverConn .Close ())
512+ require .NoError (t , clientConn .Close ())
513+ })
514+
515+ subCtx := context .WithValue (ctx , jsonrpc.ConnKey {}, & fakeConn {w : serverConn })
516+
517+ // Subscribe to new heads which will send a
518+ id , rpcErr := handler .SubscribeNewHeads (subCtx , nil )
519+ require .Nil (t , rpcErr )
520+ require .NotZero (t , id )
521+
522+ // Simulate a reorg
523+ syncer .reorgs .Send (& sync.ReorgData {
524+ StartBlockHash : utils .HexToFelt (t , "0x4e1f77f39545afe866ac151ac908bd1a347a2a8a7d58bef1276db4f06fdf2f6" ),
525+ StartBlockNum : 0 ,
526+ EndBlockHash : utils .HexToFelt (t , "0x34e815552e42c5eb5233b99de2d3d7fd396e575df2719bf98e7ed2794494f86" ),
527+ EndBlockNum : 2 ,
528+ })
529+
530+ // Receive reorg event
531+ want := `{"jsonrpc":"2.0","method":"starknet_subscriptionReorg","params":{"result":{"starting_block_hash":"0x4e1f77f39545afe866ac151ac908bd1a347a2a8a7d58bef1276db4f06fdf2f6","starting_block_number":0,"ending_block_hash":"0x34e815552e42c5eb5233b99de2d3d7fd396e575df2719bf98e7ed2794494f86","ending_block_number":2},"subscription_id":%d}}`
532+ want = fmt .Sprintf (want , id .ID )
533+ got := make ([]byte , len (want ))
534+ _ , err := clientConn .Read (got )
535+ require .NoError (t , err )
536+ require .Equal (t , want , string (got ))
537+ }
0 commit comments