utilize pydantic models from eest on t8n#1359
utilize pydantic models from eest on t8n#1359souradeep-das wants to merge 8 commits intoethereum:forks/osakafrom
Conversation
| k: v if (isinstance(v, str) and v.startswith("0x")) else hex(v) | ||
| for k, v in acc["storage"].items() | ||
| } | ||
| state = t8n.json_to_state(alloc_json) |
There was a problem hiding this comment.
This could be made more efficient without having to convert from pydantic to json and then json to state
| json_output["alloc"] = json_state | ||
| json_output["result"] = json_result | ||
| output: TransitionToolOutput = TransitionToolOutput.model_validate( | ||
| json_output, context={"exception_mapper": self.exception_mapper} |
There was a problem hiding this comment.
This could potentially also be simplified without having to convert json and then json to pydantic
There was a problem hiding this comment.
I think now a direct conversion or individually validating each part of TransitionToolOutput wouldn't really add any efficiency gains here
SamWilsn
left a comment
There was a problem hiding this comment.
So my review amounts basically to just a general Python review.
@gurukamath would you mind giving this a review with an eye specifically to design/architecture, since you've been working in this area lately?
|
|
||
| def __init__( | ||
| self, options: Any, out_file: TextIO, in_file: TextIO | ||
| self, options: Any, out_file: TextIO, in_file: TransitionToolRequest |
| output: TransitionToolOutput = TransitionToolOutput.model_validate( | ||
| json_output, context={"exception_mapper": self.exception_mapper} | ||
| ) | ||
| return output |
There was a problem hiding this comment.
Hm, so this change would break the command-line output? Is that what we want?
| def to_canonical_withdrawal(raw): | ||
| return t8n.fork.Withdrawal( | ||
| index=U64(raw.index), | ||
| validator_index=U64(raw.validator_index), | ||
| address=raw.address, | ||
| amount=U256(raw.amount), | ||
| ) |
There was a problem hiding this comment.
Should probably hoist this out of read_withdrawals to avoid creating a bunch of closures that aren't used.
| if AuthorizationCls is None: | ||
| from ethereum.osaka.fork_types import Authorization as AuthorizationCls |
There was a problem hiding this comment.
If the fork doesn't have an Authorization type, but the test transaction does, we should probably error, no? Shoving an osaka type into a frontier block is going to lead to at least an exception somewhere.
| if isinstance(val, (bytes, bytearray)) and len(val) == 20: | ||
| return Bytes20(val) | ||
| if isinstance(val, (bytes, bytearray)) and len(val) == 0: | ||
| return Bytes20(b"\x00" * 20) | ||
| if isinstance(val, (bytes, bytearray)): | ||
| return Bytes20(val.rjust(20, b"\x00")) |
There was a problem hiding this comment.
Are these special cases necessary or does the rjust handle them all properly?
| return Bytes20(bytes(val).rjust(20, b"\x00")) | ||
|
|
||
| # build the canonical transaction | ||
| if tx_cls.__name__ == "FeeMarketTransaction": |
There was a problem hiding this comment.
Can we use issubclass here instead?
| # build the canonical transaction | ||
| if tx_cls.__name__ == "FeeMarketTransaction": | ||
| return tx_cls( | ||
| chain_id=U64(tx.chain_id), |
There was a problem hiding this comment.
Instead of repeating most of the arguments in every branch, would it make sense to do something like:
arguments = {
'nonce': U256(tx.nonce),
# The rest of the common items...
}
if issubclass(tx_cls, AccessListTransaction):
arguments["access_list"] = convert_access_list(tx.access_list)
elif issubclass(tx_cls, BlobTransaction):
...
return tx_cls(**arguments)| # output_dict = json.loads(out_stream.getvalue()) | ||
| # output: TransitionToolOutput = TransitionToolOutput.model_validate( | ||
| # output_dict, context={"exception_mapper": self.exception_mapper} | ||
| # ) |
There was a problem hiding this comment.
Remove code instead of commenting it out.
5479b3c to
5a17bd9
Compare
| self.options = options | ||
| self.forks = Hardfork.discover() | ||
|
|
||
| if "stdin" in ( |
There was a problem hiding this comment.
Would we still be able to consume json files if needed? We will need to continue supporting that use case.
There was a problem hiding this comment.
yes! with this commit dc31f96 I added the dual input option where we preserve the older json input route
| ) | ||
|
|
||
| self.chain_id = parse_hex_or_int(options.state_chainid, U64) | ||
| self.alloc = Alloc(self, in_file.input.alloc) |
There was a problem hiding this comment.
Perhaps we should re-use the Alloc, Env and Txs types defined by EEST. And if the json inputs are provided, we could just serialize/de-serialize using pydantic. That way, we can get of a lot of redundant code in env.py and t8n_types.py.
There was a problem hiding this comment.
right! :) The first thing i tried was to re-use the types (pydantic models) from EEST (to not have these intermediary classes at all) But seems like our execution-spec code isn't directly able to work with those (without some translations/conversions)? To be able to utilize the EEST types directly would definitely be the most efficient - any suggestions?
There was a problem hiding this comment.
Would something like this work?
- If EEST types are the input: EEST types -> EELS BlockEnvironment -> run the t8n tool
- If json input: json input -> EEST types -> EELS BlockEnvironment -> run the t8n tool
You might have to transform the EEST Alloc to the relevant fork's State dataclass but I think this is still much cleaner than what we currently have.
…thereum#1359) * fix(types): tests: Add serialization unit tests * fix(types): tests: Fix unit tests * feat(base_types): Implement serialization RLP types * feat(base_types,types,fixtures): Apply serialization RLP types * fix(types): Auth tuple defaults * fix(fixtures,rpc,specs,types,tests): Transaction.rlp is a function * fix(base_types,types,rpc): fixes * refactor(base_types,types): Network wrapped transaction * fix(tests): Network wrapped transactions * fix(types): Fix NetworkWrappedTransaction rlp prefix * docs: Changelog * Apply suggestions from code review Co-authored-by: spencer <spencer.taylor-brown@ethereum.org> * Add network wrapper explanation * fix: tox * Update docs/CHANGELOG.md Co-authored-by: spencer <spencer.taylor-brown@ethereum.org> * Add comment --------- Co-authored-by: spencer <spencer.taylor-brown@ethereum.org>
…thereum#1359) * fix(types): tests: Add serialization unit tests * fix(types): tests: Fix unit tests * feat(base_types): Implement serialization RLP types * feat(base_types,types,fixtures): Apply serialization RLP types * fix(types): Auth tuple defaults * fix(fixtures,rpc,specs,types,tests): Transaction.rlp is a function * fix(base_types,types,rpc): fixes * refactor(base_types,types): Network wrapped transaction * fix(tests): Network wrapped transactions * fix(types): Fix NetworkWrappedTransaction rlp prefix * docs: Changelog * Apply suggestions from code review Co-authored-by: spencer <spencer.taylor-brown@ethereum.org> * Add network wrapper explanation * fix: tox * Update docs/CHANGELOG.md Co-authored-by: spencer <spencer.taylor-brown@ethereum.org> * Add comment --------- Co-authored-by: spencer <spencer.taylor-brown@ethereum.org>
|
I think we still need to figure out what we're doing for this PR, so don't worry about rebasing onto |
|
Just mentioning #1883 here since it looks to tackle a similar issue |
|
@souradeep-das the issue guru linked is still relevant, are you willing to rebase and move forward with this PR or should it be closed? |
We are working through some re-factors in #2381 post which, it should be a little easier to use the pydantic models. I am tracking this PR and will re-factor/re-base if needed |
What was wrong?
Related to Issue ##1124
How was it fixed?
Cute Animal Picture