Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: a lot, fix: a lot - no more hanging! #73

Merged
merged 277 commits into from
Jul 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
277 commits
Select commit Hold shift + click to select a range
2139770
chore: silence NON_EMPTY_DATA
BobTheBuidler Jun 26, 2023
8256c99
fix: try to fix bytes conversion err
BobTheBuidler Jun 26, 2023
cb5522c
feat: better optimized distribution of load to node
BobTheBuidler Jun 26, 2023
3e312c5
fix: AttributeError
BobTheBuidler Jun 26, 2023
021b2db
chore: add `__repr__` for JSONRPCBatch class
BobTheBuidler Jun 26, 2023
a179812
feat: tenderly warning
BobTheBuidler Jun 26, 2023
936af8d
fix: JSONRPCBatch `__repr__`
BobTheBuidler Jun 26, 2023
b3a0785
fix: JSONRPCBatch bisect_and_retry batch already started err
BobTheBuidler Jun 26, 2023
6cd9c28
fix: JSONRPCBatch bisect_and_retry batch already started err
BobTheBuidler Jun 26, 2023
936f271
chore: reduce debug logging
BobTheBuidler Jun 26, 2023
b3f26d9
fix: start bisected Multicall objects
BobTheBuidler Jun 26, 2023
2a6f8cd
chore: refactor circular import
BobTheBuidler Jun 26, 2023
9e980a2
chore: use f-strings
BobTheBuidler Jun 27, 2023
5596874
chore: refactor out unnecessary use of HexBytes
BobTheBuidler Jun 27, 2023
d24cea7
chore: refactor _err_response
BobTheBuidler Jun 27, 2023
f5769ab
feat: use msgspec with type hints for json decoding
BobTheBuidler Jun 27, 2023
c8ca11f
chore: add comment
BobTheBuidler Jun 27, 2023
563d498
fix: AttributeError
BobTheBuidler Jun 27, 2023
c554435
feat: cleaner ValidationError
BobTheBuidler Jun 27, 2023
65bee75
fix: cleaner ValidationError
BobTheBuidler Jun 27, 2023
846a5c5
chore: remove unused code
BobTheBuidler Jun 27, 2023
b3071db
chore: add comment
BobTheBuidler Jun 27, 2023
b0a2f92
fix: json batch response validator
BobTheBuidler Jun 27, 2023
c624ab6
chore: setup debugging for decode type hints
BobTheBuidler Jun 27, 2023
23482b6
feat: add eth_getBalance to RETURN_TYPES for faster decoding
BobTheBuidler Jun 27, 2023
67ead50
feat: add eth_getBlockByNumber to RETURN_TYPES for faster decoding
BobTheBuidler Jun 27, 2023
f51ad34
chore: refactor list type debugger
BobTheBuidler Jun 27, 2023
ff4a48b
feat: add erigon_getHeaderByNumber to RETURN_TYPES for faster decoding
BobTheBuidler Jun 27, 2023
f8907df
fix: accept exceptions while decoding and proceed without hints
BobTheBuidler Jun 27, 2023
6b4dac7
fix: erigon_getHeaderByNumber decoding hint
BobTheBuidler Jun 28, 2023
1f84ff3
feat: addeth_chainId to RETURN_TYPES for faster decoding
BobTheBuidler Jun 28, 2023
ff56e21
feat: add eth_getCode to RETURN_TYPES for faster decoding
BobTheBuidler Jun 28, 2023
cc80222
chore: refactor type check
BobTheBuidler Jun 28, 2023
9e13abe
feat: add eth_getGetTransactionCount and eth_getTransactionReceipt to…
BobTheBuidler Jun 28, 2023
3332f15
fix: improper dict configuration
BobTheBuidler Jun 28, 2023
2225d43
fix: eth_getTrransactionReceipt decoding type
BobTheBuidler Jun 28, 2023
491c43d
feat: add eth_getTransactionByHash to RETURN_TYPES for faster decoding
BobTheBuidler Jun 28, 2023
ce07dfb
fix: eth_getTrransactionReceipt decoding type
BobTheBuidler Jun 28, 2023
2485389
chore: refactor decode_raw
BobTheBuidler Jun 28, 2023
b83df61
fix: dec_hook
BobTheBuidler Jun 28, 2023
ff91f58
fix: decode_raw
BobTheBuidler Jun 28, 2023
ca913a0
chore: refactor multicall abi en/decoding
BobTheBuidler Jun 28, 2023
92ab112
feat: POC for JIT decoding
BobTheBuidler Jun 28, 2023
2dc4af2
chore: refactor Multicall to use Response type
BobTheBuidler Jun 28, 2023
d42af82
fix: Response.decode_result
BobTheBuidler Jun 28, 2023
8ed3f2e
chore: remove unused code
BobTheBuidler Jun 28, 2023
6875e62
chore: partially refactor away DankWorker
BobTheBuidler Jun 28, 2023
df6843f
chore: remove unused code
BobTheBuidler Jun 28, 2023
8334f70
chore: refactor out DankWorker
BobTheBuidler Jun 28, 2023
1d32a6c
chore: refactor middleware
BobTheBuidler Jun 28, 2023
a9aee62
chore: refactor file structure
BobTheBuidler Jun 28, 2023
05d4d3f
chore: refactor batcher
BobTheBuidler Jun 28, 2023
bd74f9a
chore: remove unused code
BobTheBuidler Jun 28, 2023
46ec718
fix: backward compatability
BobTheBuidler Jun 28, 2023
43629e7
feat: RawResponse class for better JIT decoding
BobTheBuidler Jun 28, 2023
1a91a5e
feat: even better JIT decoding with RawResponse class
BobTheBuidler Jun 28, 2023
bcff634
feat: use msgspec encoder
BobTheBuidler Jun 28, 2023
2abeb20
chore: smol refactor
BobTheBuidler Jun 28, 2023
1603ae4
feat: use msgspec.Struct for faster encoding of request data
BobTheBuidler Jun 28, 2023
62ab09d
chore: remove unnecessary code
BobTheBuidler Jun 28, 2023
17d4bcd
feat: PartialResponse class to skip unnecessary json decoding
BobTheBuidler Jun 28, 2023
3f68845
feat: implement PartialResponse around the codebase
BobTheBuidler Jun 28, 2023
eb971b1
feat: bypass encoding of non-required `jsonrpc` field
BobTheBuidler Jun 28, 2023
fd5daa7
feat: decode in subprocess to unblock event loop
BobTheBuidler Jun 28, 2023
0cb398a
chore: remove debug_helper
BobTheBuidler Jun 28, 2023
584fc42
chore: refactor spoof_response
BobTheBuidler Jun 28, 2023
fd7c607
chore: refactor run_in_subprocess
BobTheBuidler Jun 29, 2023
997df33
feat: implement partial decoding
BobTheBuidler Jun 29, 2023
1ebb103
chore: add stats
BobTheBuidler Jun 29, 2023
d865fcc
fix: make PartialResponse.result required
BobTheBuidler Jun 29, 2023
9c7e973
fix: do not try to decode None
BobTheBuidler Jun 29, 2023
b6c1720
fix: _DictStruct not subscriptable
BobTheBuidler Jun 29, 2023
1dea1f0
fix: accept result None for PartialResponse
BobTheBuidler Jun 29, 2023
f546c85
fix: why isn't __getitem__ working
BobTheBuidler Jun 29, 2023
2303e87
feat: minimum 2 calls per Multicall
BobTheBuidler Jun 29, 2023
80dbe94
fix: use full Request spec for Optimism
BobTheBuidler Jun 29, 2023
b7d04d4
chore: reduce debug logging
BobTheBuidler Jun 29, 2023
88dd801
fix(temp): bad hex handling
BobTheBuidler Jun 29, 2023
9246ca6
chore: reduce debug logging
BobTheBuidler Jun 29, 2023
d5265d2
fix: eth_getTransactionByHash
BobTheBuidler Jun 29, 2023
6f6f2e7
chore: increase debug logging
BobTheBuidler Jun 29, 2023
5bd3267
fix: eth_getBlockByNumber
BobTheBuidler Jun 29, 2023
4363637
revert accidental commit
BobTheBuidler Jun 29, 2023
b865130
chore: send more multicalls to subprocess for decoding
BobTheBuidler Jun 29, 2023
23beae5
chore: reduce debug logging
BobTheBuidler Jun 29, 2023
202b280
fix: AttributeDict responses
BobTheBuidler Jun 29, 2023
949340b
chore: reduce debug logging
BobTheBuidler Jun 29, 2023
58e3cd8
chore: send more multicalls to subprocess for decoding
BobTheBuidler Jun 29, 2023
4c80e2c
fix: run_in_subprocess RuntimeError
BobTheBuidler Jun 29, 2023
70bcf93
chore: bump default timeout to aiohttp default
BobTheBuidler Jun 29, 2023
adde363
chore: fix comment
BobTheBuidler Jun 29, 2023
4bfe885
potentially fix sentry error with no-name logger
BobTheBuidler Jun 29, 2023
8e2d02d
feat: use subprocesses for brownie patch en/decoding
BobTheBuidler Jun 29, 2023
0eee3b7
do a thing
BobTheBuidler Jun 29, 2023
7fd21aa
Revert "do a thing"
BobTheBuidler Jun 29, 2023
c6c05ff
Revert "Revert "do a thing""
BobTheBuidler Jun 29, 2023
91b791b
Revert "Revert "Revert "do a thing"""
BobTheBuidler Jun 29, 2023
0bee97f
fix: broken ProcessPool and PicklingError
BobTheBuidler Jun 29, 2023
87d0ddd
chore: refactor Exception handling
BobTheBuidler Jun 29, 2023
5693492
chore: remove unused code
BobTheBuidler Jun 29, 2023
509ca12
feat: basic stats
BobTheBuidler Jun 29, 2023
b13418c
fix: StatsLogger
BobTheBuidler Jun 29, 2023
1495325
feat: stats daemon
BobTheBuidler Jun 30, 2023
71ee626
chore: refactor exception handling
BobTheBuidler Jun 30, 2023
0faa7c3
fix: bump timeout to 20 minutes
BobTheBuidler Jun 30, 2023
647abad
chore: refactor exception handling
BobTheBuidler Jun 30, 2023
bc0c6e7
feat: subprocess stats
BobTheBuidler Jun 30, 2023
b0b95b6
feat: add cloudflare's timeout status code to exception handler
BobTheBuidler Jun 30, 2023
551983c
feat: custom ClientSession
BobTheBuidler Jun 30, 2023
853df18
fix: result==None
BobTheBuidler Jun 30, 2023
a6bbee8
a bunch
BobTheBuidler Jun 30, 2023
b7df5e4
chore: refactor stats
BobTheBuidler Jun 30, 2023
2321e86
chore: refactor
BobTheBuidler Jun 30, 2023
6f42b15
feat: ENVIRONMENT_VARIABLES file
BobTheBuidler Jun 30, 2023
8b4d4ed
feat: env management
BobTheBuidler Jul 1, 2023
f81b839
fix: whoops
BobTheBuidler Jul 2, 2023
3147f2d
chore: fix init
BobTheBuidler Jul 2, 2023
f5f82f5
chore: replace executor
BobTheBuidler Jul 2, 2023
a2b1318
feat: per-controller method semaphores
BobTheBuidler Jul 2, 2023
d406a3b
chore: bump deps
BobTheBuidler Jul 2, 2023
21cebd8
feat: add context to err responses
BobTheBuidler Jul 2, 2023
acb7625
feat: implement a_sync semaphores
BobTheBuidler Jul 2, 2023
1cb6d42
chore: deprecate dank_mids.semaphore
BobTheBuidler Jul 2, 2023
57e1fa0
chore: add logged warning
BobTheBuidler Jul 2, 2023
7014581
feat: implement typed-envs
BobTheBuidler Jul 3, 2023
64b730e
fix: deprecate semaphore module
BobTheBuidler Jul 3, 2023
62aec15
test fix opti
BobTheBuidler Jul 3, 2023
d73bb4e
test fix opti
BobTheBuidler Jul 3, 2023
91e1c58
fix: opti
BobTheBuidler Jul 3, 2023
1306358
fix: retry logic
BobTheBuidler Jul 3, 2023
0137971
fix: retry logic
BobTheBuidler Jul 3, 2023
2e27ff8
fix: protect mcall decoder pool from exceptions
BobTheBuidler Jul 3, 2023
7b025ef
fix: pop None results from err responses
BobTheBuidler Jul 3, 2023
c19ad89
fix: oops
BobTheBuidler Jul 3, 2023
743e240
fix: BrokenProcessPool from AttributeError from PicklingError
BobTheBuidler Jul 3, 2023
efa5f1e
feat: protect all process pools
BobTheBuidler Jul 3, 2023
10144de
fix: use empty string instead of None for empty errs
BobTheBuidler Jul 3, 2023
ed89d66
fix: broken import
BobTheBuidler Jul 3, 2023
a4613e9
fix: somehow caused an import error by moving a file and moving it back
BobTheBuidler Jul 3, 2023
27db067
fix: possible pickle err
BobTheBuidler Jul 3, 2023
88674cf
fix: possible pickle err edge case
BobTheBuidler Jul 3, 2023
39bdf6a
fix: trace call exceptions back up to the right caller
BobTheBuidler Jul 3, 2023
c40e25b
bump conc.futures queue size from 1
BobTheBuidler Jul 3, 2023
caef67f
feat: debug logger on stalled calls
BobTheBuidler Jul 3, 2023
5efcf7a
fix: forgot to call
BobTheBuidler Jul 3, 2023
3963b38
chore: add more debug logs
BobTheBuidler Jul 4, 2023
e8a9c0b
chore: set unutilized events for debug purposes
BobTheBuidler Jul 4, 2023
a662383
fix: _debug_daemon on batches
BobTheBuidler Jul 4, 2023
96b952d
fix: set string converters for envs
BobTheBuidler Jul 4, 2023
5768ba1
fix: better logic for retrying reverted mcalls
BobTheBuidler Jul 4, 2023
a52a09d
feat: better revert handling
BobTheBuidler Jul 4, 2023
c234ec9
fix: bad hex handling
BobTheBuidler Jul 5, 2023
4adec4c
fix: oversized jsonrpc batches
BobTheBuidler Jul 5, 2023
c734fc0
testing something
BobTheBuidler Jul 5, 2023
7c5bd15
feat: logic for reducing jsonrpc batch size like mcall batch size
BobTheBuidler Jul 5, 2023
d1b79ec
feat: minimum multicall size
BobTheBuidler Jul 5, 2023
c76d712
fix: potential hanging behavior caused py CancellationError edge case
BobTheBuidler Jul 5, 2023
8a3513c
chore: add comment
BobTheBuidler Jul 5, 2023
9a9be82
chore: refactor chunk sizing
BobTheBuidler Jul 5, 2023
ffa0a9e
feat: use jsonbatch instead of mcall below certain call size
BobTheBuidler Jul 5, 2023
382cb07
feat: lift brownie call response decoding out of brownie call semaphore
BobTheBuidler Jul 6, 2023
5dc0430
fix: missing return value
BobTheBuidler Jul 6, 2023
d7b7719
chore: remove whitespace
BobTheBuidler Jul 6, 2023
f3fd613
fix: revert min mcall size
BobTheBuidler Jul 7, 2023
4765226
feat: infura and application operation modes
BobTheBuidler Jul 8, 2023
a341141
chore: get rid of debug warning
BobTheBuidler Jul 8, 2023
cf81c3e
fix: AttributeError
BobTheBuidler Jul 8, 2023
f65c9ac
chore: sourcery errs
BobTheBuidler Jul 8, 2023
ee8809a
chore: dont log msg: invalid request
BobTheBuidler Jul 8, 2023
bd60519
chore: add more loggers
BobTheBuidler Jul 8, 2023
0aa72bd
fix: added detail ClientResponseError
BobTheBuidler Jul 8, 2023
7df071e
feat: BlockSemaphore
BobTheBuidler Jul 8, 2023
e27810d
feat: pre encode brownie calls
BobTheBuidler Jul 8, 2023
8716d58
fix: subclassing err
BobTheBuidler Jul 8, 2023
0db2264
chore: add loggers and shuffle call weight
BobTheBuidler Jul 8, 2023
cdb36bb
fix: batch _await
BobTheBuidler Jul 8, 2023
477e933
feat: use debug-enabled a_sync.Event instead of asyncio.Event
BobTheBuidler Jul 8, 2023
b656315
chore: juggle around call weights
BobTheBuidler Jul 8, 2023
b4fd3ad
chore: cleanup logging
BobTheBuidler Jul 8, 2023
3908d04
fix: "dictionary changed size during iteration" from pthreading race …
BobTheBuidler Jul 8, 2023
09c2f98
feat: better solution for threading race condition
BobTheBuidler Jul 8, 2023
2dcbc71
fix: brownie encoder semaphore wasn't doing its job
BobTheBuidler Jul 8, 2023
d8ca63a
fix: generalize excception detail adder
BobTheBuidler Jul 8, 2023
2d8d28a
fix: attr err
BobTheBuidler Jul 8, 2023
95e21cf
fix: clean shutdown of mcall debug daemon
BobTheBuidler Jul 9, 2023
fbae2bf
feat: use threading reanatrant lock
BobTheBuidler Jul 9, 2023
ccb65ed
feat: even better debug logging
BobTheBuidler Jul 9, 2023
05ad95a
fix: raise was missing an exception
BobTheBuidler Jul 9, 2023
f671cfa
fix: logic for reducing mcall batch size
BobTheBuidler Jul 9, 2023
17f958b
chore: more specific exception logic for Payload Too Large
BobTheBuidler Jul 9, 2023
c6a7b46
chore: refactor for readability
BobTheBuidler Jul 9, 2023
2ae0422
chore: remove less than helpful logger
BobTheBuidler Jul 9, 2023
78706f9
git feat: add error code 522 to HTTPStatusExtended int enum
BobTheBuidler Jul 9, 2023
e4312bd
feat: better use of RLock
BobTheBuidler Jul 9, 2023
f932d2c
fix: negate if check
BobTheBuidler Jul 9, 2023
6f725dd
feat: DankMidsInternalError
BobTheBuidler Jul 9, 2023
13ffe7a
fix: SyntaxError
BobTheBuidler Jul 9, 2023
595aa54
fix: _reduce_chunk_size
BobTheBuidler Jul 9, 2023
7fdc4ab
chore: raise DankMidsInternalError instead of generic ValueError
BobTheBuidler Jul 9, 2023
defedbf
feat: bifurcate multicall eth_calls from other eth_calls on batch.met…
BobTheBuidler Jul 9, 2023
7f15c08
feat: adapt batch.method_counts to new batching schema
BobTheBuidler Jul 9, 2023
8907e31
feat: use call_soon_threadsafe to set Events
BobTheBuidler Jul 9, 2023
1b27b8a
fix: refix _reduce_chunk_size
BobTheBuidler Jul 9, 2023
65c45ff
fix: call_soon_threadsafe on py 3.10+
BobTheBuidler Jul 9, 2023
ae031e6
fix: force caching of event loop at _RequestEvent init
BobTheBuidler Jul 9, 2023
3cfef2a
fix: AttributeError
BobTheBuidler Jul 9, 2023
6e1e43d
chore: add debug logs to block semaphore
BobTheBuidler Jul 9, 2023
394841c
test no controller cache
BobTheBuidler Jul 9, 2023
b72be04
chore: bump dep
BobTheBuidler Jul 10, 2023
24a30d8
feat: emergency exit for timed out calls - 60s default
BobTheBuidler Jul 11, 2023
e8aea91
fix: opti partial request issue
BobTheBuidler Jul 11, 2023
7b185e5
chore: tweak batch size math for infura
BobTheBuidler Jul 11, 2023
ceb5d8c
fix: wrap batch execution with nuclear option too
BobTheBuidler Jul 11, 2023
37aa337
fix: copypasta error
BobTheBuidler Jul 11, 2023
6b4acf1
fix: partial -> full request changeover
BobTheBuidler Jul 11, 2023
6933136
fix: partial -> full request changeover
BobTheBuidler Jul 11, 2023
f6a638a
fix: im a tard part 2
BobTheBuidler Jul 11, 2023
7ed6c05
try something: add deadlock detection to RLock
BobTheBuidler Jul 12, 2023
99cb61a
fix: missing __init__ in debugging RLock
BobTheBuidler Jul 12, 2023
1211f17
fix: tempfix AttributeError in emergency exit
BobTheBuidler Jul 12, 2023
d8f28c1
fix: dummy
BobTheBuidler Jul 12, 2023
1033066
fix: prio semaphore
BobTheBuidler Jul 12, 2023
6b85347
fix: add 'invalid request' handler to jsonrpc batch
BobTheBuidler Jul 12, 2023
4b8ed3f
fix: missing attribute lookup
BobTheBuidler Jul 12, 2023
d374669
fix: BlockSemaphore.locked
BobTheBuidler Jul 13, 2023
8a83ee9
fix: catch 3rd possible location for 'invalid request'
BobTheBuidler Jul 13, 2023
cff2542
fix: syntax err
BobTheBuidler Jul 13, 2023
ccf79d0
chore: move temp changes into ez-a-sync
BobTheBuidler Jul 13, 2023
a9ef0c3
chore: use stable release for ez-a-sync
BobTheBuidler Jul 13, 2023
f510ec9
fix: honestly don't even try to wrap your mind around this one
BobTheBuidler Jul 13, 2023
5571963
feat: add status code 530 to HTTPStatusExtended
BobTheBuidler Jul 14, 2023
3b1e05f
fix: method semaphore for non-batch eth_calls
BobTheBuidler Jul 14, 2023
4d8e437
maybe fix: refactor create_duplicate
BobTheBuidler Jul 14, 2023
61126df
feat: batch size loggers
BobTheBuidler Jul 15, 2023
a58029e
feat: set_done helper deco
BobTheBuidler Jul 16, 2023
f6bb6e1
fix: BROWNIE_ENCODER_SEMAPHORE env
BobTheBuidler Jul 16, 2023
c007ede
fix: broken import
BobTheBuidler Jul 16, 2023
b5a281a
chore: refactor done event
BobTheBuidler Jul 17, 2023
8f0c6ba
fix: skip process pool for infura mode brownie decoding
BobTheBuidler Jul 17, 2023
c2eb68d
feat: broken process pool loggers
BobTheBuidler Jul 17, 2023
ebec1dd
fix: BlockSemaphore
BobTheBuidler Jul 17, 2023
08362ad
feat: rate limit calls to node, see if this helps with conn errs
BobTheBuidler Jul 17, 2023
448942e
fix: force infura mode
BobTheBuidler Jul 17, 2023
589a3ec
fix: tighten rpc rate limiter
BobTheBuidler Jul 17, 2023
8208f8e
fix: tighten rpc rate limiter
BobTheBuidler Jul 17, 2023
4340337
fix: tighten rpc rate limiter
BobTheBuidler Jul 17, 2023
6b85353
fix: better utilize rpc rate limiter
BobTheBuidler Jul 17, 2023
2281b51
fix: tighten rpc rate limiter
BobTheBuidler Jul 17, 2023
1b11200
chore: refactor chunk size
BobTheBuidler Jul 17, 2023
91cef6e
fix: add cloudflare custom status code 520 to HTTPStatusExtended
BobTheBuidler Jul 17, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ dank_mids.egg-info
.pytest_cache
.eggs
.mypy_cache
__pycache__
__pycache__
just-leave-me-here-and-dont-touch-me-plz.log
85 changes: 85 additions & 0 deletions dank_mids/ENVIRONMENT_VARIABLES.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@

