-
Notifications
You must be signed in to change notification settings - Fork 791
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
Tx initialization on the block library crashes on initialization with only chain set on Common #757
Comments
Update: this rather in addition might need some discussion if to only set the HF internally or directly on the |
I remember having this same issue, so those TODOs are probably mine. And yes, it should be "can't". |
@ryanio ah, thanks for reopening. Good that you noticed! |
@holgerd77 np! i am working on this now |
i'm a little stuck because the block number is not available when initializing common for Block. first we have to initialize BlockHeader to get block number, but that also needs a common passed into it (here). after BlockHeader is initialized we could possibly use we could also introduce a static method on common, but we would still need to pass in blockNumber, perhaps something like: /**
* Gets the hardfork based on the block's number.
* @param chain String ('mainnet') or Number (1) chain
* @param blockNumber Block number
* @returns String identifier for hardfork ('byzantium')
*/
static getHardforkForBlock(chain: string | number, blockNumber: number): string {
const targetChain = Common._getChainParams(chain)
let hardforks = targetChain.hardforks.filter(hardfork => hardfork.block && hardfork.block >= blockNumber)
hardforks = hardforks.sort((a, b) => (a.block! > b.block!) ? 1 : -1)
return hardforks[0].name
} |
I think a static method like that would kill the possibility of using custom Testing networks, like Ganache or Buidler EVM, requires using custom |
@alcuadrado ah didn't know about custom but yeah I'm not too familiar with how this constructor is used across dependant libs so it's a bit difficult for me to see the solution. |
That's a good point. It should work then. BTW, I always have the impression that accepting |
that would be nice as it would simplify a lot of our constructors across the monorepo. |
@ryanio The I would say the most tricky part here is rather the mutability of the I would argue that on the level of blocks and tx - since chain and fork are bound to the identity of these items - should rather internally use a copy of the The block constructor could then try to set the hardfork based by block number, eventually a new method on Then the transactions can be initialized based on this modified As a side note: I would also think a transaction should throw on initialization when no HF is provided along a Common instance or generally with the constructor, since with the logic in functions like |
@alcuadrado @ryanio Also one thought, not completely thought through though yet: it might also be worth to think if we want to switch to static methods for Common for all the methods which can be used in a stateless context, so that it eventually gets easier to use Common without the need for initialization. |
Another idea, partly complementary: we can pass in a flag to the block constructor to decide if HF is implicitly determined by the block number or by the Common instance passed. |
I have the feeling that the transaction class shouldn't have a common object, but take on as parameters whenever necessary (i.e. on validation and signing methods). The information that Common represents is inherent to Block, and not to Transaction. |
@alcuadrado hmm, I am not completely convinced here. There are lots of use cases where a tx is used without the scope of an encompassing block but where there is nevertheless the need/want for a clear and non-changing context state for the transaction. Taking this statefulness away here seems not the right solution to me but rather limiting the use cases. |
The issue I see is that signing and validation are two separate actions that can use different I think this is important if the client is to be more complete. |
Fixed by #863, will close. |
When experimenting with the
ethereumjs-client
code I stumbled upon an error that block initialization crashes when a block is initialized with aCommon
instance with only the chain and no hardfork set.I triggered a test run here which shows the "Error: Method called with neither a hardfork set nor provided by param" error being triggered in this case.
This is due to an undefined HF state in the created txs which leads to undefined behavior in places like here (the
this._common.gteHardfork('spuriousDragon')
comparison throws (correctly) because it needs a base HF to compare against).The problem is already described with two TODO entries in the block constructor (I think from @alcuadrado):
I think with this current implementation behavior of a runtime crash we should rethink the weight of the immutability argument here. I would therefore suggest to internally in the block class (so: not change the common instance) use a HF computed by the block number (this might need an additional method in
Common
) if no HF is passed on block initialization and also pass this on to the created txs.I think while technically possible the context of changing the block number after object creation is unlikely and generally non-recommended style, since on a block all data is highly interdependent and changing single data pieces is very likely bringing things out of sync.
Side note: there is another bug to fix here which is the
Common
object created by default (when no instance is provided) not being passed on to the txs currently (sinceopts
is passed there). This also leads to a potentially inconsistent state.The text was updated successfully, but these errors were encountered: