@@ -121,21 +121,54 @@ func (p *processor) getNexusVerifiedContracts(ctx context.Context) (map[oasisAdd
121121 return nexusVerifiedContracts , nil
122122}
123123
124+ // getContractsMissingPreimage returns the set of verified contract addresses
125+ // that are missing their address preimage (ETH address mapping).
126+ func (p * processor ) getContractsMissingPreimage (ctx context.Context ) (map [oasisAddress ]struct {}, error ) {
127+ rows , err := p .target .Query (ctx , queries .RuntimeEVMVerifiedContractsMissingPreimage , p .runtime )
128+ if err != nil {
129+ return nil , fmt .Errorf ("querying contracts missing preimage: %w" , err )
130+ }
131+ defer rows .Close ()
132+
133+ missing := map [oasisAddress ]struct {}{}
134+ for rows .Next () {
135+ var addr oasisAddress
136+ if err = rows .Scan (& addr ); err != nil {
137+ return nil , fmt .Errorf ("scanning contract missing preimage: %w" , err )
138+ }
139+ missing [addr ] = struct {}{}
140+ }
141+ return missing , nil
142+ }
143+
124144func (p * processor ) GetItems (ctx context.Context , limit uint64 ) ([]contract , error ) {
125145 // Load all nexus-verified contracts from the DB.
126146 nexusLevels , err := p .getNexusVerifiedContracts (ctx )
127147 if err != nil {
128148 return nil , fmt .Errorf ("failed to get nexus verified contracts: %w" , err )
129149 }
130150
151+ // Load contracts that are missing their address preimage.
152+ // These need to be reprocessed to insert the preimage.
153+ missingPreimage , err := p .getContractsMissingPreimage (ctx )
154+ if err != nil {
155+ return nil , fmt .Errorf ("failed to get contracts missing preimage: %w" , err )
156+ }
157+ if len (missingPreimage ) > 0 {
158+ p .logger .Info ("found verified contracts missing preimage" , "count" , len (missingPreimage ))
159+ }
160+
131161 // Query Sourcify for list of all verified contracts.
132162 sourcifyLevels , err := p .source .GetVerifiedContractAddresses (ctx , p .runtime )
133163 if err != nil {
134164 return nil , fmt .Errorf ("failed to get verified contract addresses: %w" , err )
135165 }
136166 p .logger .Debug ("got verified contract addresses" , "addresses" , sourcifyLevels )
137167
138- // Find contracts that are verified in Sourcify and not yet verified in Nexus.
168+ // Find contracts that need processing:
169+ // 1. Verified in Sourcify but not yet verified in Nexus
170+ // 2. Upgrading from partial to full verification
171+ // 3. Missing their address preimage (need to reprocess to insert it)
139172 var items []contract
140173 for ethAddr , sourcifyLevel := range sourcifyLevels {
141174 oasisAddr , err := addresses .FromEthAddress (ethAddr .Bytes ())
@@ -145,7 +178,13 @@ func (p *processor) GetItems(ctx context.Context, limit uint64) ([]contract, err
145178 }
146179
147180 nexusLevel , isKnownToNexus := nexusLevels [oasisAddress (oasisAddr )]
148- if ! isKnownToNexus || (nexusLevel == sourcify .VerificationLevelPartial && sourcifyLevel == sourcify .VerificationLevelFull ) {
181+ _ , isMissingPreimage := missingPreimage [oasisAddress (oasisAddr )]
182+
183+ needsProcessing := ! isKnownToNexus ||
184+ (nexusLevel == sourcify .VerificationLevelPartial && sourcifyLevel == sourcify .VerificationLevelFull ) ||
185+ isMissingPreimage
186+
187+ if needsProcessing {
149188 items = append (items , contract {
150189 Addr : oasisAddress (oasisAddr ),
151190 EthAddr : ethAddr ,
@@ -209,6 +248,29 @@ func (p *processor) ProcessItem(ctx context.Context, batch *storage.QueryBatch,
209248 item .VerificationLevel ,
210249 )
211250
251+ // Insert the address preimage (ETH address -> Oasis address mapping).
252+ // This is needed for the evm_contract_code analyzer to fetch bytecode.
253+ // For contracts that were never seen by the block analyzer (e.g., created
254+ // via encrypted transactions on Sapphire), this is the only way the
255+ // preimage gets inserted.
256+ batch .Queue (
257+ queries .AddressPreimageInsert ,
258+ item .Addr ,
259+ "oasis-runtime-sdk/address: secp256k1eth" ,
260+ 0 , // context_version
261+ item .EthAddr .Bytes (),
262+ )
263+
264+ // Queue the contract for bytecode analysis. This ensures contracts discovered
265+ // via Sourcify verification get their bytecode fetched, even if the block analyzer
266+ // never saw the contract (e.g., contracts only called internally by other contracts,
267+ // or contracts created via encrypted transactions on Sapphire).
268+ batch .Queue (
269+ queries .RuntimeEVMContractCodeAnalysisInsert ,
270+ p .runtime ,
271+ item .Addr ,
272+ )
273+
212274 return nil
213275}
214276
0 commit comments