import logging

import a_sync
import typed_envs
from a_sync import AsyncProcessPoolExecutor

from dank_mids import _envs
from dank_mids._mode import OperationMode
from dank_mids.semaphores import BlockSemaphore

logger = logging.getLogger("dank_mids.envs")

if not typed_envs.logger.disabled:
logger.info("For your information, you can tweak your configuration for optimal performance using any of the envs below:")

###############
# ENVIRONMENT #
###############

# What mode should dank mids operate in?
# NOTE: infura mode is required for now
# TODO: fix the other modes, set default='default', and make this verbose again
OPERATION_MODE = _envs.create_env("OPERATION_MODE", OperationMode, default="infura", verbose=False)

# Max number of rpc calls to include in one batch call
MAX_JSONRPC_BATCH_SIZE = _envs.create_env("MAX_JSONRPC_BATCH_SIZE", int, default=500)

# Enable Demo Mode?
demo_mode = _envs._deprecated_format.create_env("DEMO_MODE", bool, default=False, verbose=False)
DEMO_MODE = _envs.create_env("DEMO_MODE", bool, default=demo_mode, verbose=False)

# Are you calling a ganache fork? Can't use state override code
ganache_fork = _envs._deprecated_format.create_env("GANACHE_FORK", bool, default=False, verbose=False)
GANACHE_FORK = _envs.create_env("GANACHE_FORK", bool, default=ganache_fork)

