Compare commits

...

217 Commits

Author SHA1 Message Date
semantic-release-bot 8993ba67d4 chore(release): 0.1.0-develop.64 [skip ci]
# [0.1.0-develop.64](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.63...v0.1.0-develop.64) (2023-10-29)

### Bug Fixes

* wrap sync in try/catch and unlock mutex in a finally ([0963794](09637948e7))
2023-10-29 01:59:29 +00:00
Derrick Hammer fd3d5facac
Merge remote-tracking branch 'origin/develop' into develop 2023-10-28 21:58:38 -04:00
Derrick Hammer 09637948e7
fix: wrap sync in try/catch and unlock mutex in a finally 2023-10-28 21:57:59 -04:00
semantic-release-bot 780b2e4e4f chore(release): 0.1.0-develop.63 [skip ci]
# [0.1.0-develop.63](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.62...v0.1.0-develop.63) (2023-10-24)

### Bug Fixes

* args should not be var args ([32bf0a4](32bf0a42e2))
2023-10-24 00:46:10 +00:00
Derrick Hammer 772d7eb21e
Merge remote-tracking branch 'origin/develop' into develop 2023-10-23 20:45:10 -04:00
Derrick Hammer 32bf0a42e2
fix: args should not be var args 2023-10-23 20:45:07 -04:00
semantic-release-bot 89749d9a8f chore(release): 0.1.0-develop.62 [skip ci]
# [0.1.0-develop.62](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.61...v0.1.0-develop.62) (2023-10-24)

### Features

* add basic non-verifying eth_getLogs support ([b405ee2](b405ee2581))
2023-10-24 00:24:21 +00:00
Derrick Hammer 833a007a1f
Merge remote-tracking branch 'origin/develop' into develop 2023-10-23 20:23:28 -04:00
Derrick Hammer b405ee2581
feat: add basic non-verifying eth_getLogs support 2023-10-23 20:23:23 -04:00
semantic-release-bot e6b215be13 chore(release): 0.1.0-develop.61 [skip ci]
# [0.1.0-develop.61](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.60...v0.1.0-develop.61) (2023-09-16)

### Bug Fixes

* need to call our boot method ([b3f8dba](b3f8dba243))
2023-09-16 16:13:53 +00:00
Derrick Hammer 77251407c3
Merge remote-tracking branch 'origin/develop' into develop 2023-09-16 12:12:35 -04:00
Derrick Hammer b3f8dba243
fix: need to call our boot method 2023-09-16 12:12:30 -04:00
semantic-release-bot 919cb0b1df chore(release): 0.1.0-develop.60 [skip ci]
# [0.1.0-develop.60](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.59...v0.1.0-develop.60) (2023-09-16)

### Features

* add method to reset the client ([87d8be6](87d8be615e))
2023-09-16 15:52:27 +00:00
Derrick Hammer 3d4d24e90b
Merge remote-tracking branch 'origin/develop' into develop 2023-09-16 11:51:36 -04:00
Derrick Hammer 87d8be615e
feat: add method to reset the client 2023-09-16 11:51:30 -04:00
semantic-release-bot bf35bdd954 chore(release): 0.1.0-develop.59 [skip ci]
# [0.1.0-develop.59](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.58...v0.1.0-develop.59) (2023-09-16)

### Bug Fixes

* if syncing manual, set latest period to value of getCurrentPeriod() before optimistic update ([e742ec8](e742ec8b64))
* send a dummy update event for chain progress ([417da9f](417da9f893))
2023-09-16 15:46:41 +00:00
Derrick Hammer 5a5c320a25
Merge remote-tracking branch 'origin/develop' into develop 2023-09-16 11:45:51 -04:00
Derrick Hammer 417da9f893
fix: send a dummy update event for chain progress 2023-09-16 11:45:45 -04:00
Derrick Hammer e742ec8b64
fix: if syncing manual, set latest period to value of getCurrentPeriod() before optimistic update 2023-09-16 11:42:24 -04:00
semantic-release-bot 57d172b8f8 chore(release): 0.1.0-develop.58 [skip ci]
# [0.1.0-develop.58](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.57...v0.1.0-develop.58) (2023-09-16)

### Bug Fixes

* bad import ([5687e13](5687e13f9d))
2023-09-16 15:27:10 +00:00
Derrick Hammer 4490d386b3
Merge remote-tracking branch 'origin/develop' into develop 2023-09-16 11:26:12 -04:00
Derrick Hammer 5687e13f9d
fix: bad import 2023-09-16 11:26:08 -04:00
semantic-release-bot 5d1a051714 chore(release): 0.1.0-develop.57 [skip ci]
# [0.1.0-develop.57](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.56...v0.1.0-develop.57) (2023-09-16)

### Bug Fixes

* need to init bls in manual ([d1e88ce](d1e88ce87f))
2023-09-16 15:21:15 +00:00
Derrick Hammer e7083618c6
Merge remote-tracking branch 'origin/develop' into develop 2023-09-16 11:20:23 -04:00
Derrick Hammer d1e88ce87f
fix: need to init bls in manual 2023-09-16 11:20:14 -04:00
semantic-release-bot 57965ef9cd chore(release): 0.1.0-develop.56 [skip ci]
# [0.1.0-develop.56](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.55...v0.1.0-develop.56) (2023-09-16)

### Bug Fixes

* if we are within 1 period of getCurrentPeriod manually call sync actions, otherwise call parent sync ([6500219](65002190b8))
2023-09-16 15:13:32 +00:00
Derrick Hammer dc35711a75
Merge remote-tracking branch 'origin/develop' into develop 2023-09-16 11:12:22 -04:00
Derrick Hammer 65002190b8
fix: if we are within 1 period of getCurrentPeriod manually call sync actions, otherwise call parent sync 2023-09-16 11:12:18 -04:00
semantic-release-bot 947e5d15c8 chore(release): 0.1.0-develop.55 [skip ci]
# [0.1.0-develop.55](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.54...v0.1.0-develop.55) (2023-09-16)

### Bug Fixes

* as a properly synced node may never hit the computed period at getCurrentPeriod... need to manually emit synced and call getLatestExecution ([19c59eb](19c59eb189))
2023-09-16 15:05:05 +00:00
Derrick Hammer e6ad5a13ed
Merge remote-tracking branch 'origin/develop' into develop 2023-09-16 11:04:15 -04:00
Derrick Hammer 19c59eb189
fix: as a properly synced node may never hit the computed period at getCurrentPeriod... need to manually emit synced and call getLatestExecution 2023-09-16 11:04:03 -04:00
semantic-release-bot 239d7c236b chore(release): 0.1.0-develop.54 [skip ci]
# [0.1.0-develop.54](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.53...v0.1.0-develop.54) (2023-09-16)

### Bug Fixes

* if startPeriod is greater than genesisPeriod, try to use latestCommittee falling back to genesisCommittee ([ec84027](ec8402714f))
2023-09-16 04:40:47 +00:00
Derrick Hammer 2de960ce28
Merge remote-tracking branch 'origin/develop' into develop 2023-09-16 00:39:42 -04:00
Derrick Hammer ec8402714f
fix: if startPeriod is greater than genesisPeriod, try to use latestCommittee falling back to genesisCommittee 2023-09-16 00:39:38 -04:00
semantic-release-bot fc23b3cdba chore(release): 0.1.0-develop.53 [skip ci]
# [0.1.0-develop.53](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.52...v0.1.0-develop.53) (2023-09-16)

### Bug Fixes

* bad import ([b9b8b26](b9b8b26ea4))
2023-09-16 02:58:57 +00:00
Derrick Hammer 908d508c05
Merge remote-tracking branch 'origin/develop' into develop 2023-09-15 22:58:11 -04:00
Derrick Hammer b9b8b26ea4
fix: bad import 2023-09-15 22:58:05 -04:00
semantic-release-bot 9bf3aaf07b chore(release): 0.1.0-develop.52 [skip ci]
# [0.1.0-develop.52](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.51...v0.1.0-develop.52) (2023-09-16)

### Features

* add syncFromCheckpoint method ([ccaca65](ccaca65a90))
2023-09-16 02:44:50 +00:00
Derrick Hammer 746e76ecfc
Merge remote-tracking branch 'origin/develop' into develop 2023-09-15 22:43:53 -04:00
Derrick Hammer ccaca65a90
feat: add syncFromCheckpoint method 2023-09-15 22:43:46 -04:00
semantic-release-bot 8470d578a5 chore(release): 0.1.0-develop.51 [skip ci]
# [0.1.0-develop.51](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.50...v0.1.0-develop.51) (2023-09-16)

### Bug Fixes

* IStore should extend EventEmitter ([9f00d8f](9f00d8fec8))
2023-09-16 02:11:37 +00:00
Derrick Hammer 178df36f93
Merge remote-tracking branch 'origin/develop' into develop 2023-09-15 22:10:44 -04:00
Derrick Hammer 9f00d8fec8
fix: IStore should extend EventEmitter 2023-09-15 22:10:36 -04:00
semantic-release-bot 2d4f911249 chore(release): 0.1.0-develop.50 [skip ci]
# [0.1.0-develop.50](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.49...v0.1.0-develop.50) (2023-09-16)

### Features

* have Store extend EventEmitter so that it can emit set on adding an update and pass the serialized data ([295aed0](295aed0845))
2023-09-16 02:07:44 +00:00
Derrick Hammer 97510bd892
Merge remote-tracking branch 'origin/develop' into develop 2023-09-15 22:06:45 -04:00
Derrick Hammer 295aed0845
feat: have Store extend EventEmitter so that it can emit set on adding an update and pass the serialized data 2023-09-15 22:06:40 -04:00
semantic-release-bot 000d03e8a9 chore(release): 0.1.0-develop.49 [skip ci]
# [0.1.0-develop.49](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.48...v0.1.0-develop.49) (2023-07-25)

### Bug Fixes

* add try/catch with mutex release on optimisticUpdateCallback ([7075966](7075966227))
2023-07-25 00:08:22 +00:00
Derrick Hammer 7075966227
fix: add try/catch with mutex release on optimisticUpdateCallback 2023-07-24 20:07:04 -04:00
semantic-release-bot 72a4975ba9 chore(release): 0.1.0-develop.48 [skip ci]
# [0.1.0-develop.48](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.47...v0.1.0-develop.48) (2023-07-24)

### Bug Fixes

* don't release lock when we have cached optimistic update data, as we never locked it ([d3664c8](d3664c8d23))
2023-07-24 15:13:57 +00:00
Derrick Hammer cd468b335c
Merge remote-tracking branch 'origin/develop' into develop 2023-07-24 11:13:05 -04:00
Derrick Hammer d3664c8d23
fix: don't release lock when we have cached optimistic update data, as we never locked it 2023-07-24 11:12:52 -04:00
semantic-release-bot c26d67f57f chore(release): 0.1.0-develop.47 [skip ci]
# [0.1.0-develop.47](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.46...v0.1.0-develop.47) (2023-07-24)

### Bug Fixes

* incorporate upstream https://github.com/lightclients/patronum/pull/23 ([8b7c85d](8b7c85dd61))
2023-07-24 14:45:36 +00:00
Derrick Hammer d6f327385f
Merge remote-tracking branch 'origin/develop' into develop 2023-07-24 10:44:39 -04:00
Derrick Hammer 8b7c85dd61
fix: incorporate upstream https://github.com/lightclients/patronum/pull/23
reverts 91144cb5a2
2023-07-24 10:44:25 -04:00
semantic-release-bot c9d3b0d2e0 chore(release): 0.1.0-develop.46 [skip ci]
# [0.1.0-develop.46](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.45...v0.1.0-develop.46) (2023-07-23)

### Features

* add synced event ([0321136](0321136ac0))
2023-07-23 16:02:09 +00:00
Derrick Hammer a7f556f998
Merge remote-tracking branch 'origin/develop' into develop 2023-07-23 12:01:18 -04:00
Derrick Hammer 0321136ac0
feat: add synced event 2023-07-23 12:01:10 -04:00
semantic-release-bot 1d391cca89 chore(release): 0.1.0-develop.45 [skip ci]
# [0.1.0-develop.45](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.44...v0.1.0-develop.45) (2023-07-23)

### Bug Fixes

* change argument to be the current update, not the 0 index ([87e7533](87e7533dcf))
2023-07-23 14:19:29 +00:00
Derrick Hammer db18efb245
Merge remote-tracking branch 'origin/develop' into develop 2023-07-23 10:18:35 -04:00
semantic-release-bot f0415992a5 chore(release): 0.1.0-develop.44 [skip ci]
# [0.1.0-develop.44](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.43...v0.1.0-develop.44) (2023-07-23)
2023-07-23 14:18:19 +00:00
Derrick Hammer 87e7533dcf
fix: change argument to be the current update, not the 0 index 2023-07-23 10:18:16 -04:00
Derrick Hammer 259c64bcea
Merge remote-tracking branch 'origin/develop' into develop 2023-07-23 10:17:11 -04:00
Derrick Hammer 02412ba934
refactor: change update event to just pass currently processed event and the total number 2023-07-23 10:17:08 -04:00
semantic-release-bot ed3cb23388 chore(release): 0.1.0-develop.43 [skip ci]
# [0.1.0-develop.43](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.42...v0.1.0-develop.43) (2023-07-23)

### Features

* use event emitter and emit "update" on every light client update processed ([232af83](232af830c9))
2023-07-23 14:07:58 +00:00
Derrick Hammer 432d4937a1
Merge remote-tracking branch 'origin/develop' into develop
# Conflicts:
#	npm-shrinkwrap.json
2023-07-23 10:06:39 -04:00
Derrick Hammer 232af830c9
feat: use event emitter and emit "update" on every light client update processed 2023-07-23 10:06:18 -04:00
semantic-release-bot f5680f6230 chore(release): 0.1.0-develop.42 [skip ci]
# [0.1.0-develop.42](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.41...v0.1.0-develop.42) (2023-07-15)
2023-07-15 04:22:33 +00:00
Derrick Hammer 5197131b77
Merge remote-tracking branch 'origin/develop' into develop 2023-07-15 00:21:30 -04:00
Derrick Hammer 11367b9803
refactor: add block cron to node client, but ensure it only runs on boot 2023-07-15 00:21:24 -04:00
Derrick Hammer fbfb9c1e06
refactor: remove block check from isSynced 2023-07-15 00:18:15 -04:00
semantic-release-bot f44be464c2 chore(release): 0.1.0-develop.41 [skip ci]
# [0.1.0-develop.41](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.40...v0.1.0-develop.41) (2023-07-14)

### Features

* add loggerInfo and loggerErr callbacks to client options ([a901ee7](a901ee76f4))
2023-07-14 15:19:05 +00:00
Derrick Hammer e49de4e907
Merge remote-tracking branch 'origin/develop' into develop 2023-07-14 11:18:12 -04:00
Derrick Hammer 45b3e884f9
fix; add syncDelay to client factory 2023-07-14 11:18:05 -04:00
Derrick Hammer a901ee76f4
feat: add loggerInfo and loggerErr callbacks to client options 2023-07-14 11:16:38 -04:00
semantic-release-bot 1895495520 chore(release): 0.1.0-develop.40 [skip ci]
# [0.1.0-develop.40](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.39...v0.1.0-develop.40) (2023-07-14)

### Bug Fixes

* add a sync delay option so that the bls verification does not hog cpu ([824dcd9](824dcd9633))
2023-07-14 13:23:17 +00:00
Derrick Hammer 8582db4eb3
Merge remote-tracking branch 'origin/develop' into develop 2023-07-14 09:22:09 -04:00
Derrick Hammer 824dcd9633
fix: add a sync delay option so that the bls verification does not hog cpu 2023-07-14 09:21:52 -04:00
semantic-release-bot b1c33bb81d chore(release): 0.1.0-develop.39 [skip ci]
# [0.1.0-develop.39](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.38...v0.1.0-develop.39) (2023-07-13)

### Bug Fixes

* compare code against codehash ([dc4c6b3](dc4c6b3f36))
2023-07-13 17:18:26 +00:00
Derrick Hammer 8aa7c11f09
Merge remote-tracking branch 'origin/develop' into develop 2023-07-13 13:17:33 -04:00
Derrick Hammer dc4c6b3f36
fix: compare code against codehash 2023-07-13 13:17:27 -04:00
semantic-release-bot 1b0bf2944c chore(release): 0.1.0-develop.38 [skip ci]
# [0.1.0-develop.38](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.37...v0.1.0-develop.38) (2023-07-13)

### Bug Fixes

* add map to return data property ([3e27281](3e27281a35))
2023-07-13 16:52:34 +00:00
Derrick Hammer 39b1dac32a
Merge remote-tracking branch 'origin/develop' into develop 2023-07-13 12:51:39 -04:00
Derrick Hammer 3e27281a35
fix: add map to return data property 2023-07-13 12:51:34 -04:00
semantic-release-bot 42d167d575 chore(release): 0.1.0-develop.37 [skip ci]
# [0.1.0-develop.37](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.36...v0.1.0-develop.37) (2023-07-13)

### Bug Fixes

* parse from u, not u.data ([8677bc1](8677bc1294))
2023-07-13 16:46:48 +00:00
Derrick Hammer 5e426327ff
Merge remote-tracking branch 'origin/develop' into develop 2023-07-13 12:45:53 -04:00
Derrick Hammer 8677bc1294
fix: parse from u, not u.data 2023-07-13 12:45:49 -04:00
semantic-release-bot f76fc9b9e8 chore(release): 0.1.0-develop.36 [skip ci]
# [0.1.0-develop.36](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.35...v0.1.0-develop.36) (2023-07-13)

### Bug Fixes

* need to use concat not push ([b87017e](b87017eb67))
* Revert "fix: create fixSerializedUint8Array helper method to deal with weird quirk of ssz serialize" ([6ef18db](6ef18dbc05))
* temporarily disable block hash check as it is bugged ([91144cb](91144cb5a2))
* use byteArrayEquals ([157811b](157811b234))
2023-07-13 16:27:45 +00:00
Derrick Hammer 91144cb5a2
fix: temporarily disable block hash check as it is bugged 2023-07-13 12:26:41 -04:00
Derrick Hammer 157811b234
fix: use byteArrayEquals 2023-07-13 12:25:21 -04:00
Derrick Hammer b87017eb67
fix: need to use concat not push 2023-07-13 12:23:33 -04:00
Derrick Hammer 6ef18dbc05
fix: Revert "fix: create fixSerializedUint8Array helper method to deal with weird quirk of ssz serialize"
This reverts commit d8430b4a11.
2023-07-13 10:40:25 -04:00
semantic-release-bot 20b6d56c23 chore(release): 0.1.0-develop.35 [skip ci]
# [0.1.0-develop.35](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.34...v0.1.0-develop.35) (2023-07-13)

### Bug Fixes

* need to disable useClones in node cache ([07845bf](07845bf4d0))
2023-07-13 12:28:06 +00:00
Derrick Hammer 2540970887
Merge remote-tracking branch 'origin/develop' into develop 2023-07-13 08:27:05 -04:00
Derrick Hammer 07845bf4d0
fix: need to disable useClones in node cache 2023-07-13 08:26:58 -04:00
semantic-release-bot 5f5c665aed chore(release): 0.1.0-develop.34 [skip ci]
# [0.1.0-develop.34](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.33...v0.1.0-develop.34) (2023-07-13)

### Bug Fixes

* create fixSerializedUint8Array helper method to deal with weird quirk of ssz serialize ([d8430b4](d8430b4a11))
2023-07-13 12:09:59 +00:00
Derrick Hammer cbc652ccb1
Merge remote-tracking branch 'origin/develop' into develop 2023-07-13 08:09:06 -04:00
Derrick Hammer d8430b4a11
fix: create fixSerializedUint8Array helper method to deal with weird quirk of ssz serialize 2023-07-13 08:09:00 -04:00
semantic-release-bot 3bf72603bb chore(release): 0.1.0-develop.33 [skip ci]
# [0.1.0-develop.33](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.32...v0.1.0-develop.33) (2023-07-13)
2023-07-13 11:12:58 +00:00
Derrick Hammer 75ed669eb7
Merge remote-tracking branch 'origin/develop' into develop 2023-07-13 07:11:55 -04:00
Derrick Hammer cfa1462505
refactor: handle case where returned items are less than the total requested and loop until we have them all 2023-07-13 07:10:48 -04:00
semantic-release-bot d1a133d859 chore(release): 0.1.0-develop.32 [skip ci]
# [0.1.0-develop.32](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.31...v0.1.0-develop.32) (2023-07-13)

### Features

* add getCurrentBlock and getLastBlock methods ([661e146](661e146636))
2023-07-13 08:36:38 +00:00
Derrick Hammer 6eaf874e44
Merge remote-tracking branch 'origin/develop' into develop 2023-07-13 04:35:37 -04:00
Derrick Hammer e567d5017d
refactor: call getLatestExecution in sync and add an arg to getLatestExecution to skip syncing 2023-07-13 04:35:29 -04:00
Derrick Hammer f68688ab61
refactor: have isSynced check the period and the block 2023-07-13 04:32:18 -04:00
Derrick Hammer 661e146636
feat: add getCurrentBlock and getLastBlock methods 2023-07-13 04:31:55 -04:00
semantic-release-bot 253a677695 chore(release): 0.1.0-develop.31 [skip ci]
# [0.1.0-develop.31](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.30...v0.1.0-develop.31) (2023-07-13)
2023-07-13 08:06:29 +00:00
Derrick Hammer 256f29b692
Merge remote-tracking branch 'origin/develop' into develop 2023-07-13 04:05:38 -04:00
Derrick Hammer 93ab07c5c3
refactor: make getLatestExecution public 2023-07-13 04:05:34 -04:00
semantic-release-bot f767ed6bb4 chore(release): 0.1.0-develop.30 [skip ci]
# [0.1.0-develop.30](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.29...v0.1.0-develop.30) (2023-07-13)
2023-07-13 08:02:04 +00:00
Derrick Hammer 2281fa8f35
Merge remote-tracking branch 'origin/develop' into develop 2023-07-13 04:00:48 -04:00
Derrick Hammer 391a4f968a
refactor: if we have a _latestOptimisticUpdate, check the estimated current block against the block we have, and return it as cached data if we don't need to fetch again. Also use a mutex to prevent race conditions 2023-07-13 04:00:42 -04:00
Derrick Hammer 36f9f4c910
tidy: unneeded var 2023-07-13 03:47:44 -04:00
Derrick Hammer c5a2dc86e1
refactor: don't run automatic optimistic updates 2023-07-13 03:35:33 -04:00
semantic-release-bot d9ad98f694 chore(release): 0.1.0-develop.29 [skip ci]
# [0.1.0-develop.29](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.28...v0.1.0-develop.29) (2023-07-13)
2023-07-13 07:22:26 +00:00
Derrick Hammer 232f5ba730
Merge remote-tracking branch 'origin/develop' into develop 2023-07-13 03:21:34 -04:00
Derrick Hammer 11791ff08b
refactor: split subscribe into syncToLatestBlock 2023-07-13 03:18:05 -04:00
Derrick Hammer 4836ddb32e
style: reformat 2023-07-13 03:14:06 -04:00
Derrick Hammer b3e5607132
refactor: store optimistic update back into _latestOptimisticUpdate with a getter. 2023-07-13 03:13:22 -04:00
Derrick Hammer a7786fa21c
style: fix typos 2023-07-13 03:12:49 -04:00
semantic-release-bot 87e85b2387 chore(release): 0.1.0-develop.28 [skip ci]
# [0.1.0-develop.28](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.27...v0.1.0-develop.28) (2023-07-13)

### Bug Fixes

* add optimisticUpdateCallback to client factory ([c3b47e6](c3b47e67e7))
* add optimisticUpdateCallback to options ([464fb21](464fb21095))
* pass client to prover after creating client in factory. don't try to parse thr messages ([481757e](481757e019))
* simplify logic and use LightClientUpdate.fromJson ([17cb002](17cb00231c))
* use _client not client ([76e22fa](76e22fa342))
2023-07-13 06:55:11 +00:00
Derrick Hammer c3b47e67e7
fix: add optimisticUpdateCallback to client factory 2023-07-13 02:53:23 -04:00
Derrick Hammer 977d33b768
refactor: make optimisticUpdateCallback a dedicated type 2023-07-13 02:53:00 -04:00
Derrick Hammer 4b9aca2086
Merge remote-tracking branch 'origin/develop' into develop 2023-07-13 02:43:34 -04:00
Derrick Hammer 464fb21095
fix: add optimisticUpdateCallback to options 2023-07-13 02:33:07 -04:00
Derrick Hammer 4be6c339c7
chore: cleanup imports 2023-07-13 02:32:46 -04:00
Derrick Hammer 51d6d23942
refactor: getLatestExecution needs to actually call optimistic update, but add a callback in the client options to avoid creating a subclass 2023-07-13 02:25:05 -04:00
Derrick Hammer 5aa37d4a61
refactor: don't use un-needed for loop 2023-07-13 01:46:45 -04:00
Derrick Hammer 17cb00231c
fix: simplify logic and use LightClientUpdate.fromJson 2023-07-13 01:45:43 -04:00
Derrick Hammer 76e22fa342
fix: use _client not client 2023-07-13 01:44:26 -04:00
Derrick Hammer 481757e019
fix: pass client to prover after creating client in factory. don't try to parse thr messages 2023-07-13 01:44:25 -04:00
semantic-release-bot 03fe02cd09 chore(release): 0.1.0-develop.27 [skip ci]
# [0.1.0-develop.27](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.26...v0.1.0-develop.27) (2023-07-12)

