-
Notifications
You must be signed in to change notification settings - Fork 189
Conversation
adrianbrink
commented
Aug 19, 2017
•
edited
Loading
edited
- add tests
- double check the logic in go-ethereum for validateTx and update it accordingly
Codecov Report
@@ Coverage Diff @@
## develop #276 +/- ##
===========================================
+ Coverage 24.91% 26.77% +1.86%
===========================================
Files 11 11
Lines 578 605 +27
===========================================
+ Hits 144 162 +18
- Misses 410 417 +7
- Partials 24 26 +2
Continue to review full report at Codecov.
|
@adrianbrink could you please educate me on the benefit from using a cached state for this purpose other than the normal benefits of using a cached copy of something(avoid extraneous lookup)? |
The purpose of a cachedState here is that it allows us to send multiple TXs from the same account in a single block. When I send a transaction J from account A, I increase the nonce from x to x+1. When Ethermint receives a transaction in CheckTx it checks that this condition is met, however it doesn't update any state so it always check against the state from the last block. Another reason is that with transaction H I might create a new account B. This account won't show up in the state that checkTx sees until the next block is created. However it is perfectly valid to send a transaction from account B in the same block, which won't work without state, since Ethermint currently thinks that account B doesn't exist. If we have cached state all these use cases work. |
app/app.go
Outdated
@@ -207,6 +218,10 @@ func (app *EthermintApplication) validateTx(tx *ethTypes.Transaction) abciTypes. | |||
AppendLog(core.ErrInvalidSender.Error()) | |||
} | |||
|
|||
// Update ether balances | |||
currentState.SubBalance(from, tx.Value()) |
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.
what about subtracting gas fees ?
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.
these should also probably go after the checks for having enough.
app/app_test.go
Outdated
@@ -132,7 +132,6 @@ func TestBumpingNonces(t *testing.T) { | |||
stack.Stop() // nolint: errcheck | |||
} | |||
|
|||
// TestMultipleTxOneAcc sends multiple TXs from the same account in the same block |
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.
why lose the comment ?
app/app_test.go
Outdated
stack, err := makeTestSystemNode(tempDatadir, addresses, mockclient) | ||
// Test transaction from Acc1 to new Acc2 and then from Acc2 to another address | ||
// in the same block | ||
func TestFromAccToAcc(t *testing.T) { |
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.
nice. did we check this fails without the rest of this PR ?
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.
@@ -164,6 +173,11 @@ func (app *EthermintApplication) Commit() abciTypes.Result { | |||
app.logger.Error("Error getting latest ethereum state", "err", err) // nolint: errcheck | |||
return abciTypes.ErrInternalError.AppendLog(err.Error()) | |||
} | |||
state, err := app.getCurrentState() | |||
if err != nil { | |||
app.logger.Error("Error getting latest state", "err", err) // nolint: errcheck |
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.
what does it take for this to err? do we need to catch it properly?
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.
It could happen if the underlying ethereum state gets corrupted.
We might want to abort here.
For now it only affects the checktx state though.
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.
presumably state
will be nil if there is an error and the call to Copy below will panic. So we should instead catch that and return an InternalError result so Tendermint knows something went wrong, logs the error, and halts
app/app.go
Outdated
backend: backend, | ||
rpcClient: client, | ||
getCurrentState: backend.Ethereum().BlockChain().State, | ||
cacheState: state.Copy(), |
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.
I think maybe call it checkTxState, to emphasize that it's not for deliverTx caching.
2862557
to
6e00ad4
Compare
app/app.go
Outdated
from, err := ethTypes.Sender(signer, tx) | ||
if err != nil { | ||
return abciTypes.ErrBaseInvalidSignature. | ||
AppendLog(core.ErrInvalidSender.Error()) | ||
} | ||
|
||
// Heuristic limit, reject transactions over 32KB to prevent DOS attacks | ||
if tx.Size() > 32*1024 { |
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.
This should be a const declared above, at least.
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.
Why 32KB? This seems to break from Ethereum...
app/app.go
Outdated
return abciTypes.ErrBaseInvalidInput. | ||
SetLog(core.ErrNegativeValue.Error()) | ||
// Check for nonce errors | ||
if currentState.GetNonce(from) > tx.Nonce() { |
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.
Nonce needs to be strictly incrementing by 1.
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.
Ethereum itself doesn't currently do that.
What is the benefit of doing it our way?
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.
https://ethereum.stackexchange.com/questions/2808/what-happens-when-a-transaction-nonce-is-too-high
See that Ethereum blocks still require nonces to be strictly incrementing by 1, even if there is no "ErrNonceTooHigh" error, due to the way the mempool works in Ethereum. (nonces that are too high are kept in the mempool for a while).
We should just use this error instead: https://github.com/tendermint/abci/blob/master/types/types.proto#L15
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.
For future reference:
For a transaction to be valid it needs to have the same nonce as the account that sends it.
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.
Do we still need this check if we just check for equality directly below ?
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.
No, we don't. I removed it.
app/app.go
Outdated
// Update ether balances | ||
// amount + gasprice * gaslimit | ||
currentState.SubBalance(from, tx.Cost()) | ||
currentState.AddBalance(*tx.To(), tx.Value()) |
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.
Nonce should be incremented as well.
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.
Can we test this nonce issue?
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.
Added it on top of the file TestIncrementingNonces
.
app/app_test.go
Outdated
@@ -49,10 +49,12 @@ func (mc *MockClient) Call(method string, params map[string]interface{}, result | |||
switch method { | |||
case "status": | |||
result = &ctypes.ResultStatus{} | |||
|
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.
Kinda strange to have blank spaces here.
app/app_test.go
Outdated
// 1. put Acc1 and Acc2 to genesis with some amounts (X) | ||
// 2. transfer 10 amount from Acc1 to Acc2 | ||
// 3. in the same block transfer from Acc2 to another Acc all his amounts (X+10) | ||
func TestFromAccToAcc2(t *testing.T) { |
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.
There's a lot of repeated code between this and the one above it.
(I think) we should refactor the tests to pull out the common components, and also create a new test that ensures that two checkTxs where the second has the wrong nonce (e.g. too high or too low) will fail.
setup/genesis.json
Outdated
@@ -13,6 +13,6 @@ | |||
"gasLimit": "0x8000000", | |||
"alloc": { | |||
"0x7eff122b94897ea5b0e2a9abf47b86337fafebdc": { "balance": "10000000000000000000000000000000000" }, | |||
"0xc6713982649D9284ff56c32655a9ECcCDA78422A": { "balance": "10000000000000000000000000000000000" } | |||
"0xc6713982649D9284ff56c32655a9ECcCDA78422A": { "balance": "10000000000000000000000000000000000" } |
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.
some spacing issue, not aligned with the line above this.
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.
Almost done, please address these issues!
7315a50
to
2b71315
Compare
I refactored the @odeke-em I would appreciate a review :-) |
Just need to run make test_integrations
a74445c
to
c139ec6
Compare
@@ -0,0 +1,3 @@ | |||
# TODO | |||
|
|||
* Document performance numbers for Tendermint and Ethermint and write a blog post about it |
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.
this can just be an issue, no? TODO files in a repo are unnecessary IMO ... it confuses what there is to do with issues
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.
alright
Tendermint RPC lib seems broken
* Add stateful checkTx * Tests for stateful checktx * Mirror validateTx logic from tx_pool.go. Move checkTxState updates * Move transaction size limit into const. Remove uneeded fmt import * Enable nonces to be strictly increasing * Extract all directory setup into functional style tests This change removes the duplicated code to setup temporary directories for each test. Now all code is grouped in the setupTestCase() function instead of being littered around all the test cases. There are no side effects of this. * Refactor app_test.go to remove the duplicated code The tests where getting unwieldy since they duplicated a lot of code. With the new setup it is much easier to create new test cases, since the setup and tear-down are handled nicely. There are no side effects. * Add test case for non-incremental nonces This test case checks that transactions have to have strictly increasing nonces. It tests by sending a transaction with nonce 0, and then tries to send a transaction with nonce 2. The second transaction should fail, since it is not strictly increasing. Some of the error descriptions have changed, but no one should be matching for a specific error string. * Refactor tests and RPC library This change is the last refactor of the app_tests and was needed for clarity. Also, it upgrades everything to use a typed RPC client instead of passing strings to get to raw endpoints. * Add check whether it's contract creation * Update Changelog Signed-off-by: Adrian Brink <[email protected]>
* Add stateful checkTx * Tests for stateful checktx * Mirror validateTx logic from tx_pool.go. Move checkTxState updates * Move transaction size limit into const. Remove uneeded fmt import * Enable nonces to be strictly increasing * Extract all directory setup into functional style tests This change removes the duplicated code to setup temporary directories for each test. Now all code is grouped in the setupTestCase() function instead of being littered around all the test cases. There are no side effects of this. * Refactor app_test.go to remove the duplicated code The tests where getting unwieldy since they duplicated a lot of code. With the new setup it is much easier to create new test cases, since the setup and tear-down are handled nicely. There are no side effects. * Add test case for non-incremental nonces This test case checks that transactions have to have strictly increasing nonces. It tests by sending a transaction with nonce 0, and then tries to send a transaction with nonce 2. The second transaction should fail, since it is not strictly increasing. Some of the error descriptions have changed, but no one should be matching for a specific error string. * Refactor tests and RPC library This change is the last refactor of the app_tests and was needed for clarity. Also, it upgrades everything to use a typed RPC client instead of passing strings to get to raw endpoints. * Add check whether it's contract creation * Update Changelog Signed-off-by: Adrian Brink <[email protected]>
* Add stateful checkTx * Tests for stateful checktx * Mirror validateTx logic from tx_pool.go. Move checkTxState updates * Move transaction size limit into const. Remove uneeded fmt import * Enable nonces to be strictly increasing * Extract all directory setup into functional style tests This change removes the duplicated code to setup temporary directories for each test. Now all code is grouped in the setupTestCase() function instead of being littered around all the test cases. There are no side effects of this. * Refactor app_test.go to remove the duplicated code The tests where getting unwieldy since they duplicated a lot of code. With the new setup it is much easier to create new test cases, since the setup and tear-down are handled nicely. There are no side effects. * Add test case for non-incremental nonces This test case checks that transactions have to have strictly increasing nonces. It tests by sending a transaction with nonce 0, and then tries to send a transaction with nonce 2. The second transaction should fail, since it is not strictly increasing. Some of the error descriptions have changed, but no one should be matching for a specific error string. * Refactor tests and RPC library This change is the last refactor of the app_tests and was needed for clarity. Also, it upgrades everything to use a typed RPC client instead of passing strings to get to raw endpoints. * Add check whether it's contract creation * Update Changelog Signed-off-by: Adrian Brink <[email protected]>
* Add stateful checkTx * Tests for stateful checktx * Mirror validateTx logic from tx_pool.go. Move checkTxState updates * Move transaction size limit into const. Remove uneeded fmt import * Enable nonces to be strictly increasing * Extract all directory setup into functional style tests This change removes the duplicated code to setup temporary directories for each test. Now all code is grouped in the setupTestCase() function instead of being littered around all the test cases. There are no side effects of this. * Refactor app_test.go to remove the duplicated code The tests where getting unwieldy since they duplicated a lot of code. With the new setup it is much easier to create new test cases, since the setup and tear-down are handled nicely. There are no side effects. * Add test case for non-incremental nonces This test case checks that transactions have to have strictly increasing nonces. It tests by sending a transaction with nonce 0, and then tries to send a transaction with nonce 2. The second transaction should fail, since it is not strictly increasing. Some of the error descriptions have changed, but no one should be matching for a specific error string. * Refactor tests and RPC library This change is the last refactor of the app_tests and was needed for clarity. Also, it upgrades everything to use a typed RPC client instead of passing strings to get to raw endpoints. * Add check whether it's contract creation * Update Changelog Signed-off-by: Adrian Brink <[email protected]>
* Add stateful checkTx * Tests for stateful checktx * Mirror validateTx logic from tx_pool.go. Move checkTxState updates * Move transaction size limit into const. Remove uneeded fmt import * Enable nonces to be strictly increasing * Extract all directory setup into functional style tests This change removes the duplicated code to setup temporary directories for each test. Now all code is grouped in the setupTestCase() function instead of being littered around all the test cases. There are no side effects of this. * Refactor app_test.go to remove the duplicated code The tests where getting unwieldy since they duplicated a lot of code. With the new setup it is much easier to create new test cases, since the setup and tear-down are handled nicely. There are no side effects. * Add test case for non-incremental nonces This test case checks that transactions have to have strictly increasing nonces. It tests by sending a transaction with nonce 0, and then tries to send a transaction with nonce 2. The second transaction should fail, since it is not strictly increasing. Some of the error descriptions have changed, but no one should be matching for a specific error string. * Refactor tests and RPC library This change is the last refactor of the app_tests and was needed for clarity. Also, it upgrades everything to use a typed RPC client instead of passing strings to get to raw endpoints. * Add check whether it's contract creation * Update Changelog Signed-off-by: Adrian Brink <[email protected]>
* Add stateful checkTx * Tests for stateful checktx * Mirror validateTx logic from tx_pool.go. Move checkTxState updates * Move transaction size limit into const. Remove uneeded fmt import * Enable nonces to be strictly increasing * Extract all directory setup into functional style tests This change removes the duplicated code to setup temporary directories for each test. Now all code is grouped in the setupTestCase() function instead of being littered around all the test cases. There are no side effects of this. * Refactor app_test.go to remove the duplicated code The tests where getting unwieldy since they duplicated a lot of code. With the new setup it is much easier to create new test cases, since the setup and tear-down are handled nicely. There are no side effects. * Add test case for non-incremental nonces This test case checks that transactions have to have strictly increasing nonces. It tests by sending a transaction with nonce 0, and then tries to send a transaction with nonce 2. The second transaction should fail, since it is not strictly increasing. Some of the error descriptions have changed, but no one should be matching for a specific error string. * Refactor tests and RPC library This change is the last refactor of the app_tests and was needed for clarity. Also, it upgrades everything to use a typed RPC client instead of passing strings to get to raw endpoints. * Add check whether it's contract creation * Update Changelog Signed-off-by: Adrian Brink <[email protected]>
* update rpc tests * cleanup * add log assertion to getTransacionReceipt * fix queurier_test * address comment