# We set the default to 20 minutes to account for potentially long event loop times if you're doing serious work.
AIOHTTP_TIMEOUT = _envs.create_env("AIOHTTP_TIMEOUT", int, default=20*60, string_converter=int)

# Brownie call Semaphore
# Used because I experienced some OOM errs due to web3 formatters when I was batching an absurd number of brownie calls.
# We need a separate semaphore here because the method-specific semaphores are too late in the code to prevent this OOM issue.
brownie_semaphore = _envs._deprecated_format.create_env("BROWNIE_CALL_SEMAPHORE", int, default=100_000, string_converter=int, verbose=False)
BROWNIE_CALL_SEMAPHORE = _envs.create_env("BROWNIE_CALL_SEMAPHORE", BlockSemaphore, default=brownie_semaphore, string_converter=int, verbose=not OPERATION_MODE.infura)
BROWNIE_ENCODER_SEMAPHORE = _envs.create_env("BROWNIE_ENCODER_SEMAPHORE", BlockSemaphore, default=BROWNIE_CALL_SEMAPHORE._default_value * 2, string_converter=int, verbose=not OPERATION_MODE.infura)

# Processes for decoding. This determines process pool size, not total subprocess count.
# There are 3 pools, each initialized with the same value.
# NOTE: Don't stress, these are good for you and will not hog your cpu. You can disable them by setting the var = 0. #TODO: lol u cant yet
BROWNIE_ENCODER_PROCESSES = _envs.create_env("BROWNIE_ENCODER_PROCESSES", AsyncProcessPoolExecutor, default=0 if OPERATION_MODE.infura else 1, string_converter=int, verbose=not OPERATION_MODE.infura)
BROWNIE_DECODER_PROCESSES = _envs.create_env("BROWNIE_DECODER_PROCESSES", AsyncProcessPoolExecutor, default=0 if OPERATION_MODE.infura else 1, string_converter=int, verbose=not OPERATION_MODE.infura)
MULTICALL_DECODER_PROCESSES = _envs.create_env("MULTICALL_DECODER_PROCESSES", AsyncProcessPoolExecutor, default=0 if OPERATION_MODE.infura else 1, string_converter=int, verbose=not OPERATION_MODE.infura)