### Bug Fixes

* fix import ([baa9562](baa9562749))
2023-07-12 22:01:26 +00:00
Derrick Hammer 816bd93e80
Merge remote-tracking branch 'origin/develop' into develop 2023-07-12 18:00:11 -04:00
Derrick Hammer baa9562749
fix: fix import 2023-07-12 17:59:56 -04:00
semantic-release-bot b8028c70c1 chore(release): 0.1.0-develop.26 [skip ci]
# [0.1.0-develop.26](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.25...v0.1.0-develop.26) (2023-07-12)
2023-07-12 21:45:29 +00:00
Derrick Hammer 835669a0a0
Merge remote-tracking branch 'origin/develop' into develop 2023-07-12 17:44:28 -04:00
Derrick Hammer 6408098050
refactor: heavily simplify and consolidate implementations to just use light sync updates and not the optimistic_update endpoint, and use a generic callback interface 2023-07-12 17:40:59 -04:00
semantic-release-bot 07569eaa04 chore(release): 0.1.0-develop.25 [skip ci]
# [0.1.0-develop.25](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.24...v0.1.0-develop.25) (2023-07-12)
2023-07-12 06:10:33 +00:00
Derrick Hammer cc6f53e6e8
Merge remote-tracking branch 'origin/develop' into develop 2023-07-12 02:09:42 -04:00
Derrick Hammer 30c7caace7
refactor: store latest optimistic update in the node client class to be referenced 2023-07-12 02:09:35 -04:00
semantic-release-bot 7f2db6f381 chore(release): 0.1.0-develop.24 [skip ci]
# [0.1.0-develop.24](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.23...v0.1.0-develop.24) (2023-07-11)

### Bug Fixes

* syncFromGenesis was a no-op ([822b0b4](822b0b46b6))
2023-07-11 20:55:07 +00:00
Derrick Hammer 822b0b46b6
fix: syncFromGenesis was a no-op 2023-07-11 16:54:13 -04:00
semantic-release-bot ebfd606a9d chore(release): 0.1.0-develop.23 [skip ci]
# [0.1.0-develop.23](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.22...v0.1.0-develop.23) (2023-07-11)

### Reverts

* Revert "fix: ensure @ethereumjs/util matches the version required by @ethereumjs/evm" ([bad87ac](bad87ac7e1))
2023-07-11 12:49:48 +00:00
Derrick Hammer 4066193846
refactor: Revert "refactor: downgrade ethereum libraries due to bundling issues"
This reverts commit 23d54062
2023-07-11 08:48:52 -04:00
Derrick Hammer bad87ac7e1
Revert "fix: ensure @ethereumjs/util matches the version required by @ethereumjs/evm"
This reverts commit 0949e8d427.
2023-07-11 08:47:35 -04:00
semantic-release-bot cfcbcb14ef chore(release): 0.1.0-develop.22 [skip ci]
# [0.1.0-develop.22](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.21...v0.1.0-develop.22) (2023-07-11)

### Bug Fixes

* ensure @ethereumjs/util matches the version required by @ethereumjs/evm ([0949e8d](0949e8d427))
2023-07-11 12:34:27 +00:00
Derrick Hammer 0949e8d427
fix: ensure @ethereumjs/util matches the version required by @ethereumjs/evm 2023-07-11 08:33:24 -04:00
Derrick Hammer 23d54062af
refactor: downgrade ethereum libraries due to bundling issues 2023-07-11 08:24:59 -04:00
semantic-release-bot 4e74fd7e8a chore(release): 0.1.0-develop.21 [skip ci]
# [0.1.0-develop.21](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.20...v0.1.0-develop.21) (2023-07-11)

### Bug Fixes

* @noble/curves import ([5c8394a](5c8394af2d))
2023-07-11 08:38:24 +00:00
Derrick Hammer e229c6246b
Merge remote-tracking branch 'origin/develop' into develop 2023-07-11 04:37:33 -04:00
Derrick Hammer 4f45d0ac24
chore: cleanup imports 2023-07-11 04:37:27 -04:00
Derrick Hammer 5c8394af2d
fix: @noble/curves import 2023-07-11 04:36:56 -04:00
semantic-release-bot 3cb2d95460 chore(release): 0.1.0-develop.20 [skip ci]
# [0.1.0-develop.20](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.19...v0.1.0-develop.20) (2023-07-11)
2023-07-11 08:28:13 +00:00
Derrick Hammer 3e9c3c4b7a
Merge remote-tracking branch 'origin/develop' into develop 2023-07-11 04:27:15 -04:00
Derrick Hammer 2a27a16c25
refactor: create the IClientVerifyingProvider child interface and add rpcCall to the client Client instead of exposing the provider in a getter 2023-07-11 04:27:11 -04:00
semantic-release-bot 14f58027bd chore(release): 0.1.0-develop.19 [skip ci]
# [0.1.0-develop.19](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.18...v0.1.0-develop.19) (2023-07-11)

### Features

* add getter for provider ([b85e177](b85e1779ee))
2023-07-11 08:16:35 +00:00
Derrick Hammer 5dd99f24e9
Merge remote-tracking branch 'origin/develop' into develop 2023-07-11 04:15:46 -04:00
Derrick Hammer b85e1779ee
feat: add getter for provider 2023-07-11 04:15:35 -04:00
semantic-release-bot 2f391770fc chore(release): 0.1.0-develop.18 [skip ci]
# [0.1.0-develop.18](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.17...v0.1.0-develop.18) (2023-07-11)

### Bug Fixes

* update ProverRequestCallback type to return a promise ([0884030](08840308f8))
2023-07-11 08:14:58 +00:00
Derrick Hammer 9ef95b339e
Merge remote-tracking branch 'origin/develop' into develop 2023-07-11 04:13:51 -04:00
Derrick Hammer 08840308f8
fix: update ProverRequestCallback type to return a promise 2023-07-11 04:13:44 -04:00
semantic-release-bot 75b23c225c chore(release): 0.1.0-develop.17 [skip ci]
# [0.1.0-develop.17](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.16...v0.1.0-develop.17) (2023-07-11)

### Bug Fixes

* beacon url is not used on the client side ([f353b3e](f353b3e102))
2023-07-11 08:10:00 +00:00
Derrick Hammer 2a2bd1d8cc
Merge remote-tracking branch 'origin/develop' into develop 2023-07-11 04:08:50 -04:00
Derrick Hammer f353b3e102
fix: beacon url is not used on the client side 2023-07-11 04:08:46 -04:00
semantic-release-bot d5e407a2cd chore(release): 0.1.0-develop.16 [skip ci]
# [0.1.0-develop.16](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.15...v0.1.0-develop.16) (2023-07-11)

### Bug Fixes

* fix reference to isValidLightClientHeader ([0f8746d](0f8746dac2))
2023-07-11 07:44:17 +00:00
Derrick Hammer 8244f766ae
Merge remote-tracking branch 'origin/develop' into develop 2023-07-11 03:43:19 -04:00
Derrick Hammer 0f8746dac2
fix: fix reference to isValidLightClientHeader 2023-07-11 03:43:12 -04:00
semantic-release-bot 26e29924ce chore(release): 0.1.0-develop.15 [skip ci]
# [0.1.0-develop.15](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.14...v0.1.0-develop.15) (2023-07-11)

### Bug Fixes

* implement isValidLightClientHeader ([6f07421](6f07421fe8))
2023-07-11 07:27:42 +00:00
Derrick Hammer 7932fbbf12
Merge remote-tracking branch 'origin/develop' into develop 2023-07-11 03:26:48 -04:00
Derrick Hammer c90c3db973
chore: update LICENSE 2023-07-11 03:26:40 -04:00
Derrick Hammer 6f07421fe8
fix: implement isValidLightClientHeader 2023-07-11 03:24:38 -04:00
semantic-release-bot 23d0f91eac chore(release): 0.1.0-develop.14 [skip ci]
# [0.1.0-develop.14](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.13...v0.1.0-develop.14) (2023-07-11)

### Bug Fixes

* further chainConfig fixes ([8b11911](8b1191165a))
2023-07-11 07:17:38 +00:00
Derrick Hammer e197dea9a5
Merge remote-tracking branch 'origin/develop' into develop 2023-07-11 03:16:45 -04:00
Derrick Hammer 8b1191165a
fix: further chainConfig fixes 2023-07-11 03:16:39 -04:00
semantic-release-bot 253be43db6 chore(release): 0.1.0-develop.13 [skip ci]
# [0.1.0-develop.13](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.12...v0.1.0-develop.13) (2023-07-11)

### Bug Fixes

* use call to getDefaultClientConfig to get chain config ([948d4d6](948d4d6109))
2023-07-11 07:08:16 +00:00
Derrick Hammer 82f4d702eb
Merge remote-tracking branch 'origin/develop' into develop 2023-07-11 03:07:22 -04:00
Derrick Hammer 948d4d6109
fix: use call to getDefaultClientConfig to get chain config 2023-07-11 03:07:18 -04:00
semantic-release-bot ff83ba0994 chore(release): 0.1.0-develop.12 [skip ci]
# [0.1.0-develop.12](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.11...v0.1.0-develop.12) (2023-07-11)

### Bug Fixes

* fix usage of deserializeSyncCommittee ([80fdc45](80fdc45ccd))
2023-07-11 06:43:59 +00:00
Derrick Hammer 43ffe2b41c
Merge remote-tracking branch 'origin/develop' into develop 2023-07-11 02:43:00 -04:00
Derrick Hammer 80fdc45ccd
fix: fix usage of deserializeSyncCommittee 2023-07-11 02:42:54 -04:00
semantic-release-bot a4f5631176 chore(release): 0.1.0-develop.11 [skip ci]
# [0.1.0-develop.11](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.10...v0.1.0-develop.11) (2023-07-11)

### Bug Fixes

* return data property from update ([a5c0153](a5c01533fe))
2023-07-11 06:34:35 +00:00
Derrick Hammer a5bfec403a
Merge remote-tracking branch 'origin/develop' into develop 2023-07-11 02:33:32 -04:00
Derrick Hammer a6759ec243
refactor: temp use js only bls 2023-07-11 02:33:28 -04:00
Derrick Hammer a5c01533fe
fix: return data property from update 2023-07-11 02:32:41 -04:00
semantic-release-bot fd789c8133 chore(release): 0.1.0-develop.10 [skip ci]
# [0.1.0-develop.10](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.9...v0.1.0-develop.10) (2023-07-11)
2023-07-11 06:22:43 +00:00
Derrick Hammer 474c61e759
Merge remote-tracking branch 'origin/develop' into develop 2023-07-11 02:21:37 -04:00
Derrick Hammer 208ca03e80
refactor: expose subscribe on the base client, with optional callback and call on child clients 2023-07-11 02:21:30 -04:00
semantic-release-bot 4ac5b109a2 chore(release): 0.1.0-develop.9 [skip ci]
# [0.1.0-develop.9](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.8...v0.1.0-develop.9) (2023-07-11)

### Bug Fixes

* getConsensusOptimisticUpdate does not return ([67827c3](67827c3776))
2023-07-11 05:54:55 +00:00
Derrick Hammer 69e29a532a
Merge remote-tracking branch 'origin/develop' into develop 2023-07-11 01:54:05 -04:00
Derrick Hammer 67827c3776
fix: getConsensusOptimisticUpdate does not return 2023-07-11 01:54:01 -04:00
semantic-release-bot c39ba96760 chore(release): 0.1.0-develop.8 [skip ci]
# [0.1.0-develop.8](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.7...v0.1.0-develop.8) (2023-07-11)
2023-07-11 05:52:12 +00:00
Derrick Hammer 911c95d9ee
Merge remote-tracking branch 'origin/develop' into develop 2023-07-11 01:51:11 -04:00
Derrick Hammer f8eba3644b
refactor: export getConsensusOptimisticUpdate and getCommitteeHash 2023-07-11 01:51:05 -04:00
Derrick Hammer efc657b790
refactor: move optimistic_update fetch logic to utility function 2023-07-11 01:50:42 -04:00
semantic-release-bot 6ff730c97a chore(release): 0.1.0-develop.7 [skip ci]
# [0.1.0-develop.7](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.6...v0.1.0-develop.7) (2023-07-11)

### Bug Fixes

* export RPC types ([bfa5d22](bfa5d227a0))
2023-07-11 05:36:47 +00:00
Derrick Hammer 408e1c4034
Merge remote-tracking branch 'origin/develop' into develop 2023-07-11 01:35:45 -04:00
Derrick Hammer bfa5d227a0
fix: export RPC types 2023-07-11 01:35:41 -04:00
semantic-release-bot ac54298fa0 chore(release): 0.1.0-develop.6 [skip ci]
# [0.1.0-develop.6](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.5...v0.1.0-develop.6) (2023-07-11)
2023-07-11 05:31:18 +00:00
Derrick Hammer 800bf02a19
Merge remote-tracking branch 'origin/develop' into develop 2023-07-11 01:30:29 -04:00
Derrick Hammer f24fdc5489
refactor: remove use of getExecutionFromBlockRoot in node client 2023-07-11 01:30:22 -04:00
semantic-release-bot 6520bba0c3 chore(release): 0.1.0-develop.5 [skip ci]
# [0.1.0-develop.5](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.4...v0.1.0-develop.5) (2023-07-11)

### Bug Fixes

* add missing methods to IStore interface ([52aca21](52aca21b78))
2023-07-11 05:10:41 +00:00
Derrick Hammer 4dbd3fc51d
Merge remote-tracking branch 'origin/develop' into develop 2023-07-11 01:09:55 -04:00
Derrick Hammer 52aca21b78
fix: add missing methods to IStore interface 2023-07-11 01:09:50 -04:00
semantic-release-bot 457c20616a chore(release): 0.1.0-develop.4 [skip ci]
# [0.1.0-develop.4](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.3...v0.1.0-develop.4) (2023-07-11)

### Bug Fixes

* add getter for store in baseclient ([3a48a52](3a48a52a53))
2023-07-11 05:02:10 +00:00
Derrick Hammer bfb02263ef
Merge remote-tracking branch 'origin/develop' into develop 2023-07-11 01:01:21 -04:00
Derrick Hammer 3a48a52a53
fix: add getter for store in baseclient 2023-07-11 01:01:10 -04:00
semantic-release-bot 2923e91d18 chore(release): 0.1.0-develop.3 [skip ci]
# [0.1.0-develop.3](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.2...v0.1.0-develop.3) (2023-07-11)

### Bug Fixes

* export all interfaces ([a50271e](a50271ec5b))
2023-07-11 04:32:00 +00:00
Derrick Hammer 836a8429c7
Merge remote-tracking branch 'origin/develop' into develop 2023-07-11 00:31:04 -04:00
Derrick Hammer a50271ec5b
fix: export all interfaces 2023-07-11 00:30:59 -04:00
semantic-release-bot 908e82a8a3 chore(release): 0.1.0-develop.2 [skip ci]
# [0.1.0-develop.2](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.1...v0.1.0-develop.2) (2023-07-11)

### Bug Fixes

* trigger release ([0bc05bf](0bc05bf6ca))
2023-07-11 04:24:48 +00:00
Derrick Hammer abe9c0925b
Merge remote-tracking branch 'origin/develop' into develop 2023-07-11 00:23:51 -04:00
Derrick Hammer 0bc05bf6ca
fix: trigger release 2023-07-11 00:22:12 -04:00
semantic-release-bot 416c6a1b74 chore(release): 0.1.0-develop.1 [skip ci]
# [0.1.0-develop.1](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.0.1...v0.1.0-develop.1) (2023-07-11)

### Bug Fixes

* add missing repository to package.json ([127b1aa](127b1aa0d7))
* export createDefaultClient ([5d1bdec](5d1bdec620))

### Features

* Initial version ([24cd98b](24cd98bb3c))
* Initial version ([5843acb](5843acb79b))
2023-07-11 04:20:11 +00:00
Derrick Hammer 127b1aa0d7
fix: add missing repository to package.json 2023-07-11 00:19:07 -04:00
Derrick Hammer 5d1bdec620
fix: export createDefaultClient 2023-07-11 00:15:54 -04:00
Derrick Hammer 840dad7ad1
ci: setup 2023-07-10 16:49:47 -04:00
Derrick Hammer 24cd98bb3c
feat: Initial version 2023-07-10 16:48:01 -04:00
Derrick Hammer 5843acb79b
feat: Initial version 2023-07-10 16:47:50 -04:00
24 changed files with 24520 additions and 2 deletions

13
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,13 @@
name: Build/Publish
on:
push:
branches:
- master
- develop
- develop-*
jobs:
main:
uses: lumeweb/github-node-deploy-workflow/.github/workflows/main.yml@master
secrets: inherit

5
.presetterrc.json Normal file
View File

@ -0,0 +1,5 @@
{
"preset": [
"@lumeweb/node-library-preset"
]
}

402
CHANGELOG.md Normal file
View File

