@@ -611,6 +611,92 @@ var App = (function() {
611611 * Process a batch of blocks sequentially, then save checkpoint.
612612 */
613613 function _processBlockBatch ( startBlock , endBlock , chainHead ) {
614+ if ( _shouldUseArchiveEventBatch ( startBlock , endBlock , chainHead ) ) {
615+ _processArchiveEventBatch ( startBlock , endBlock , chainHead , function ( usedArchive ) {
616+ if ( ! usedArchive ) {
617+ _processBlockBatchFromRpc ( startBlock , endBlock , chainHead ) ;
618+ }
619+ } ) ;
620+ return ;
621+ }
622+
623+ _processBlockBatchFromRpc ( startBlock , endBlock , chainHead ) ;
624+ }
625+
626+ function _shouldUseArchiveEventBatch ( startBlock , endBlock , chainHead ) {
627+ return typeof HistorySource !== 'undefined' &&
628+ HistorySource . getEventsRange &&
629+ chainHead - startBlock > 1000 ;
630+ }
631+
632+ function _processArchiveEventBatch ( startBlock , endBlock , chainHead , done ) {
633+ HistorySource . getEventsRange ( {
634+ protocol : VizMagicConfig . PROTOCOLS . VM ,
635+ start : startBlock ,
636+ end : endBlock ,
637+ limit : 1000
638+ } , function ( err , events ) {
639+ if ( err || ! events ) {
640+ done ( false ) ;
641+ return ;
642+ }
643+
644+ events = events || [ ] ;
645+ events . sort ( function ( a , b ) {
646+ if ( ( a . blockNum || 0 ) !== ( b . blockNum || 0 ) ) return ( a . blockNum || 0 ) - ( b . blockNum || 0 ) ;
647+ if ( ( a . txIndex || 0 ) !== ( b . txIndex || 0 ) ) return ( a . txIndex || 0 ) - ( b . txIndex || 0 ) ;
648+ return ( a . opIndex || 0 ) - ( b . opIndex || 0 ) ;
649+ } ) ;
650+
651+ var grouped = { } ;
652+ var order = [ ] ;
653+ for ( var i = 0 ; i < events . length ; i ++ ) {
654+ var ev = events [ i ] ;
655+ var blockNum = ev . blockNum || 0 ;
656+ if ( ! blockNum ) continue ;
657+ if ( ! grouped [ blockNum ] ) {
658+ grouped [ blockNum ] = {
659+ vmActions : [ ] ,
660+ voicePosts : [ ] ,
661+ veEvents : [ ] ,
662+ awards : [ ] ,
663+ blockHash : ev . block_id || ev . previous || '' ,
664+ blockNum : blockNum ,
665+ timestamp : ev . timestamp || ''
666+ } ;
667+ order . push ( blockNum ) ;
668+ }
669+ var parsedAction = VMProtocol . parseAction ( ev . raw && ev . raw . json ? ev . raw . json : JSON . stringify ( ev . payload || { } ) ) ;
670+ if ( parsedAction ) {
671+ grouped [ blockNum ] . vmActions . push ( {
672+ sender : ev . sender || '' ,
673+ action : parsedAction ,
674+ blockNum : blockNum ,
675+ raw : ev . raw || { }
676+ } ) ;
677+ }
678+ }
679+
680+ var eventsCollected = [ ] ;
681+ for ( var j = 0 ; j < order . length ; j ++ ) {
682+ var processed = grouped [ order [ j ] ] ;
683+ var stateEvents = StateEngine . processBlock ( processed ) ;
684+ for ( var k = 0 ; k < stateEvents . length ; k ++ ) {
685+ eventsCollected . push ( stateEvents [ k ] ) ;
686+ }
687+ }
688+
689+ // Archive mode intentionally skips empty blocks. Advance the head so
690+ // stale checkpoints can catch up in seconds without replaying tens
691+ // of thousands of empty blocks through RPC.
692+ var state = StateEngine . getState ( ) ;
693+ state . headBlock = endBlock ;
694+ _finishProcessedBatch ( endBlock , chainHead , eventsCollected ) ;
695+ done ( true ) ;
696+ } ) ;
697+ }
698+
699+ function _processBlockBatchFromRpc ( startBlock , endBlock , chainHead ) {
614700 var eventsCollected = [ ] ;
615701
616702 BlockProcessor . processBlockRange ( startBlock , endBlock , function ( processed , blockNum ) {
@@ -620,36 +706,40 @@ var App = (function() {
620706 eventsCollected . push ( events [ i ] ) ;
621707 }
622708 } , function ( err ) {
623- _lastPolledBlock = endBlock ;
709+ _finishProcessedBatch ( endBlock , chainHead , eventsCollected ) ;
710+ } ) ;
711+ }
624712
625- // Emit game events to EventBus for UI reactivity
626- for ( var i = 0 ; i < eventsCollected . length ; i ++ ) {
627- var evt = eventsCollected [ i ] ;
628- if ( evt . type ) {
629- Helpers . EventBus . emit ( evt . type , evt ) ;
630- }
713+ function _finishProcessedBatch ( endBlock , chainHead , eventsCollected ) {
714+ _lastPolledBlock = endBlock ;
715+
716+ // Emit game events to EventBus for UI reactivity
717+ for ( var i = 0 ; i < eventsCollected . length ; i ++ ) {
718+ var evt = eventsCollected [ i ] ;
719+ if ( evt . type ) {
720+ Helpers . EventBus . emit ( evt . type , evt ) ;
631721 }
722+ }
632723
633- // Save checkpoint periodically (every batch)
634- StateEngine . saveCheckpoint ( function ( cpErr ) {
635- if ( cpErr ) {
636- console . log ( 'App: Checkpoint save error:' , cpErr ) ;
637- }
724+ // Save checkpoint periodically (every batch)
725+ StateEngine . saveCheckpoint ( function ( cpErr ) {
726+ if ( cpErr ) {
727+ console . log ( 'App: Checkpoint save error:' , cpErr ) ;
728+ }
638729
639- _updateSyncStatus ( _calculateSyncPercent ( endBlock , chainHead ) ) ;
640- _refreshActiveScreenAfterSync ( eventsCollected ) ;
730+ _updateSyncStatus ( _calculateSyncPercent ( endBlock , chainHead ) ) ;
731+ _refreshActiveScreenAfterSync ( eventsCollected ) ;
641732
642- // If there are more blocks to process, continue immediately
643- if ( endBlock < chainHead ) {
644- var nextStart = endBlock + 1 ;
645- var nextEnd = _nextCatchupBatchEnd ( nextStart , chainHead ) ;
646- _processBlockBatch ( nextStart , nextEnd , chainHead ) ;
647- } else {
648- _syncStartBlock = 0 ;
649- _updateSyncStatus ( 100 ) ;
650- _pollBusy = false ;
651- }
652- } ) ;
733+ // If there are more blocks to process, continue immediately
734+ if ( endBlock < chainHead ) {
735+ var nextStart = endBlock + 1 ;
736+ var nextEnd = _nextCatchupBatchEnd ( nextStart , chainHead ) ;
737+ _processBlockBatch ( nextStart , nextEnd , chainHead ) ;
738+ } else {
739+ _syncStartBlock = 0 ;
740+ _updateSyncStatus ( 100 ) ;
741+ _pollBusy = false ;
742+ }
653743 } ) ;
654744 }
655745
@@ -672,6 +762,7 @@ var App = (function() {
672762 map : true ,
673763 chronicle : true ,
674764 guild : true ,
765+ arena : true ,
675766 marketplace : true ,
676767 leaderboard : true
677768 } ;
0 commit comments