# NOTE: EXPORT_STATS is not implemented
# TODO: implement this
EXPORT_STATS = _envs.create_env("EXPORT_STATS", bool, default=False, verbose=False)
# NOTE: COLLECT_STATS is implemented
COLLECT_STATS = _envs.create_env("COLLECT_STATS", bool, default=EXPORT_STATS, verbose=not EXPORT_STATS)

# You probably don't need to use this unless you know you need to
STUCK_CALL_TIMEOUT = _envs.create_env("STUCK_CALL_TIMEOUT", int, default=60)

# Method-specific Semaphores
method_semaphores = {
"eth_call": _envs.create_env("ETH_CALL_SEMAPHORE", BlockSemaphore, default=BROWNIE_CALL_SEMAPHORE._value, string_converter=int),
"eth_getBlock": _envs.create_env("ETH_GETBLOCK_SEMAPHORE", a_sync.Semaphore, default=50, string_converter=int),
"eth_getLogs": _envs.create_env("ETH_GETLOGS_SEMAPHORE", a_sync.Semaphore, default=64, string_converter=int),
"eth_getTransaction": _envs.create_env("ETH_GETTRANSACTION_SEMAPHORE", a_sync.Semaphore, default=100, string_converter=int),
}

if not typed_envs.logger.disabled:
logger.info("More details can be found in dank_mids/ENVIRONMENT_VARIABLES.py")
logger.info("NOTE: You can disable these logs by setting the `TYPEDENVS_SHUTUP` env var to any value.")


