-
Notifications
You must be signed in to change notification settings - Fork 773
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
Block, Tx: Caching for hash method #1445
Changes from 5 commits
3650857
8a274bd
4203861
a1e33ac
837830b
37073bf
3c7912b
e5b56cc
2039403
b44210e
ccda170
f8bf704
bec1cff
95ac4d7
296c25c
2b8eceb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,6 +38,8 @@ export default class FeeMarketEIP1559Transaction extends BaseTransaction<FeeMark | |
|
||
public readonly common: Common | ||
|
||
private readonly _cachedHash?: Buffer | ||
|
||
/** | ||
* The default HF if the tx type is active on that HF | ||
* or the first greater HF where the tx is active. | ||
|
@@ -228,6 +230,9 @@ export default class FeeMarketEIP1559Transaction extends BaseTransaction<FeeMark | |
|
||
const freeze = opts?.freeze ?? true | ||
if (freeze) { | ||
if (this.isSigned()) { | ||
this._cachedHash = this.hash() | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi there, thanks for the PR! 😄 The cache creation for the hash shouldn't be done in the constructor but in the If your problem is that the object actually will get frozen after the constructor is called: I did some experiments on this and I guess it should work to wrap the > const inner = { hash: '123' }
'use strict'
> const outer = { inner, test: 5 }
undefined
> outer.test = 4
4
> outer
{ inner: { hash: '123' }, test: 4 }
> Object.freeze(outer)
{ inner: { hash: '123' }, test: 4 }
> outer.test = 3
3
> outer
{ inner: { hash: '123' }, test: 4 }
> outer.inner.hash = '345'
'345'
> outer
{ inner: { hash: '345' }, test: 4 } So as one can see the Maybe choose some structure like: private cache = { hash: undefined } Then we can eventually expand this with other stuff. 😄 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good - will give it a try There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @holgerd77 I have an implementation in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that looks good, ready to proceed! 😄 |
||
Object.freeze(this) | ||
} | ||
} | ||
|
@@ -330,6 +335,10 @@ export default class FeeMarketEIP1559Transaction extends BaseTransaction<FeeMark | |
throw new Error('Cannot call hash method if transaction is not signed') | ||
} | ||
|
||
if (this._cachedHash) { | ||
return this._cachedHash | ||
} | ||
|
||
return keccak256(this.serialize()) | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,8 @@ export default class Transaction extends BaseTransaction<Transaction> { | |
|
||
public readonly common: Common | ||
|
||
private readonly _cachedHash?: Buffer | ||
|
||
/** | ||
* Instantiate a transaction from a data dictionary. | ||
* | ||
|
@@ -129,6 +131,9 @@ export default class Transaction extends BaseTransaction<Transaction> { | |
|
||
const freeze = opts?.freeze ?? true | ||
if (freeze) { | ||
if (this.isSigned()) { | ||
this._cachedHash = this.hash() | ||
} | ||
Object.freeze(this) | ||
} | ||
} | ||
|
@@ -232,6 +237,14 @@ export default class Transaction extends BaseTransaction<Transaction> { | |
* Use {@link Transaction.getMessageToSign} to get a tx hash for the purpose of signing. | ||
*/ | ||
hash(): Buffer { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @holgerd77 One thing I noticed while working on this... The comment for the Contrast with the other transaction types, which both have an explicit check: It's definitely possible I'm not understanding fully, but wanted to surface the question in case it is missing the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good catch, seems like it should be added to legacy. |
||
if (!this.isSigned()) { | ||
throw new Error('Cannot call hash method if transaction is not signed') | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe I am getting paranoid, but I am getting a bit shaky here and wondering if we did have some reason to not throw here yet and rather just add to the new typed txs for some weird backwards compatibility reason. CC-ing @jochem-brouwer in here, was just seeing that you wrote a lot around the whole topic in your typed tx implementation #1048. Can you eventually remember something on this? (if not we should really do here and give this a final go) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do remember that I wanted to implement that logic first, but that broke things for some reason which is why we did not edit it. (It is a breaking change also, I guess?). I'll take a look this afternoon to figure out what it was. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The thing that prompted me to add it to this PR was this comment - https://github.com/ethereumjs/ethereumjs-monorepo/blob/master/packages/tx/src/legacyTransaction.ts#L231. I noticed the typed txs had an explicit check but the legacy tx didn't, so I thought it might just have been missed. But maybe the comment was copied over and it wasn't meant to be implemented. Happy to take out that change if that's the case. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jochem-brouwer Ok, thanks for the clarification. I guess this is to risky then to add on the side line here, I've reverted the change respectively replaced with a longer comment so that no future devs will stumble upon this again. Will also add a note to the breaking changes TODO so that we will not forget on next breaking tx release. |
||
|
||
if (this._cachedHash) { | ||
return this._cachedHash | ||
} | ||
|
||
return rlphash(this.raw()) | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-> to
hash()
function (see tx comment).