@@ -71,14 +71,82 @@ export class RunestoneIndexer {
7171 return ;
7272 }
7373
74- this . _updateInProgress = this . updateRuneUtxoBalancesImpl ( ) ;
74+ this . _updateInProgress = this . _rpc . getblockhashbyheight
75+ ? this . updateRuneUtxoBalancesWithBlockHeightImpl (
76+ this . _rpc . getblockhashbyheight . bind ( this . _rpc )
77+ )
78+ : this . updateRuneUtxoBalancesImpl ( ) ;
7579 try {
7680 await this . _updateInProgress ;
7781 } finally {
7882 this . _updateInProgress = null ;
7983 }
8084 }
8185
86+ private async updateRuneUtxoBalancesWithBlockHeightImpl (
87+ getblockhashbyheight : ( blockheight : number ) => Promise < string | null >
88+ ) {
89+ const currentStorageBlock = await this . _storage . getCurrentBlock ( ) ;
90+ if ( currentStorageBlock ) {
91+ // walk down until matching hash is found
92+ const reorgBlockhashesToIndex : string [ ] = [ ] ;
93+ let blockheight = currentStorageBlock . height ;
94+ let blockhash = await getblockhashbyheight ( blockheight ) ;
95+ let storageBlockHash : string | null = currentStorageBlock . hash ;
96+ while ( storageBlockHash !== blockhash ) {
97+ if ( blockhash ) {
98+ reorgBlockhashesToIndex . push ( blockhash ) ;
99+ }
100+
101+ blockheight -- ;
102+ blockhash = await getblockhashbyheight ( blockheight ) ;
103+ storageBlockHash = await this . _storage . getBlockhash ( blockheight ) ;
104+ }
105+
106+ // process blocks that are reorgs
107+ for ( const blockhash of reorgBlockhashesToIndex ) {
108+ const blockResult = await this . _rpc . getblock ( { blockhash, verbosity : 2 } ) ;
109+ if ( blockResult . error !== null ) {
110+ throw blockResult . error ;
111+ }
112+ const block = blockResult . result ;
113+
114+ const runeUpdater = new RuneUpdater ( this . _network , block , true , this . _storage , this . _rpc ) ;
115+
116+ for ( const [ txIndex , tx ] of block . tx . entries ( ) ) {
117+ await runeUpdater . indexRunes ( tx , txIndex ) ;
118+ }
119+
120+ await this . _storage . saveBlockIndex ( runeUpdater ) ;
121+ }
122+ }
123+
124+ // start from first rune height or next block height, whichever is greater
125+ let blockheight = Math . max (
126+ Network . getFirstRuneHeight ( this . _network ) ,
127+ currentStorageBlock ? currentStorageBlock . height + 1 : 0
128+ ) ;
129+ let blockhash = await getblockhashbyheight ( blockheight ) ;
130+ while ( blockhash !== null ) {
131+ const blockResult = await this . _rpc . getblock ( { blockhash, verbosity : 2 } ) ;
132+ if ( blockResult . error !== null ) {
133+ throw blockResult . error ;
134+ }
135+ const block = blockResult . result ;
136+
137+ const runeUpdater = new RuneUpdater ( this . _network , block , false , this . _storage , this . _rpc ) ;
138+
139+ for ( const [ txIndex , tx ] of block . tx . entries ( ) ) {
140+ await runeUpdater . indexRunes ( tx , txIndex ) ;
141+ }
142+
143+ await this . _storage . saveBlockIndex ( runeUpdater ) ;
144+
145+ blockheight ++ ;
146+ blockhash = await getblockhashbyheight ( blockheight ) ;
147+ }
148+ }
149+
82150 private async updateRuneUtxoBalancesImpl ( ) {
83151 const newBlockhashesToIndex : string [ ] = [ ] ;
84152
0 commit comments