# Validate some stuffs

# NOTE: The other modes are (probably) bugging out right now. More investigation needed. For now you use infura mode.
if not OPERATION_MODE.infura:
raise ValueError("Dank mids must be run in infura mode for now")

if OPERATION_MODE.infura:
for process_pool in {MULTICALL_DECODER_PROCESSES, BROWNIE_DECODER_PROCESSES, BROWNIE_ENCODER_PROCESSES}:
if process_pool._max_workers:
raise ValueError(f"You cannot set env var {process_pool.name} while running dank in infura mode.")
11 changes: 11 additions & 0 deletions dank_mids/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@



from dank_mids._how_is_this_real import _the_most_absurd_fix_youve_ever_seen
from dank_mids.controller import instances
from dank_mids.helpers import setup_dank_w3, setup_dank_w3_from_sync
from dank_mids.middleware import dank_middleware


def _configure_concurrent_future_work_queue_size():
import concurrent.futures.process as _cfp
_cfp.EXTRA_QUEUED_CALLS = 50_000

_configure_concurrent_future_work_queue_size()
_the_most_absurd_fix_youve_ever_seen()
35 changes: 0 additions & 35 deletions dank_mids/_config.py

This file was deleted.

4 changes: 2 additions & 2 deletions dank_mids/_demo_mode.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import logging
from typing import Any

