@@ -14,28 +14,22 @@ import {
14
14
} from '@ethersproject/abstract-provider' ;
15
15
import { AcalaEvmTX , checkSignatureType , parseTransaction } from '@acala-network/eth-transactions' ;
16
16
import { AccessList , accessListify } from 'ethers/lib/utils' ;
17
- import { AccountId , H160 , Header } from '@polkadot/types/interfaces' ;
18
17
import { ApiPromise } from '@polkadot/api' ;
19
18
import { AsyncAction } from 'rxjs/internal/scheduler/AsyncAction' ;
20
19
import { AsyncScheduler } from 'rxjs/internal/scheduler/AsyncScheduler' ;
21
20
import { BigNumber , BigNumberish , Wallet } from 'ethers' ;
22
21
import { Deferrable , defineReadOnly , resolveProperties } from '@ethersproject/properties' ;
23
- import { EvmAccountInfo , EvmContractInfo } from '@acala-network/types/interfaces' ;
24
22
import { Formatter } from '@ethersproject/providers' ;
25
- import { FrameSystemAccountInfo } from '@polkadot/types/lookup ' ;
23
+ import { Header } from '@polkadot/types/interfaces ' ;
26
24
import { ISubmittableResult } from '@polkadot/types/types' ;
27
25
import { Logger } from '@ethersproject/logger' ;
26
+ import { ModuleEvmModuleAccountInfo } from '@polkadot/types/lookup' ;
28
27
import { Network } from '@ethersproject/networks' ;
29
28
import { Observable , ReplaySubject , Subscription , firstValueFrom , throwError } from 'rxjs' ;
30
- import { Option , decorateStorage , unwrapStorageType } from '@polkadot/types' ;
31
- import { Storage } from '@polkadot/types/metadata/decorate/types' ;
32
29
import { SubmittableExtrinsic } from '@polkadot/api/types' ;
33
- import { VersionedRegistry } from '@polkadot/api/base/types' ;
34
- import { createHeaderExtended } from '@polkadot/api-derive' ;
35
30
import { filter , first , timeout } from 'rxjs/operators' ;
36
31
import { getAddress } from '@ethersproject/address' ;
37
32
import { hexDataLength , hexValue , hexZeroPad , hexlify , isHexString , joinSignature } from '@ethersproject/bytes' ;
38
- import { isNull , u8aToHex , u8aToU8a } from '@polkadot/util' ;
39
33
import BN from 'bn.js' ;
40
34
import LRUCache from 'lru-cache' ;
41
35
@@ -44,7 +38,6 @@ import {
44
38
BLOCK_GAS_LIMIT ,
45
39
BLOCK_STORAGE_LIMIT ,
46
40
CACHE_SIZE_WARNING ,
47
- DUMMY_ADDRESS ,
48
41
DUMMY_BLOCK_NONCE ,
49
42
DUMMY_LOGS_BLOOM ,
50
43
EMPTY_HEX_STRING ,
@@ -78,6 +71,7 @@ import {
78
71
filterLogByTopics ,
79
72
getAllReceiptsAtBlock ,
80
73
getHealthResult ,
74
+ getTimestamp ,
81
75
getTransactionRequest ,
82
76
hexlifyRpcResult ,
83
77
isEvmExtrinsic ,
@@ -309,8 +303,7 @@ export abstract class BaseProvider extends AbstractProvider {
309
303
readonly localMode : boolean ;
310
304
readonly verbose : boolean ;
311
305
readonly maxBlockCacheSize : number ;
312
- readonly storages : WeakMap < VersionedRegistry < 'promise' > , Storage > = new WeakMap ( ) ;
313
- readonly storageCache : LRUCache < string , Uint8Array | null > ;
306
+ readonly queryCache : LRUCache < string , any > ;
314
307
readonly blockCache : BlockCache ;
315
308
readonly finalizedBlockHashes : MaxSizeSet ;
316
309
@@ -347,7 +340,7 @@ export abstract class BaseProvider extends AbstractProvider {
347
340
this . localMode = localMode ;
348
341
this . verbose = verbose ;
349
342
this . maxBlockCacheSize = maxBlockCacheSize ;
350
- this . storageCache = new LRUCache ( { max : storageCacheSize } ) ;
343
+ this . queryCache = new LRUCache ( { max : storageCacheSize } ) ;
351
344
this . blockCache = new BlockCache ( this . maxBlockCacheSize ) ;
352
345
this . finalizedBlockHashes = new MaxSizeSet ( this . maxBlockCacheSize ) ;
353
346
@@ -523,67 +516,6 @@ export abstract class BaseProvider extends AbstractProvider {
523
516
defineReadOnly ( this , '_api' , api ) ;
524
517
} ;
525
518
526
- queryStorage = async < T = any > (
527
- module : `${string } .${string } `,
528
- args : any [ ] ,
529
- _blockTag ?: BlockTag | Promise < BlockTag > | Eip1898BlockTag
530
- ) : Promise < T > => {
531
- const blockTag = await this . _ensureSafeModeBlockTagFinalization ( await parseBlockTag ( _blockTag ) ) ;
532
- const blockHash = await this . _getBlockHash ( blockTag ) ;
533
-
534
- const registry = await this . api . getBlockRegistry ( u8aToU8a ( blockHash ) ) ;
535
-
536
- if ( ! this . storages . get ( registry ) ) {
537
- const storage = decorateStorage (
538
- registry . registry ,
539
- registry . metadata . asLatest ,
540
- registry . metadata . version ,
541
- ) ;
542
- this . storages . set ( registry , storage ) ;
543
- }
544
-
545
- const storage = this . storages . get ( registry ) ! ;
546
-
547
- const [ section , method ] = module . split ( '.' ) ;
548
-
549
- const entry = storage [ section ] [ method ] ;
550
- const key = entry ( ...args ) ;
551
-
552
- const outputType = unwrapStorageType (
553
- registry . registry ,
554
- entry . meta . type ,
555
- entry . meta . modifier . isOptional ,
556
- ) ;
557
-
558
- const cacheKey = `${ module } -${ blockHash } -${ args . join ( ',' ) } ` ;
559
- const cached = this . storageCache . get ( cacheKey ) ;
560
-
561
- let input : Uint8Array | null = null ;
562
-
563
- if ( cached ) {
564
- input = cached ;
565
- } else {
566
- const value : any = await this . api . rpc . state . getStorage ( key , blockHash ) ;
567
-
568
- const isEmpty = isNull ( value ) ;
569
-
570
- // we convert to Uint8Array since it maps to the raw encoding, all
571
- // data will be correctly encoded (incl. numbers, excl. :code)
572
- input = isEmpty
573
- ? null
574
- : u8aToU8a ( entry . meta . modifier . isOptional ? value . toU8a ( ) : value . isSome ? value . unwrap ( ) . toU8a ( ) : null ) ;
575
-
576
- this . storageCache . set ( cacheKey , input ) ;
577
- }
578
-
579
- const result = registry . registry . createTypeUnsafe ( outputType , [ input ] , {
580
- blockHash,
581
- isPedantic : ! entry . meta . modifier . isOptional ,
582
- } ) ;
583
-
584
- return result as any as T ;
585
- } ;
586
-
587
519
get api ( ) : ApiPromise {
588
520
return this . _api ?? logger . throwError ( 'the api needs to be set' , Logger . errors . UNKNOWN_ERROR ) ;
589
521
}
@@ -672,19 +604,15 @@ export abstract class BaseProvider extends AbstractProvider {
672
604
const blockHash = header . hash . toHex ( ) ;
673
605
const blockNumber = header . number . toNumber ( ) ;
674
606
675
- const [ block , validators , now , receiptsFromSubql ] = await Promise . all ( [
607
+ const [ block , headerExtended , timestamp , receiptsFromSubql ] = await Promise . all ( [
676
608
this . api . rpc . chain . getBlock ( blockHash ) ,
677
- this . api . query . session ? this . queryStorage ( 'session.validators' , [ ] , blockHash ) : ( [ ] as any ) ,
678
- this . queryStorage ( 'timestamp.now' , [ ] , blockHash ) ,
609
+ this . api . derive . chain . getHeader ( blockHash ) ,
610
+ getTimestamp ( this . api , blockHash ) ,
679
611
this . subql ?. getAllReceiptsAtBlock ( blockHash ) ,
680
612
] ) ;
681
613
682
- const headerExtended = createHeaderExtended ( header . registry , header , validators ) ;
683
-
684
614
// blockscout need `toLowerCase`
685
- const author = headerExtended . author
686
- ? ( await this . getEvmAddress ( headerExtended . author . toString ( ) ) ) . toLowerCase ( )
687
- : DUMMY_ADDRESS ;
615
+ const author = ( await this . getEvmAddress ( headerExtended . author . toString ( ) ) ) . toLowerCase ( ) ;
688
616
689
617
let receipts : TransactionReceipt [ ] ;
690
618
if ( receiptsFromSubql ?. length ) {
@@ -709,7 +637,7 @@ export abstract class BaseProvider extends AbstractProvider {
709
637
number : blockNumber ,
710
638
stateRoot : headerExtended . stateRoot . toHex ( ) ,
711
639
transactionsRoot : headerExtended . extrinsicsRoot . toHex ( ) ,
712
- timestamp : Math . floor ( now . toNumber ( ) / 1000 ) ,
640
+ timestamp : Math . floor ( timestamp / 1000 ) ,
713
641
nonce : DUMMY_BLOCK_NONCE ,
714
642
mixHash : ZERO_BLOCK_HASH ,
715
643
difficulty : ZERO ,
@@ -750,11 +678,8 @@ export abstract class BaseProvider extends AbstractProvider {
750
678
751
679
const substrateAddress = await this . getSubstrateAddress ( address , blockHash ) ;
752
680
753
- const accountInfo = await this . queryStorage < FrameSystemAccountInfo > (
754
- 'system.account' ,
755
- [ substrateAddress ] ,
756
- blockHash
757
- ) ;
681
+ const apiAt = await this . api . at ( blockHash ) ;
682
+ const accountInfo = await apiAt . query . system . account ( substrateAddress ) ;
758
683
759
684
return nativeToEthDecimal ( accountInfo . data . free . toBigInt ( ) ) ;
760
685
} ;
@@ -779,9 +704,7 @@ export abstract class BaseProvider extends AbstractProvider {
779
704
}
780
705
781
706
const accountInfo = await this . queryAccountInfo ( addressOrName , blockTag ) ;
782
- const minedNonce = accountInfo . isNone
783
- ? 0
784
- : accountInfo . unwrap ( ) . nonce . toNumber ( ) ;
707
+ const minedNonce = accountInfo ?. nonce ?. toNumber ?.( ) ?? 0 ;
785
708
786
709
return minedNonce + pendingNonce ;
787
710
} ;
@@ -791,23 +714,14 @@ export abstract class BaseProvider extends AbstractProvider {
791
714
_blockTag ?: BlockTag | Promise < BlockTag > | Eip1898BlockTag
792
715
) : Promise < string > => {
793
716
const blockTag = await this . _ensureSafeModeBlockTagFinalization ( await parseBlockTag ( _blockTag ) ) ;
717
+ const blockHash = await this . _getBlockHash ( blockTag ) ;
794
718
795
- const [ address , blockHash ] = await Promise . all ( [
796
- addressOrName ,
797
- this . _getBlockHash ( blockTag ) ,
798
- ] ) ;
799
-
800
- const contractInfo = await this . queryContractInfo ( address , blockHash ) ;
801
-
802
- if ( contractInfo . isNone ) {
803
- return '0x' ;
804
- }
805
-
806
- const codeHash = contractInfo . unwrap ( ) . codeHash ;
807
-
808
- const api = blockHash ? await this . api . at ( blockHash ) : this . api ;
719
+ const accountInfo = await this . queryAccountInfo ( addressOrName , blockHash ) ;
720
+ const contractInfo = accountInfo ?. contractInfo . unwrapOr ( null ) ;
721
+ if ( ! contractInfo ) { return '0x' ; }
809
722
810
- const code = await api . query . evm . codes ( codeHash ) ;
723
+ const apiAt = await this . api . at ( blockHash ) ;
724
+ const code = await apiAt . query . evm . codes ( contractInfo . codeHash ) ;
811
725
812
726
return code . toHex ( ) ;
813
727
} ;
@@ -904,7 +818,8 @@ export abstract class BaseProvider extends AbstractProvider {
904
818
Promise . resolve ( position ) . then ( hexValue ) ,
905
819
] ) ;
906
820
907
- const code = await this . queryStorage ( 'evm.accountStorages' , [ address , hexZeroPad ( resolvedPosition , 32 ) ] , blockHash ) ;
821
+ const apiAt = await this . api . at ( blockHash ) ;
822
+ const code = await apiAt . query . evm . accountStorages ( address , hexZeroPad ( resolvedPosition , 32 ) ) ;
908
823
909
824
return code . toHex ( ) ;
910
825
} ;
@@ -1185,51 +1100,39 @@ export abstract class BaseProvider extends AbstractProvider {
1185
1100
} ;
1186
1101
} ;
1187
1102
1188
- getSubstrateAddress = async ( addressOrName : string , blockTag ?: BlockTag ) : Promise < string > => {
1189
- const [ address , blockHash ] = await Promise . all ( [
1190
- addressOrName ,
1191
- this . _getBlockHash ( blockTag ) ,
1192
- ] ) ;
1193
-
1194
- const substrateAccount = await this . queryStorage < Option < AccountId > > ( 'evmAccounts.accounts' , [ address ] , blockHash ) ;
1103
+ getSubstrateAddress = async ( address : string , blockTag ?: BlockTag ) : Promise < string > => {
1104
+ const blockHash = await this . _getBlockHash ( blockTag ) ;
1105
+ const apiAt = await this . api . at ( blockHash ) ;
1106
+ const substrateAccount = await apiAt . query . evmAccounts . accounts ( address ) ;
1195
1107
1196
- return substrateAccount . isEmpty ? computeDefaultSubstrateAddress ( address ) : substrateAccount . toString ( ) ;
1108
+ return substrateAccount . isEmpty
1109
+ ? computeDefaultSubstrateAddress ( address )
1110
+ : substrateAccount . toString ( ) ;
1197
1111
} ;
1198
1112
1199
1113
getEvmAddress = async ( substrateAddress : string , blockTag ?: BlockTag ) : Promise < string > => {
1200
1114
const blockHash = await this . _getBlockHash ( blockTag ) ;
1201
- const evmAddress = await this . queryStorage < Option < H160 > > ( 'evmAccounts.evmAddresses' , [ substrateAddress ] , blockHash ) ;
1115
+ const apiAt = await this . api . at ( blockHash ) ;
1116
+ const evmAddress = await apiAt . query . evmAccounts . evmAddresses ( substrateAddress ) ;
1202
1117
1203
1118
return getAddress ( evmAddress . isEmpty ? computeDefaultEvmAddress ( substrateAddress ) : evmAddress . toString ( ) ) ;
1204
1119
} ;
1205
1120
1206
1121
queryAccountInfo = async (
1207
1122
addressOrName : string | Promise < string > ,
1208
1123
_blockTag ?: BlockTag | Promise < BlockTag > | Eip1898BlockTag
1209
- ) : Promise < Option < EvmAccountInfo > > => {
1124
+ ) : Promise < ModuleEvmModuleAccountInfo | null > => {
1210
1125
const blockTag = await this . _ensureSafeModeBlockTagFinalization ( await parseBlockTag ( _blockTag ) ) ;
1211
1126
1212
1127
const [ address , blockHash ] = await Promise . all ( [
1213
1128
addressOrName ,
1214
1129
this . _getBlockHash ( blockTag ) ,
1215
1130
] ) ;
1216
1131
1217
- const accountInfo = await this . queryStorage < Option < EvmAccountInfo > > ( 'evm.accounts' , [ address ] , blockHash ) ;
1132
+ const apiAt = await this . api . at ( blockHash ) ;
1133
+ const accountInfo = await apiAt . query . evm . accounts ( address ) ;
1218
1134
1219
- return accountInfo ;
1220
- } ;
1221
-
1222
- queryContractInfo = async (
1223
- addressOrName : string | Promise < string > ,
1224
- blockTag ?: BlockTag | Promise < BlockTag >
1225
- ) : Promise < Option < EvmContractInfo > > => {
1226
- const accountInfo = await this . queryAccountInfo ( addressOrName , blockTag ) ;
1227
-
1228
- if ( accountInfo . isNone ) {
1229
- return this . api . createType < Option < EvmContractInfo > > ( 'Option<EvmContractInfo>' , null ) ;
1230
- }
1231
-
1232
- return accountInfo . unwrap ( ) . contractInfo ;
1135
+ return accountInfo . unwrapOr ( null ) ;
1233
1136
} ;
1234
1137
1235
1138
_getSubstrateGasParams = ( ethTx : Partial < AcalaEvmTX > ) : {
@@ -1287,7 +1190,7 @@ export abstract class BaseProvider extends AbstractProvider {
1287
1190
storageLimit : storageLimit . toBigInt ( ) ,
1288
1191
tip : 0n ,
1289
1192
} ;
1290
- } catch ( error ) {
1193
+ } catch {
1291
1194
// v2
1292
1195
v2 = true ;
1293
1196
@@ -1471,7 +1374,8 @@ export abstract class BaseProvider extends AbstractProvider {
1471
1374
result . blockNumber = startBlock ;
1472
1375
result . blockHash = startBlockHash ;
1473
1376
1474
- result . timestamp = Math . floor ( ( await this . queryStorage ( 'timestamp.now' , [ ] , result . blockHash ) ) . toNumber ( ) / 1000 ) ;
1377
+ const timestamp = await getTimestamp ( this . api , result . blockHash ) ;
1378
+ result . timestamp = Math . floor ( timestamp / 1000 ) ;
1475
1379
1476
1380
result . wait = async ( confirms ?: number , timeoutMs ?: number ) => {
1477
1381
if ( confirms === null || confirms === undefined ) {
@@ -1561,26 +1465,23 @@ export abstract class BaseProvider extends AbstractProvider {
1561
1465
}
1562
1466
1563
1467
const isFinalized = blockNumber . lte ( await this . finalizedBlockNumber ) ;
1564
- const cacheKey = `blockHash-${ blockNumber . toString ( ) } ` ;
1468
+ const cacheKey = `blockHash-${ blockNumber . toHexString ( ) } ` ;
1565
1469
1566
1470
if ( isFinalized ) {
1567
- const cached = this . storageCache . get ( cacheKey ) ;
1471
+ const cached = this . queryCache . get ( cacheKey ) ;
1568
1472
if ( cached ) {
1569
- return u8aToHex ( cached ) ;
1473
+ return cached ;
1570
1474
}
1571
1475
}
1572
1476
1573
- const _blockHash = await this . api . rpc . chain . getBlockHash ( blockNumber . toBigInt ( ) ) ;
1574
-
1575
- if ( _blockHash . isEmpty ) {
1576
- //@ts -ignore
1577
- return logger . throwError ( 'header not found' , PROVIDER_ERRORS . HEADER_NOT_FOUND , { blockNumber } ) ;
1578
- }
1579
-
1580
- const blockHash = _blockHash . toHex ( ) ;
1477
+ // TODO: test header not found should throw
1478
+ const blockHash = ( await this . api . rpc . chain . getBlockHash ( blockNumber . toBigInt ( ) ) ) . toHex ( ) ;
1479
+ // if (_blockHash.isEmpty) {
1480
+ // return logger.throwError('header not found', Logger.errors.CALL_EXCEPTION, { blockNumber });
1481
+ // }
1581
1482
1582
1483
if ( isFinalized ) {
1583
- this . storageCache . set ( cacheKey , _blockHash . toU8a ( ) ) ;
1484
+ this . queryCache . set ( cacheKey , blockHash ) ;
1584
1485
}
1585
1486
1586
1487
return blockHash ;
0 commit comments