-
Notifications
You must be signed in to change notification settings - Fork 847
SpuriousDragon HF Support #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
Changes from all commits
0ef4add
d6fcb8e
e91cbb4
7b4bf93
024f5c9
2e9572f
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 |
|---|---|---|
|
|
@@ -401,9 +401,15 @@ export const handlers: { [k: string]: OpHandler } = { | |
| runState.stack.push(new BN(keccak256(code))) | ||
| }, | ||
| RETURNDATASIZE: function (runState: RunState) { | ||
| if (!runState._common.gteHardfork('byzantium')) { | ||
|
Contributor
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. Just a side-note: we won't be needing these checks anymore after
Member
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. Yup these can be removed as these changes are in master.
Member
Author
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, but this will be another PR. Can you approve here again so that we can merge? Sina already did but I dismissed by doing the rebase. 😋 |
||
| trap(ERROR.INVALID_OPCODE) | ||
| } | ||
| runState.stack.push(runState.eei.getReturnDataSize()) | ||
| }, | ||
| RETURNDATACOPY: function (runState: RunState) { | ||
| if (!runState._common.gteHardfork('byzantium')) { | ||
| trap(ERROR.INVALID_OPCODE) | ||
| } | ||
| let [memOffset, returnDataOffset, length] = runState.stack.popN(3) | ||
|
|
||
| if (returnDataOffset.add(length).gt(runState.eei.getReturnDataSize())) { | ||
|
|
@@ -769,6 +775,9 @@ export const handlers: { [k: string]: OpHandler } = { | |
| runState.stack.push(ret) | ||
| }, | ||
| STATICCALL: async function (runState: RunState) { | ||
| if (!runState._common.gteHardfork('byzantium')) { | ||
| trap(ERROR.INVALID_OPCODE) | ||
| } | ||
| const value = new BN(0) | ||
| let [gasLimit, toAddress, inOffset, inLength, outOffset, outLength] = runState.stack.popN(6) | ||
| const toAddressBuf = addressToBuffer(toAddress) | ||
|
|
@@ -797,6 +806,9 @@ export const handlers: { [k: string]: OpHandler } = { | |
| runState.eei.finish(returnData) | ||
| }, | ||
| REVERT: function (runState: RunState) { | ||
| if (!runState._common.gteHardfork('byzantium')) { | ||
| trap(ERROR.INVALID_OPCODE) | ||
| } | ||
| const [offset, length] = runState.stack.popN(2) | ||
| subMemUsage(runState, offset, length) | ||
| let returnData = Buffer.alloc(0) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -44,21 +44,17 @@ export interface RunBlockResult { | |
| /** | ||
| * Receipts generated for transactions in the block | ||
| */ | ||
| receipts: TxReceipt[] | ||
| receipts: (PreByzantiumTxReceipt | PostByzantiumTxReceipt)[] | ||
| /** | ||
| * Results of executing the transactions in the block | ||
| */ | ||
| results: RunTxResult[] | ||
| } | ||
|
|
||
| /** | ||
| * Receipt generated for a transaction | ||
| * Abstract interface with common transaction receipt fields | ||
| */ | ||
| export interface TxReceipt { | ||
| /** | ||
| * Status of transaction, `1` if successful, `0` if an exception occured | ||
| */ | ||
| status: 0 | 1 | ||
| interface TxReceipt { | ||
holgerd77 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| /** | ||
| * Gas used | ||
| */ | ||
|
|
@@ -73,6 +69,28 @@ export interface TxReceipt { | |
| logs: any[] | ||
| } | ||
|
|
||
| /** | ||
| * Pre-Byzantium receipt type with a field | ||
| * for the intermediary state root | ||
| */ | ||
| export interface PreByzantiumTxReceipt extends TxReceipt { | ||
| /** | ||
| * Intermediary state root | ||
| */ | ||
| stateRoot: Buffer | ||
| } | ||
|
|
||
| /** | ||
| * Receipt type for Byzantium and beyond replacing the intermediary | ||
| * state root field with a status code field (EIP-658) | ||
| */ | ||
| export interface PostByzantiumTxReceipt extends TxReceipt { | ||
| /** | ||
| * Status of transaction, `1` if successful, `0` if an exception occured | ||
| */ | ||
| status: 0 | 1 | ||
| } | ||
|
|
||
| /** | ||
| * @ignore | ||
| */ | ||
|
|
@@ -219,12 +237,28 @@ async function applyTransactions(this: VM, block: any, opts: RunBlockOpts) { | |
| // Combine blooms via bitwise OR | ||
| bloom.or(txRes.bloom) | ||
|
|
||
| const txReceipt: TxReceipt = { | ||
| status: txRes.execResult.exceptionError ? 0 : 1, // Receipts have a 0 as status on error | ||
| const abstractTxReceipt: TxReceipt = { | ||
| gasUsed: gasUsed.toArrayLike(Buffer), | ||
| bitvector: txRes.bloom.bitvector, | ||
| logs: txRes.execResult.logs || [], | ||
| } | ||
| let txReceipt | ||
| if (this._common.gteHardfork('byzantium')) { | ||
| txReceipt = { | ||
| status: txRes.execResult.exceptionError ? 0 : 1, // Receipts have a 0 as status on error | ||
| ...abstractTxReceipt, | ||
| } as PostByzantiumTxReceipt | ||
holgerd77 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } else { | ||
| // This is just using a dummy place holder for the state root right now. | ||
| // Giving the correct intermediary state root would need a too depp intervention | ||
| // into the current checkpointing mechanism which hasn't been considered | ||
| // to be worth it on a HF backport, 2020-06-26 | ||
| txReceipt = { | ||
| stateRoot: Buffer.alloc(32), | ||
| ...abstractTxReceipt, | ||
| } as PreByzantiumTxReceipt | ||
| } | ||
|
|
||
|
Member
Author
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. Ok, @s1na @alcuadrado please have a look if you are satisfied with this implementation, I thought it is not worth to update the checkpointing mechanism here, since this is a feature (which we then doesn't fully provide for pre-Byzantium) rather than consensus critical code. We can alternatively also just fill in an empty Buffer and avoid changing the StateManager interface (might generally be a useful addition, not sure though). 🤔
Member
Author
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. Some working note: just tested to run the blockchain tests on older HFs with These are currently NOT working and throwing errors like The
Member
Author
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 would rather suggest not to do this investigation here but do this separately. Otherwise the scope here gets too big.
Contributor
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 receiptTrie field in the block header is a commitment to the tx receipts, so I wouldn't be surprised if they were incorrect. But I agree we can probably handle this separately because as you said it needs deeper changes. I'd suggest however till then to keep the StateManager interface unchanged and if the intermediate state root is incorrect anyway then just return a dummy value until we dig deeper. |
||
| receipts.push(txReceipt) | ||
|
|
||
| // Add receipt to trie to later calculate receipt root | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,8 +14,8 @@ | |
| "coverage:test": "npm run build && tape './tests/api/**/*.js' ./tests/tester.js --state --dist", | ||
| "docs:build": "typedoc --options typedoc.js", | ||
| "test:state": "ts-node ./tests/tester --state", | ||
| "test:state:allForks": "npm run test:state -- --fork=Byzantium && npm run test:state -- --fork=Constantinople && npm run test:state -- --fork=Petersburg && npm run test:state -- --fork=Istanbul && npm run test:state -- --fork=MuirGlacier", | ||
| "test:state:selectedForks": "npm run test:state -- --fork=Petersburg && npm run test:state -- --fork=Istanbul && npm run test:state -- --fork=MuirGlacier", | ||
| "test:state:allForks": "npm run test:state -- --fork=SpuriousDragon && npm run test:state -- --fork=Byzantium && npm run test:state -- --fork=Constantinople && npm run test:state -- --fork=Petersburg && npm run test:state -- --fork=Istanbul && npm run test:state -- --fork=MuirGlacier", | ||
| "test:state:selectedForks": "npm run test:state -- --fork=Petersburg && npm run test:state -- --fork=SpuriousDragon", | ||
|
Contributor
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. State tests are our bottleneck, I was thinking in splitting state tests in two jobs, so instead of a 12min job, it could be two jobs of 6:30s each. Let me know if that would speed up your work @holgerd77, so I can implement it right into this PR
Member
Author
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. Thanks for the offer, not necessary here on this round, but definitely useful to split these up. We can do Just a first-shot idea, feel free to take on or not.
Contributor
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've been thinking about an experiment re state tests, and that'd be to have the test runner accept multiple forks, prepare everything once and run each test for all the forks consecutively. It probably won't yield much of a speed-up, but might be worth trying out if the effort required isn't that high.
Contributor
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. Can you re-add
Member
Author
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. My suggestion was to leave this to Everton to readd (see comment below) along splitting the state test run CI command into two (for performance reasons). Could you live with that as well? |
||
| "test:state:slow": "npm run test:state -- --runSkipped=slow", | ||
| "test:buildIntegrity": "npm run test:state -- --test='stackOverflow'", | ||
| "test:blockchain": "node -r ts-node/register --stack-size=1500 ./tests/tester --blockchain", | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.