from dank_mids._config import DEMO_MODE
from dank_mids import ENVIRONMENT_VARIABLES


class DummyLogger:
""" Replace a `logging.Logger` object with a dummy to save precious time """
def info(self, *args: Any, **kwargs: Any) -> None:
...

demo_logger = logging.getLogger("dank_mids.demo") if DEMO_MODE else DummyLogger()
demo_logger = logging.getLogger("dank_mids.demo") if ENVIRONMENT_VARIABLES.DEMO_MODE else DummyLogger()
8 changes: 8 additions & 0 deletions dank_mids/_envs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

from typed_envs import EnvVarFactory

_factory = EnvVarFactory("DANKMIDS")
create_env = _factory.create_env

# This only applies to the oldest of dank's envs
_deprecated_format = EnvVarFactory("DANK_MIDS")
45 changes: 45 additions & 0 deletions dank_mids/_exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

from typing import TYPE_CHECKING, Union
import logging

from aiohttp.client_exceptions import ClientResponseError

if TYPE_CHECKING:
from dank_mids.types import PartialRequest, PartialResponse


logger = logging.getLogger("dank_mids.exceptions")

class BadResponse(ValueError):
def __init__(self, response: "PartialResponse") -> None:
self.response = response
super().__init__(response.to_dict())