@ -0,0 +1,402 @@
# [0.1.0-develop.64](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.63...v0.1.0-develop.64) (2023-10-29)
### Bug Fixes
* wrap sync in try/catch and unlock mutex in a finally ([0963794](https://git.lumeweb.com/LumeWeb/libethsync/commit/09637948e71e88c66b9e40389b4a46c60659f6e3))
# [0.1.0-develop.63](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.62...v0.1.0-develop.63) (2023-10-24)
### Bug Fixes
* args should not be var args ([32bf0a4](https://git.lumeweb.com/LumeWeb/libethsync/commit/32bf0a42e2ee22b907768496b094cc1bee4a42cf))
# [0.1.0-develop.62](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.61...v0.1.0-develop.62) (2023-10-24)
### Features
* add basic non-verifying eth_getLogs support ([b405ee2](https://git.lumeweb.com/LumeWeb/libethsync/commit/b405ee2581953acc6e8a66dece1a8d1789d5428d))
# [0.1.0-develop.61](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.60...v0.1.0-develop.61) (2023-09-16)
### Bug Fixes
* need to call our boot method ([b3f8dba](https://git.lumeweb.com/LumeWeb/libethsync/commit/b3f8dba243465e9a0a6030727e69ab1491cbd2dc))
# [0.1.0-develop.60](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.59...v0.1.0-develop.60) (2023-09-16)
### Features
* add method to reset the client ([87d8be6](https://git.lumeweb.com/LumeWeb/libethsync/commit/87d8be615e42fef0ae122a29b83cd1974e4ee1a7))
# [0.1.0-develop.59](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.58...v0.1.0-develop.59) (2023-09-16)
### Bug Fixes
* if syncing manual, set latest period to value of getCurrentPeriod() before optimistic update ([e742ec8](https://git.lumeweb.com/LumeWeb/libethsync/commit/e742ec8b6482d63469381670ae3f70653757a4fc))
* send a dummy update event for chain progress ([417da9f](https://git.lumeweb.com/LumeWeb/libethsync/commit/417da9f89302bded91066ab33722fc89adfbd76e))
# [0.1.0-develop.58](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.57...v0.1.0-develop.58) (2023-09-16)
### Bug Fixes
* bad import ([5687e13](https://git.lumeweb.com/LumeWeb/libethsync/commit/5687e13f9d0a9bb2473829a5dd780948c0478bcc))
# [0.1.0-develop.57](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.56...v0.1.0-develop.57) (2023-09-16)
### Bug Fixes
* need to init bls in manual ([d1e88ce](https://git.lumeweb.com/LumeWeb/libethsync/commit/d1e88ce87fa908ca47c176937decd5be96456b0c))
# [0.1.0-develop.56](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.55...v0.1.0-develop.56) (2023-09-16)
### Bug Fixes
* if we are within 1 period of getCurrentPeriod manually call sync actions, otherwise call parent sync ([6500219](https://git.lumeweb.com/LumeWeb/libethsync/commit/65002190b834c5a31c5c8ca1dcf0f5953f83594d))
# [0.1.0-develop.55](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.54...v0.1.0-develop.55) (2023-09-16)
### Bug Fixes
* as a properly synced node may never hit the computed period at getCurrentPeriod... need to manually emit synced and call getLatestExecution ([19c59eb](https://git.lumeweb.com/LumeWeb/libethsync/commit/19c59eb18944bd6528983fec0f848143aed4742a))
# [0.1.0-develop.54](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.53...v0.1.0-develop.54) (2023-09-16)
### Bug Fixes
* if startPeriod is greater than genesisPeriod, try to use latestCommittee falling back to genesisCommittee ([ec84027](https://git.lumeweb.com/LumeWeb/libethsync/commit/ec8402714f6f9c7ec405c465ea6cc965eabacad5))
# [0.1.0-develop.53](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.52...v0.1.0-develop.53) (2023-09-16)
### Bug Fixes
* bad import ([b9b8b26](https://git.lumeweb.com/LumeWeb/libethsync/commit/b9b8b26ea478fce2ed9a3c9c94fa09846b5feca7))
# [0.1.0-develop.52](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.51...v0.1.0-develop.52) (2023-09-16)
### Features
* add syncFromCheckpoint method ([ccaca65](https://git.lumeweb.com/LumeWeb/libethsync/commit/ccaca65a900ec75adc1605e5b22caab4182587dd))
# [0.1.0-develop.51](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.50...v0.1.0-develop.51) (2023-09-16)
### Bug Fixes
* IStore should extend EventEmitter ([9f00d8f](https://git.lumeweb.com/LumeWeb/libethsync/commit/9f00d8fec80d05592974d28c557117419027d21e))
# [0.1.0-develop.50](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.49...v0.1.0-develop.50) (2023-09-16)
### Features
* have Store extend EventEmitter so that it can emit set on adding an update and pass the serialized data ([295aed0](https://git.lumeweb.com/LumeWeb/libethsync/commit/295aed0845249ab81852e4106de66fdca3c5885e))
# [0.1.0-develop.49](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.48...v0.1.0-develop.49) (2023-07-25)
### Bug Fixes
* add try/catch with mutex release on optimisticUpdateCallback ([7075966](https://git.lumeweb.com/LumeWeb/libethsync/commit/7075966227515151490639b0f22a804d6e3b2583))
# [0.1.0-develop.48](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.47...v0.1.0-develop.48) (2023-07-24)
### Bug Fixes
* don't release lock when we have cached optimistic update data, as we never locked it ([d3664c8](https://git.lumeweb.com/LumeWeb/libethsync/commit/d3664c8d23c1bbfef53816542f47fc211f94c63c))
# [0.1.0-develop.47](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.46...v0.1.0-develop.47) (2023-07-24)
### Bug Fixes
* incorporate upstream https://github.com/lightclients/patronum/pull/23 ([8b7c85d](https://git.lumeweb.com/LumeWeb/libethsync/commit/8b7c85dd61c585d96e711deca5d0e014a5aa1d12))
# [0.1.0-develop.46](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.45...v0.1.0-develop.46) (2023-07-23)
### Features
* add synced event ([0321136](https://git.lumeweb.com/LumeWeb/libethsync/commit/0321136ac00216e6e009f531ffcfb25a4b8f3e09))
# [0.1.0-develop.45](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.44...v0.1.0-develop.45) (2023-07-23)
### Bug Fixes
* change argument to be the current update, not the 0 index ([87e7533](https://git.lumeweb.com/LumeWeb/libethsync/commit/87e7533dcfdad99c534b5f54f63e2c1ccb08d769))
# [0.1.0-develop.44](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.43...v0.1.0-develop.44) (2023-07-23)
# [0.1.0-develop.43](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.42...v0.1.0-develop.43) (2023-07-23)
### Features
* use event emitter and emit "update" on every light client update processed ([232af83](https://git.lumeweb.com/LumeWeb/libethsync/commit/232af830c9c844fa5b6f2e5b4c50c2f0a067188e))
# [0.1.0-develop.42](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.41...v0.1.0-develop.42) (2023-07-15)
# [0.1.0-develop.41](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.40...v0.1.0-develop.41) (2023-07-14)
### Features
* add loggerInfo and loggerErr callbacks to client options ([a901ee7](https://git.lumeweb.com/LumeWeb/libethsync/commit/a901ee76f4703d6e7f4793e96cfe173037f2103f))
# [0.1.0-develop.40](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.39...v0.1.0-develop.40) (2023-07-14)
### Bug Fixes
* add a sync delay option so that the bls verification does not hog cpu ([824dcd9](https://git.lumeweb.com/LumeWeb/libethsync/commit/824dcd96339410ffa9f0afb744a1baf3bed722d6))
# [0.1.0-develop.39](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.38...v0.1.0-develop.39) (2023-07-13)
### Bug Fixes
* compare code against codehash ([dc4c6b3](https://git.lumeweb.com/LumeWeb/libethsync/commit/dc4c6b3f3635a60ebc6e1a7be9811ff5ada9df66))
# [0.1.0-develop.38](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.37...v0.1.0-develop.38) (2023-07-13)
### Bug Fixes
* add map to return data property ([3e27281](https://git.lumeweb.com/LumeWeb/libethsync/commit/3e27281a3568c7979bb9a185a2081f9e571e5b07))
# [0.1.0-develop.37](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.36...v0.1.0-develop.37) (2023-07-13)
### Bug Fixes
* parse from u, not u.data ([8677bc1](https://git.lumeweb.com/LumeWeb/libethsync/commit/8677bc1294a81d37f42cd23d1b7860c458a93e19))
# [0.1.0-develop.36](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.35...v0.1.0-develop.36) (2023-07-13)
### Bug Fixes
* need to use concat not push ([b87017e](https://git.lumeweb.com/LumeWeb/libethsync/commit/b87017eb678282bf47758ca834e2acbc1cf6e516))
* Revert "fix: create fixSerializedUint8Array helper method to deal with weird quirk of ssz serialize" ([6ef18db](https://git.lumeweb.com/LumeWeb/libethsync/commit/6ef18dbc05b5b5801a6b05cea5056d631e8a094d))
* temporarily disable block hash check as it is bugged ([91144cb](https://git.lumeweb.com/LumeWeb/libethsync/commit/91144cb5a2b5d05fd301b11501861aadd10a69b5))
* use byteArrayEquals ([157811b](https://git.lumeweb.com/LumeWeb/libethsync/commit/157811b2348fa94d5d6b076219f34b3b340a50ac))
# [0.1.0-develop.35](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.34...v0.1.0-develop.35) (2023-07-13)
### Bug Fixes
* need to disable useClones in node cache ([07845bf](https://git.lumeweb.com/LumeWeb/libethsync/commit/07845bf4d024f2c62d656201beb97123a3052a3a))
# [0.1.0-develop.34](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.33...v0.1.0-develop.34) (2023-07-13)
### Bug Fixes
* create fixSerializedUint8Array helper method to deal with weird quirk of ssz serialize ([d8430b4](https://git.lumeweb.com/LumeWeb/libethsync/commit/d8430b4a11f99f38f33cf14abfc9ed841e5226e1))
# [0.1.0-develop.33](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.32...v0.1.0-develop.33) (2023-07-13)
# [0.1.0-develop.32](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.31...v0.1.0-develop.32) (2023-07-13)
### Features
* add getCurrentBlock and getLastBlock methods ([661e146](https://git.lumeweb.com/LumeWeb/libethsync/commit/661e146636a9f685e8cbae04c52b1d0a1ede3bff))
# [0.1.0-develop.31](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.30...v0.1.0-develop.31) (2023-07-13)
# [0.1.0-develop.30](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.29...v0.1.0-develop.30) (2023-07-13)
# [0.1.0-develop.29](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.28...v0.1.0-develop.29) (2023-07-13)
# [0.1.0-develop.28](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.27...v0.1.0-develop.28) (2023-07-13)
### Bug Fixes
* add optimisticUpdateCallback to client factory ([c3b47e6](https://git.lumeweb.com/LumeWeb/libethsync/commit/c3b47e67e760aea5c841985ab4d44fb36cff1dae))
* add optimisticUpdateCallback to options ([464fb21](https://git.lumeweb.com/LumeWeb/libethsync/commit/464fb2109514b147b25d1d760eb4a7677ac8fea3))
* pass client to prover after creating client in factory. don't try to parse thr messages ([481757e](https://git.lumeweb.com/LumeWeb/libethsync/commit/481757e019729ce3790c5cd07cb89c5d7ded7cf4))
* simplify logic and use LightClientUpdate.fromJson ([17cb002](https://git.lumeweb.com/LumeWeb/libethsync/commit/17cb00231c44d734cb6f24f48d1a6a045f0c7ae4))
* use _client not client ([76e22fa](https://git.lumeweb.com/LumeWeb/libethsync/commit/76e22fa34258c771da281457e983a5addfef440b))
# [0.1.0-develop.27](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.26...v0.1.0-develop.27) (2023-07-12)
### Bug Fixes
* fix import ([baa9562](https://git.lumeweb.com/LumeWeb/libethsync/commit/baa9562749e34db490997b62f5a8f370b355945c))
# [0.1.0-develop.26](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.25...v0.1.0-develop.26) (2023-07-12)
# [0.1.0-develop.25](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.24...v0.1.0-develop.25) (2023-07-12)
# [0.1.0-develop.24](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.23...v0.1.0-develop.24) (2023-07-11)
### Bug Fixes
* syncFromGenesis was a no-op ([822b0b4](https://git.lumeweb.com/LumeWeb/libethsync/commit/822b0b46b6efed5fab2908d6103e47bbf55fb957))
# [0.1.0-develop.23](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.22...v0.1.0-develop.23) (2023-07-11)
### Reverts
* Revert "fix: ensure @ethereumjs/util matches the version required by @ethereumjs/evm" ([bad87ac](https://git.lumeweb.com/LumeWeb/libethsync/commit/bad87ac7e101cd8106b3b60901e9a60adebd6848))
# [0.1.0-develop.22](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.21...v0.1.0-develop.22) (2023-07-11)
### Bug Fixes
* ensure @ethereumjs/util matches the version required by @ethereumjs/evm ([0949e8d](https://git.lumeweb.com/LumeWeb/libethsync/commit/0949e8d427b6a70497bc5c93bd6df5a72247b848))
# [0.1.0-develop.21](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.20...v0.1.0-develop.21) (2023-07-11)
### Bug Fixes
* @noble/curves import ([5c8394a](https://git.lumeweb.com/LumeWeb/libethsync/commit/5c8394af2d4561247605181720e799fc5c271f17))
# [0.1.0-develop.20](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.19...v0.1.0-develop.20) (2023-07-11)
# [0.1.0-develop.19](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.18...v0.1.0-develop.19) (2023-07-11)
### Features
* add getter for provider ([b85e177](https://git.lumeweb.com/LumeWeb/libethsync/commit/b85e1779ee7e4d8fccb6c7b8ee0e66f332823d19))
# [0.1.0-develop.18](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.17...v0.1.0-develop.18) (2023-07-11)
### Bug Fixes
* update ProverRequestCallback type to return a promise ([0884030](https://git.lumeweb.com/LumeWeb/libethsync/commit/08840308f8f0eb3560bbac4855222c8b4af46887))
# [0.1.0-develop.17](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.16...v0.1.0-develop.17) (2023-07-11)
### Bug Fixes
* beacon url is not used on the client side ([f353b3e](https://git.lumeweb.com/LumeWeb/libethsync/commit/f353b3e102438fa5d0af434519e3cd1927b85d75))
# [0.1.0-develop.16](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.15...v0.1.0-develop.16) (2023-07-11)
### Bug Fixes
* fix reference to isValidLightClientHeader ([0f8746d](https://git.lumeweb.com/LumeWeb/libethsync/commit/0f8746dac2442086cc4355a00c80c93178383141))
# [0.1.0-develop.15](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.14...v0.1.0-develop.15) (2023-07-11)
### Bug Fixes
* implement isValidLightClientHeader ([6f07421](https://git.lumeweb.com/LumeWeb/libethsync/commit/6f07421fe80f008255cbe472204d8530e2bb3352))
# [0.1.0-develop.14](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.13...v0.1.0-develop.14) (2023-07-11)
### Bug Fixes
* further chainConfig fixes ([8b11911](https://git.lumeweb.com/LumeWeb/libethsync/commit/8b1191165addc8bd981b57a62e3870e54bb6c0ea))
# [0.1.0-develop.13](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.12...v0.1.0-develop.13) (2023-07-11)
### Bug Fixes
* use call to getDefaultClientConfig to get chain config ([948d4d6](https://git.lumeweb.com/LumeWeb/libethsync/commit/948d4d610939e4f19210c187eec9e03d89060cd4))
# [0.1.0-develop.12](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.11...v0.1.0-develop.12) (2023-07-11)
### Bug Fixes
* fix usage of deserializeSyncCommittee ([80fdc45](https://git.lumeweb.com/LumeWeb/libethsync/commit/80fdc45ccd3993e96a57849bd3acae75cf46eb76))
# [0.1.0-develop.11](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.10...v0.1.0-develop.11) (2023-07-11)
### Bug Fixes
* return data property from update ([a5c0153](https://git.lumeweb.com/LumeWeb/libethsync/commit/a5c01533fe81f12b0651c6e039bb9f29b7c0ec93))
# [0.1.0-develop.10](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.9...v0.1.0-develop.10) (2023-07-11)
# [0.1.0-develop.9](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.8...v0.1.0-develop.9) (2023-07-11)
### Bug Fixes
* getConsensusOptimisticUpdate does not return ([67827c3](https://git.lumeweb.com/LumeWeb/libethsync/commit/67827c3776171caf0699e5449307c3731fc81b9a))
# [0.1.0-develop.8](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.7...v0.1.0-develop.8) (2023-07-11)
# [0.1.0-develop.7](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.6...v0.1.0-develop.7) (2023-07-11)
### Bug Fixes
* export RPC types ([bfa5d22](https://git.lumeweb.com/LumeWeb/libethsync/commit/bfa5d227a056a11b3aed61087d5c3c5b1006e43d))
# [0.1.0-develop.6](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.5...v0.1.0-develop.6) (2023-07-11)
# [0.1.0-develop.5](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.4...v0.1.0-develop.5) (2023-07-11)
### Bug Fixes
* add missing methods to IStore interface ([52aca21](https://git.lumeweb.com/LumeWeb/libethsync/commit/52aca21b781160055b57ec983edd1ed8e9c0e3e4))
# [0.1.0-develop.4](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.3...v0.1.0-develop.4) (2023-07-11)
### Bug Fixes
* add getter for store in baseclient ([3a48a52](https://git.lumeweb.com/LumeWeb/libethsync/commit/3a48a52a5397b6ae02406a05e90a623fc920b875))
# [0.1.0-develop.3](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.2...v0.1.0-develop.3) (2023-07-11)
### Bug Fixes
* export all interfaces ([a50271e](https://git.lumeweb.com/LumeWeb/libethsync/commit/a50271ec5bb2f8f702b70fc450f64fba7a5ab0e8))
# [0.1.0-develop.2](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.1...v0.1.0-develop.2) (2023-07-11)
### Bug Fixes
* trigger release ([0bc05bf](https://git.lumeweb.com/LumeWeb/libethsync/commit/0bc05bf6ca4d03b29f293cf90834683b545ef499))
# [0.1.0-develop.1](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.0.1...v0.1.0-develop.1) (2023-07-11)
### Bug Fixes
* add missing repository to package.json ([127b1aa](https://git.lumeweb.com/LumeWeb/libethsync/commit/127b1aa0d7f312ebfbc9ab1c88b595ecdc6b8e7a))
* export createDefaultClient ([5d1bdec](https://git.lumeweb.com/LumeWeb/libethsync/commit/5d1bdec620a0e077849606860634e935cdc2bd19))
### Features
* Initial version ([24cd98b](https://git.lumeweb.com/LumeWeb/libethsync/commit/24cd98bb3ccb888400fe9e205fc45606c934f879))
* Initial version ([5843acb](https://git.lumeweb.com/LumeWeb/libethsync/commit/5843acb79bacca113cf08c9fd64a3edb6f97dc5c))

View File

@ -1,6 +1,7 @@
MIT License
Copyright (c) <year> <copyright holders>
Copyright (c) 2023 Hammer Technologies LLC
Copyright (c) 2022 Shresth Agrawal
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View File

@ -1,2 +1,2 @@
# libethclient
# libethsync

21601
npm-shrinkwrap.json generated Normal file

File diff suppressed because it is too large Load Diff

61
package.json Normal file
View File

@ -0,0 +1,61 @@
{
"name": "@lumeweb/libethsync",
"version": "0.1.0-develop.64",
"type": "module",
"repository": {
"type": "git",
"url": "gitea@git.lumeweb.com:LumeWeb/libethsync.git"
},
"devDependencies": {
"@lumeweb/node-library-preset": "^0.2.7",
"presetter": "*"
},
"readme": "ERROR: No README data found!",
"scripts": {
"prepare": "presetter bootstrap",
"build": "run build",
"semantic-release": "semantic-release"
},
"exports": {
"./client": {
"import": "./lib/client/index.js",
"typings": "./lib/client/index.d.ts"
},
"./node": {
"import": "./lib/node/index.js",
"typings": "./lib/node/index.d.ts"
}
},
"dependencies": {
"@chainsafe/as-sha256": "^0.3.1",
"@chainsafe/bls": "7.1.1",
"@chainsafe/blst": "0.2.9",
"@chainsafe/ssz": "0.11.1",
"@ethereumjs/block": "^4.3.0",
"@ethereumjs/blockchain": "^6.3.0",
"@ethereumjs/common": "^3.2.0",
"@ethereumjs/trie": "^5.1.0",
"@ethereumjs/tx": "^4.2.0",
"@ethereumjs/util": "^8.1.0",
"@ethereumjs/vm": "^6.5.0",
"@lodestar/config": "1.9.1",
"@lodestar/light-client": "1.9.1",
"@lodestar/params": "1.9.1",
"@lodestar/types": "1.9.1",
"async-mutex": "^0.4.0",
"axios": "^1.4.0",
"axios-retry": "^3.5.1",
"detect-node": "^2.1.0",
"ethereum-cryptography": "^2.0.0",
"events": "^3.3.0",
"node-cache": "^5.1.2",
"rlp": "^3.0.0",
"web3-types": "^1.0.1"
},
"files": [
"lib"
],
"publishConfig": {
"access": "public"
}
}

334
src/baseClient.ts Normal file
View File

@ -0,0 +1,334 @@
import { ClientConfig, ExecutionInfo, IProver, IStore } from "#interfaces.js";
import { POLLING_DELAY } from "#constants.js";
import {
computeSyncPeriodAtSlot,
deserializeSyncCommittee,
getCurrentSlot,
} from "@lodestar/light-client/utils";
import bls, { init } from "@chainsafe/bls/switchable";
import { Mutex } from "async-mutex";
import { fromHexString, toHexString } from "@chainsafe/ssz";
import {
deserializePubkeys,
getDefaultClientConfig,
optimisticUpdateVerify,
} from "#util.js";
import {
LightClientUpdate,
OptimisticUpdate,
OptimisticUpdateCallback,
} from "#types.js";
import { assertValidLightClientUpdate } from "@lodestar/light-client/validation";
import * as capella from "@lodestar/types/capella";
import { EventEmitter } from "events";
export interface BaseClientOptions {
prover: IProver;
store: IStore;
optimisticUpdateCallback: OptimisticUpdateCallback;
syncDelay?: number;
loggerInfo: (...any) => void;
loggerErr: (...any) => void;
}
export default abstract class BaseClient extends EventEmitter {
protected latestCommittee?: Uint8Array[];
protected latestBlockHash?: string;
protected config: ClientConfig = getDefaultClientConfig();
protected genesisCommittee: Uint8Array[] = this.config.genesis.committee.map(
(pk) => fromHexString(pk),
);
protected genesisPeriod = computeSyncPeriodAtSlot(this.config.genesis.slot);
protected booted = false;
protected options: BaseClientOptions;
private genesisTime = this.config.genesis.time;
private syncMutex = new Mutex();
private optimisticMutex = new Mutex();
constructor(options: BaseClientOptions) {
super();
this.options = options;
}
private _latestOptimisticUpdate?: Uint8Array;
get latestOptimisticUpdate(): Uint8Array {
return this._latestOptimisticUpdate as Uint8Array;
}
protected _latestPeriod: number = -1;
get latestPeriod(): number {
return this._latestPeriod;
}
public get isSynced() {
return this._latestPeriod === this.getCurrentPeriod();
}
public get store(): IStore {
return this.options.store as IStore;
}
public async sync(): Promise<void> {
await init("herumi");
await this._sync();
await this.getLatestExecution(false);
}
public getCurrentPeriod(): number {
return computeSyncPeriodAtSlot(
getCurrentSlot(this.config.chainConfig, this.genesisTime),
);
}
public getCurrentBlock(): number {
return getCurrentSlot(this.config.chainConfig, this.genesisTime);
}
public getLastBlock(): number | null {
if (this._latestOptimisticUpdate) {
return capella.ssz.LightClientOptimisticUpdate.deserialize(
this._latestOptimisticUpdate,
).attestedHeader.beacon.slot;
}
return null;
}
public async getNextValidExecutionInfo(
retry: number = 10,
): Promise<ExecutionInfo> {
if (retry === 0)
throw new Error(
"no valid execution payload found in the given retry limit",
);
const ei = await this.getLatestExecution();
if (ei) return ei;
// delay for the next slot
await new Promise((resolve) => setTimeout(resolve, POLLING_DELAY));
return this.getNextValidExecutionInfo(retry - 1);
}
async syncProver(
startPeriod: number,
currentPeriod: number,
startCommittee: Uint8Array[],
): Promise<{ syncCommittee: Uint8Array[]; period: number }> {
try {
const updates = await this.options.prover.getSyncUpdate(
startPeriod,
currentPeriod - startPeriod,
);
for (let i = 0; i < updates.length; i++) {
const curPeriod = startPeriod + i;
const update = updates[i];
const validOrCommittee = await this.syncUpdateVerifyGetCommittee(
startCommittee,
curPeriod,
update,
);
if (!(validOrCommittee as boolean)) {
this.options.loggerInfo(
`Found invalid update at period(${curPeriod})`,
);
return {
syncCommittee: startCommittee,
period: curPeriod,
};
}
await this.options.store.addUpdate(curPeriod, update);
startCommittee = validOrCommittee as Uint8Array[];
this.emit("update", i + 1, updates.length);
if (this.options.syncDelay) {
await new Promise((resolve) =>
setTimeout(resolve, this.options.syncDelay),
);
}
}
} catch (e) {
console.error(`failed to fetch sync update for period(${startPeriod})`);
return {
syncCommittee: startCommittee,
period: startPeriod,
};
}
return {
syncCommittee: startCommittee,
period: currentPeriod,
};
}
protected async _sync() {
await this.syncMutex.acquire();
try {
const currentPeriod = this.getCurrentPeriod();
if (currentPeriod > this._latestPeriod) {
if (!this.booted) {
this.latestCommittee = await this.syncFromGenesis();
} else {
this.latestCommittee = await this.syncFromLastUpdate();
}
this._latestPeriod = currentPeriod;
this.emit("synced");
}
} catch (e) {
console.log(e);
} finally {
this.syncMutex.release();
}
}
protected async subscribe(callback?: (ei: ExecutionInfo) => void) {
setInterval(async () => {
await this.syncToLatestBlock(callback);
}, POLLING_DELAY);
}
public async syncToLatestBlock(callback?: (ei: ExecutionInfo) => void) {
try {
const ei = await this.getLatestExecution();
if (ei && ei.blockHash !== this.latestBlockHash) {
this.latestBlockHash = ei.blockHash;
return await callback?.(ei);
}
} catch (e) {
console.error(e);
}
}
async getLatestExecution(sync = true): Promise<ExecutionInfo | null> {
if (sync) {
await this._sync();
}
const getExecInfo = (u: OptimisticUpdate) => {
return {
blockHash: toHexString(u.attestedHeader.execution.blockHash),
blockNumber: u.attestedHeader.execution.blockNumber,
};
};
if (this._latestOptimisticUpdate) {
const update = capella.ssz.LightClientOptimisticUpdate.deserialize(
this._latestOptimisticUpdate,
);
const diffInSeconds = Date.now() / 1000 - this.genesisTime;
const currentSlot = Math.floor(
diffInSeconds / this.config.chainConfig.SECONDS_PER_SLOT,
);
if (currentSlot <= update.attestedHeader.beacon.slot) {
return getExecInfo(update);
}
}
await this.optimisticMutex.acquire();
let update: OptimisticUpdate;
try {
update = await this.options.optimisticUpdateCallback();
} catch (e) {
this.optimisticMutex.release();
throw e;
}
const verify = await optimisticUpdateVerify(
this.latestCommittee as Uint8Array[],
update,
);
// TODO: check the update against the latest sync committee
if (!verify.correct) {
this.optimisticMutex.release();
console.error(`Invalid Optimistic Update: ${verify.reason}`);
return null;
}
this._latestOptimisticUpdate =
capella.ssz.LightClientOptimisticUpdate.serialize(update);
this.options.loggerInfo(
`Optimistic update verified for slot ${update.attestedHeader.beacon.slot}`,
);
this.optimisticMutex.release();
return getExecInfo(update);
}
protected async syncUpdateVerifyGetCommittee(
prevCommittee: Uint8Array[],
period: number,
update: LightClientUpdate,
): Promise<false | Uint8Array[]> {
const updatePeriod = computeSyncPeriodAtSlot(
update.attestedHeader.beacon.slot,
);
if (period !== updatePeriod) {
console.error(
`Expected update with period ${period}, but received ${updatePeriod}`,
);
return false;
}
const prevCommitteeFast = deserializeSyncCommittee({
pubkeys: prevCommittee,
aggregatePubkey: bls.PublicKey.aggregate(
deserializePubkeys(prevCommittee),
).toBytes(),
});
try {
// check if the update has valid signatures
await assertValidLightClientUpdate(
this.config.chainConfig,
prevCommitteeFast,
update,
);
return update.nextSyncCommittee.pubkeys;
} catch (e) {
console.error(e);
return false;
}
}
protected async syncFromGenesis(): Promise<Uint8Array[]> {
return this.syncFromLastUpdate(this.genesisPeriod);
}
protected async syncFromLastUpdate(
startPeriod = this.latestPeriod,
): Promise<Uint8Array[]> {
const currentPeriod = this.getCurrentPeriod();
let startCommittee =
startPeriod > this.genesisPeriod
? this.latestCommittee ?? this.genesisCommittee
: this.genesisCommittee;
console.debug(
`Sync started from period(${startPeriod}) to period(${currentPeriod})`,
);
const { syncCommittee, period } = await this.syncProver(
startPeriod,
currentPeriod,
startCommittee,
);
if (period === currentPeriod) {
console.debug(
`Sync completed from period(${startPeriod}) to period(${currentPeriod})`,
);
return syncCommittee;
}
throw new Error("no honest prover found");
}
}

77
src/client/client.ts Normal file
View File

@ -0,0 +1,77 @@
import BaseClient, { BaseClientOptions } from "#baseClient.js";
import { IProver, IVerifyingProviderConstructor } from "#interfaces.js";
import { IClientVerifyingProvider } from "#client/verifyingProvider.js";
import { LightClientUpdate } from "#types.js";
import { computeSyncPeriodAtSlot } from "@lodestar/light-client/utils";
import { init } from "@chainsafe/bls/switchable";
interface Config extends BaseClientOptions {
prover: IProver;
provider: IVerifyingProviderConstructor<IClientVerifyingProvider>;
rpcHandler: Function;
}
export default class Client extends BaseClient {
protected declare options: Config;
constructor(options: Config) {
super(options);
}
private provider?: IClientVerifyingProvider;
async sync(): Promise<void> {
await super.sync();
await this.boot();
}
private async boot() {
if (!this.provider) {
const { blockHash, blockNumber } = await this.getNextValidExecutionInfo();
const factory = this.options.provider;
const provider = new factory(
this.options.rpcHandler,
blockNumber,
blockHash,
);
this.subscribe((ei) => {
this.options.loggerInfo(
`Received a new blockheader: ${ei.blockNumber} ${ei.blockHash}`,
);
provider.update(ei.blockNumber, ei.blockHash);
});
this.provider = provider;
this.booted = true;
}
}
public reset() {
this._latestPeriod = 0;
this.latestCommittee = undefined;
this.booted = false;
this.store.clear();
}
public async syncFromCheckpoint(checkpoint: LightClientUpdate) {
this._latestPeriod = computeSyncPeriodAtSlot(
checkpoint.attestedHeader.beacon.slot,
);
this.latestCommittee = checkpoint.nextSyncCommittee.pubkeys;
if (this._latestPeriod + 1 === this.getCurrentPeriod()) {
this.emit("synced");
await init("herumi");
this._latestPeriod = this.getCurrentPeriod();
this.emit("update", 1, 1);
await this.getLatestExecution(false);
} else {
await super.sync();
}
await this.boot();
}
public async rpcCall(method: string, params: any) {
return this.provider?.rpcMethod(method, params);
}
}

31
src/client/index.ts Normal file
View File

@ -0,0 +1,31 @@
import Client from "./client.js";
import Prover, { ProverRequestCallback } from "../prover.js";
import VerifyingProvider from "./verifyingProvider.js";
import Store from "#store.js";
import { BaseClientOptions } from "#baseClient.js";
import { OptimisticUpdateCallback } from "#types.js";
function createDefaultClient(
proverHandler: ProverRequestCallback,
rpcHandler: Function,
optimisticUpdateHandler: OptimisticUpdateCallback,
loggerInfo: (...any) => void,
loggerErr: (...any) => void,
syncDelay?: number,
): Client {
return new Client({
prover: new Prover(proverHandler),
store: new Store(60 * 60),
provider: VerifyingProvider,
rpcHandler,
optimisticUpdateCallback: optimisticUpdateHandler,
loggerInfo,
loggerErr,
syncDelay,
});
}
export { RPCRequest, RPCRequestRaw, RPCResponse } from "./rpc.js";
export { Client, Prover, VerifyingProvider, createDefaultClient };
export { ProverRequestCallback };
export * from "#interfaces.js";

81
src/client/rpc.ts Normal file
View File

@ -0,0 +1,81 @@
export type RPCRequest = {
method: string;
params: any[];
};
export type RPCRequestRaw = RPCRequest & {
jsonrpc: string;
id: string;
};
export type RPCResponse = {
success: boolean;
result: any;
};
export class RPC {
private callback: Function;
constructor(callback: Function) {
this.callback = callback;
}
async request(request: RPCRequest) {
return await this._retryRequest(request);
}
async requestBatch(requests: RPCRequest[]) {
const res: RPCResponse[] = [];
for (const request of requests) {
const r = await this._retryRequest(request);
res.push(r);
}
return res;
}
private async _retryRequest(
_request: RPCRequest,
retry = 5,
): Promise<RPCResponse> {
const request = {
..._request,
jsonrpc: "2.0",
id: this.generateId(),
};
for (let i = retry; i > 0; i--) {
const res = await this._request(request);
if (res.success) {
return res;
} else if (i == 1) {
console.error(
`RPC batch request failed after maximum retries: ${JSON.stringify(
request,
null,
2,
)} ${JSON.stringify(res, null, 2)}`,
);
}
}
throw new Error("RPC request failed");
}
private generateId(): string {
return Math.floor(Math.random() * 2 ** 64).toFixed();
}
protected async _request(request: RPCRequestRaw): Promise<RPCResponse> {
try {
const response = await this.callback(request);
return {
success: !response.error,
result: response.error || response.result,
};
} catch (e) {
return {
success: false,
result: { message: `request failed: ${e}` },
};
}
}
}

65
src/client/types.ts Normal file
View File

@ -0,0 +1,65 @@
import { Bytes32 } from "#types.js";
export type AddressHex = string;
export type HexString = string;
export type Bytes = string;
export type AccountResponse = GetProof;
export type CodeResponse = string;
export type AccessList = { address: AddressHex; storageKeys: Bytes32[] }[];
export interface RPCTx {
from?: string;
to?: string;
gas?: string;
gasPrice?: string;
maxFeePerGas?: string;
maxPriorityFeePerGas?: string;
accessList?: AccessList;
value?: string;
data?: string;
}
export type JSONRPCReceipt = {
transactionHash: string;
transactionIndex: string;
blockHash: string;
blockNumber: string;
from: string;
to: string | null;
cumulativeGasUsed: string;
effectiveGasPrice: string;
gasUsed: string;
contractAddress: string | null;
logs: JSONRPCLog[];
logsBloom: string;
root?: string;
status?: string;
};
export type JSONRPCLog = {
removed: boolean;
logIndex: string | null;
transactionIndex: string | null;
transactionHash: string | null;
blockHash: string | null;
blockNumber: string | null;
address: string;
data: string;
topics: string[];
};
export interface GetProof {
address: string;
balance: string;
codeHash: string;
nonce: string;
storageHash: string;
accountProof: string[];
storageProof: StorageProof[];
}
export interface StorageProof {
key: string;
value: string;
proof: string[];
}

71
src/client/utils.ts Normal file
View File

@ -0,0 +1,71 @@
import {
Account,
bigIntToHex,
setLengthLeft,
toBuffer,
} from "@ethereumjs/util";
import { BlockData, HeaderData } from "@ethereumjs/block";
import {
AccessListEIP2930TxData,
FeeMarketEIP1559TxData,
TxData,
} from "@ethereumjs/tx";
const isTruthy = (val: any) => !!val;
// TODO: fix blockInfo type
export function headerDataFromWeb3Response(blockInfo: any): HeaderData {
return {
parentHash: blockInfo.parentHash,
uncleHash: blockInfo.sha3Uncles,
coinbase: blockInfo.miner,
stateRoot: blockInfo.stateRoot,
transactionsTrie: blockInfo.transactionsRoot,
receiptTrie: blockInfo.receiptsRoot,
logsBloom: blockInfo.logsBloom,
difficulty: BigInt(blockInfo.difficulty),
number: BigInt(blockInfo.number),
gasLimit: BigInt(blockInfo.gasLimit),
gasUsed: BigInt(blockInfo.gasUsed),
timestamp: BigInt(blockInfo.timestamp),
extraData: blockInfo.extraData,
mixHash: (blockInfo as any).mixHash, // some reason the types are not up to date :(
nonce: blockInfo.nonce,
baseFeePerGas: blockInfo.baseFeePerGas
? BigInt(blockInfo.baseFeePerGas)
: undefined,
withdrawalsRoot: blockInfo.withdrawalsRoot,
};
}
export function txDataFromWeb3Response(
txInfo: any,
): TxData | AccessListEIP2930TxData | FeeMarketEIP1559TxData {
return {
...txInfo,
data: txInfo.input,
gasPrice: BigInt(txInfo.gasPrice),
gasLimit: txInfo.gas,
to: isTruthy(txInfo.to)
? setLengthLeft(toBuffer(txInfo.to), 20)
: undefined,
value: BigInt(txInfo.value),
maxFeePerGas: isTruthy(txInfo.maxFeePerGas)
? BigInt(txInfo.maxFeePerGas)
: undefined,
maxPriorityFeePerGas: isTruthy(txInfo.maxPriorityFeePerGas)
? BigInt(txInfo.maxPriorityFeePerGas)
: undefined,
};
}
export function blockDataFromWeb3Response(blockInfo: any): BlockData {
return {
header: headerDataFromWeb3Response(blockInfo),
transactions: blockInfo.transactions.map(txDataFromWeb3Response),
};
}
export { bigIntToHex };
export const emptyAccountSerialize = new Account().serialize();

View File

@ -0,0 +1,740 @@
import { IVerifyingProvider } from "#interfaces.js";
import _ from "lodash";
import { Trie } from "@ethereumjs/trie";
import rlp from "rlp";
import { Common, Chain, Hardfork } from "@ethereumjs/common";
import {
Account,
Address,
bufferToHex,
KECCAK256_NULL_S,
setLengthLeft,
toBuffer,
toType,
TypeOutput,
} from "@ethereumjs/util";
import { VM } from "@ethereumjs/vm";
import { Blockchain } from "@ethereumjs/blockchain";
import { TransactionFactory } from "@ethereumjs/tx";
import { Block, BlockHeader } from "@ethereumjs/block";
import { Bytes32 } from "#types.js";
import type { BlockNumberOrTag } from "web3-types";
import {
DEFAULT_BLOCK_PARAMETER,
MAX_BLOCK_FUTURE,
MAX_BLOCK_HISTORY,
ZERO_ADDR,
} from "#constants.js";
import {
bigIntToHex,
blockDataFromWeb3Response,
emptyAccountSerialize,
headerDataFromWeb3Response,
} from "./utils.js";
import {
AccessList,
AccountResponse,
AddressHex,
Bytes,
CodeResponse,
GetProof,
HexString,
JSONRPCReceipt,
RPCTx,
} from "./types.js";
import { keccak256 } from "ethereum-cryptography/keccak";
import { byteArrayEquals, fromHexString } from "@chainsafe/ssz";
import { RPC } from "#client/rpc.js";
export interface IClientVerifyingProvider extends IVerifyingProvider {
rpcMethod(method: string, params: any);
}
export default class VerifyingProvider implements IClientVerifyingProvider {
common: Common;
vm: VM | null = null;
private blockHashes: { [blockNumberHex: string]: Bytes32 } = {};
private blockPromises: {
[blockNumberHex: string]: { promise: Promise<void>; resolve: () => void };
} = {};
private blockHeaders: { [blockHash: string]: BlockHeader } = {};
private latestBlockNumber: number;
private _methods: Map<string, Function> = new Map<string, Function>(
Object.entries({
eth_getBalance: this.getBalance,
eth_blockNumber: this.blockNumber,
eth_chainId: this.chainId,
eth_getCode: this.getCode,
eth_getTransactionCount: this.getTransactionCount,
eth_call: this.call,
eth_estimateGas: this.estimateGas,
eth_sendRawTransaction: this.sendRawTransaction,
eth_getTransactionReceipt: this.getTransactionReceipt,
eth_getLogs: this.getLogs,
}),
);
private rpc: RPC;
constructor(
rpcHandler: Function,
blockNumber: number,
blockHash: Bytes32,
chain: bigint | Chain = Chain.Mainnet,
) {
this.common = new Common({
chain,
hardfork: chain === Chain.Mainnet ? Hardfork.Shanghai : undefined,
});
const _blockNumber = BigInt(blockNumber);
this.latestBlockNumber = blockNumber;
this.blockHashes[bigIntToHex(_blockNumber)] = blockHash;
this.rpc = new RPC(rpcHandler);
}
update(blockNumber: number, blockHash: Bytes32) {
const blockNumberHex = bigIntToHex(BigInt(blockNumber));
if (
blockNumberHex in this.blockHashes &&
this.blockHashes[blockNumberHex] !== blockHash
) {
console.log(
"Overriding an existing verified blockhash. Possibly the chain had a reorg",
);
}
const latestBlockNumber = this.latestBlockNumber;
this.latestBlockNumber = blockNumber;
this.blockHashes[blockNumberHex] = blockHash;
if (blockNumber > latestBlockNumber) {
for (
let b = BigInt(latestBlockNumber) + BigInt(1);
b <= blockNumber;
b++
) {
const bHex = bigIntToHex(b);
if (bHex in this.blockPromises) {
this.blockPromises[bHex].resolve();
}
}
}
}
public async rpcMethod(method: string, params: any) {
if (this._methods.has(method)) {
return this._methods.get(method)?.bind(this)(...params);
}
throw new Error("method not found");
}
private async getBalance(
addressHex: AddressHex,
blockOpt: BlockNumberOrTag = DEFAULT_BLOCK_PARAMETER,
) {
const header = await this.getBlockHeader(blockOpt);
const address = Address.fromString(addressHex);
const { result: proof, success } = await this.rpc.request({
method: "eth_getProof",
params: [addressHex, [], bigIntToHex(header.number)],
});
if (!success) {
throw new Error(`RPC request failed`);
}
const isAccountCorrect = await this.verifyProof(
address,
[],
header.stateRoot,
proof,
);
if (!isAccountCorrect) {
throw new Error("Invalid account proof provided by the RPC");
}
return bigIntToHex(proof.balance);
}
private async blockNumber(): Promise<HexString> {
return bigIntToHex(BigInt(this.latestBlockNumber));
}
private async chainId(): Promise<HexString> {
return bigIntToHex(this.common.chainId());
}
private async getCode(
addressHex: AddressHex,
blockOpt: BlockNumberOrTag = DEFAULT_BLOCK_PARAMETER,
): Promise<HexString> {
const header = await this.getBlockHeader(blockOpt);
const res = await this.rpc.requestBatch([
{
method: "eth_getProof",
params: [addressHex, [], bigIntToHex(header.number)],
},
{
method: "eth_getCode",
params: [addressHex, bigIntToHex(header.number)],
},
]);
if (res.some((r) => !r.success)) {
throw new Error(`RPC request failed`);
}
const [accountProof, code] = [res[0].result, res[1].result];
const address = Address.fromString(addressHex);
const isAccountCorrect = await this.verifyProof(
address,
[],
header.stateRoot,
accountProof,
);
if (!isAccountCorrect) {
throw new Error(`invalid account proof provided by the RPC`);
}
const isCodeCorrect = await this.verifyCodeHash(
code,
accountProof.codeHash,
);
if (!isCodeCorrect) {
throw new Error(
`code provided by the RPC doesn't match the account's codeHash`,
);
}
return code;
}
private async getTransactionCount(
addressHex: AddressHex,
blockOpt: BlockNumberOrTag = DEFAULT_BLOCK_PARAMETER,
): Promise<HexString> {
const header = await this.getBlockHeader(blockOpt);
const address = Address.fromString(addressHex);
const { result: proof, success } = await this.rpc.request({
method: "eth_getProof",
params: [addressHex, [], bigIntToHex(header.number)],
});
if (!success) {
throw new Error(`RPC request failed`);
}
const isAccountCorrect = await this.verifyProof(
address,
[],
header.stateRoot,
proof,
);
if (!isAccountCorrect) {
throw new Error(`invalid account proof provided by the RPC`);
}
return bigIntToHex(proof.nonce.toString());
}
private async call(
transaction: RPCTx,
blockOpt: BlockNumberOrTag = DEFAULT_BLOCK_PARAMETER,
) {
try {
this.validateTx(transaction);
} catch (e: any) {
throw new Error((e as Error).message);
}
const header = await this.getBlockHeader(blockOpt);
const vm = await this.getVM(transaction, header);
const {
from,
to,
gas: gasLimit,
gasPrice,
maxPriorityFeePerGas,
value,
data,
} = transaction;
try {
const runCallOpts = {
caller: from ? Address.fromString(from) : undefined,
to: to ? Address.fromString(to) : undefined,
gasLimit: toType(gasLimit, TypeOutput.BigInt),
gasPrice: toType(gasPrice || maxPriorityFeePerGas, TypeOutput.BigInt),
value: toType(value, TypeOutput.BigInt),
data: data ? toBuffer(data) : undefined,
block: { header },
};
const { execResult } = await vm.evm.runCall(runCallOpts);
return bufferToHex(execResult.returnValue);
} catch (error: any) {
throw new Error(error.message.toString());
}
}
private async estimateGas(
transaction: RPCTx,
blockOpt: BlockNumberOrTag = DEFAULT_BLOCK_PARAMETER,
) {
try {
this.validateTx(transaction);
} catch (e) {
throw new Error((e as Error).message);
}
const header = await this.getBlockHeader(blockOpt);
if (transaction.gas == undefined) {
// If no gas limit is specified use the last block gas limit as an upper bound.
transaction.gas = bigIntToHex(header.gasLimit);
}
const txType = BigInt(
transaction.maxFeePerGas || transaction.maxPriorityFeePerGas
? 2
: transaction.accessList
? 1
: 0,
);
if (txType == BigInt(2)) {
transaction.maxFeePerGas =
transaction.maxFeePerGas || bigIntToHex(header.baseFeePerGas!);
} else {
if (
transaction.gasPrice == undefined ||
BigInt(transaction.gasPrice) === BigInt(0)
) {
transaction.gasPrice = bigIntToHex(header.baseFeePerGas!);
}
}
const txData = {
...transaction,
type: bigIntToHex(txType),
gasLimit: transaction.gas,
};
const tx = TransactionFactory.fromTxData(txData, {
common: this.common,
freeze: false,
});
const vm = await this.getVM(transaction, header);
// set from address
const from = transaction.from
? Address.fromString(transaction.from)
: Address.zero();
tx.getSenderAddress = () => {
return from;
};
try {
const { totalGasSpent } = await vm.runTx({
tx,
skipNonce: true,
skipBalance: true,
skipBlockGasLimitValidation: true,
block: { header } as any,
});
return bigIntToHex(totalGasSpent);
} catch (error: any) {
throw new Error(error.message.toString());
}
}
private async sendRawTransaction(signedTx: string): Promise<string> {
// TODO: brodcast tx directly to the mem pool?
const { success } = await this.rpc.request({
method: "eth_sendRawTransaction",
params: [signedTx],
});
if (!success) {
throw new Error(`RPC request failed`);
}
const tx = TransactionFactory.fromSerializedData(toBuffer(signedTx), {
common: this.common,
});
return bufferToHex(tx.hash());
}
private async getTransactionReceipt(
txHash: Bytes32,
): Promise<JSONRPCReceipt | null> {
const { result: receipt, success } = await this.rpc.request({
method: "eth_getTransactionReceipt",
params: [txHash],
});
if (!(success && receipt)) {
return null;
}
const header = await this.getBlockHeader(receipt.blockNumber);
const block = await this.getBlock(header);
const index = block.transactions.findIndex(
(tx) => bufferToHex(tx.hash()) === txHash.toLowerCase(),
);
if (index === -1) {
throw new Error("the recipt provided by the RPC is invalid");
}
const tx = block.transactions[index];
return {
transactionHash: txHash,
transactionIndex: bigIntToHex(BigInt(index)),
blockHash: bufferToHex(block.hash()),
blockNumber: bigIntToHex(block.header.number),
from: tx.getSenderAddress().toString(),
to: tx.to?.toString() ?? null,
cumulativeGasUsed: "0x0",
effectiveGasPrice: "0x0",
gasUsed: "0x0",
contractAddress: null,
logs: [],
logsBloom: "0x0",
status: BigInt(receipt.status) ? "0x1" : "0x0", // unverified!!
};
}
private async getLogs(args: any) {
const { result: logs, success } = await this.rpc.request({
method: "eth_getLogs",
params: [args],
});
if (!(success && logs)) {
return null;
}
return logs;
}
private async getVMCopy(): Promise<VM> {
if (this.vm === null) {
const blockchain = await Blockchain.create({ common: this.common });
// path the blockchain to return the correct blockhash
(blockchain as any).getBlock = async (blockId: number) => {
const _hash = toBuffer(await this.getBlockHash(BigInt(blockId)));
return {
hash: () => _hash,
};
};
this.vm = await VM.create({ common: this.common, blockchain });
}
return await this.vm!.copy();
}
private async getVM(tx: RPCTx, header: BlockHeader): Promise<VM> {
// forcefully set gasPrice to 0 to avoid not enough balance error
const _tx = {
to: tx.to,
from: tx.from ? tx.from : ZERO_ADDR,
data: tx.data,
value: tx.value,
gasPrice: "0x0",
gas: tx.gas ? tx.gas : bigIntToHex(header.gasLimit!),
};
const { result, success } = await this.rpc.request({
method: "eth_createAccessList",
params: [_tx, bigIntToHex(header.number)],
});
if (!success) {
throw new Error(`RPC request failed`);
}
const accessList = result.accessList as AccessList;
accessList.push({ address: _tx.from, storageKeys: [] });
if (_tx.to && !accessList.some((a) => a.address.toLowerCase() === _tx.to)) {
accessList.push({ address: _tx.to, storageKeys: [] });
}
const vm = await this.getVMCopy();
await vm.stateManager.checkpoint();
const requests = accessList
.map((access) => {
return [
{
method: "eth_getProof",
params: [
access.address,
access.storageKeys,
bigIntToHex(header.number),
],
},
{
method: "eth_getCode",
params: [access.address, bigIntToHex(header.number)],
},
];
})
.flat();
const rawResponse = await this.rpc.requestBatch(requests);
if (rawResponse.some((r: any) => !r.success)) {
throw new Error(`RPC request failed`);
}
const responses = rawResponse
.map((r: any) => r.result)
.reduce(
(acc, curr, idx, arr) =>
idx % 2 === 0 ? acc.concat([[curr, arr[idx + 1]]]) : acc,
[],
) as [AccountResponse, CodeResponse][];
for (let i = 0; i < accessList.length; i++) {
const { address: addressHex, storageKeys } = accessList[i];
const [accountProof, code] = responses[i];
const {
nonce,
balance,
codeHash,
storageProof: storageAccesses,
} = accountProof;
const address = Address.fromString(addressHex);
const isAccountCorrect = await this.verifyProof(
address,
storageKeys,
header.stateRoot,
accountProof,
);
if (!isAccountCorrect) {
throw new Error(`invalid account proof provided by the RPC`);
}
const isCodeCorrect = await this.verifyCodeHash(code, codeHash);
if (!isCodeCorrect) {
throw new Error(
`code provided by the RPC doesn't match the account's codeHash`,
);
}
const account = Account.fromAccountData({
nonce: BigInt(nonce),
balance: BigInt(balance),
codeHash,
});
await vm.stateManager.putAccount(address, account);
for (let storageAccess of storageAccesses) {
await vm.stateManager.putContractStorage(
address,
setLengthLeft(toBuffer(storageAccess.key), 32),
setLengthLeft(toBuffer(storageAccess.value), 32),
);
}
if (code !== "0x")
await vm.stateManager.putContractCode(address, toBuffer(code));
}
await vm.stateManager.commit();
return vm;
}
private async getBlockHeader(
blockOpt: BlockNumberOrTag,
): Promise<BlockHeader> {
const blockNumber = this.getBlockNumberByBlockNumberOrTag(blockOpt);
await this.waitForBlockNumber(blockNumber);
const blockHash = await this.getBlockHash(blockNumber);
return this.getBlockHeaderByHash(blockHash);
}
private getBlockNumberByBlockNumberOrTag(blockOpt: BlockNumberOrTag): bigint {
// TODO: add support for blockOpts below
if (
typeof blockOpt === "string" &&
["pending", "earliest", "finalized", "safe"].includes(blockOpt)
) {
throw new Error(`"pending" is not yet supported`);
} else if (blockOpt === "latest") {
return BigInt(this.latestBlockNumber);
} else {
const blockNumber = BigInt(blockOpt as any);
if (blockNumber > BigInt(this.latestBlockNumber) + MAX_BLOCK_FUTURE) {
throw new Error("specified block is too far in future");
} else if (blockNumber + MAX_BLOCK_HISTORY < this.latestBlockNumber) {
throw new Error(
`specified block cannot older that ${MAX_BLOCK_HISTORY}`,
);
}
return blockNumber;
}
}
private async waitForBlockNumber(blockNumber: bigint) {
if (blockNumber <= this.latestBlockNumber) return;
console.log(`waiting for blockNumber ${blockNumber}`);
const blockNumberHex = bigIntToHex(blockNumber);
if (!(blockNumberHex in this.blockPromises)) {
let r: () => void = () => {};
const p = new Promise<void>((resolve) => {
r = resolve;
});
this.blockPromises[blockNumberHex] = {
promise: p,
resolve: r,
};
}
return this.blockPromises[blockNumberHex].promise;
}
private async getBlockHeaderByHash(blockHash: Bytes32) {
if (!this.blockHeaders[blockHash]) {
const { result: blockInfo, success } = await this.rpc.request({
method: "eth_getBlockByHash",
params: [blockHash, true],
});
if (!success) {
throw new Error(`RPC request failed`);
}
const headerData = headerDataFromWeb3Response(blockInfo);
const header = new BlockHeader(headerData, { common: this.common });
if (!header.hash().equals(toBuffer(blockHash))) {
throw new Error(
`blockhash doesn't match the blockInfo provided by the RPC`,
);
}
this.blockHeaders[blockHash] = header;
}
return this.blockHeaders[blockHash];
}
private async verifyProof(
address: Address,
storageKeys: Bytes32[],
stateRoot: Buffer,
proof: GetProof,
): Promise<boolean> {
const trie = new Trie();
const key = keccak256(address.toBuffer());
const expectedAccountRLP = await trie.verifyProof(
stateRoot,
toBuffer(key),
proof.accountProof.map((a) => toBuffer(a)),
);
const account = Account.fromAccountData({
nonce: BigInt(proof.nonce),
balance: BigInt(proof.balance),
storageRoot: proof.storageHash,
codeHash: proof.codeHash,
});
const isAccountValid = account
.serialize()
.equals(expectedAccountRLP ? expectedAccountRLP : emptyAccountSerialize);
if (!isAccountValid) {
return false;
}
if (storageKeys.length !== proof?.storageProof.length) {
console.error("missing storageProof");
throw new Error("missing storageProof");
}
for (let i = 0; i < storageKeys.length; i++) {
const sp = proof.storageProof[i];
const key = keccak256(setLengthLeft(toBuffer(storageKeys[i]), 32));
const expectedStorageRLP = await trie.verifyProof(
toBuffer(proof.storageHash),
toBuffer(key),
sp.proof.map((a) => toBuffer(a)),
);
const isStorageValid =
(!expectedStorageRLP && sp.value === "0x0") ||
(!!expectedStorageRLP &&
expectedStorageRLP.equals(Buffer.from(rlp.encode(sp.value))));
if (!isStorageValid) {
return false;
}
}
return true;
}
private verifyCodeHash(code: Bytes, codeHash: Bytes32): boolean {
return (
(code === "0x" && codeHash === "0x" + KECCAK256_NULL_S) ||
byteArrayEquals(keccak256(fromHexString(code)), fromHexString(codeHash))
);
}
private validateTx(tx: RPCTx) {
if (tx.gasPrice !== undefined && tx.maxFeePerGas !== undefined) {
throw new Error("Cannot send both gasPrice and maxFeePerGas params");
}
if (tx.gasPrice !== undefined && tx.maxPriorityFeePerGas !== undefined) {
throw new Error("Cannot send both gasPrice and maxPriorityFeePerGas");
}
if (
tx.maxFeePerGas !== undefined &&
tx.maxPriorityFeePerGas !== undefined &&
BigInt(tx.maxPriorityFeePerGas) > BigInt(tx.maxFeePerGas)
) {
throw new Error(
`maxPriorityFeePerGas (${tx.maxPriorityFeePerGas.toString()}) is bigger than maxFeePerGas (${tx.maxFeePerGas.toString()})`,
);
}
}
private async getBlock(header: BlockHeader) {
const { result: blockInfo, success } = await this.rpc.request({
method: "eth_getBlockByNumber",
params: [bigIntToHex(header.number), true],
});
if (!success) {
throw new Error(`RPC request failed`);
}
// TODO: add support for uncle headers; First fetch all the uncles
// add it to the blockData, verify the uncles and use it
const blockData = blockDataFromWeb3Response(blockInfo);
const block = Block.fromBlockData(blockData, { common: this.common });
if (!block.header.hash().equals(header.hash())) {
throw new Error(
`BN(${header.number}): blockhash doest match the blockData provided by the RPC`,
);
}
if (!(await block.validateTransactionsTrie())) {
throw new Error(
`transactionTree doesn't match the transactions provided by the RPC`,
);
}
return block;
}
private async getBlockHash(blockNumber: bigint) {
if (blockNumber > this.latestBlockNumber)
throw new Error("cannot return blockhash for a blocknumber in future");
// TODO: fetch the blockHeader is batched request
let lastVerifiedBlockNumber = this.latestBlockNumber;
while (lastVerifiedBlockNumber > blockNumber) {
const hash =
this.blockHashes[bigIntToHex(BigInt(lastVerifiedBlockNumber))];
const header = await this.getBlockHeaderByHash(hash);
lastVerifiedBlockNumber--;
const parentBlockHash = bufferToHex(header.parentHash);
const parentBlockNumberHex = bigIntToHex(BigInt(lastVerifiedBlockNumber));
if (
parentBlockNumberHex in this.blockHashes &&
this.blockHashes[parentBlockNumberHex] !== parentBlockHash
) {
console.log(
"Overriding an existing verified blockhash. Possibly the chain had a reorg",
);
}
this.blockHashes[parentBlockNumberHex] = parentBlockHash;
}
return this.blockHashes[bigIntToHex(blockNumber)];
}
}

536
src/constants.ts Normal file
View File

@ -0,0 +1,536 @@
export const BEACON_SYNC_COMMITTEE_SIZE = 512;
export const mainnetConfig = {
genesis_time: "1606824023",
genesis_validator_root:
"0x4b363db94e286120d76eb905340fdd4e54bfe9f06bf33ff6cf5ad27f511bfe95",
slot: "6275237",
committee_pk: [
"0x9163821b21398fabd7fc110483c7100d4561f84d34eb8fe702762f5ad15b21c1de05b7552e400750ef87107054d2024c",
"0xb5b3eed089c61c731ea4b8da89d79953d1dcd076f0388e5a9a83d06601ccf8daf0b853ca706f79fee60ed2cd9a385f24",
"0xa84a73bbc11ea45136d6b315ae470c6494c418f9ec66648f3345f73f886e2b79171f1dc8bd7ca678064a71976ddd6866",
"0x86de1398c34f7ef2a0d6ad10f8d09591c7d1fa1dc5336513bba619933c0bd48be956367261aad5d17553aa6052434b34",
"0xb97cb89ec7055b04c7b9fd7eccc4a45715395c7316e42c9e241eadaaf7744b82b70b78acd6c64f95dd7138978356cd6c",
"0x8ee3b246427b9a208b272db2613fdde603b40550e0f3205a6f005d5e38cb028bdba44803287a78bc9c577324ae9e5251",
"0xa29f0427fc761318e6122277937b066950a6d749a5795f26e80b9fe1d2b41accb26c344b241d39e354638892b7f617f4",
"0x91246b7f68034b436ba623979c9a665746f3de5de495115c042a2332f23578131ed0c61aa69c24a1b1c3ea0732dec40b",
"0x8dbe5cf5acd2e860969a29165e04c5e7126070526dc160e2a77ebdccb1921be81bc1cc8d6d3bf704ff5efa9e47e4c355",
"0xa372476af4b0896ffb47efe4725537f9d4a49e563058008c74d1397f5d0a66c934b2c29078bd8e89f4b055d817453f03",
"0x8deaccd6915a70536cf44352e36139ce41dcac10bdf28616cb61b0b3f2dfb819267255709969497c986602d46f24e49e",
"0x877c5114d0fd6b1e3fe5853d297c31768c25f5aaf4a56d21c0d1167497009c9360e323810fefa294768555509f1da41f",
"0xa909c87e08c44584aae53f9380652edbf2373a0f7042e57d4340b4353d932495dadc8f340048180e578d9f93be77ca74",
"0x84e194104f1fab523bb2e5a91367612b15bdcd4d736e7f4633df695e0c1aabedea01b3440915cf0790661eb2a47af9f4",
"0xb1b58b4efd14539178aa289ca9a1a3b57efc8b12e3fb94ce6ee0014d7ad30c5c93f4e652cb5773f9f7d375f3e01dce3b",
"0x92b2a5471d662a302c6b2b90f3eae2c055ac3eeaf29c90f1a41f43eb4564f0eb15a641077f83bf4b59b61dec0bd651d5",
"0xb83ad1c495bc838742bebf2b5a31f4abf201ec93565146b95417a6794ad9c9cb0b944d7945d35735995b248d0d30f687",
"0xb64c8327897cb8b16a02a180242ea8eb3a7e8053db0ee4bbdc83bbf00b87b2300f386e43caf4dfac7627844a441d1727",
"0x836eba6f2f08438b95cc2f9e8f45ec42fc843892def3005df9291de9ff0bb8a26442270c6acbad1ea009b1026dfdd09b",
"0x90fcf0aecdf3bae07054961cd0b13922a61215e2bc128d481cbaa76eb98dae426b5fc848d4c357b46aff6eabf766ba6b",
"0x8208bfbf689752bed2c110b19f66d90e336be2f93331f0e32f355652a258366f79843a0f528f17c893e6a7feaadc5a11",
"0xa1e099011217619de38f780b46ab4bb97c88968ba994e3e0b47c9c32fabc985f1f74fb40deafa6670d5fcb41add29c4d",
"0x8184b64e342d9c02e47461b494782247bb178613d6ba814b7e96dab1170675fb45d0a2dddd3cf119361c022ffb58f55e",
"0x939fddb7877e6064ad39888f06ee733bbfb8523adc72d381e5429592ecbfb16fd26cc7b009fcfa03c56390f2e5da7cda",
"0x98421b84b58fbf62c1017c0b252848ae09d91c461693834e8b016a3dc476fa95aa4673fe858422a1ddacc0f7c85ef4c5",
"0xa3f69eb68d11d8fdf2f3718b114a8f6deda97474e9986e879acd503c0cb4cb2de319a015ce28c10f161f4fa485354857",
"0x8c14681476836e1b86f9d6c52c56b48269d1ef359f6006eac5063b7831cc73ab5d30eaba8a1fa99edbe9da03e9755969",
"0xa4f1ecba907961d6a86aea821550b28f00551814188b0f5ddbbb486f3ac4d063554c48b4cd685b7104707f1b13dc1b2a",
"0x96d7b0775111dbbb747242bbf9735e441aa9775a58f915418dff8507a0990532256bf0dd03b8bab011d99ff6e2c35cd9",
"0x8c81dcaa669a0ce8fa46920385ed3abdcc8b8a3209a176c2d2aff1f3a1deee8f22e2b9477a33d58c1d91ec62eda1a931",
"0xae05610abffb2d21709f64b04d4b59e12a0d8a738fb8e9161705b0bbbf40a69a7f432850c82c4bfff96db7875fb69ced",
"0x8078a2aea4c2b52d93f2686caa0f128b18600c02b24725314b2d02e701ba0b60c8d1f168de8e4364b2cae31ecced4094",
"0xb6a4f4de40f1c39a3d99dda56fa3815d394e4585632e98c39873348053006099c317db09b2028e9d45644dbeab45a9fb",
"0x85950570508f1567455863018614ee8aaf58aff2e6d5f54c7ec3b8cad69257bc642355fbb652eea772b4e8f5ea6dfcb5",
"0xa8f5a8bf2ea05042da3a5e77e881e4002dceee5229839c2e19a78931a91fd162a8ca1b70493d21bb8c80dbc0d03ac10f",
"0x8e6e04cd6608d961a225c22b9d07420f545dba1855de35a2e541b15843c2fb9abc4165c61bca5f5ab8298870d99054ef",
"0x992de481659c968b23c03dcdd5a8ad0fa9d00ad54e6a348f754b6dfda5e133bea2c52c295059a6467e4d1e65636f8d0f",
"0x95c16a1ba548e4d7af503921a92d4af407e6da7cc383ce5153916b2dfb49ccd27fd513a1a0599b8b0a2bf75c0c3dff10",
"0xab7bf86088748ebd4a24eb8db91bc72351094e0203f3109194ff1506e239bf9102d128a37ecd911005e74ab7ee57397b",
"0xb375c65fddd939dd19563262fe63cda6f8eef858cce226c95023acff69a3748fdc15d6e2b51caeb6adc60e36cb741ef6",
"0x8cacf8dfc5ca961a13ab4adc6a21e2c8d81a575d70eb2007bf6d78d8e01b032b2774e978855d226d8fceb2c57b5cd69a",
"0x9279d1e437728bbb0c9f79b534a5c394e08c48b5f39fdbc5f4743a36f5b58717bcd0def9c30170f4e2ce761137645f14",
"0xb2c5e1fb714cd67aef7a4b35d379c13f5341236cf66b17aeccebe84d250d1b5ace9605b767b1d1abad7d226be50b003b",
"0x805a7629f90f4a8efd744248741c128b02369f3e680ab3029164faf47bb2bfc5fe02f02f4bc3c76ad83b3397335d19c3",
"0xae31a38e151d69ce1c95f26a92472c3c29a8574c438cc2766a7da55bc563fb92f190c4a2322080f3344c504c0aee1556",
"0xa2c0bf5e88743903136a30ba8b49a635b85d112c2edd6770bbad3889cb6200632fe42f44bcdafcba905a4328e98ba3ba",
"0x8f0797a0ab508ac3dab337611afb42691919caf378bd9cce9cdfd0c4d158f20dc30ac33c2393a013c25873452b4320f4",
"0x907b31004301d30af194fb1951b01a954da2ee8b791b3c0eed31b623da59c0c7d6f13a8a906948d4b70c06356cf63892",
"0xa6ddc27d9b7e792a03eecf475f805106bfbf2fbfd0e1035e52926e9c6c5e111e5c5fcd6b93fc904320b0a770d9fa06ae",
"0x86ea128a4659dc60f32980d144cb23f1ad443049f343b8f06ff7d279c8afab03cc897e6d39dd4ed202edc559de2ea5ba",
"0xa847919d88e51fdd2c332938698154aadd5e7628f7a369a21600302b9756f7ec549e583b5d8f251fc0db6e917d4fdeda",
"0x8919698051604efa30f649fe84ec5ca0f893194a488f9b88d4e40f84a8bf79bb71433e3f91e7e4b63fdb3bc1b82c5e15",
"0x944752bea5b4ed9fde39739746571e3d33a42431774cb0b3f25e3b42bfd050f871d40f1f38674e4c8dc01b82a3c6ec60",
"0xb44651084265cb025249812a12d80bd4d4d187d341e63798a3471d3a790e3dcb65fd48feb94e677f346b1f71fea92d05",
"0x8da7a161a38d2b3679a9639ae6b33e06115ed92c20bad3dd9fe6cc17400dfb039cc7e96c764f00ed03635633b2947cb6",
"0x93ac2f91830afe49e824584a8633c90fcb33a107162788e709239e73879663a6a2a0777832d5374d5b7f2e2a84cd9a55",
"0x865733ae45cc093be1897cc5196f35b2dffb03d0a182550010bbce35d32489b0e4fdccbf74070c76e17a4465308e1f58",
"0xb900529b1f646d4f4f7dc3c314133553e27df54b6e46546e08e9977f5d4a171e59154c421976610560747e151edd5db6",
"0x9037840cba56ac61fe37ec3f58df287bd71cd73918fa43617bfe426715e118daaa21694beb2e8ad66bce407d4040e2a2",
"0x84f928611fc07144a10ed7fcd58f00e47fe9db2fceec778c9fad72dd68ce8d9e52aab9a8b62e7544a8d823108e10a87c",
"0x909dc44d972c837208e21aa96bb0a75d8e790afbad70f68a30893214fd0265e8d9a804e33ed851952fa52b6f1272bf52",
"0xb8f6f6371dd30318d1d6b0fde75d2eacb335eaa5bedba11137cee60aa0e533c4e6b56051d5265402f75e03fab98abb57",
"0x85543d8fafee7869b282fbc80e4022c8c1852ad83f8ddf363c86d72316fe356d0ca707c41d59ec46a736aecf54d1ce7b",
"0x86d0674250fe443f2aad96afa74a0b6f34c4aa62cf2053810e113c5184556ab9d8bb06f2080a0602ee2ea1bb3626a285",
"0xab5646a6e44a5ee2b2eb689d8090796795ef31cffa3e7262335f9180a93c104b7873d4829724b2c81dce812555e69622",
"0x8ca50b96907f6d0f5a1018d222e4ec6442fa47703ebfad8ecb01447e367d388ccb9292e8300aa0d7053cafbe923b3a31",
"0x8e6e81a3f7ce719acdb9aa84a56d4deff67497e1c355ba013173e05d760909eed1db0c2a4b9a2957925f21a564b71e19",
"0xa1f791e32fe47e794a5a25305e284b4d7aaaa6bdebb32421ac359968a2273412da334daaa8e25443748d88ac3a9d058b",
"0x9144aed94e9f3c8a6b9bc88ccdcd157c847261e382cca8ed3bbd3a896fcdb9146f00b9f8bb0f413aa7c9f3ddbe9af077",
"0x80a1d46002224cc82258626314616fa2b1a672212adee0e1be1ebd2f4feaaf6acb909b2fcf555c72867f83566df007ec",
"0xb1cb3dedf781792268c8c41eebd20fdf67211d3a9b6972637d677e58c3da6d8aaf5f163adb1bb779a3dc73dbeb4c3b8a",
"0xa547ae87c696c5f0b7679946de05ec0c55c1b2b00fb36855b05564c2d2d6c1df57b5696b309ba131b0097dfa7c264822",
"0xa24784af730f8c666df2b36d5d9a88f6c15e3cf605963fc84ca045b93b1df4360b0fdf74f977f06bc148a7d038c34c9e",
"0xb6e456c86204188f6e0f23493629a0df21180cbc8055ad69bdec0d31d948c4fb261ed891bdb5610eedae965aa5cb0234",
"0x8b9698a450cae8ea9c5b0245bd06ada77d98ee2de47c60bcce7b59cf7d8aa411c8ee1434e0d56959e56debfaab394451",
"0x86410dedbfa4e37aba412d876838fd96d83947cfb4f9aa1a6afa96ab2e1cc07714ec6255f0b824aac1581b14f0ef99dc",
"0x89236f180a6ca981ccd89ef342494da4e8dc04f7f7e42889febfe3c9cbb3311c03f4dab9846b828a3f3ff94669516bac",
"0x8bd93d986021291acc100bb8562ec7775c5c71eca443cf682c9aab507400467a8a9f36fc739879da14cf9f8f50f86486",
"0xb9ddd4bbc087e5fd6a5cce0d21d142d497f49cfd078c0ca9c27ab0f3f5dde41001fd571ccb13eca44069dbb35643a747",
"0x87644ba29892ec195c66cc47b33724d31f9d15633e4748f4c083aa08158cdf21e33778f94e5a247b46a485ca5a79ff66",
"0x96d8bc88cc4e4b5f8cb71be343f05dd29b89ab13fdd33691aa169eea0d156af67df7deabee94314ea10318650f380765",
"0xa45fb5dee7aba8112920024ba029d2b23615af2648e1141c76c382aae6d335eada20ca0c503b41743f24a87add4c2f64",
"0xaaa7a332e371a849b6711b86cbb6d36976b61fa761a5c610ff4cc0dbcfe1dc7381eade5a307cb7ed1e6da9f6f7f42327",
"0xa486ac6f702a73c5fd7e0752d6e6962b5918962ff906ca64b450f658c95fbc48d59e727044e9405c9881b8a32ba1a93c",
"0x91dd9404e0dda11f2f5784c394803f213c6509e95e22d803548a9439ae27ae76026eba5f9f78c4ef3f73eafcb11fbbe3",
"0x949d97a470d36c554d0da958c85f0fd1621cf16d877ffc8a2957d23eff77905cec853b039f37dd8e2f1f0b40642423eb",
"0xafb9ba62f707059ec63c3a39b232faaeb5244354d766bc224976d213f825f6ffee9ced5f6e611ce3d3314976c658b51e",
"0xb3e23d1869da02c7ff6d55b44ff40edb199b8524af88e0ea3bff03b0012d55be9491c18bb97cae04f74f9356197e7d4a",
"0xaab0f191119f0bbccd6316a1761817b312245fd712b5ceb115acf8f86b7f82c70fd24cd0ac0a8617ebea09f96ba528d7",
"0xb78d30f275f3f3016683ccbe8fccd49d1a6e6fa10d06da86a4e1d72cfbd9f13866b837327ed2dcc79a81a5968c59eb5b",
"0x8a430c56f61a5fa20199cfb52ac535e6a147ab9687043f41458c6e87e84d4a57a40072d0e5a6bfc941a666adcfdbcc97",
"0x8a0a0d206e18121f7f9fe9719c13b2efc1e385f53a9188b3ad018af66abd9514d8499969d8bb58b524859904e6a32cd6",
"0x8a21a7a34d4c083ac84cbb1e5b1706e042669edc6e84bb23aeef9db6fde4a8fe22f9c7fdeb97cf4b3a19519743e73d7a",
"0xa5857a5f1ec2debaef32525829914b7a1668a3b52ff2a26ea48b0a4b0426a0355c0eca3c0c1ed92449bfdf75a39932e3",
"0xada21f5e0e6f21f4256ab23752bd48f4d48c02079c24a5ff2e7d77ffff3148de1d22694c2d94f65043d1d73e189ba3e8",
"0xab4c8587a33bd087a31613caba1c378b6e6111b47af9db3484098a04c941cabb1e500ff20b9e28f19868cc2ed3a13412",
"0xac0f11d9713e5dc46a4a43d66a048ecbca27bdb8f5f1589ab7e6ae80dc7866475379c2d7db0fa224d3ecbd36fbb12b2b",
"0xb4842ffa87ad2a0560a2939c1dc5f78aa8cb306a4e8d47233be3a590763acb099c22e08eaa5382f711b989d680a583ed",
"0xa3b3cc88fd5a5df2ef1afa6b70a7f39c97460e0b78b1594081e89d0fcbb6d69002fe2a30682bb121673e84132a73ef9c",
"0xb5319fe0d851ed2738b13fc4a6687520424c902942e72c175bab19554e70fdd397d4328dd2f67d9988742aa1d295d86e",
"0x8a106834fb0c69b90b03e3e3cd0b3b5bc083775ab0d30795dc42d7e37fdd372700776f5f60974d6aecc9d7a3160f8788",
"0xac3e836d6c610f54eed01704a05e06dd04def07d9fe12c73c4ffce98a5f99e6950632bd4adcbaa198a16e4d3a71a6c71",
"0xa5d9a61c29a8ebc4b5aeabd97c0e67d8398d66e5614f690bec37f775e1b3c94d51ae870add02263a644272c29b0fa3e7",
"0xa08e9832ecf90a010011578594374740814927d96e7bd9a3dbfb238ee470ed24cd7d93b8431c620b7a15e53427306fb9",
"0xa37765e8a2c0886fcb1c32ca9f338badcbbeaba45a0db564a752fe6cd61ec64592c637d4defdaa2fdfa6fa9515dfc3f7",
"0x8a85b0d436dfa151fb5bd2b3df5f1c154419059886fa9d1295878018ff4d74776594d7b20e156d444dcade3bdcf547de",
"0x8f3833b1571998fa57be9195519518c561a294f6e6f3e4c03053421352d72e0a9b2bc19480418dbce10c0ac5fec11357",
"0xa1cd3e2391e05997e16e9776f1446d24c8bafb296c13967eee3a4ab2c6dd24ead01991d33e82ade45b75dc97f00a0f12",
"0xb7f45ea9f523fb0d29a1353ccae680ea66304d8177190a41c230906022dd67f95711bf554f0ec30d1ee0533e719ea731",
"0xaa4eb2d468695bd198f7ce1054787f39406a2b6e3929a2173437291c274580e07e7e1c544ba481bad1e13e72924e590e",
"0x93e872b659ade13c32ea74866057438d66297c593014c25288a6141be575fe710c636d77d8e761d83a13168bdde4e933",
"0x97f754596f032abbc8e2ab8aa71ffc17275d132b2b4f009622cfd988cfdcc3ceb4c7979354481ff4c18af0a3f2c42b1e",
"0x90bd5f97e38f3f740cd1cd2863428681c9b612e2466fe0b2bd649b6c16cb92416bc78cd4d4459d7085a3babfef419d31",
"0xa94f67e0937f6d765766d48e2713008bb47a67348f80ac5f3bbf982eaf3b0356c05c324e165a1a36074acd6f2cd021ed",
"0xa29490c145a7c33ba638c605551628109a2f328ee05d30d28e37085c60842e5996f0e5e63c9d087ffa191244b6496e20",
"0x870745a995e60cfa4545f2fe6ae55045e573eca266875f5c92ba5b11f1b26ae6a244a6f75474164606a540ae950cfb5d",
"0xa3022e81838ec7c8fef8ca0849ef14490ed955abee69ab5ba48c375fe2d6e12d3d931c6ce5534841fe655bbcccf76d65",
"0x85dfea2494655ac9b82d2708da3ec3e2d2dbb0e817cb6f00e59e25ff53de21d27a0433a3268a664a99a2dd1cdd259dcb",
"0x95669f663ffe70e67af25b46eeb9afb86601e5deef3770c4dedfd6d0974175a88451a9ed847771b0842e53cf3ddd5357",
"0x8b55e41a5057d38b88712dc4a1649dabc7d38ecb996e2fa623d9d19a614a933251dbf4e895659fbb94592e6513565fb6",
"0xa13c4e9cc82631e7217d8557921dbe000192aa05e84c8038606fc51ff6f6782466ff98b320899f5632f582d48ea12b0e",
"0xa4899e162292b9cc13a4c8934346ef674d0685f8663785b9d50c9d40239ccf03e15518886c7c649979c4841ab25a0e10",
"0x94dbe72e948f1cdec8b960a2446ff6ce503d3a3f675de779426c16bf57aeca042ce2e0b094e60f1dfedc56cf9c4e744d",
"0xb488f3f8785bb01d42ec360660beb46511703930e14d9c3926ff3f9061d2a9e16bcc30cfd99f2d276898ba93f409693f",
"0x8080faf7973fab3ff4424387e80dac2ebeb6e3618c0054f29e5f2cd8ac4caad12cf14ff2f4f76fb44d2afacf78cc0fef",
"0x8d759531132862a31cac44662ca6b8fadfd848e793aed946719c2b58ac1a7a53aa8bc47e749cd70e1f2bfb4316334260",
"0x8918947325c09614b9ddb3521723a21ef977643158a859a7a5af014831a342252e7bcc359c608c212f1f186c1f564ddf",
"0x803a5e75f70847146e14e8d5b9f1c0a2cd355cfb8ddaa151ad91096be609a68773da47e3bba260037624b2cf89547709",
"0x831fcf30734803fc34220d29cc5e939a9d0bb4e83f4eac0e57c26ef7801e2834ea0f3f18efc0a5fb189f720a6473f8b2",
"0xa69b91fe7f287be29869b3462b3a312df9e10dd648e30c05a6a71f4e34b3e4756cc0fae4efa03644f2e897d36a1121d5",
"0xa201fdded1e4a5e49a7cdbe9265e3874ec46443200ac7b8df9900ec20ab8cb689e8f3f2ea6bb13e073d61afb3f26abda",
"0xafd013a39a1b2159f6249d84411923f15c458b009c639089ce17dba43e4f546ca1fdaeba62692b87caa1125f9ad61e3c",
"0x8d234bb8dd507f21e65ec21ec7e7d876bc5137614cdc745c77afd1fbac8d64a51627c3ae4de156cc6cd7fa3a4e7ffdb1",
"0x90e6c41e75238c3ba010af024f58cbb8893616f04fe5296f40a31fdbcbfe9a867969be2d89e71675a6655f774919bc1a",
"0xaf41621c6301884b11a87442d832d0a4d7c80100d93a39ca16100cd0024af86554e267a2d2a7ec363abdf732c895ea0d",
"0x8426c8051e86a4af7cc5641f48eaa4fcefc40aa8a2c42102db9447b87d42d1d380a671038ba021df8989bea77eb8f258",
"0xa8a343e34e38fdaf99c026a039768c776c6d390cf9a5830a9f9b32aaaf9770a0d3dfced4d704375f8396cfd5a02558ff",
"0xa89a5e97ebfbca0b61bd7d81a42af2c90f50e76a29939ec1a91a3546c98079262a073e741321f6c3c46358db96225cd2",
"0xb2057a06e5af142dc850be51703eb33f99cee07b4348ab39789d56c473811155bc6b64062d4f555ea8f54bf73dd69f92",
"0xb9b1e37dd03b29ef65395174814fbd79796b44ced47b0fe8b96b679893d682c45f241db1fa3aefddbc952ebfa1fe4ba5",
"0x925de4b7d055d3672fcb06437fd963a2b73c02aa7e595924e96737c456f00fa29e200b4f4589e9da1946f17c8d0785f0",
"0xb1cf4441d5aeb008b7dc186a00373086d1aefa275b6b5b778529e17e32198ec2ed9793bac75e25c6b12235e36efa2cac",
"0xb97bf89e459a049e74b2090577d49cc4818449a57d7df2d4706dbdd7532a6bc910074f6440023aeb09c6bee7e67900d9",
"0xb162d62cfe6a00e0d978ea2f6d8ab587cd12a14be2805646ae5f1b8588a340a4f8b6171bc092439157afa501f39d15bc",
"0xac100aa45c48a11686d7e2573e66723ff49b06af4d96d900ce6c08dc1ffd0e01baeada1fc5e7374caf126b50e33e57cd",
"0xa775f58424f7d8ed1a5adee9219e049180cca30b16b2502ea44fc9adfc20e2d00a4309e9a680acb2740063df3fe19662",
"0x8eb562c31dbfd222c5c2741a9e3db283d74bdecfe84b25ce3ee9e134a800445be360ca87489738e413315ac72b1c5e17",
"0x805ea03698e30932bfb6ea2687be573457df1393a7599c9d8631686a77e364337c4cdb54db14294e90366947941883ef",
"0x9486feee2d5bcef469e1b51f1a8a73bd7711923b4e126855f4dc8858c4fbc9b77ee8a56eb814d97534832e25375ce099",
"0x8d2f02f84ed2218f6f871e074d50ebe15d5ed2408d26b2ae6fdbb6984c02b0f2cfdcb283b287aa78723f4e75e7b5d176",
"0x964a3dcffcfc66c46b67c80e8511f695c6012b8f233cb18d7273d61d8c0dd27e35ff5dea42f1e1e9650e2008a6f3cbef",
"0x93c510e082c19788830888a30ebdbe92716488ee0a205c2b7d839a380cf716f5e241a19a3a859e2f80dec8a42c7d68b2",
"0x9376c105d2eb1f55e39332af0d70e587be9ef398e239b49b01560fefb0c950389761cadf39a32e324d71859c317e1788",
"0xb3fd7ba1d7401cdc8422e2f8fecd745dea850882c909e7b812de4067fcc5f745bd252c5132a9f83c1554c1dfa4c66ec8",
"0x958ef935d5bc06a876498d77a1cc2950a7f6990bf8f9d4ef8866d387f800d74b5833d608124a413287d063a23abb7093",
"0x8b338bdb7a1114f13bf88d21ae925a4c8487c96982e9e0f08062a11603aaf22273fdde9dc8807286b9bf91e2449b8ac8",
"0xaf273415edef8bd34a9b593531bcb6b631ef3f8f2db78e9ed73596d3d6943415df5bd1a587e99c378510540a12109e64",
"0x8ac7b7421acd1962ec8a91c8feee71dc245578265a95dd24549a86e8a3525b608c4dc08c5ed7dd79c78cddc41232c74f",
"0xa85c85174ca8b7bcbbac0e2483514326bebcd2f489fdeefce7bab04fb78c92609c364a4c2b3226275dabd660647eb3e0",
"0x8e46723134d662536ded0356d98de24629d7d182538a13143af285ed001f77c6d8df18b1a64e6f3ca0106413ec9e7afb",
"0x8b23bda51177933888aae4911eadf355cc94d8c4a84eb7f448f7ac3189557f0fa5c4be4af851abd3eecaa7c34fa30b6b",
"0xace70d08c5b8cd039a114175a30d8403f2255ce8f2f558b3d421333236886c1cc5afc8dd691d265b398689644ab10395",
"0xaa5b937a8505a3e504b37d5e4f7b36dbab2dfc70e18afb97dee96912fcd89997063df8ec843bf121c9bf4617eff7eae3",
"0x9977305cc2e85a095d06ee266d9adbda6231a9daf90840e3fbd835a36a6864b34909a06623f972abbcf863094816328e",
"0x92c092833083640d786a37d02c61b624243713734c3da43f75276fee4b40d2c8eb965ef2e9d9670e211a5468039886ee",
"0xb1c7da2b1303369115a611e872c7a399aa4ca5cabd404028dd52072e01ccbec5b2dcdf9a2e5849b138bc72022c810ac8",
"0xb8f291719beaebfe457bca35b64ab848e9cf16d0a3f628ceef371b370e51aa22d76af65ac5551a23b18f4a39faa4b2e1",
"0x82b589989909ed2c6d1d32d389d8becd01200425539d9051f29f54aea94221e7f1b272015f79dbac0515d1e4328e979b",
"0x80d0cef079e1e8f6a780fca47879fb7034061c6c06dcc2693a495b706a9802c53cb87d576c262fa08f435aa32244db43",
"0x9577cc69857028913d17fceb515add33b0dc600afa3d9b63ec3c6968d82652798db5adc2ae38f5fb2c0b7ac5a5f769b2",
"0x8a511d3ba6f7b4f7a711c1e60d2636c04b522da38875345923b0a7bb678c3e82590d0267b5263d4c12bd792f4f5e132c",
"0xb08b7c5fcb1a7547bd4ea9f41f0866fdc85a9aa61033d08082c9e30665663d48ccd027e1cd7d10510239fe69f990307f",
"0xa2e899191cd1c3b01a7466610c2b587fe618996b220599c63484c4ee529af1151782a94c14c63496578f1df3104811f8",
"0xa1ff0a31b2230b4da5a0dec6e319d00083dc41d79b7c47c82c82c8605b0d9691a35d88b10fbfbab8c59e46e9c4080b4e",
"0x8d430b795e6919b6badce0b418951301f93588c1b054ed569bdd48f5d6e8dbf75d02b4377ff1f8b95560cb4ba181c2c3",
"0x8624dd4a9d5098044c09466d33d5b66b435073bcfd58002ff7a0901031c3594ba650762d6ffc88a3a8b94477205fbeaf",
"0x993e49e0b4918e68f6957bcb5f53ef20af64b3aadee53aceb5a14fc298196ab93549718b54e76cdd75451e8b301497cb",
"0xb1a2f00560c27d32a4ab3f396ad40f1e62aaa1db4deb1c39006dbfba03489debbae7458c76ad72b039fb34c31117ba34",
"0xa9882d23d069a540ba42dece3a39e1f233e3658381519579120e42b500c5dd3c8395512f656ea7e78aba3d73083092f0",
"0xa21f9fd8759ae47fc212bf3580f359942bf1b3b4145eb638aed042a5142501aa5c224dc497032476e78007a491ca2459",
"0x90d6a0201f12f1a47ec332d8c516faf10453cc422a34252de1560f7624a0e1d9c20e3a53b42a5677e5b48fcdd31d7935",
"0xa16ff223344ee621c16899ac061beac3a582843f6194e5a02bbc9d874ab2e7e58012c0e144c02f7ab23091ddc10827d3",
"0xaa30c72c04063b1d662921793967e7a5bb3b97ad6f677d7c7f4aa4dd72315f2c3f8d85d5b6ed33905f49a842734fc4c1",
"0xa046a6611bfa2321073ba0a4dbcf87cf0b3f94c5cfa9e5e6be5dd90c0cd29dc5d348c4f6f9167838116b3111df1b5147",
"0x8b886a87b701b9a57b6be2a9a5903c149b8710cc7523c5127f71948781135fd0d56dd1d22f2ca527a9f69a41330adbc7",
"0xb3348862f36087d86c408888fc6fad04e77f74110b78fc34e15cfe30856c1647534525b00a8592f90ae914f44b83e641",
"0xa0d27975bef72262f888ad6428267cb8ece0a543316a514955b44bdf0886d2ff0a9e580f5211ee70cf385e1563c06027",
"0x96237f46287c98839dfb2b49fa6dde42c5ad8a7a1a6a99d0015ac93d3e053ab926b993c5f98c9ac7f4e94caaa6899ef6",
"0xb3fcf279120a43fd4e48adccd42ae8290acc86991372d23d02040e84d7949ac397bde6d4241af6db509968b4fe7990ba",
"0x8457306541e0d888c6c5b6d6d141a102fb3d8b30e279fbf49c9c8f9771b28eededeba5faef0f5867721f18d4e1918da7",
"0x9308534c4c250bb7f82a3c9e44ee5d63ced5e2871acfd06b4b24517621ecce952751b4be0944ed822c3a9fe6bb4a285d",
"0xa3d3475c09357bd8e07d952c4f6ab4256eb029d427f882e80fe2109910b88af8f1d18da9dd5bdd895a8925dadfd40a14",
"0x91381256ae84f35322b2a65d924afca1cea930484f55f5f4e65a9d4aeb81626add7cd0f9e59ff74f69f523466d386e64",
"0x8bc8747ab34f8658d0398a2bbeca402d6c1ae9b5dc77a7a90a139ece106f34ef81ca069ac82920000ed887b6ec7c111d",
"0x8ab97cb412c0b5b436f5382cb9068c2af675bcbb4915537cd2161271ee658f779ad46af5fa2db3a09c6234290cc867e6",
"0xb31ae2f6e63e8d5f9df27c07ea330e244bf332c584f7b0c02aa62793796e28ef03a9fa96291978fd0ad27130628aae2c",
"0x92325d0cc40757e5de4e2513d714ecf4bc39e5ee3144c257d290e06c7aba2199d7c7fc0013438cca5d1ed3e057cd6662",
"0x85b6c7f3f071199de43235311a369c92c332ee522e9a43da5759615718695f03b7a7d1113311e85a5985d4c1e65a28c5",
"0x94034a9a0e112bcf064ace23bbec3e31e3691dd31f7c20813523f12f1a727d1f87cee4d550f074bdcf0b0c9ca9dc5240",
"0xb5c07216d45b69e1871f3e2e92326ef3c3fcefa313f4214a682853e7742173b722004fe08a40ef61ff0079ae2cf677f7",
"0x8168732d5f9a050a3f8aa46adc05ae570c5881544d7a48394a3e4839a511e2ec3ccf4b05112bb057713f5eff36ed35a6",
"0x95b234dad219e722070e7da16b761c8a28eeff074ad8a154ad25b8f2c9a8dee34778479ac61bd51bf1d4c2aa91df8b82",
"0x826a4fcb0eee37fe69de350e523a898bbc2208ab6973c78fbf5f28714335343ed682cacca1f7233237cbbf4d0e9d3c60",
"0xaa3cb3e4238c6cc359224f222a7b2498fb74bb8229f449c79d00abff7d699caefb20cb0e7ab284bc7bc8e161df206639",
"0xa400558c0e1c36c22b251f05716a57af8a7c8089871f1dcd84b831532b3edb56573f3dd6a988d2c55bc0b013e0164ad7",
"0xa3870970003cd3537a1b0d0db691ce32d84f556287fc7c5e688961c676efe81d91024027b6d2456ff9c315c10f94447b",
"0xa32aaead7538e44b5ec52501ea42abd8e1f6c158db5ce0ef6cb0242963c2d7875976cf38b77d13d326cb36914152fc29",
"0xb9b665eb858c4353ad64332624d5bd317a073f88e41cef4cd1c1517d5cdf7fdb40395ffbcbcdbe31dba86ecc7f37cd69",
"0xb7707bb96a8b0bc7a6c7e6cbc2224b8d79fc80f96db45cd48e6a5b12700c2352e3c5bd34e559bf2fd4b47f1a12f85edd",
"0xad7d4977af9e831ef85991fab8858139c10f28ad40e888e23b7adb6c9e7facd52b38d8978cfbec1c57b9346032b7356b",
"0xa1d450c53027339add61685b096c41b45b9b9498b6627de8b072167c5fdee1127e9accc3b30af51a9890be0db54de234",
"0x86b0221caf110587b1aa27a0a2340cd66356a43896581d00bb7cb310e3fa387c56d03ee296ca73467047ebe0bca38e2b",
"0xa759f0b3a520717b3aa3b193276d1dbe01411e7433a03a8d5e48c4b1e6aa4c98e3d7a90084bd696137bd6de5cf53d1dc",
"0x882d19da7ecb524f2762becaa73b070e659d7bec3a6e05405543ab6a6e42e134dae2f5bb614c7741b70ee87f7bc63cfe",
"0xb84589fe4447c3aa9d857f2218945b6156527287d31b36043236bc779b96f36620cc76fc7f66a42c4e1b5942ce6f0dd9",
"0x90f98c0462b1c2653ce9cbef68a18631a2466270a33ccb8c7bde2280d3a476943caa359320b4dfb564d47baae576cc89",
"0x946d75e88c9fd69cf473d311e9e9d5b4ac615e1ae1394066f55cd41e40f623e4438bb4e185942f2c98e0a35117289003",
"0xaf4ccb6e0f27a9d023477285fe15106fe1f9bd0fc35643c07a653cdcaf30f3bb6a91a2599e08d7d73a3aa74ca81ad174",
"0xa8b3622f97290ee4cc0156447987306a22976c2d5a6c5a35ec9bfe9adb591199edee8f7267966a656d944978101379aa",
"0xa850201489281fad169f4911d5d1bbea5d1e53eb65feeb33c86de716838d221834b0b39adb373782227d40daad772913",
"0xb77aede1e6a4aab734a53a7bbd1cf4dd328deebac27361155a1719e682bec97381c79d9adefbecaa3a244cdd78afbf7c",
"0x92f57406af66fd1232cd11938f20b87311e6765eb9e84e632f6ebcae99d219538c8f02c72fdb67ff035205bd9545c54a",
"0xabe544f9baae40dbc866e07241d3b69bae9ea3bc6a5250bde7c29c3cfc1c3a66d8502aac438fe11bb9593bc523a62055",
"0xa324942b374e96ed23fb946171b4fa108cd1de6e2ddc81269134279a8422926b34df97e1a86f59fea9f4f4fd5b3fa56c",
"0xab0244f85591da41ae6b7ba8eab39ae7486123748997ce811bd64d9a3edf5f8f7333e081972a25aa5d54c85de58fa0f8",
"0x92d0fe78f0b39f3dcafd8d127008262e4ab2a73fd4056eaed26074d47dee5a14973563b39210504481710393da9369ea",
"0x8903c66bbbc31d472fc121029f9ab2eb5fe5cecb76b79c4cf41770b13ea9ba8ffd3457eb02b2a9357a4b95e4b34daf0e",
"0xb13f55bcbe2b7bdf277596b5946998877a61ea9d4856ef89ba53a7a2e30f0f4fc09bf8890b6154fa99a203859449e347",
"0x93a3d7808dd94434172f4848be6b19fac64bfa44cb876e6541e54dbc5a7c85ab02eab556c7b5893e6d4e770bd495d94a",
"0xaf10d2b17141deb640cd4de9c4dda8c99e15d0e37b4ae52fd1458c28d07e5b1f9ff1304d4a9ee6afd2e728ec9dd0ed3c",
"0x85839b47f0666be16cebea74d7d6eb6ec5da98f4c24384821e8aca25fec913099d1531bf531806108abf3edf6cacb226",
"0x8d785392212fc074ec334084f3b70e16655897c7e2c8c142684e51187bdfc8ce7764eb3045b98a38f6fd8837b6b06a6e",
"0x97629511182f8f17fcb413e3ea1de9f43d7018e7cb89299b80b39d613024dc2723b0ed1c867301cdeb093f4e22397972",
"0x9295f4a46938606af852fd8e2a1e74d34bcd34998f74ab1397d30c36ae09209e83c1883f01866c66aa583ec69e24bc60",
"0x83e2ccc4210d18fb8b8ccf934b16f9f215a1139a8af3c0a115f3cbf973a43e1043c2e7a6aaedbb50dcd60179c0d71571",
"0x959e82159d314239308a48e9094053a7a12e667b936b9888483760b86c8deb050e3c5ef703c140f5457a51cf443be8d2",
"0x8b7baf0f488f83bd46ac5d02e8c3dd615cb78d9576d4e62db01d247dcd2cb15aaf1a8a0253a087aaab49e3c04731197f",
"0xa81997d6fc06d45d544c9069237b3aa7a5538a8afe9171c49e711a54bc00ca7ea6d9b0332f2327e11c1235ddb8944e93",
"0xad8bee10f9bb91a29069b55ed79c0f7e0c31f574ae133f99237e4031e12e19611e4e98a4a0d180ac9c8b8e8e88db9687",
"0xad9e6b92135e4e2b817f45dc2943ad635da76ec384f2818924d53616de36b60ed62278e9325d71f608028c5df05697e5",
"0x86679fb63540f8b3190dfd6baafb6a1810ac2e4486cd0c80624ed5faf811a0e4df51ba4e352d85126276b6cb27ae4e79",
"0xb269ac860ae99194ea92aa7b68a1ea7564684be06b23364f28e031521297a05a60ed44fc79b93634fce2429c28bca972",
"0x9910e52b68a1a97a874080a10dd5687a2e536c7c9106e65c16f45ef6fdaa3dea20d5e0089f000c6005fc44af878c7283",
"0xb91859c182d3b713b14743ddfd6da5dee1f0f7aa964a2b79f4f2b78218f550128dfdef442a9f8df8a91c1bce494ec1a8",
"0xb96dd044adc70aa4943bdb911c10cf1d69aa78da9b0753e9da4ba274dbc9686d5bfdbe444a9e9983a42f77fb545c225d",
"0xa10dfd035212ffc6a568b2cb4b6f2d9a501db926f686b9c6932ebd7ac64a608f23bc1102fd0ac3adcf36279e9b41f906",
"0xa0057a101105641b0381dfa5955dcff7382e72659885056b88ce399d50c1706c340909c7769e9c02304a133ca8ee5898",
"0x96102cb239f7358b06029ca15775383ad1d438e4956fbe3b99848d069494ae472d1d9bed852b041a224ccac772014d2b",
"0xa741c8ca68a72e14e379b715612f32362dc1952017a710dada744f8866fe7b980fb653560f4e83c4c616eec7f9094db4",
"0xa3409f9b99f39f7ddd567f6504b2c3bc8140bdf0d1e635a1fc8b0c7377183c9154ab64e8f5753c1ba647e006718618f7",
"0x8c32ad2e87b0146010f2225dd182e88c0c70f128314e3d7032dc5baaa1713a0c25a19cc9169532b820e0aadd15e991af",
"0x85433efd595dd9f49b2604d421fee903f9a49af910068bf92c79f938a3001404031c00dd92bbf2385cd2d884ff428d9c",
"0x86cebb07a6b312b5fa55c5ae4deb0a726f85a953ee16947ae38de316b84cb7e307599d9964d4bc41c7e3e3eba50551da",
"0xa13a4db1aa6e6c58e1ea4be8a8ad270a326e9dccb1e20922b5a131d46184b41ac5559bb56516565967fdbe234afddc7f",
"0x94a66d71c99736ef434e1edff5cfd15fc03cad9222dbfa6b9f7b71b3259bb01f0cef0759959710fe307f19e7eb8a50be",
"0xb84b94694295efee1616f5b1f078249aad56f2be720593edb422909db286b4afec85583aba79ad2161610869cbb7b23b",
"0x95e24ae991a496af69bf6ff2e98a218c8fbadcb81997e2122259e00e1156bd957bbb7b56e63b451499307cdc5aaee84a",
"0xa2cf774951105d3ec53c0ab329c4c382fbeac36f24e2f8a0575c988eff5d9cc42a1c4cdf58d5fe867eb11e2b1d4c6ede",
"0x99680bdaeae98104c93a0fae79cba5197529a2802c06506758e26e41ca9c2cfba3727fe56476b329153d36dafa092429",
"0xb18ab0d63b90ffd798b3e2f3c8b79be43c85b4d8e103526117ee3ba9d14a486524e99bfa19c1c13877add76ec21a077d",
"0xb32f88abadc42328bafb33eddf360cbcbcd27397c64120dcc90afd4c80c80ec6f97b3a1c0a6e25b98e26b1e0a8dea903",
"0x8b8197a841f9893f0275296fb1f57f5697de753d8be6ba3ea76641358a5b0ee5fd23d16d53f4f459759377979eb9741e",
"0x8d0dd5d40aba0a62bdbd192b129f13e8203bc03acce08b09ae705458bb8c15719f8de6903e37f6f2c3466df1e8396d7d",
"0xaff3f5e10cabcc9fa6624e604d26ecbce7fd26d0b34b057a21a964ff23ade401e2a6cd77bda988a2b6b2a4c36fa36ee2",
"0xa338d853d99d56d53059d31de905b42d5b5480b5994082f91d2d87aa96faafabaa0efcc27ea3a14c768618502d19dbb2",
"0xb456f5b0b675d13cf537a397e9f7ec7d76c51617dfe01fd2eabd4e50b531f52d4bd66b585bbc3f56c8021b1927e297cd",
"0xac59fb0e115d239d86dd1c21bf66beb489f4b82284beed54711f229f979738faee0e6ab330bf1c05b9d9b669015f396e",
"0xb9f2a77117913a5c5378a5d4d59c6ba4ae380f8dfbe9d483a43a88c54c013ec4862e9186b8cfd06ec2f83cb077ff9316",
"0x9539bceca5d4de820da497357f20a4674f477de4b26ffbee6bf08dbfff8c80372b7bd192e24964f913bb2dd2a3d3c79d",
"0x8fa6acfbc88c8758e6d6dcf14be47b05ee669d9f763f86fe41c3fce243a126c5cd9c7f7034292b8e9b6f090d0f39cde3",
"0x86066d43fb75848eccfc3b43bd5a7a4da0f874d25052cca08ef93dd029e415520fab71dd315a76555b7c35d5c9288206",
"0xaa151bb710a3854ba341e4996637af9f478f85c1c0d979d74660503b16168c37ef1ac011818163ceb92438ae15f8002e",
"0x80ff5ea2842f428ad9914259a59b60860bd4e6e573c3f47d093a1551887cb6739ad8f590be086cc25f3178defa094a2f",
"0xb2d2c18d9457ba1606533570937f8902e5ec761e8ce8f9784d6632e4253909fcd4bc6634c410d219ece1f736ede92baa",
"0xa3155bd01319dfd6bd152ef7a349c548027ae853809e6c8b115889748d45ed627ac81fb7898aa81225d902bdbeb224f2",
"0xb09d4b9868cc7c1ea66fdbe8f129713dcf20ffcccd3a2f95513025a389efc24478ea8a850dccd74d1002f904a0f45072",
"0xad01e82c9d49c980f4021b0662a03cd740a97824ae03982fba066e017956c370d954119f6c8a353debd342fbc3c3d46d",
"0xa4300dbb6154a5907b55f74517b79d9ae1af452e0614768447ebcb7c48cdb5e91758d363ebf9510f035c135315afb081",
"0x897c9855dc4cbe4c2f2eed4b21e5ba3a009f2cb813919eb638083c3bbf2fa7f6bafa59f61bdb083c05e061126e1efb84",
"0x96caa39bbd5d27208320413015be1441e3c990a0fe997692c27fa0977e979e2d9073e01cb3247fbc92fe1566dc217c78",
"0x8e7270b698cb176292569516f62be18ffc315e97067a410de613e8586a18f7e19a11b1c40e7a570e36534e7b4762f0d6",
"0x95b82aae7d22fe483328d398d75cc73889cb8ee18de8256d9fc2279964cff2c20ae636f577e76096eaced79be649c668",
"0x9368f97633651d5ee902d87b431a1d0162f349896b3d8ee5a897c647b898599d2a0026584b7311438a918660a2ea68ee",
"0x8cdc5af25eee85daa46c79d4dfc0526b0c88d167f155f848469fcf7e3727866a67b0451eae2443abb8a91f46a6004a9c",
"0x96046065bc1a9b7f2c13f2aa5e573c344090da66eff7d0ca91caa49419388b8231102bd2e10f8c89a168d91a392b1728",
"0xb4f88e34774dfb2755aa471720a984b70ad0494a8b835d9eef732b7082fafef76da60a810a878bdafc6fc244e1ef08b0",
"0x826f863bf891a98ca3a82dff3950a0a0335f4d635b2d46abca7eb14b3d47038d09cbda998d6e3851bd41001e33db1482",
"0xb56dba2acab7be7284712a20324da40907a9210d78ddec77127928ffcc2cdbe6a7a5647c1bef055fa89e0793add4db00",
"0x84d66107df60bda44425262f1793d4c92b8584b973d4838ad222637be5132fc501431b7201c39bd8287327c1f18935df",
"0x83f81afd28b343a82c4b88c6c1d0db7258d9dbe4227001073cdeccdc0f2dc1b84c3b40db96414ea50d3f23a48bde5246",
"0xa90c68f55c1c77343c5251246ed431c0c4b3ddac65c60a75424b59ee35bf2d3e110d71a0057f613d88a0f848290b2c6f",
"0xb2431c6719cbb23ce38e76b488ee4a736838bafa76b4447ace74c667efa412b13a27b8e08fcf5d4d279db8247bd5109b",
"0xa8e6d94483a12d27ad570f199a9ddef6d70ac96607a08fa329e913722dd1093c920efccf47f9239bbfd0a3156603d0d8",
"0xa0416492b181729ee18066905a7af555f839bdeb30d31019c5a8822f0ce60aa9eb203bc1a144fb7c1c4af171dc2077f5",
"0xa367b6caa6497183e91c96fb0f347c638f10af942c29f03e7e127ef2ca61ac8acbe18022c80088615e4099ff2c6ce600",
"0xb4ab6fa53ffe64a61b1a9f09ef54c241b3f3f202966ae760deefa3fc7932821a394c3fcbcdc2f8d0d44498f961b5b196",
"0xa72eb051b039505d1959cf8c4574ce4be9de70b8b1846e51f98c2e086bbed3d5213fa5b947bf92084610139e1ef4df56",
"0xa99862e9b6f37da912255cd4dfceec3d3879766865d1cb7f80c823b22ee542ebefda6cd6e65e1c9d0659179420041afe",
"0xb4268aece8f8039d719bd002da7f1ad2b1b148344c4269c882ba588d744858bf8d7ad2a339c2c0e90c78043652a65187",
"0xa19497340f145a0fa19a488c0ec54908b66edc213f120159ea11f9d60f32cc460835f8dd2dff622cdea92a17214c7e19",
"0xa18648500ef9da6fbbef4cb6ed8f5c2dbcd461542149c7f34f3d2ace96ba0af6f938d700cdde0484d7cf4415ae17e49a",
"0xaebe6ad5614295905967bc90bdcedca109ddbe92a06a4e7d184487f044db67ab4c300e9bc372c9ab717d563cb7902799",
"0xb0cd81b5b26bd618312ea68e481a82432a79515e041e4e575089c5267059367941bb773d81673fd264fd6939695639ca",
"0xb6d7f9796e87d926c4cce21a2461d7aed5186219a638baae776d4b2ca99d4aecdee5e00f74d201b6f7a26e8a82b03dd2",
"0xb270337e07e1b25204e18addeb13a85686906ffc51996405198efe4e827682c7de3a68002932f9be95af0f149c49e8b2",
"0x84e47e48cf0876f2fa73cfee25612f1884a6f97111722fc4b2387ef6a6eae31e82b2b9aeb99566e8029928f2ff3b8f27",
"0xa961ee0ca2ea364a922d526bd4fb81949a952db511fc13b2ce8396ebf53ca7ff7ba60654373d4fe6ead27f1a7d07c5a1",
"0xb2779d398c462262fb1b5ecb4ebc50d00c44337e6ed20210ada4b8b6321b99ef262455e50647a61452aa2678e64def15",
"0xa6beac4c37c76e0bb175795d366178ab96ae0a3eabc1765c8983854822dc4bb11e2326a41c0847bcbfdad2c7f8a657f3",
"0xb9d7cb3c48d41a81e1348b21a3bc05d380a4e44fca5030f3926e390fd4f818829fc4e274bb22e1c8d5306ca9310b40d0",
"0x949b56bada8fb97e1aaa6a63903aa7fae44f412f9babc52671b78fd2fa3d1547ade93e54ebbf454730779434408d639a",
"0xaf8e0ebf68cf4f49984f29b045f9cce238cf69ed2d36f8652b3ebd7751716978795738b7113d6e3f41c912f31b5fcfd0",
"0x8f9c926f14ee78d6d4fc0cf19710f4dcac8c72e40d333790917eb7e233b60628fd7e5567019885c0f2e4e454f7bb7073",
"0xaf9ab693263d93cdd9e477b6675776fbd59812e11674fd44a5bd7049b6c8776f4480660d2f44dee719a6a98150fe4aba",
"0xa118ec8ccccca09b338e913c0acf5bb917926bcf2f48f52ba97f9971485b6b18cbcac42361431fe4614b2b40a520299c",
"0xac58b8a0d7d19a3ce3087f2b15ca749e857a2585d1b3eef55c117dadd491a0a46421e4dfb74f89633a1d09678a6317ca",
"0x96911acde9d9bc39b083edafc4768301c19f50dfaecbc3e0dd918ebc3e2f8c91b8c2d33bb54680a2f6891c73168cea5a",
"0x90af3bfbb5a7953639ed669914b13a8faea3dcf4af2c00c112196a4de4beaf2fbc83d1ba72ee1b9c3749cc0e5d87681e",
"0xa305e5ca2dc6015c07572a5985d5eb914c7561ee1e444f5df9076c7e9a38b11a95f28db3b53feb4eafc9ddf7d481d451",
"0x998e2106a2974c1370b012c01fd2e4fa60822e9f590be486454cceb7ffafed60858a8faa667c9285553819aa46a90b18",
"0xb0faa71cb1173a1b1bdbfc404f1378325935025bc802a5e210bdc63006aa9d83b64439e0e2c82694ccd5488f919f7c7c",
"0xb8ae8d18f5d8a5b7bacf03329a65f5d5e8ce46d83111a58ff8dc045c2d94e54b26c3f79a2c096c822d3a0dd81fd56e64",
"0x91a53eae8476239a7fb2e10ff05be47df93e1fbe8716d2d8a6568323c3682e49caa579c9348a9c59825dd2537f39b416",
"0x92ebf45084b9648ac36ffe91b2c6f15ce42aa5473b7f41e5d308847305fa2a30a70729449736d68ebf9e219999949613",
"0x89786449560b57f1bb488b0e0086428659801b0c7ff3e87d47bf9daffe3ff609d3a2b77e4a3e884549ef70b8aa16e1e9",
"0xa6df5f0147272d946d8ddc07a8a3e50866405a5a8b9a6968374a8550a8d5a0ab355f36bf65ba139d3acde7099baa803b",
"0x84af618b175ddc21598b33e1c5469a6b45f312f4bc27d5881479391cd20ff3b714228893ab05b81f40d88cf899b073fb",
"0xa13973bd367f5b4b9661bcc26ec6dc106d610e96f0d5dd9d0f451d1dfad0acda5fd375f6a522fdf58baae20e133827cd",
"0x8bc9e32be12843787401de4b6514e038ac608dcbeb2c4732d6bac5d6a6beccd0c41400b9f0a1fcde08affef34618ec68",
"0x826dd5d136d74f6eb10bf6a47f9242773830f71397919b7e0b42d53e18220a3532e8c730a8f7c6472b2aa2b48bd71e9d",
"0x95b39bec44b860590c0bec77a9c80519cd938cb094620fca4bebe2dd7a578188359b915f4b29103eb76807a4d0c11c36",
"0x8d5ecbcd0bb59e8269e3c50003455031824194d913d591e41a449d19f1e0c5fe0326d53a0d06957dfb8906cd4a75ea86",
"0xa6b0032fdb9df2334b86212046fed56282aa3f038b16814cd0b2806c598af57e3fa67786178b94b90f02d7f9acbfa5cb",
"0x95fdfa19cf1403dd221a5f0b7c6a38f9f171d3a1f4074f7cc272cdc96963b5aedc9eb72806c9abec3ab743d13a281cac",
"0x8f33a8ede0da0832b40b65715c4c2e0056d33f432e8a0899ccfacf321923a30a99468e6b83b8810be67dc95558861b64",
"0x89d7b1a8169809bd347259506fb80f92abc42a2a804b2384e29ba6245965c2e53f22018b691a9024dc87368e8af844fb",
"0x9793d3600db605c285fa413c7f796f62e79f3f599ac2813ac48bb74ac000180a3125cd1aec74d0f439ca45da3bcdb699",
"0xb93f409beff63139669695e4e20919bd3665038712fd63fd09a07e47bc8f924614bbbad715c55d6b393a14cc97e705ff",
"0x82ddb743e31b992a04a5ee6f6235a771e18af79deb7f3325fd53feeab7699f3bdcc91769cc4f4a3064192d6ff73fe0b4",
"0xb87a4545c62f56ccef2dc3cc294bba393df4b63a67bd6fb9ce41568aad4134d66f10105a41a43062b7ebe805493c68b4",
"0x95d60dfaf2dfb9defc0fe7555da49a68b847dc289c076e2639e48e11f116d0aebaa816f34958dcfb508b14883ee014ac",
"0x82c3c6a7fb9c0800179aa7fdd6a749f47177c99effd22b278efae2ffc0bdf046e087222ff3b5b911d037b1ff4d547c10",
"0x97dfdab2cf2be6d3719ad64a3be77a918a760ebf5287724097708a45833d4f82d868aef9e8ef5a4535bd7f89e18e7ac1",
"0xb7da1e4551561b4d1d5dd010f6c1ff7903f8a07ae9fb18fdb36804cec70c94dd7250141d0ed40fba025e9502af731f07",
"0x9749ffce13b359ab07a0aec5b66c302d6322f83e1696acfea333c823bbb99a8d9e81dfdad6ea54fa1bd7f8707173e399",
"0xaea9e0a4a251107cd9ef36a1f530487acc2daaf98169e602b15a46308286a7b1dc86cc5f1925e65ae99104bf11b63f88",
"0xafbb3f4474b95689059ff263013919e1d573f1495d23deb31cb2755f6bf9611f037366b144d7553b2a366fd1a6bfa280",
"0x8e760ace7e6b443b9655b44550946866495c353738bab1881eb9661507f5ee85108641a8e1a3217764f02b36f4e27695",
"0x8036cc56f2418f3cf027cee6357ea2f9dfbba27e21b3faf86e164ec1908e6e8ce89e3bbcdfa34ef5f86703e41f0a6164",
"0x8449b61c699086cd8b8fab8e79dfe5c30b9d1f0a29ba4b5b629e0f32f52c298500b5aec9cd07785b6345c00c197db3b3",
"0x8c90d9a3412dcbf2a0aa937ec9737abd5466712685f1faa556216a0caf2badbadca99c489cacff54208bb82ded592691",
"0xb1d383fdc7df32115dba9d25bbc1ba24ae0f1b5aefac87a513bc0de6444f00c409038b55ef826bc0f694e62fc1109b4f",
"0x88c00a4476534efcf45b74c29287f13827312bca83a1d5b487c359073951eac62a35dccd2fbd9fee5a956da29fa51602",
"0x8cddc3236f2df5064240e1759104370e55dcac8d592490e6e17720a81297d6eef5f9deef17a9b7b2db818dd015a8e206",
"0xa2b0fe20fe9fcf3db612ad3b1427310b23977ba9e7f58228daa0d32923db0f7319bc03d7d66ad603f927b0653c662977",
"0xa8bd0a1bf9d724eecd6d342e06e60c01fd9d6588b5b146520a24b4acac133bb24696da3968e1fd80d07badfcffdbbe6a",
"0xa281cb84af30f3989ca6a9274866cc6ed514b733aed3fdd623d2dada24845d487f11c3d41a785aa6c78465029987d066",
"0x811a31d4ccc4276ab6c9a20ed963b04c78dfdab1cf4be9267db0ff0199502d417bbb379a392ecd4d68211e7e48233328",
"0xa4c43910dec1f8db35a2e4ae537f20f865a08bf313b614c66af4e6c682f67bfabb7c4401c01aef0cf9d7a50de034c2fb",
"0xb2e85a231753a8158106751d85b725d996c3f4e85393fa488c2fe1eb8dd1a61e605e26cdeb304cde9a67095e57d8b495",
"0x91a89b32f7ad2f4c15309befff4ed2755a4dced9c3da7dd8ca8c471888e4d3961779b6cc821c8dacedf60562ddb174bd",
"0xaeaa2cbd26d616a00f08a39427f10ce8247ecfa03a3e1660b991731e8af499466f93b91f6af3d2f848bdd768b36d9977",
"0x93d5b5ab7738e739ff410102597b157a3c075278562a46a136c42bc92be9e4dcb0d3c707a11cb7c485e90c315c8b6897",
"0x988ac3ce5b274cfd99238d073116a5ff9e43c66a21c7a98b3f6715a3a12a5fe8dfce1a3b746a2582a379d18317d4bcf8",
"0x93d23a114b4ba96c6050f59a2d0c4440020fa15e4355065e3a98d075509744412e08c4b017d5b131e7b47c7434c970f4",
"0x93f83ceeeb39768c36dd53e03211d70dca278e3b9f62a09d3e5b131aab0d3c90857c1e6fc6cefcba776a861c8fbe68cf",
"0xa38f5834bbd02d778cf0271e203d622292d60a4cb304574372c511fc40975f977b478b36ed2504b6a09aadca73195a32",
"0xae98edbc84043997e689b803ca8e1c135abf5381c874cb191d7a2cc490276bac5da4788506eb0dbdd5b7a5aa2df8c9f7",
"0x87f714197f65adc2d1ef88993c081b09f9c41f278175234d816c1f84b4e4b80161b3d67f4fd6e0eeea7c6e06847d5128",
"0xabb630876f09c6917e46c97d6e3154528ece8274b26fe9825d38e40a3290f1849d21639e28dde6b1231739d0f34efd23",
"0xb892f6b8582705faa67ae814fa4eaa5a30a097c178f53f8a0b9d58dd99b5dc914ce48dbc9172772a398464425e322bb9",
"0xb140718f955286f027074962bcf413958d66ba282f7fa45a4c15c2f6fa4b1a23e9271f47b3c8e894a66cce02279827fc",
"0x87b5c395ddda461e84d36cccd335afe71c9c5fe8ff7d9a011e56af5a4e2d5059b5a77c4c40f4582f83142e01663ecfbf",
"0xb86f0a61634c096c1547d3f6d5074c7d41493c3d5a4cf0b79b441e2ac8c10c6e2769c3737627594da32fcec25cc50d0f",
"0x8f157cbf5a2a2d1582cdf2c1a013da3aa04bf694209e2cce5c3efda6cc07999b73a57d5063358646c35711d951aa24b5",
"0xaaa675dd6ce103c6374ca148647ff4518c092ecddc5652b3e8d123a9d2d8b5ba1a878aeb275f224b50c0e6d718729501",
"0x818548e74a34e7f2b3f4e1af8f72fef5d6c96f5da596a02027d11f8d4ae93f8752d1a69bc6796b5370816f0586d5e49d",
"0x91b640fad117cd3a18e01605e12a5ec2ae81d7857529f4b1dcd98b1bc30b438f9583cf1ab7f2a3d3ec4ef342c63b10e5",
"0x8e5fe6dc7c5c220680741db6891ea41c239419a08af8daf4a4fd7d89499b1299679a32a413074181c0b83a6837e557db",
"0x98158add05884e701ea06b0365d2c5ac977b8502e570175f987ad7d5b09d7cdfd70e18003165e82ec8c53de32ceb251e",
"0x93aef40c696ecbe9058952c7abd5700aebc2144a89c720d05d99bfaedcff712d97bc0b5cda0b2aad2ed9b1b0aec0c4df",
"0x921b1c7d631771e28dc54846b8d3076c195cdfad1955b7d6c3c97befa62a02b779b65279679cc1dd89d50f0ba7afc8cb",
"0x93562f10036add83b59f62f2d7448c99dabfbd3f51c50399ea5f546c11ec8afc727b7a96732af41297978c0569140c3a",
"0xac8d6d26e3548c0622652c103361a0b2a7d6ebd7bf3cf1ba5b6d586becb1c61b166a0cbd289596b52e7997d245fb9050",
"0x8d1125dbb21e4899fc2438da5972a18e7d4ff49b1d48ff1c7e2946c0c4cd29ca7840ebdb30d3eecc80268806f58d20bc",
"0xad46ed09c5ac5807ba587edfb180984574e55b551d94d88a8db59c1b1f1656e98b74f39918957a0b9f3fc9e0f91672d7",
"0x852efa4ab9ad3114fe145b1f31031f6914240162203afddbf49cde3b1ecd29a68bc6c9a8df18aaea8b23ca4b77d8d38f",
"0x8570af9e007ab0b1d82f5958a7d8c91aa0cd006a3e43138002833cc5fbb0bd53e1db536d2ce7dcfd13a2a06e3b490946",
"0xa676181c8a6f628b907a8d60513a15d74bc51fa3d83343ab0627d8ac4a14dabb122c287d264ef2ecee03fb79bba76114",
"0x8f0c8c9cadcf34820f162ea8584b6b61dabbe16a61b0ae4faa03305c393c26796ca2106ab8a1fddf17af71b063e63524",
"0xb13a75a960eb73fc858807237666d7ad86c328cf74da947bc80cd874afc1cc3b417a90f75b0f3558f0fe30445a163333",
"0x9141877bf22764a12270f232b4c812555f7840fa1c1c67b4ca6cbe5d10ccfdebd7b0690a70dfc99d1366fc56aa5fb8cf",
"0x8c5a115c9287c550b747916787e4d671c628b0d0b688d3be91622ac66302468385429d881420232fe9eff14b84af4793",
"0x8325ed8de505dd3848ece76a2425c34f35ad4a488b77107889843dda4646be95458caa090e3a4c3c0c9cced560d57b79",
"0xb7727e8a2a246b6ab264efc8b8a851fbfe91780013f88b1d686ba6e2dd3f88099ae5cd50b087eaee4a229a209e4e11c1",
"0x874c00eae6040f8f371b3c68fed8279ba292f776f7ab0d25364c8bee33f0a865d36ef8285a92c16b84a9ceae684bc7d4",
"0xb7531fc6846e16c5950362cece96f172fa39cf8dff71e37b0ae142f74b25828cf91bff25ff91687977dc13e875942c6d",
"0x877b381025d9d3e286d40f2091514bed9a664410e58f1be36461bef1943f4fb4c63f88b1ee3115c25550868316409c4a",
"0xaca83783c5621787be754db26c5711f82f0900835a840746d01da65bc4416e5db432124bd743fee77845414974c2049e",
"0xb8185e31d16c9527f6b7311be0254f8741f58180724c4c983d2db9b2c770fbc654185b4744f5ef7f03c1b94cc2abcdad",
"0x92e2993a2632dcafd8ba986c68a1f086424dffa5f6038325c7d4effb6c2f0673f60ec57d62cdf278d809d7539b395aa9",
"0x88566790bda485f19e689bbe24dda0a977f97f199ce2633e266b9e88179a7adec98a465670ad97552913f9b5a4d32e85",
"0xa211b30b5a60935e13cbabd302216058305f8a1c3d9b53260df052590f9999c951e291dc3520510357835bcf756bd7d9",
"0x8c46615a602aa3c5f162dd0d378853b5625bc081c8da5bc68450029b53f7183431a6cc41ab4a78fc450f8d4558db80f1",
"0xa2af75fc3e8ad935405d9fc72558793107aa37d83c2f4ddfb734c747ce0afb36b217b72a1779f12cf1e647bc3d1ab543",
"0xb4606a0a3014dbd58b24859f08e1368b9e5a066d89ff2124985d9820bce141c52f07fd2bb218e963e6c05d785abf850a",
"0xa285ac44a970485c2d705fd1487d5f4b5d2fb9f1537c891d0eb5936a7d4ca50f74c7a6c660cc19a23757cbae81a2c455",
"0xb720f8dfb918aee85a09feac2ecc48ccc41545d9bf7d5a95a0ab8ddafcd627b62529fd20ed013c516b34220015fd596f",
"0x9543688acfcd61632778782c77230aa53ce964a004cb3186be5914a9a62ccaa70f1c72734a83337c89107fdb2c184b9c",
"0x91a4e2ab7f3efcccdd433415298344a3a98516f529e02f8bf9483ab9a52d3a814c17c7a6b40c87302e84242ac4b7b4d9",
"0x8eab08992fe9606efac72326ba6e03c9ac7f3dd6c9997d17346e87a0eb6bee47f94e7e3e429b2fe1e159ef38a3a917e3",
"0x97f76b38b6a5fc51c7b476a28237129d0382196efc9357f1e5590fa5217e4496710ccc9beeda38f6cf0d5f01c330909c",
"0xa076bd5dfdd2ec2ca7bba3116996210147cf9b81f4cbfe3518ee13f9b53eb762f2c2165f70e532da161b0c6ec98d01bd",
"0xa9c7c16704060e56e71a08aa2f6c6ad8b0f22272a8d64f13a4cce07c37466f45e94e963c20ab799c8230fd5bafa13b88",
"0xb6c3420776327ced738aa33ac2a4066bcb6b79970172a602125f8d5516c2e247db5ce2ece8d1961f5daf9c2d75070d5d",
"0xa80b7cd2f212be04f646f11276fb2cffb7317f9c666749dafa11507fc76819b9594ac03de562d75219dac77e86b8c5e8",
"0x8d2b8f2d0b3c067a1c17bfa4cb6fd14abcc71dccef549ed919414424fe3416a5f7980a524882ab11362478e25bf79247",
"0x81eb2c94c95572089095f5857cbc3cab4cb0e0f39d154bee873ebb921099039ca09f374a66dcf3b170db9528741d6b2b",
"0xa6a1413c8267c31e14b4ba5f39398630310dc26a3e19841eb3af16983f0b6a7005968c602c41e36eabed868b14d7e072",
"0x8eb6298d4445f3ce9c86eb34f2907d2583934c810aa94f8b91b571da3cc3056de86701ec00e6d5ba9ce90d5d56c6138f",
"0xabf9926830ece12b985435b97cb9c5e52498ddbf282cb6ea2a280542058d3834ad77ed05d512e2ca8e9e13a91d9432dd",
"0x8b55691fdd7a96a67700e9c312fc3152b524032757d6786f591c93cb3a4a620c7576d6a2bd054607ca12952fa3622724",
"0x8547b122267b6e1ab1632e4ddb2af5e273c4323471efcdacf16a77f1c5a97817ce0d59a686842d6d45b5e350759b37d4",
"0xa0c3b915a9b4e9c20a55354a7d62e4cbeba0010aeb2326bf9365cbccf1b8b3d18c6eaac6c793daaf5cce15153af93483",
"0x8c770c76f380dc1bfe9e79cf7f60e9868af37300f30528380ee6b6f161e7ce09a8a1b5a5dd23903cc551a52c43fad6d5",
"0xb233d0349242b965e6c69c4d286fe12c378ffb3ddd8e08938098298a0b23c59e0686d2a190b28a13d86b5ff618476959",
"0xaade99bd0c2923fe2df52bb8dac4321387e51f3256eba99a7f0645b0aaf55af4885d158eb427d9e84d450002254bd262",
"0x95050a292a0bb69c866d92bf1095581ad2aa94ed585b5760f794d4de947e313f05171025c2a85b5a825aace731933c19",
"0x803eb6752b16d33d92c84e2abdbf1056fd2f89df51e00734fc33ca6f9b2a2bdc103e6bc368cca32a6616cdb600284c3d",
"0xae93b201d1dfc90ec61cfc379ff1eab01558308a22a77a32765eb8cc27467fb86fbf2339011f525de26a4e37a9d4d060",
"0x8a4c740d4a881d4dc0514a212f8cf88d96c711cf660956566e1026eeae96b25c42ad7474046ab08115c2353a125841be",
"0x8afa88a77d7e847ce9b13201b19764caf07c79666f150122b133bf29eaeea07a2c5d7d868bf9a983d426ef5977efd7fb",
"0x95f586105b14e1bab698e18f94a0bf2cf223f092271d28c9f6e72c3de88d6232527d85906190b77f953ab4289ca2ce39",
"0xa74adf3914fdc3717beb02a98ae0223d0c6e093220a43504ff73c9fb0225bbf145a718d78dd448015143fed8bea66d2a",
"0xb1a6f5883ef2afb4bcde5cc018fd29e56d4d7e65a9e829d7f5f07d3d210deceb48dd4972dbf740334ccc99b61e46eba6",
"0x851aa8cfe9538ccfa863700af3fe7395bdd3d051eff006e86053e912d1d60fc1bcd87aee23eeb8ecb3f547b17dfd53ec",
"0xac4aa49cdafb0847f1f7a9bc2a44af01ee8696fe189f618b751dce4cdf9f041e9a1e34d3c096317483f432df7799db33",
"0xa274d9ce5fe87a0436b1d6b606db605c1fb27594aab1af81c2e185b2653ee15fe1526c5e6177a44fcf9cedbb2d4793b8",
"0xb971066e3bed163cfa364fda1e11dc7c8176eb6721d98937d29d5103c3cac1dcba1d610e54bac9e74341fb3d4c5961ab",
"0xb6c74d8a586690b97d10bc4b99b2e9acc1dcb1d58634a327729d699fef68da9cfdca7b408fd74efc267eaed553257024",
"0xb827864273932536c3135ed80e9378e27e6d21d73157ec24ec31bdca4ab6457be1dd4830671ba6429a74aed3c02fec32",
"0x949894777c68920cdc9de840ff2748633964458e4b9dbbe18b21bba5a01d3f0357611d3c59b2fe5509a4245fdff89f84",
"0xb9bb52f7147392b8f0d1662825c64e1caabaacf11b7499c3fe6f9d6f86a3a51548a75ba8e9e5fc5aa656c8a34aaa6b9b",
"0xa32b694ffc3ff7005e6aac7a988950e4f2da29b567e38acc73207f95ba3f7b3594de1537898cd9b4d1f5907211858f26",
"0x849ba686af1f6054de495636a2301805c8c01da3470592d2ad3d18d678de22ae332c8dca6b8420e10f42361beb5baf90",
"0xb99832e7f0cc9e018bacad7c1196c1be70b6abd81e389d977839ce6662ffc981f10657ebf9ac30e23d7a27363eec4077",
"0x99c6e19e57d69e577be61c6266f81cde376b9f35abb0184a2686882e4476967439862b9a530cae0ead29b741d2eb172e",
"0x942de4b667daa85d48e352b051ee29c8f3752b90ee92863f854866f21b99c97babeabe972224b4d84db621ca782ebf4f",
"0x85d94096a35da022155562bf5d21f99228062ca203888975d59d2b3e91fa4dff6dda6930f304f51f9f7aa54679b82e6a",
"0x822544b8a8eeb609f2837123433d0170ea512a16b2b10db245102f6026599a042ffc521efb92eb141a1d2a4214bb6917",
"0xa62e2cdc1486f555f0f58a3b4abe8576388e8d6fa650656b0d4fbf75510768a9f45a889d9171a2deec3fd98f50eca558",
"0x833b9040774febef4caa97b47a825cab0d1150da5304be94bb7e5fb36f2ce5918bb46106a987f0d8d8b4e35c86f6e308",
"0x85ca18e6f8c9f5e0d4e8c2d203395be3a17b941b15cbf911e581f99a4bac640c399daa180820c1afb1f591e5416a476b",
"0x837649d4fa89066ec02b4ea6bc0839a3394b26c38e2a46e75dc2da15ba8be23e9a7f9f66015b549beefb325b5c77f1c8",
"0xa2d82f55ed9a3e31133708dd5aa27a37d12d5df7ab2f00455a3846de7562d27a5d06a7735dd506edf11cb10e93fec320",
"0x8e5e3ad45313da6bffeb52325561188611d23ce9e38c781757b591987cad3b14f5b8b6889cbd550888128619fe3f1b5e",
"0x8d037d57cfe814d91dd8f44431ebfebe16382402246a89303776fae8c746709fc069b0825227db0a15b5cd75195db910",
"0x940c9c5f145d64f1ff2dbe20c73361f8031aa5c28243d4740e0feea66c3a9922e63596f49d5ee6184a58ae92ed126a2c",
"0x9165f88c51f25491e3c48b5414758ba124f4d43741977665e1d910b29e2df84f0a615ce143504e7353ab0b47c46e1646",
"0xb1f39e3644cc1ed40328fc0098dd4064a258722cf65e80dbd9cd9ebe0f11cab31842fd9483be201627e3660500ff2c23",
"0xb5e47f405760322b46d37f63955bea7555f6065ac17a580d2eda371309d48759aa462bfd4067aac6730ea6391a9bdb0a",
"0xb949285d17dd61438eea643d1ff0f85463b552d98ccb4a65c9439d84e43ee1db49f3af027e5febb56e1f6f5d80c91412",
"0x8b6ae62bb33cd0966d7fd59d6b7f92c7c258c8c718eda58bc0b9ab61e60ca94c82af267d7a2857f694f0c517c7593a6f",
"0xa8709ee9482be378884a40098e5066c9e66beafb454505a7a300f38f102d61ed70d5ae00e9c248b9840cc45139d0a446",
"0xa5cbb5daaaf6fc5d5a9caf82c88666f33bbeb695997eac016995c687bdf91cbad2b9f32213bbe2c9bc558a4717892056",
"0x979c292e65c2fab5639a5d684dc1529888bd60f0aee97dec899725bfc9e22a98fd8374d022d366e10e2f0a3d4c3e6b66",
"0x82c0597dd33bc8e9b3b3e66a0dfe80b3058003d733518255471ce634dcdbd26b12dfc2b7ed7062181a84fd939261ecb3",
"0x95e1c90de7bede21c3270301f6fb9ad6ee18c86604a68999d2421be3b09b66299775cabe49c83658b1c34ab132a240ba",
"0xb6c3e5fe6262b8bd3472516d05fa170993dfbc24adb4aa5dffb8b387cad1a4024850400b27be8ad7a88c6ded0cfb40b5",
"0xb652d5448b08a9acb8820583d69037d6eac4538bf01100aa2ccc0a35d0e741511047edcacd9e1fbbbf144dc7a68e3a62",
"0xad26a763e5b9bfcf1e9da160227ae3184ceb0ca160e497ed955eb5474cb1fb15222ebd2b95bf5f79df34b708826b5135",
"0x80bd2a8cc1238f91209cb483297e3fcbb7aa6baf3124a75d98da96a075107c0cbe4cbed9fe8bd901fc5c9583e68f8318",
"0x948f28741b3e4cf9eb2f1e14620c011030b6d38ed2cd0ee9fe41ca5bd54529cac5c7b7f581212878ed48f30a298c05cf",
"0xa34fbf6ef71e8bafe5fb98e7ee99de5fc60f6dd8f2b15407d052158d0f34a7ebce63490ec71f4da534816840be83cfbd",
"0xaaf6740dc86b6c4501a19068e190d44b9d07af8e2a3801875db6e3d183c10a86c61e0d362d3c11bfc73a1f8c9a55183b",
"0xaee2373d7868128c28bb58637d85c148f1aed881d8157090ed998af6d961bf1dc37391294b0e361f5578d3fcb5bd60ca",
"0x842edd482f9bddf87300b2d1c916f141340691ccb6b36fdd396f50cf79fb856d793bd50c8eafef5c949faa33d57ad54b",
"0x8fb98a9e82933843b995ec0d929fb775c27efe51f01e9fe3d4abf11b03281cb6df26c3b844102902097397ba8a4ed95b",
"0x890d76989026e2ec0ffb92eeec65a552ec7671c17cdad6c22fed7aa7752a9531304239661ea07ce12b93404d1d556127",
"0x98bf7919c81f8b14e6ebda09844bb2609860669a28347a13c303bc62893f62762159fb8009ad9a8fd4d320ee4d2b3cfe",
"0xa69571f3cd933820ba3b81c20630a75a49aa6e9a019cf9815da31efab1d906fa0d02dc65b3726460de6f8dd001ca8526",
"0xa21e6285c2dd8ab627e9052440c859e59937d83d2ba9b85f65ab7f9249c4a2de746b3feaeee4350d478fcdf0421422b6",
"0x90273ef6426d6b128763e367507615e6a79220aba9c30d8a194c5da350c065bfd378c061b6e3e57ca5dad6e430e9c6a7",
"0x89df93db35de1404230f5af7561385929220d5cbeaca1559bc5f3097458477b20739847b707e52e5cf31edba92529a21",
"0xb3fe1edd1d8dce5efb068dce704e073a3473b2f78d04b59e43d3b96d58778d4fa00d4f08f60a267c14e61f8f629f7205",
"0x881a126490d54dfedbb4bd1e951f8cdfeafff7b164a1b4786ec577cdb7c9a75b29e2c65ca1749e0417fd9cd2cc3a3cb1",
"0x810646bb3b98b0fa7d4541ce5cebf5526e501807455aaaf5c0e7a393f832a93e61b701b5e14c713ce519979085aca5fe",
"0xa27e64f8d9cad96f156bee43b5002970f034149ed74833a3a85cf5ff7e0c73fbd7704c696db98cf79c80e37c1d091d59",
"0xa78dcd5e2b7934fef51673c465419e2c057399f792e36002ef5aee09d2efa0845b4bc8e001bd70ba957a567d233159e4",
"0xad4ecb76e8a30e427af08dfc7fdd37d3b69ce3f41dc374d28bbc1b4be3b82984a3c32b9792fbd20333a5305a7cdd23b4",
"0x85c01bdf47745c94c1e93e92575133c757a419c91546d681902d50b94dde97f7d3fc0323337f791283762026e0ba4b17",
"0xb9cef0b3c0055475dfa4f8bc9c30ba514be1caca38275a1215215c8731aa21959c7097582002f8fabb8f3bf54623489e",
"0xa96e8620be447aeb3eeba0277da17537206f23ffcde12ec63fef45d741bb28a973ee48bf5be317caf7a2d172e38ab550",
"0x8dae5a64d0a980ec81caea6ae9971f0723feb042d30e8aa6a109a1ed8ae5689b05792d48b1ed54d95388fdc618e25505",
"0x96130e73fb0cb8e56d11e2939c977999cdbf01bc0598b228d7485067b55d9b9ec896f0490afa2ae6699b802585b0b00d",
"0x85bb03bd0cca1030979a01ffa2dc8178bd1add6c739179f950e21bbd576b10f3dd41de5148f3d4eaf0f6019bacfc19de",
"0x8155b105b3f0d6198cf80c62aae83185182a717189c00c6180a6b620a5c094b993324201c4638d65a95e04210b41dcb2",
"0x853ccde301148f3e5aff12409a29f87deaf319bbd0245b0a20f10c117227ab33a5aa5ae81447aca9c0dc708ea7d809ec",
"0x909b5a6b09ffd5a64ac1cdce0143d09833a5c9bf5c5d190995dd37e5945c2c89d3aa5d1cd7cb5a46318752c8b6832152",
"0x94c5d61e616b16eabffdc6fe35e9bae55d8da01580ccb15a18802502d1872484b386b50893801ee8c15c8ac7ed7ed176",
"0xa49feb98f5e8872446e5f8e919d20b7bbb82f2fabe59458f416deb4fe2f415d579bd7ac45b286d522557c53e7df2b82b",
"0x9071145e343177cfb81dc5e68648309b8b61636d30eb0ab6624bae58e8992d98951c299665a4139d12d4ea2f505ce265",
"0xa68a488b0aaa3b060c0778a6e87e4f2dff7c806abf0a2125f96bbf3f0ad191d32fcf87d27cfa06eca4a9618eb48b2bee",
"0x991febb335fc4eb22cd341abca8320fefa132e394d115cc8d6ca5b0d5de5487d458c5165a0b504bd85ea8c842a8dbf29",
"0xa12bcbdb57fb851f0fa9ea0e1caf0929e8bef55ac71bb236c70124abae06581bff34a2b93d8a063e2bd42711ff535316",
"0xa6a0ee28bf7027849b5605965c14ee75db82dc5d9374a8fe568fef6123719ca1698bed51f74fe872e6075c6ae0d3c8cb",
"0x8559c5305305b10adee0b87536e18b3e70978b4f458531aacf3af132fffa68f7111c5155fdb1e5aedec27b746a99dff2",
"0xa6a5d24dd7822c51f5b2fef526c735733a2eb5ab9ee6848f4e0777367bb2fd966e830056a54943f9ad9ee712dde5866a",
"0x901b638eea2e8e7b1405ca19b80ea9be8d84fd117b1f8c22bd176a918fd5093d38eb720a423df577b8f219ed2fd994e9",
"0xb5810330244b12529cb2596b4a3ff31305f8aab243bfba01da770b5754ee2d73ff7c9aa657a9e0cd0900410207c23644",
"0x8451719fd8c98232f9b9cbb1ded46b1caff52b3d7509533016621fa49c461f129c2adbcd4941a500fd5209c9196acaf4",
"0xa9749b942997de005582043d60ceeeaa6ac945c688ee3258e46ecd927690cd15412f827a6bd43b42c26f3d887415ff35",
],
};
export const BEACON_SYNC_SUPER_MAJORITY = Math.ceil(
(BEACON_SYNC_COMMITTEE_SIZE * 2) / 3,
);
// These are the rough numbers from benchmark experiments
export const DEFAULT_BATCH_SIZE = 200;
export const DEFAULT_TREE_DEGREE = 200;
export const POLLING_DELAY = 13 * 1000; //13s (slightly higher than the slot time)
export const DEFAULT_BLOCK_PARAMETER = "latest";
export const MAX_BLOCK_HISTORY = BigInt(256);
export const MAX_BLOCK_FUTURE = BigInt(3);
export const ZERO_ADDR = "0x0000000000000000000000000000000000000000";

46
src/interfaces.ts Normal file
View File

@ -0,0 +1,46 @@
import { BeaconConfig } from "@lodestar/config";
import { GenesisData, LightClientUpdate } from "#types.js";
import { ProverRequestCallback } from "#client/index.js";
import BaseClient from "#baseClient.js";
import { EventEmitter } from "events";
export interface IProver {
get callback(): ProverRequestCallback;
set client(value: BaseClient);
getSyncUpdate(
startPeriod: number,
period: number,
): Promise<LightClientUpdate[]>;
}
export interface IStore extends EventEmitter {
addUpdate(period: number, update: LightClientUpdate): void;
getUpdate(period: number): Uint8Array;
hasUpdate(period: number): boolean;
clear(): void;
}
export interface IVerifyingProvider {
update(blockNumber: number, blockHash: string): void;
}
export type IVerifyingProviderConstructor<
U extends IVerifyingProvider = IVerifyingProvider,
> = new (requestHandler: Function, blockNumber: number, blockHash: string) => U;
export interface ClientConfig {
genesis: GenesisData;
chainConfig: BeaconConfig;
// treeDegree in case of Superlight and batchSize in case of Light and Optimistic
n?: number;
}
export interface ExecutionInfo {
blockHash: string;
blockNumber: number;
}
export interface ConsensusCommitteeUpdateRequest {
start: number;
count: number;
}

38
src/node/client.ts Normal file
View File

@ -0,0 +1,38 @@
import BaseClient, { BaseClientOptions } from "#baseClient.js";
import { IStore } from "#interfaces.js";
import axios, { AxiosInstance } from "axios";
import axiosRetry from "axios-retry";
import { consensusClient } from "#util.js";
axiosRetry(axios, { retries: 3 });
interface Config extends BaseClientOptions {
store: IStore;
beaconUrl: string;
}
export default class Client extends BaseClient {
private beaconUrl: string;
private http: AxiosInstance = consensusClient;
constructor(config: Config) {
super(config);
if (!config.beaconUrl) {
throw new Error("beaconUrl required");
}
this.beaconUrl = config.beaconUrl;
this.http.defaults.baseURL = this.beaconUrl;
}
async sync(): Promise<void> {
await super.sync();
if (!this.booted) {
this.subscribe();
this.booted = true;
}
}
}

35
src/node/index.ts Normal file
View File

@ -0,0 +1,35 @@
import Client from "./client.js";
import Store from "../store.js";
import Prover from "#prover.js";
import * as capella from "@lodestar/types/capella";
import { consensusClient, getConsensusOptimisticUpdate } from "#util.js";
function createDefaultClient(beaconUrl: string): Client {
const options = {
store: new Store(),
prover: new Prover(async (args) => {
return (
await consensusClient.get(
`/eth/v1/beacon/light_client/updates?start_period=${args.start}&count=${args.count}`,
)
).data.map((item) => item.data);
}),
beaconUrl,
async optimisticUpdateCallback() {
const update = await getConsensusOptimisticUpdate();
return capella.ssz.LightClientOptimisticUpdate.fromJson(update);
},
loggerInfo: console.log,
loggerErr: console.error,
};
const client = new Client(options);
options.prover.client = client;
return client;
}
export { Client, Prover, Store, createDefaultClient };
export * from "#interfaces.js";
export { getConsensusOptimisticUpdate, getCommitteeHash } from "#util.js";

90
src/prover.ts Normal file
View File

@ -0,0 +1,90 @@
import { ConsensusCommitteeUpdateRequest, IProver } from "#interfaces.js";
import { LightClientUpdate } from "#types.js";
import * as capella from "@lodestar/types/capella";
import BaseClient from "#baseClient.js";
export type ProverRequestCallback = (
args: ConsensusCommitteeUpdateRequest,
) => Promise<any>;
export default class Prover implements IProver {
constructor(callback: ProverRequestCallback) {
this._callback = callback;
}
private _client?: BaseClient;
set client(value: BaseClient) {
this._client = value;
}
private _callback: ProverRequestCallback;
get callback(): ProverRequestCallback {
return this._callback;
}
async getSyncUpdate(
startPeriod: number,
count: number,
): Promise<LightClientUpdate[]> {
let end = startPeriod + count;
let hasStart = this._client?.store.hasUpdate(startPeriod);
let hasEnd = this._client?.store.hasUpdate(startPeriod + count);
let trueStart = startPeriod;
let trueCount = count;
if (hasStart && !hasEnd) {
for (let i = startPeriod; i <= end; i++) {
if (!this.client.store.hasUpdate(i)) {
trueStart = i;
trueCount = end - i;
}
}
}
const existingUpdates: LightClientUpdate[] = [];
const results: Uint8Array[][] = [];
let batchedStart = trueStart;
let batchedCount = trueCount;
while (true) {
const res = await this.callback({
start: batchedStart,
count: batchedCount,
});
if (res.length <= batchedCount) {
if (res.length > 0) {
results.push(res);
batchedStart += res.length;
batchedCount -= res.length;
}
}
if (batchedCount == 0) {
break;
}
}
if (trueStart != startPeriod) {
for (let i = 0; i < trueStart - startPeriod; i++) {
existingUpdates.push(
capella.ssz.LightClientUpdate.deserialize(
this.client.store.getUpdate(startPeriod + i),
),
);
}
}
return existingUpdates.concat(
results
.reduce((prev, cur) => {
return prev.concat(cur);
}, [])
.map((u: any) => capella.ssz.LightClientUpdate.fromJson(u)),
);
}
}

23
src/ssz.ts Normal file
View File

@ -0,0 +1,23 @@
import {
ByteVectorType,
ListCompositeType,
VectorCompositeType,
} from "@chainsafe/ssz";
import * as capella from "@lodestar/types/capella";
import { BEACON_SYNC_COMMITTEE_SIZE } from "./constants.js";
const MAX_BATCHSIZE = 10000;
//@ts-ignore
export const LightClientUpdatesSSZ = new ListCompositeType(
capella.ssz.LightClientUpdate as any,
MAX_BATCHSIZE,
);
export const CommitteeSSZ = new VectorCompositeType(
new ByteVectorType(48),
BEACON_SYNC_COMMITTEE_SIZE,
);
const HashSSZ = new ByteVectorType(32);
export const HashesSSZ = new ListCompositeType(HashSSZ, MAX_BATCHSIZE);

53
src/store.ts Normal file
View File

@ -0,0 +1,53 @@
import { digest } from "@chainsafe/as-sha256";
import { CommitteeSSZ, HashesSSZ } from "#ssz.js";
import { IStore } from "#interfaces.js";
import { concatBytes } from "@noble/hashes/utils";
import { LightClientUpdate } from "#types.js";
import * as capella from "@lodestar/types/capella";
import NodeCache from "node-cache";
import { EventEmitter } from "events";
export interface StoreItem {
update: Uint8Array;
nextCommittee: Uint8Array;
nextCommitteeHash: Uint8Array;
}
export default class Store extends EventEmitter implements IStore {
private store = new NodeCache({ useClones: false });
constructor(expire: number = 0) {
super();
this.store.options.stdTTL = 0;
}
clear(): void {
this.store.flushAll();
}
addUpdate(period: number, update: LightClientUpdate) {
try {
const serialized = capella.ssz.LightClientUpdate.serialize(update);
this.store.set(period, {
update: serialized,
nextCommittee: CommitteeSSZ.serialize(update.nextSyncCommittee.pubkeys),
nextCommitteeHash: digest(
concatBytes(...update.nextSyncCommittee.pubkeys),
),
});
this.emit("set", period, serialized);
} catch (e) {
console.log(e);
}
}
getUpdate(period: number): Uint8Array {
if (this.store.has(period)) {
return this.store.get<StoreItem>(period)?.update as Uint8Array;
}
throw new Error(`update unavailable for period ${period}`);
}
hasUpdate(period: number): boolean {
return this.store.has(period);
}
}

22
src/types.ts Normal file
View File

@ -0,0 +1,22 @@
import * as capella from "@lodestar/types/capella";
import * as phase0 from "@lodestar/types/phase0";
export type PubKeyString = string;
export type Slot = number;
export type Bytes32 = string;
export type LightClientUpdate = capella.LightClientUpdate;
export type OptimisticUpdate = capella.LightClientOptimisticUpdate;
export type GenesisData = {
committee: PubKeyString[];
slot: Slot;
time: number;
};
export type VerifyWithReason =
| { correct: true }
| { correct: false; reason: string };
export { capella, phase0 };
export type OptimisticUpdateCallback = () => Promise<OptimisticUpdate>;

133
src/util.ts Normal file
View File

@ -0,0 +1,133 @@
import {
createBeaconConfig,
BeaconConfig,
ChainForkConfig,
} from "@lodestar/config";
import { allForks } from "@lodestar/types";
import { BEACON_SYNC_SUPER_MAJORITY, mainnetConfig } from "./constants.js";
import { networksChainConfig } from "@lodestar/config/networks";
import { fromHexString } from "@chainsafe/ssz";
import { capella, OptimisticUpdate, phase0, VerifyWithReason } from "#types.js";
import { assertValidSignedHeader } from "@lodestar/light-client/validation";
import bls from "@chainsafe/bls/switchable";
import axiosRetry from "axios-retry";
import axios from "axios";
import { digest } from "@chainsafe/as-sha256";
import { concatBytes } from "@noble/hashes/utils";
import {
deserializeSyncCommittee,
isValidMerkleBranch,
} from "@lodestar/light-client/utils";
import {
BLOCK_BODY_EXECUTION_PAYLOAD_DEPTH as EXECUTION_PAYLOAD_DEPTH,
BLOCK_BODY_EXECUTION_PAYLOAD_INDEX as EXECUTION_PAYLOAD_INDEX,
} from "@lodestar/params";
export function getDefaultClientConfig() {
const chainConfig = createBeaconConfig(
networksChainConfig.mainnet,
fromHexString(mainnetConfig.genesis_validator_root),
);
return {
genesis: {
committee: mainnetConfig.committee_pk,
slot: parseInt(mainnetConfig.slot),
time: parseInt(mainnetConfig.genesis_time),
},
chainConfig,
n: 1,
};
}
export function optimisticUpdateFromJSON(update: any): OptimisticUpdate {
return capella.ssz.LightClientOptimisticUpdate.fromJson(update);
}
export async function optimisticUpdateVerify(
committee: Uint8Array[],
update: OptimisticUpdate,
): Promise<VerifyWithReason> {
try {
const { attestedHeader: header, syncAggregate } = update;
const headerBlockRoot = phase0.ssz.BeaconBlockHeader.hashTreeRoot(
header.beacon,
);
const chainConfig = getDefaultClientConfig().chainConfig;
const committeeFast = deserializeSyncCommittee({
pubkeys: committee,
aggregatePubkey: bls.PublicKey.aggregate(
deserializePubkeys(committee),
).toBytes(),
});
try {
assertValidSignedHeader(
chainConfig,
committeeFast,
syncAggregate,
headerBlockRoot,
header.beacon.slot,
);
} catch (e) {
return { correct: false, reason: "invalid signatures" };
}
const participation =
syncAggregate.syncCommitteeBits.getTrueBitIndexes().length;
if (participation < BEACON_SYNC_SUPER_MAJORITY) {
return { correct: false, reason: "insufficient signatures" };
}
if (!isValidLightClientHeader(chainConfig, header)) {
return { correct: false, reason: "invalid header" };
}
return { correct: true };
} catch (e) {
console.error(e);
return { correct: false, reason: (e as Error).message };
}
}
export function deserializePubkeys(pubkeys) {
return pubkeys.map((pk) => bls.PublicKey.fromBytes(pk));
}
export function getCommitteeHash(committee: Uint8Array[]): Uint8Array {
return digest(concatBytes(...committee));
}
export const consensusClient = axios.create();
axiosRetry(consensusClient, { retries: 3 });
export async function getConsensusOptimisticUpdate() {
const resp = await consensusClient.get(
`/eth/v1/beacon/light_client/optimistic_update`,
);
const update = resp.data;
if (!update) {
throw Error(`fetching optimistic update failed`);
}
return update.data;
}
function isValidLightClientHeader(
config: ChainForkConfig,
header: allForks.LightClientHeader,
): boolean {
return isValidMerkleBranch(
config
.getExecutionForkTypes(header.beacon.slot)
.ExecutionPayloadHeader.hashTreeRoot(
(header as capella.LightClientHeader).execution,
),
(header as capella.LightClientHeader).executionBranch,
EXECUTION_PAYLOAD_DEPTH,
EXECUTION_PAYLOAD_INDEX,
header.beacon.bodyRoot,
);
}

60
tsconfig.json Normal file
View File

@ -0,0 +1,60 @@
{
"compilerOptions": {
"outDir": "lib",
"module": "ESNext",
"target": "ESNext",
"declaration": true,
"inlineSourceMap": true,
"noEmit": true,
"noImplicitUseStrict": false,
"preserveConstEnums": true,
"removeComments": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"isolatedModules": false,
"alwaysStrict": true,
"noImplicitAny": false,
"noImplicitThis": false,
"strictBindCallApply": true,
"strictFunctionTypes": true,
"strictNullChecks": true,
"strictPropertyInitialization": true,
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
"noFallthroughCasesInSwitch": false,
"skipLibCheck": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"baseUrl": ".",
"paths": {
"#*": [
"src/*"
],
"*": [
"*",
"types/*"
]
},
"lib": [
"ES2020",
"ES2021",
"dom"
]
},
"include": [
"**/*.json",
"**/*.ts",
"**/*.cts",
"**/*.mts"
],
"exclude": [
"**/node_modules",
"lib"
]
}