class EmptyBatch(ValueError):
pass

class ResponseNotReady(ValueError):
pass

class PayloadTooLarge(BadResponse):
pass

class DankMidsClientResponseError(ClientResponseError):
"""A wrapper around the standard aiohttp ClientResponseError that attaches the request that generated the error."""
def __init__(
self,
exc: ClientResponseError,
request: "PartialRequest",
) -> None:
self.request = request
super().__init__(exc.request_info, exc.history, code=exc.code, status=exc.status, message=exc.message, headers=exc.headers)
self.args = (*exc.request_info, exc.history, request)
self._exception = exc

internal_err_types = Union[AttributeError, TypeError, UnboundLocalError, NotImplementedError, RuntimeError, SyntaxError]

class DankMidsInternalError(Exception):
def __init__(self, e: internal_err_types) -> None:
logger.warning(f"unhandled exception inside dank mids internals: {e}", exc_info=True)
self._original_exception = e
super().__init__(e.__repr__())
37 changes: 37 additions & 0 deletions dank_mids/_how_is_this_real.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@

import logging
from logging.handlers import RotatingFileHandler

LOGS_PATH = 'just-leave-me-here-and-dont-touch-me-plz.log'
ONE_KB = 1024

silencer = RotatingFileHandler(LOGS_PATH, maxBytes=500*ONE_KB, backupCount=0)

def _the_most_absurd_fix_youve_ever_seen():
"""
Somehow this resolves a race condition enough for the library to work as intended.
How? I have no idea at all. Please don't ask me, its magic.
I'll debug this later once I've pooshed a stable release to prod.
"""
enable_logger_but_divert_stream('a_sync.abstract')
enable_logger_but_divert_stream('a_sync.base')
enable_logger_but_divert_stream('dank_mids.controller')
enable_logger_but_divert_stream('dank_mids.session')
enable_logger_but_divert_stream('dank_mids.semaphores')

def enable_logger_but_divert_stream(name, show_every_x=None):
logger = logging.getLogger(name)
if logging.root.isEnabledFor(logging.DEBUG) or logger.isEnabledFor(logging.DEBUG):
# We don't need to do anything, the user has indicated they want the debug logs enabled and shown
return
# Break the logger apart from the root logger and its handlers
logger.propagate = False
# Enable the logger regardless of root settings
logger.setLevel(logging.DEBUG)
# remove the root handler that was added at basicConfig step (not sure if this is actually necessary)
logger.removeHandler(logging.StreamHandler())
# ensure the logger has no handlers
assert logger.handlers == [], logger.handlers
# add the silencer handler to direct the logs to a throwaway file
logger.addHandler(silencer)

22 changes: 22 additions & 0 deletions dank_mids/_mode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

from functools import cached_property

MODES = ["default", "application", "infura"]

class OperationMode(str):
@cached_property
def application(self) -> bool:
# This mode keeps the event loop as unblocked as possible so an asyncio application can run as designed
return self.mode == "application"
@cached_property
def default(self) -> bool:
return self.mode == "default"
@cached_property
def infura(self) -> bool:
# This mode minimizes the total number of calls sent to the node
return self.mode == "infura"
@property
def mode(self) -> str:
if self not in MODES:
raise ValueError(f'dank mids operation mode {self} is invalid', f'valid modes: {MODES}', str(self))
return self
77 changes: 77 additions & 0 deletions dank_mids/batch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@

import asyncio
import logging
from typing import TYPE_CHECKING, Any, Generator, List

from dank_mids._exceptions import DankMidsInternalError
from dank_mids.requests import JSONRPCBatch, RPCRequest, _Batch
from dank_mids.types import Multicalls

if TYPE_CHECKING:
from dank_mids.controller import DankMiddlewareController

MIN_SIZE = 1 # TODO: Play with this
CHECK = MIN_SIZE - 1

logger = logging.getLogger(__name__)

class DankBatch:
""" A batch of jsonrpc batches. This is pretty much deprecated and needs to be refactored away."""
def __init__(self, controller: "DankMiddlewareController", multicalls: Multicalls, rpc_calls: List[RPCRequest]):
self.controller = controller
self.multicalls = multicalls
self.rpc_calls = rpc_calls
self._started = False

def __await__(self) -> Generator[Any, None, Any]:
self.start()
return self._await().__await__()

async def _await(self) -> None:
batches = tuple(self.coroutines)
for batch, result in zip(batches, await asyncio.gather(*batches, return_exceptions=True)):
if isinstance(result, Exception):
if not isinstance(result, DankMidsInternalError):
logger.error(f"That's not good, there was an exception in a {batch.__class__.__name__}. These are supposed to be handled.\n{result}\n", exc_info=True)
raise result

def start(self) -> None:
for mcall in self.multicalls.values():
mcall.start(self, cleanup=False)
for call in self.rpc_calls:
call.start(self)
self._started = True

@property
def coroutines(self) -> Generator["_Batch", None, None]:
# Combine multicalls into one or more jsonrpc batches

# Create empty batch
working_batch = JSONRPCBatch(self.controller)

check_len = min(CHECK, self.controller.batcher.step)
# Go thru the multicalls and add calls to the batch
for mcall in self.multicalls.values():
# NOTE: If a multicall has less than `CHECK` calls, we should just throw the calls into a jsonrpc batch individually.
try: # NOTE: This should be faster than using len().
mcall[check_len]
working_batch.append(mcall, skip_check=True)
except IndexError:
working_batch.extend(mcall, skip_check=True)
if working_batch.is_full:
yield working_batch
working_batch = JSONRPCBatch(self.controller)

rpc_calls_to_batch = self.rpc_calls[:]
while rpc_calls_to_batch:
if working_batch.is_full:
yield working_batch
working_batch = JSONRPCBatch(self.controller)
working_batch.append(rpc_calls_to_batch.pop(), skip_check=True)
if working_batch:
if working_batch.is_single_multicall:
yield working_batch[0] # type: ignore [misc]
elif len(working_batch) == 1:
yield working_batch[0].make_request()
else:
yield working_batch
Loading
Loading