-
Notifications
You must be signed in to change notification settings - Fork 9
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
Local state using remote registers #562
base: main
Are you sure you want to change the base?
Conversation
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.
Actionable comments posted: 5
Outside diff range and nitpick comments (9)
tests/e2e_web3js_test.go (2)
31-35
: Update the TODO comment and follow up on the progress.It's great to see a new test case being added for "cadence arch and environment calls". However, the TODO comment indicates that this test is currently failing due to an issue with the cadence arch replayer.
Consider updating the TODO comment with more details about the specific issue or converting it to a GitHub issue for better tracking and visibility.
Also, please check with Ramtin on the progress of the fix and update the codebase accordingly once it's available.
159-159
: Clarify the reason for increasing the gas limit.The gas limit for the contract deployment transaction has been increased from
1_250_000
to1_550_000
. While increasing the gas limit may be necessary to accommodate the complexity of the contract being deployed, it would be helpful to understand the specific reason behind this change.Please consider:
- Adding a comment explaining the need for the higher gas limit.
- Evaluating the trade-offs between allowing more computational work and the increased transaction costs.
- Adjusting the gas limit based on the contract complexity and transaction cost constraints.
go.mod (1)
91-91
: LGTM!The addition of the indirect dependency
github.com/hashicorp/golang-lru/v2 v2.0.7
should not cause any issues, as it is managed by the Go module system.As a best practice, consider reviewing the release notes or changelog of the added dependency to ensure there are no known issues or vulnerabilities.
services/evm/client.go (1)
53-57
: Address the TODO comment about extracting transaction submission to a separate type.Consider creating a new interface, such as
TransactionSubmitter
, to handle transaction submission responsibilities. This will help separate concerns and improve the cohesion of theEVMClient
interface.tests/fixtures/storage.sol (1)
11-11
: Nitpick: Explicitly specifyuint256
instead ofuint
for consistencyIn the event declaration for
BlockTime
, consider usinguint256
instead ofuint
to maintain consistency with the other event declarations and improve code clarity.Apply this diff:
-event BlockTime(address indexed caller, uint value); +event BlockTime(address indexed caller, uint256 value);tests/web3js/build_evm_state_test.js (1)
176-176
: Review the necessity of extending the test timeoutA timeout of
180*1000
milliseconds (180 seconds) has been added to the test case. Please confirm that this extended duration is necessary for the test to complete and consider optimizing the test to reduce execution time if possible.tests/web3js/cadence_arch_env_test.js (3)
7-13
: Improve the clarity and grammar of the introductory commentsThe comments in lines 7-13 contain grammatical errors and could be rephrased for better readability and understanding.
Consider updating the comments as follows:
-// this test calls different environment and cadenc arch functions. It uses view -// function to call and return the value which it compares with the block on the network, -// behind the scene these causes the local client to make such a call and return the value -// and this test makes sure the on-chain data is same as local-index data. Secondly, this -// test also submits a transaction that emits the result, which checks the local state -// re-execution of transaction, and makes sure both receipt matches (remote and local), -// this in turn tests the local state re-execution. +// This test calls different environment and Cadence architecture functions. It uses view +// functions to call and return values, which it compares with the blocks on the network. +// Behind the scenes, this causes the local client to make such calls and return the values, +// ensuring that the on-chain data is the same as the local index data. Secondly, this +// test also submits a transaction that emits the result, which checks the local state +// re-execution of the transaction, and makes sure both receipts (remote and local) match. +// This, in turn, tests the local state re-execution.
18-18
: Preferconst
overlet
for variables that are not reassignedIn lines 18, 32, and 51, the variables
res
,block
, anddeployed
are declared withlet
but are not reassigned. Usingconst
can prevent accidental reassignment and improve code clarity.Update the variable declarations:
- let res = await helpers.signAndSend({ + const res = await helpers.signAndSend({- let block = await web3.eth.getBlock('latest') + const block = await web3.eth.getBlock('latest')- let deployed = await helpers.deployContract('storage') + const deployed = await helpers.deployContract('storage')Also applies to: 32-32, 51-51
60-62
: Address the TODO regarding block environment functionsThe TODO comment indicates an issue where Ethereum calls are executed at the provided block height, but block environment functions (number, hash, etc.) point to the next block (the block proposal). This discrepancy may affect test accuracy.
Would you like assistance in investigating this issue or opening a GitHub issue to track and resolve this problem?
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files ignored due to path filters (2)
tests/go.sum
is excluded by!**/*.sum
tests/web3js/package-lock.json
is excluded by!**/package-lock.json
Files selected for processing (16)
- bootstrap/bootstrap.go (7 hunks)
- go.mod (1 hunks)
- services/evm/client.go (13 hunks)
- services/evm/executor.go (1 hunks)
- tests/e2e_web3js_test.go (2 hunks)
- tests/fixtures/storage.byte (1 hunks)
- tests/fixtures/storage.sol (4 hunks)
- tests/fixtures/storageABI.json (4 hunks)
- tests/go.mod (1 hunks)
- tests/helpers.go (3 hunks)
- tests/web3js/build_evm_state_test.js (2 hunks)
- tests/web3js/cadence_arch_env_test.js (1 hunks)
- tests/web3js/eth_deploy_contract_and_interact_test.js (2 hunks)
- tests/web3js/eth_filter_endpoints_test.js (2 hunks)
- tests/web3js/eth_revert_reason_test.js (2 hunks)
- tests/web3js/eth_transaction_type_fees_test.js (3 hunks)
Files skipped from review as they are similar to previous changes (2)
- bootstrap/bootstrap.go
- services/evm/executor.go
Additional comments not posted (53)
tests/web3js/eth_revert_reason_test.js (2)
44-44
: LGTM!The change simplifies the process of obtaining the reverted transaction by directly using the transaction hash, eliminating the need to fetch the latest block. This improves code efficiency.
74-74
: Duplicate change.This change is identical to the one at line 44. It simplifies the process of obtaining the reverted transaction by directly using the transaction hash, eliminating the need to fetch the latest block. This improves code efficiency.
tests/web3js/eth_transaction_type_fees_test.js (4)
24-24
: LGTM!The change updates the expected gas used value, which aligns with the AI-generated summary. The new value seems reasonable.
30-30
: LGTM!The change updates the expected sender balance, which aligns with the AI-generated summary. The new value seems reasonable.
75-75
: LGTM!The change updates the expected sender balance, which aligns with the AI-generated summary. The new value seems reasonable.
132-132
: LGTM!The change updates the expected sender balance, which aligns with the AI-generated summary. The new value seems reasonable.
tests/web3js/eth_deploy_contract_and_interact_test.js (2)
21-21
: LGTM!The change in the expected gas usage for the contract deployment process is valid and does not introduce any issues.
236-236
: LGTM!The change in the expected gas estimate for the contract interaction is valid and does not introduce any issues.
tests/fixtures/storageABI.json (16)
23-41
: LGTM!The
BlockHash
event is well-defined with clear input names and appropriate types. Indexing thecaller
input is a good practice for efficient event filtering.
42-60
: LGTM!The
BlockNumber
event is well-defined with clear input names and appropriate types. Indexing thecaller
input is a good practice for efficient event filtering.
61-79
: LGTM!The
BlockTime
event is well-defined with clear input names and appropriate types. Indexing thecaller
input is a good practice for efficient event filtering.
111-129
: LGTM!The
ChainID
event is well-defined with clear input names and appropriate types. Indexing thecaller
input is a good practice for efficient event filtering.
149-167
: LGTM!The
Random
event is well-defined with clear input names and appropriate types. Indexing thecaller
input is a good practice for efficient event filtering.
168-186
: LGTM!The
Retrieved
event is well-defined with clear input names and appropriate types. Indexing thecaller
input is a good practice for efficient event filtering.
187-205
: LGTM!The
VerifyArchCallToFlowBlockHeight
event is well-defined with clear input names and appropriate types. Indexing thecaller
input is a good practice for efficient event filtering.
206-224
: LGTM!The
VerifyArchCallToRandomSource
event is well-defined with clear input names and appropriate types. Indexing thecaller
input is a good practice for efficient event filtering.
225-243
: LGTM!The
VerifyArchCallToRevertibleRandom
event is well-defined with clear input names and appropriate types. Indexing thecaller
input is a good practice for efficient event filtering.
244-262
: LGTM!The
VerifyArchCallToVerifyCOAOwnershipProof
event is well-defined with clear input names and appropriate types. Indexing thecaller
input is a good practice for efficient event filtering.
355-367
: LGTM!The
emitBlockHash
function is well-defined with a clear parameter name and appropriate type. Thenonpayable
modifier is suitable for a function that emits an event without modifying the contract state.
368-374
: LGTM!The
emitBlockNumber
function is well-defined with a clear name. Thenonpayable
modifier is suitable for a function that emits an event without modifying the contract state.
375-381
: LGTM!The
emitBlockTime
function is well-defined with a clear name. Thenonpayable
modifier is suitable for a function that emits an event without modifying the contract state.
382-388
: LGTM!The
emitChainID
function is well-defined with a clear name. Thenonpayable
modifier is suitable for a function that emits an event without modifying the contract state.
389-395
: LGTM!The
emitRandom
function is well-defined with a clear name. Thenonpayable
modifier is suitable for a function that emits an event without modifying the contract state.
396-402
: LGTM!The
emitRetrieve
function is well-defined with a clear name. Thenonpayable
modifier is suitable for a function that emits an event without modifying the contract state.tests/helpers.go (2)
65-68
: LGTM!The changes to the
testLogWriter
function look good. The function now creates a newzerolog.ConsoleWriter
instance, sets the global time field format totime.RFC3339Nano
, and configures the writer's time format to "04:05.0000" before returning the writer.
338-339
: Looks good!The change to the
evmSign
function signature, moving thedata []byte
parameter to a new line, improves readability without altering the function's behavior.tests/go.mod (1)
156-156
: Verify compatibility of the dependency update.The
github.com/onflow/flow/protobuf/go/flow
dependency has been updated from versionv0.4.6
tov0.4.7
.While minor version updates are generally safe, it's important to ensure that this update is compatible with the rest of the project dependencies and doesn't introduce any breaking changes or issues.
Run the following script to check if the update causes any issues:
tests/web3js/eth_filter_endpoints_test.js (2)
364-364
: LGTM!The updated transaction hash looks good and matches the expected format.
417-417
: Looks good!The updated
hash
andvalue
fields in the expected transaction object are valid and match the Ethereum transaction format.Also applies to: 422-422
services/evm/client.go (10)
93-102
: LGTM!The
RemoteClient
struct has the appropriate dependencies and fields to implement theEVMClient
interface. The naming and organization of the fields are clear and follow Go conventions.
Line range hint
120-197
: LGTM!The
NewEVM
function properly initializes theRemoteClient
instance with the provided dependencies. The checks for the COA account balance and the creation of the COA resource based on the configuration flag are useful safeguards. The function logic is clear and follows best practices.
Line range hint
201-259
: LGTM!The
SendRawTransaction
method follows the expected steps for sending a raw transaction. The validation of the transaction, the check for the minimum gas price, and the building of the Flow transaction are all good practices. The method logic is clear and well-structured. The logging of the transaction details provides good visibility into the process.
Line range hint
260-308
: LGTM!The
buildTransaction
method follows the necessary steps to build a valid Flow transaction. Retrieving the latest block and signer information concurrently using an error group is an efficient approach. Setting the transaction fields with the appropriate values and signing the transaction envelope with the configured signer ensures a properly constructed and authorized transaction. The error handling and formatting of error messages are appropriate.
310-321
: LGTM!The
GetBalance
method retrieves the balance of an address at a given EVM height using thestateAt
method to get the state database. Retrieving the balance using theGetBalance
method of the state database is the correct approach. The method returns the balance as a*big.Int
, which is the expected type for balances in Go-Ethereum. The method logic is clear and follows best practices.
323-334
: LGTM!The
GetNonce
method retrieves the nonce of an address at a given EVM height using thestateAt
method to get the state database. Retrieving the nonce using theGetNonce
method of the state database is the correct approach. The method returns the nonce as auint64
, which is the expected type for nonces in Go-Ethereum. The method logic is clear and follows best practices.
Line range hint
336-348
: LGTM!The
GetStorageAt
method retrieves the storage value at a given address and hash at a specific EVM height using thestateAt
method to get the state database. Retrieving the storage value using theGetState
method of the state database is the correct approach. The method returns the storage value as acommon.Hash
, which is the expected type for storage values in Go-Ethereum. The method logic is clear and follows best practices.
350-357
: LGTM!The
GetCode
method retrieves the code at a given address at a specific EVM height using thestateAt
method to get the state database. Retrieving the code using theGetCode
method of the state database is the correct approach. The method returns the code as a byte slice, which is the expected type for code in Go-Ethereum. The method logic is clear and follows best practices.
359-379
: LGTM!The
EstimateGas
method estimates the gas required for a given transaction data at a specific EVM height using theexecutorAt
method to get the block executor. Calling theCall
method of the block executor to execute the transaction and get the gas consumed is the correct approach. The method handles the error cases and returns the appropriate error type based on the execution result, which is a good practice. The method logic is clear and follows best practices.
381-411
: LGTM!The
Call
method executes a given transaction data at a specific EVM height using theexecutorAt
method to get the block executor. Calling theCall
method of the block executor to execute the transaction and get the result is the correct approach. The method handles the error cases and returns the appropriate error type based on the execution result, which is a good practice. Ensuring that the returned data is an empty slice if it is nil is a good practice to match the behavior of the remote client. The method logic is clear and follows best practices.tests/fixtures/storage.sol (10)
46-48
: FunctionemitRetrieve
correctly emitsRetrieved
eventThe
emitRetrieve
function properly emits theRetrieved
event with the caller's address and the stored number.
60-62
: FunctionemitBlockNumber
correctly emitsBlockNumber
eventThe
emitBlockNumber
function properly emits theBlockNumber
event with the caller's address and the current block number.
68-70
: FunctionemitBlockTime
correctly emitsBlockTime
eventThe
emitBlockTime
function properly emits theBlockTime
event with the caller's address and the current block timestamp.
84-86
: FunctionemitRandom
correctly emitsRandom
eventThe
emitRandom
function properly emits theRandom
event with the caller's address and theblock.prevrandao
value.
92-94
: FunctionemitChainID
correctly emitsChainID
eventThe
emitChainID
function properly emits theChainID
event with the caller's address and the current chain ID.
104-105
: FunctioncustomError
correctly uses a custom errorThe
customError
function correctly demonstrates how to revert with the custom errorMyCustomError
.
115-118
: FunctionemitVerifyArchCallToRandomSource
correctly emits eventThe
emitVerifyArchCallToRandomSource
function correctly callsverifyArchCallToRandomSource
and emits theVerifyArchCallToRandomSource
event with the caller's address and the output.
127-130
: FunctionemitVerifyArchCallToRevertibleRandom
correctly emits eventThe
emitVerifyArchCallToRevertibleRandom
function correctly callsverifyArchCallToRevertibleRandom
and emits theVerifyArchCallToRevertibleRandom
event with the caller's address and the output.
139-142
: FunctionemitVerifyArchCallToFlowBlockHeight
correctly emits eventThe
emitVerifyArchCallToFlowBlockHeight
function correctly callsverifyArchCallToFlowBlockHeight
and emits theVerifyArchCallToFlowBlockHeight
event with the caller's address and the output.
151-154
: FunctionemitVerifyArchCallToVerifyCOAOwnershipProof
correctly emits eventThe
emitVerifyArchCallToVerifyCOAOwnershipProof
function correctly callsverifyArchCallToVerifyCOAOwnershipProof
and emits theVerifyArchCallToVerifyCOAOwnershipProof
event with the caller's address and the output.tests/web3js/build_evm_state_test.js (2)
158-158
: Confirm that the increased estimated gas value is expectedThe estimated gas value has been updated to
29338n
. Please verify that this increase is intentional and aligns with the expected changes in the contract or gas estimation logic.
165-165
: Confirm that the increased contract code length is expectedThe length of the contract code retrieved at the latest block has increased to
12180
. This significant change suggests alterations in the contract's bytecode. Please ensure that this is expected and corresponds to the updates made.tests/web3js/cadence_arch_env_test.js (2)
74-76
: Address the TODO regarding block environment functionsThe same issue regarding block environment functions pointing to the next block is mentioned here. It's important to resolve this to ensure test reliability.
90-92
: Address the TODO regarding block environment functionsThis TODO repeats the concern about block environment functions pointing to the next block instead of the provided block height. Resolving this will enhance the accuracy of your tests.
function emitBlockHash(uint num) public { | ||
emit BlockHash(msg.sender, blockhash(num)); | ||
} |
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.
Add input validation for num
parameter in emitBlockHash
The blockhash
function only returns meaningful values for the 256 most recent blocks. To prevent unexpected results, consider adding input validation to ensure that num
is within the valid range (block.number - 256 <= num < block.number
).
Apply this diff:
function emitBlockHash(uint num) public {
+ require(num >= block.number - 256 && num < block.number, "Invalid block number");
emit BlockHash(msg.sender, blockhash(num));
}
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
function emitBlockHash(uint num) public { | |
emit BlockHash(msg.sender, blockhash(num)); | |
} | |
function emitBlockHash(uint num) public { | |
require(num >= block.number - 256 && num < block.number, "Invalid block number"); | |
emit BlockHash(msg.sender, blockhash(num)); | |
} |
web3.eth.abi.decodeParameter('uint', res.value).toString(), | ||
(prev.timestamp+1n).toString(), // investigate why timestamp is increasing 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.
Prevent TypeError due to mixing BigInt
and Number
types
The expression (prev.timestamp + 1n).toString()
may cause a TypeError because prev.timestamp
is a Number
, and 1n
is a BigInt
.
Convert prev.timestamp
to a BigInt
before the addition:
- (prev.timestamp+1n).toString(), // investigate why timestamp is increasing by 1
+ (BigInt(prev.timestamp) + 1n).toString(), // investigate why timestamp is increasing by 1
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
web3.eth.abi.decodeParameter('uint', res.value).toString(), | |
(prev.timestamp+1n).toString(), // investigate why timestamp is increasing by 1 | |
) | |
web3.eth.abi.decodeParameter('uint', res.value).toString(), | |
(BigInt(prev.timestamp) + 1n).toString(), // investigate why timestamp is increasing by 1 | |
) |
assert.equal( | ||
web3.eth.abi.decodeParameter('uint256', res.value), | ||
res.block.number+1n, | ||
) |
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.
Prevent TypeError due to mixing BigInt
and Number
types
Adding a BigInt
(1n
) to a Number
(res.block.number
) can cause a TypeError in JavaScript. You cannot mix BigInt
and Number
types in arithmetic operations.
Convert res.block.number
to a BigInt
before performing the addition:
- res.block.number+1n,
+ BigInt(res.block.number) + 1n,
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
assert.equal( | |
web3.eth.abi.decodeParameter('uint256', res.value), | |
res.block.number+1n, | |
) | |
assert.equal( | |
web3.eth.abi.decodeParameter('uint256', res.value), | |
BigInt(res.block.number) + 1n, | |
) |
await testEmitTx(methods.emitRandom()) | ||
|
||
let res = await testCall(methods.random()) | ||
assert.isNotEmpty(web3.eth.abi.decodeParameter('uint256', res.value).toString()) |
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.
Use a valid assertion method
The assert.isNotEmpty
method may not exist in Chai's assert
interface. To verify that the value is not empty, consider checking the length of the string.
Update the assertion as follows:
- assert.isNotEmpty(web3.eth.abi.decodeParameter('uint256', res.value).toString())
+ assert.isAbove(web3.eth.abi.decodeParameter('uint256', res.value).toString().length, 0)
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
assert.isNotEmpty(web3.eth.abi.decodeParameter('uint256', res.value).toString()) | |
assert.isAbove(web3.eth.abi.decodeParameter('uint256', res.value).toString().length, 0) |
60806040526105395f819055506117c9806100195f395ff3fe608060405234801561000f575f80fd5b50600436106101c2575f3560e01c80639075ef95116100f7578063bc31124b11610095578063d0d250bd1161006f578063d0d250bd14610420578063dda3a7bd1461043e578063ea8d8ccf14610448578063fe027d1114610478576101c2565b8063bc31124b146103dc578063c550f90f146103f8578063cbaff5f914610416576101c2565b8063adc879e9116100d1578063adc879e91461038c578063af32a363146103aa578063b2821c8f146103b4578063b7ec3e5f146103d2576101c2565b80639075ef9514610322578063911007b41461032c5780639967062d1461035c576101c2565b80635ec01e4d1161016457806364fc013a1161013e57806364fc013a146102b05780636babb224146102cc57806383197ef0146102e857806385df51fd146102f2576101c2565b80635ec01e4d1461025a5780635f0f73fb146102785780636057361d14610294576101c2565b80634cbefa6a116101a05780634cbefa6a1461020c57806357e871e7146102285780635b5764f4146102465780635e4268e614610250576101c2565b80632e64cec1146101c657806346c38ab0146101e457806348b15166146101ee575b5f80fd5b6101ce610482565b6040516101db9190610f06565b60405180910390f35b6101ec61048a565b005b6101f66104da565b6040516102039190610f06565b60405180910390f35b61022660048036038101906102219190610f5a565b6104e1565b005b6102306104ea565b60405161023d9190610f06565b60405180910390f35b61024e6104f1565b005b61025861054d565b005b61026261059d565b60405161026f9190610f06565b60405180910390f35b610292600480360381019061028d9190610f5a565b6105a4565b005b6102ae60048036038101906102a99190610f5a565b6105f6565b005b6102ca60048036038101906102c59190610fc2565b6105ff565b005b6102e660048036038101906102e19190610f5a565b61065d565b005b6102f06106aa565b005b61030c60048036038101906103079190610f5a565b6106c3565b6040516103199190611005565b60405180910390f35b61032a6106cd565b005b61034660048036038101906103419190610fc2565b61071d565b6040516103539190611005565b60405180910390f35b61037660048036038101906103719190611051565b61087f565b604051610383919061109e565b60405180910390f35b6103946108e9565b6040516103a19190610f06565b60405180910390f35b6103b26108f0565b005b6103bc61094c565b6040516103c991906110c6565b60405180910390f35b6103da610aa1565b005b6103f660048036038101906103f1919061129f565b610af1565b005b610400610b53565b60405161040d91906110c6565b60405180910390f35b61041e610ca8565b005b610428610cea565b604051610435919061131a565b60405180910390f35b610446610cf7565b005b610462600480360381019061045d919061129f565b610d35565b60405161046f919061134d565b60405180910390f35b610480610e9d565b005b5f8054905090565b3373ffffffffffffffffffffffffffffffffffffffff167fcdda07d20845760c8f1960f9992eb7b5253a2e6a68eb2340137c70a30e3af38b436040516104d09190610f06565b60405180910390a2565b5f42905090565b805f8190555f80fd5b5f43905090565b5f6104fa610b53565b90503373ffffffffffffffffffffffffffffffffffffffff167f226e31c8dfdcc17bec5aa64ce3cd9856d9bb4637e48450d27f62e0bda5bca6498260405161054291906110c6565b60405180910390a250565b3373ffffffffffffffffffffffffffffffffffffffff167fb8a2de765c79a4dd09c7a683c268e826303e1bbd5425c29706963329538a7534466040516105939190610f06565b60405180910390a2565b5f44905090565b3373ffffffffffffffffffffffffffffffffffffffff167f9c5f2f6f83b58de8294bc8af0de4c9e4fdd2c335eaf0d9a2461b5a5e4b014e8682406040516105eb9190611005565b60405180910390a250565b805f8190555050565b5f6106098261071d565b90503373ffffffffffffffffffffffffffffffffffffffff167f3c1e946213ca4a4f826f561e68d2e244c2db896d9612980bf786cd7da2c6ccdf826040516106519190611005565b60405180910390a25050565b803373ffffffffffffffffffffffffffffffffffffffff167f043cc306157a91d747b36aba0e235bbbc5771d75aba162f6e5540767d22673c660405160405180910390a3805f8190555050565b3373ffffffffffffffffffffffffffffffffffffffff16ff5b5f81409050919050565b3373ffffffffffffffffffffffffffffffffffffffff167f52481872d5402d9c11fcd282d57bfa9af8a0edcc9115a4ba1936f3bb45e286bb446040516107139190610f06565b60405180910390a2565b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff168460405160240161075191906110c6565b6040516020818303038152906040527f78a75fbe000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516107db91906113b8565b5f60405180830381855afa9150503d805f8114610813576040519150601f19603f3d011682016040523d82523d5f602084013e610818565b606091505b50915091508161085d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085490611428565b60405180910390fd5b5f81806020019051810190610872919061145a565b9050809350505050919050565b5f80828461088d91906114b2565b905082843373ffffffffffffffffffffffffffffffffffffffff167f76efea95e5da1fa661f235b2921ae1d89b99e457ec73fb88e34a1d150f95c64b846040516108d7919061109e565b60405180910390a48091505092915050565b5f46905090565b5f6108f961094c565b90503373ffffffffffffffffffffffffffffffffffffffff167f7f3eb80b1815b51402bef9f6393921916f5c7391ff4f5e82e2f5d7f866c65fb78260405161094191906110c6565b60405180910390a250565b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f705fab20000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516109ff91906113b8565b5f60405180830381855afa9150503d805f8114610a37576040519150601f19603f3d011682016040523d82523d5f602084013e610a3c565b606091505b509150915081610a81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a789061153d565b60405180910390fd5b5f81806020019051810190610a96919061156f565b905080935050505090565b3373ffffffffffffffffffffffffffffffffffffffff167f05a74f03de8d43b274ce924e4542bad549dea8f3572574a2b81d6ba62fc717b442604051610ae79190610f06565b60405180910390a2565b5f610afd848484610d35565b90503373ffffffffffffffffffffffffffffffffffffffff167f19481a9edff48c370d941b1f368fd2198a0f3117e18748a56d5e193b36dc569a82604051610b45919061134d565b60405180910390a250505050565b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f53e87d66000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610c0691906113b8565b5f60405180830381855afa9150503d805f8114610c3e576040519150601f19603f3d011682016040523d82523d5f602084013e610c43565b606091505b509150915081610c88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c7f90611428565b60405180910390fd5b5f81806020019051810190610c9d919061156f565b905080935050505090565b5f610ce8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cdf906115e4565b60405180910390fd5b565b6801000000000000000181565b60056040517f9195785a000000000000000000000000000000000000000000000000000000008152600401610d2c919061168e565b60405180910390fd5b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff16868686604051602401610d6d93929190611702565b6040516020818303038152906040527f5ee837e7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610df791906113b8565b5f60405180830381855afa9150503d805f8114610e2f576040519150601f19603f3d011682016040523d82523d5f602084013e610e34565b606091505b509150915081610e79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e709061153d565b60405180910390fd5b5f81806020019051810190610e8e9190611768565b90508093505050509392505050565b3373ffffffffffffffffffffffffffffffffffffffff167f094703abe6f34e06c217139505bcc40e39f606853962e503a74d776a28f1148f5f54604051610ee49190610f06565b60405180910390a2565b5f819050919050565b610f0081610eee565b82525050565b5f602082019050610f195f830184610ef7565b92915050565b5f604051905090565b5f80fd5b5f80fd5b610f3981610eee565b8114610f43575f80fd5b50565b5f81359050610f5481610f30565b92915050565b5f60208284031215610f6f57610f6e610f28565b5b5f610f7c84828501610f46565b91505092915050565b5f67ffffffffffffffff82169050919050565b610fa181610f85565b8114610fab575f80fd5b50565b5f81359050610fbc81610f98565b92915050565b5f60208284031215610fd757610fd6610f28565b5b5f610fe484828501610fae565b91505092915050565b5f819050919050565b610fff81610fed565b82525050565b5f6020820190506110185f830184610ff6565b92915050565b5f819050919050565b6110308161101e565b811461103a575f80fd5b50565b5f8135905061104b81611027565b92915050565b5f806040838503121561106757611066610f28565b5b5f6110748582860161103d565b92505060206110858582860161103d565b9150509250929050565b6110988161101e565b82525050565b5f6020820190506110b15f83018461108f565b92915050565b6110c081610f85565b82525050565b5f6020820190506110d95f8301846110b7565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611108826110df565b9050919050565b611118816110fe565b8114611122575f80fd5b50565b5f813590506111338161110f565b92915050565b61114281610fed565b811461114c575f80fd5b50565b5f8135905061115d81611139565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6111b18261116b565b810181811067ffffffffffffffff821117156111d0576111cf61117b565b5b80604052505050565b5f6111e2610f1f565b90506111ee82826111a8565b919050565b5f67ffffffffffffffff82111561120d5761120c61117b565b5b6112168261116b565b9050602081019050919050565b828183375f83830152505050565b5f61124361123e846111f3565b6111d9565b90508281526020810184848401111561125f5761125e611167565b5b61126a848285611223565b509392505050565b5f82601f83011261128657611285611163565b5b8135611296848260208601611231565b91505092915050565b5f805f606084860312156112b6576112b5610f28565b5b5f6112c386828701611125565b93505060206112d48682870161114f565b925050604084013567ffffffffffffffff8111156112f5576112f4610f2c565b5b61130186828701611272565b9150509250925092565b611314816110fe565b82525050565b5f60208201905061132d5f83018461130b565b92915050565b5f8115159050919050565b61134781611333565b82525050565b5f6020820190506113605f83018461133e565b92915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f61139282611366565b61139c8185611370565b93506113ac81856020860161137a565b80840191505092915050565b5f6113c38284611388565b915081905092915050565b5f82825260208201905092915050565b7f756e7375636365737366756c2063616c6c20746f2061726368200000000000005f82015250565b5f611412601a836113ce565b915061141d826113de565b602082019050919050565b5f6020820190508181035f83015261143f81611406565b9050919050565b5f8151905061145481611139565b92915050565b5f6020828403121561146f5761146e610f28565b5b5f61147c84828501611446565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6114bc8261101e565b91506114c78361101e565b92508282019050828112155f8312168382125f8412151617156114ed576114ec611485565b5b92915050565b7f756e7375636365737366756c2063616c6c20746f2061726368000000000000005f82015250565b5f6115276019836113ce565b9150611532826114f3565b602082019050919050565b5f6020820190508181035f8301526115548161151b565b9050919050565b5f8151905061156981610f98565b92915050565b5f6020828403121561158457611583610f28565b5b5f6115918482850161155b565b91505092915050565b7f417373657274204572726f72204d6573736167650000000000000000000000005f82015250565b5f6115ce6014836113ce565b91506115d98261159a565b602082019050919050565b5f6020820190508181035f8301526115fb816115c2565b9050919050565b5f819050919050565b5f819050919050565b5f61162e61162961162484611602565b61160b565b610eee565b9050919050565b61163e81611614565b82525050565b7f56616c756520697320746f6f206c6f77000000000000000000000000000000005f82015250565b5f6116786010836113ce565b915061168382611644565b602082019050919050565b5f6040820190506116a15f830184611635565b81810360208301526116b28161166c565b905092915050565b5f82825260208201905092915050565b5f6116d482611366565b6116de81856116ba565b93506116ee81856020860161137a565b6116f78161116b565b840191505092915050565b5f6060820190506117155f83018661130b565b6117226020830185610ff6565b818103604083015261173481846116ca565b9050949350505050565b61174781611333565b8114611751575f80fd5b50565b5f815190506117628161173e565b92915050565b5f6020828403121561177d5761177c610f28565b5b5f61178a84828501611754565b9150509291505056fea264697066735822122088b3fe8589df5bd1c9d7d46b543867f57d179028bd99eeec4aca768ba9581a3f64736f6c634300081a0033 |
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.
Consider excluding generated bytecode from version control
Including compiled bytecode (storage.byte
) in version control is generally discouraged. It can lead to larger repository sizes and potential merge conflicts when the bytecode changes. It's best practice to generate bytecode during the build or testing process.
Consider removing storage.byte
from the repository and adding it to .gitignore
to prevent future commits:
+ echo "tests/fixtures/storage.byte" >> .gitignore
Committable suggestion was skipped due to low confidence.
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.
Actionable comments posted: 0
Outside diff range and nitpick comments (1)
services/ingestion/engine_test.go (1)
553-559
: LGTM! Consider extracting magic numbers.The refactoring to use
types.NewBlock
constructor improves code readability and maintainability. It's a good change that simplifies the block creation process.Consider extracting the magic numbers (1337 and 100) into named constants for better clarity and maintainability. For example:
+const ( + defaultBlockNonce = uint64(1337) + defaultTotalSupply = 100 +) gethBlock := types.NewBlock( gethCommon.HexToHash("0x1"), height, - uint64(1337), - big.NewInt(100), + defaultBlockNonce, + big.NewInt(defaultTotalSupply), gethCommon.HexToHash("0x15"), )
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (5)
- models/block.go (2 hunks)
- models/block_test.go (2 hunks)
- services/ingestion/engine_test.go (1 hunks)
- tests/web3js/cadence_arch_env_test.js (1 hunks)
- tests/web3js/eth_transaction_type_fees_test.js (4 hunks)
Files skipped from review as they are similar to previous changes (2)
- tests/web3js/cadence_arch_env_test.js
- tests/web3js/eth_transaction_type_fees_test.js
Additional comments not posted (4)
models/block.go (3)
78-81
: NewfixedHash
variable introduced to handle specific case.A new
fixedHash
variable has been introduced to handle cases wherePrevRandao
equals0x0
. This change seems to address a specific edge case or compatibility issue.To understand the context and necessity of this change, please run the following script:
#!/bin/bash # Search for references to PrevRandao and 0x0 hash rg --type go "PrevRandao.*0x0|0x0.*PrevRandao"This will help us understand if this is a common scenario in the codebase and if similar checks are performed elsewhere.
Also applies to: 95-95
Line range hint
75-95
: Summary of changes indecodeBlockEvent
functionThe changes in this function appear to be part of a larger refactoring effort. Key modifications include:
- Simplified error handling
- Introduction of a
fixedHash
variable to handle specific cases- Removal of legacy block event decoding logic
While these changes simplify the codebase and address specific scenarios, they might affect backwards compatibility.
To ensure the safety of these changes, please run the following script to check for any tests that might be affected:
#!/bin/bash # Search for tests related to block decoding rg --type go "func.*Test.*Block.*Decod|func.*Test.*Decod.*Block" testReview the results to ensure that existing tests still pass and consider adding new tests to cover the modified behavior, especially the new
fixedHash
logic.
75-76
: Simplified error handling might affect backwards compatibility.The error handling has been simplified to directly return the error from
events.DecodeBlockEventPayload
. While this makes the function more straightforward, it removes the attempt to decode a legacy block event.To ensure this change doesn't break existing functionality, please run the following script to check for any other usages of legacy block event decoding in the codebase:
If there are no results, this change is likely safe. Otherwise, we may need to update those occurrences as well.
models/block_test.go (1)
Line range hint
153-163
: Refactoring of block decoding test and stronger assertionsThe changes in this test function improve its focus and add a crucial assertion:
The function
decodeBlockEvent
is now used instead ofdecodeLegacyBlockEvent
. This suggests a consolidation of decoding logic, which is good for maintainability. However, ensure that this change is consistent across the codebase and that no legacy decoding functions are left unused.The addition of
require.NotNil(t, b.FixedHash)
is a valuable assertion. It ensures that the decoded block has a non-nil FixedHash, which is important for the integrity of the block data.The removal of the second decoding (
b2
) and its comparison simplifies the test, focusing on the correctness of a single decoding operation. This change makes the test more straightforward and easier to understand.These changes appear to strengthen the test while simplifying its logic. However, to ensure completeness:
Let's verify if there are any remaining uses of
decodeLegacyBlockEvent
in the codebase:Also, let's check if there are any other tests or functions that might need similar updates:
Verification successful
Verification Successful:
decodeLegacyBlockEvent
has been fully removed from the codebase. All references now usedecodeBlockEvent
.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for any remaining uses of decodeLegacyBlockEvent rg "decodeLegacyBlockEvent" --type goLength of output: 37
Script:
#!/bin/bash # Search for other potential legacy decoding functions rg "decode.*BlockEvent" --type goLength of output: 485
68d27a8
to
8ccf6d5
Compare
8ccf6d5
to
a0e6820
Compare
WalkthroughThe pull request introduces significant changes across multiple files, primarily focusing on restructuring the codebase to enhance the Ethereum Virtual Machine (EVM) integration with the Flow blockchain. Key modifications include updating client types, refining transaction execution logic, and implementing caching mechanisms for improved performance. Additionally, the Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant EVMClient
participant Ledger
participant Emulator
User->>EVMClient: Send Transaction
EVMClient->>Ledger: Fetch State
Ledger->>EVMClient: Return State
EVMClient->>Emulator: Execute Transaction
Emulator->>EVMClient: Return Execution Result
EVMClient->>User: Return Transaction Receipt
Assessment against linked issues
Possibly related issues
Suggested labels
Suggested reviewers
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (3)
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
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.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (17)
services/evm/rotation_signer.go (3)
Line range hint
26-49
: LGTM with a minor suggestion: Consider initializing theindex
field.The constructor implementation is solid, with good compatibility checks between private keys and the hashing algorithm. However, consider explicitly initializing the
index
field to 0 in the struct initialization for clarity, even though it's the zero value for int.Consider updating the struct initialization as follows:
return &KeyRotationSigner{ keys: keys, hasher: hasher, keyLen: len(keys), + index: 0, }, nil
Line range hint
63-72
: Implementation looks good, but the TODO needs to be addressed.The
PublicKey
method is correctly implemented with proper read locking for thread safety. However, the TODO comment highlights an important issue that needs to be resolved:// todo make this function to wait if the transactions that used this public key // is not yet executed on the network, this is so it prevents using // the same public key for fetching key sequence number before the transaction // that already used it is not executed and thus the key would be incremented.This issue is crucial for maintaining the correct sequence of transactions and preventing potential conflicts.
Please implement the waiting mechanism described in the TODO comment to ensure proper transaction sequencing. This might involve:
- Keeping track of pending transactions for each key.
- Implementing a waiting mechanism that checks if a transaction has been executed before allowing the use of the same public key again.
- Potentially using a condition variable or a channel-based approach for efficient waiting.
Consider opening a separate issue to track this task if it's not feasible to implement in this PR.
Line range hint
1-72
: Overall, the implementation looks good with one important TODO to address.The
KeyRotationSigner
implementation aligns well with the PR objectives, providing a thread-safe mechanism for signing with rotating keys. The code is well-structured and documented. The main point that needs attention is the TODO in thePublicKey
method, which is crucial for maintaining correct transaction sequencing.Consider the following suggestions for improving the overall design:
- Implement the waiting mechanism described in the TODO comment of the
PublicKey
method.- Add a method to check if all pending transactions for a specific key have been executed.
- Consider adding a configurable timeout for waiting on transaction execution to prevent indefinite blocking.
- Implement error handling for cases where a key becomes unusable (e.g., network issues preventing transaction execution).
These improvements will enhance the robustness and reliability of the key rotation mechanism in high-concurrency scenarios.
services/evm/kms_key_rotation_signer.go (3)
Line range hint
35-73
: LGTM: Well-implemented initialization function with proper error handling.The
NewKMSKeyRotationSigner
function is well-structured and correctly initializes theKMSKeyRotationSigner
struct. It properly handles errors at various stages of the initialization process and includes helpful logging.Consider wrapping the error returned from
kmsClient.SignerForKey
to provide more context:kmsSigner, err := kmsClient.SignerForKey(ctx, key) if err != nil { - return nil, fmt.Errorf( - "could not create KMS signer for the key with ID: %s: %w", - key.KeyID, - err, - ) + return nil, fmt.Errorf("could not create KMS signer for the key with ID %s: %w", key.KeyID, err) }This change makes the error message more concise while still providing all necessary information.
Line range hint
75-106
: LGTM: Thread-safe implementation with proper key rotation and performance logging.The
Sign
method is well-implemented, ensuring thread-safety through the use of a mutex. The key rotation logic is correct, and the inclusion of performance logging is a good practice for monitoring.Consider simplifying the error handling:
signature, err := signer.Sign(message) if err != nil { - return nil, fmt.Errorf( - "failed to sign message with public key %s: %w", - signer.PublicKey(), - err, - ) + return nil, fmt.Errorf("failed to sign message with public key %s: %w", signer.PublicKey(), err) } -return signature, err +return signature, nilThis change makes the error handling more concise and explicitly returns
nil
for the error when signing is successful.
Line range hint
1-122
: Summary: Well-implemented KMSKeyRotationSigner supporting PR objectivesThe
KMSKeyRotationSigner
implementation in this file aligns well with the PR objectives of implementing state reading and execution through the remote registers API. Key features include:
- Efficient key rotation mechanism for optimizing transaction submissions.
- Thread-safe implementation of signing and public key retrieval methods.
- Proper error handling and informative logging throughout the code.
The code quality is high, with comprehensive documentation and adherence to best practices. This implementation should contribute positively to the goal of local re-execution of transactions using the flow-go EVM Emulator.
To address the scalability concerns mentioned in the linked issue #574, consider the following:
- Implement a caching mechanism for frequently used register values to reduce API requests.
- Add configurable timeouts for KMS operations to prevent potential bottlenecks.
- Consider implementing a batching mechanism for signing operations to optimize performance under high load.
These enhancements could help mitigate potential performance issues related to register API requests during re-execution.
services/evm/cross-spork_client_test.go (2)
Line range hint
36-71
: Test_CrossSporkClients is good, but could be enhanced.The
Test_CrossSporkClients
function effectively tests theadd
andcontinuous
methods of thesporkClients
struct. It covers important scenarios such as:
- Adding clients in non-sequential order
- Retrieving clients based on various heights
- Checking continuity of ranges
However, we could enhance the test coverage with additional scenarios:
Consider adding the following test cases:
- Attempt to add overlapping ranges and verify the behavior.
- Test the behavior when adding a client with a range that exactly touches another (e.g., 101-200 and 201-300).
- Verify the behavior when attempting to retrieve a client at the exact boundary between two ranges.
Here's a sample implementation for the first suggestion:
t.Run("add overlapping ranges", func(t *testing.T) { clients := &sporkClients{} client1 := testutils.SetupClientForRange(10, 100) client2 := testutils.SetupClientForRange(50, 150) require.NoError(t, clients.add(client1)) err := clients.add(client2) require.Error(t, err) require.Contains(t, err.Error(), "overlapping range") })
Line range hint
73-134
: Test_CrossSpork is comprehensive but could be more structured.The
Test_CrossSpork
function covers a wide range of functionality for the CrossSporkClient, including:
- Client retrieval for different heights
- Past spork checks
- Error handling for out-of-range heights
- Various API method behaviors
While the coverage is good, we can improve the test structure and clarity:
Consider the following improvements:
- Split the large test into smaller, focused subtests. This will improve readability and make it easier to identify which specific functionality is failing if a test breaks.
- Use table-driven tests for similar checks (e.g., out-of-range error checks).
- Add more descriptive error messages to assertions.
Here's an example of how you could refactor a portion of the test:
func Test_CrossSpork(t *testing.T) { // Setup code... t.Run("getClientForHeight", func(t *testing.T) { testCases := []struct { name string height uint64 expectedClient access.Client expectedError error }{ {"past1 client", 150, past1, nil}, {"past2 client", past2Last - 1, past2, nil}, {"current client", 600, current, nil}, {"out of range", 10, nil, errs.ErrHeightOutOfRange}, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { c, err := client.getClientForHeight(tc.height) if tc.expectedError != nil { require.ErrorIs(t, err, tc.expectedError) } else { require.NoError(t, err) require.Equal(t, tc.expectedClient, c) } }) } }) // More subtests... }This refactoring improves readability and makes it easier to add new test cases in the future.
tests/fixtures/storage.sol (5)
42-48
: LGTM: Good addition ofemitRetrieve
functionThe new
emitRetrieve
function is a good addition, allowing event-based tracking ofretrieve
calls without modifying the original function. This separation of concerns is a good practice.Consider adding a
view
modifier toemitRetrieve
since it doesn't modify the contract state:- function emitRetrieve() public { + function emitRetrieve() public view { emit Retrieved(msg.sender, number); }
100-105
: LGTM: Error handling functions addedThe new
assertError
andcustomError
functions are good additions for demonstrating different error handling mechanisms in Solidity. The use of a custom error incustomError
is particularly good for gas efficiency.Consider adding comments to explain the purpose of these functions, especially if they are intended for testing or educational purposes:
+ // Function to demonstrate a simple assert error function assertError() public pure { require(false, "Assert Error Message"); } + // Function to demonstrate a custom error with parameters function customError() public pure { revert MyCustomError(5, "Value is too low"); }
115-118
: LGTM:emitVerifyArchCallToRandomSource
function addedThe new
emitVerifyArchCallToRandomSource
function is a good addition, allowing event-based tracking of random source verifications. This can be useful for auditing and monitoring purposes.Consider adding a comment to explain the purpose of the
height
parameter:- function emitVerifyArchCallToRandomSource(uint64 height) public { + // Emits the result of verifying the random source for a specific block height + function emitVerifyArchCallToRandomSource(uint64 height) public { bytes32 output = verifyArchCallToRandomSource(height); emit VerifyArchCallToRandomSource(msg.sender, output); }
127-142
: LGTM: Verification emit functions addedThe new
emitVerifyArchCallToRevertibleRandom
andemitVerifyArchCallToFlowBlockHeight
functions are good additions, allowing event-based tracking of their respective verifications. This enhances the contract's ability to provide off-chain visibility into these operations.Consider adding comments to explain the purpose of these functions:
+ // Emits the result of verifying a revertible random number function emitVerifyArchCallToRevertibleRandom() public { uint64 output = verifyArchCallToRevertibleRandom(); emit VerifyArchCallToRevertibleRandom(msg.sender, output); } + // Emits the current Flow block height function emitVerifyArchCallToFlowBlockHeight() public { uint64 output = verifyArchCallToFlowBlockHeight(); emit VerifyArchCallToFlowBlockHeight(msg.sender, output); }
144-154
: LGTM with suggestions:emitVerifyArchCallToVerifyCOAOwnershipProof
function addedThe new
emitVerifyArchCallToVerifyCOAOwnershipProof
function is a good addition, allowing event-based tracking of COA ownership proof verifications. This can be useful for auditing and monitoring purposes.Consider the following improvements for clarity and documentation:
- Add comments to explain the purpose of the function and its parameters:
+ // Verifies and emits the result of a COA ownership proof + // @param arg0 The address to verify ownership for + // @param arg1 The hash of the ownership proof + // @param arg2 The ownership proof data function emitVerifyArchCallToVerifyCOAOwnershipProof(address arg0, bytes32 arg1, bytes memory arg2) public { bool output = verifyArchCallToVerifyCOAOwnershipProof(arg0, arg1, arg2); emit VerifyArchCallToVerifyCOAOwnershipProof(msg.sender, output); }
- Consider using more descriptive parameter names to improve readability:
- function emitVerifyArchCallToVerifyCOAOwnershipProof(address arg0, bytes32 arg1, bytes memory arg2) public { + function emitVerifyArchCallToVerifyCOAOwnershipProof(address ownerAddress, bytes32 proofHash, bytes memory proofData) public { - bool output = verifyArchCallToVerifyCOAOwnershipProof(arg0, arg1, arg2); + bool output = verifyArchCallToVerifyCOAOwnershipProof(ownerAddress, proofHash, proofData); emit VerifyArchCallToVerifyCOAOwnershipProof(msg.sender, output); }services/evm/cross-spork_client.go (4)
Line range hint
29-83
: LGTM: Well-implemented sporkClients type and methods, with a suggestion for error handling.The
sporkClients
type and its methods (add
,get
, andcontinuous
) are well-implemented and serve their purposes effectively. The sorting of clients and the continuity check are particularly important for maintaining the integrity of the spork client list.However, consider improving error handling in the
add
method:
- In the
add
method, consider wrapping the errors returned fromGetLatestBlockHeader
andGetNodeVersionInfo
with more context, perhaps including the client details.- You might want to add error checking after the
append
operation to ensure it was successful.Example:
if err := client.GetLatestBlockHeader(context.Background(), true); err != nil { return fmt.Errorf("failed to get latest block header for client %v: %w", client, err) }
Line range hint
103-137
: Improve the temporary fix for the Emulator.The current implementation has a temporary fix for the Emulator, which doesn't support the
GetNodeVersionInfo
method. Consider the following improvements:
- Add a TODO comment explaining why this fix is temporary and what the long-term solution should be.
- Instead of checking the chain ID, consider adding a method to the
access.Client
interface that checks ifGetNodeVersionInfo
is supported, and use that check instead.Example:
// TODO: This is a temporary fix. Long-term solution should involve updating the Emulator to support GetNodeVersionInfo. if supportsNodeVersionInfo(currentSpork) { info, err := currentSpork.GetNodeVersionInfo(context.Background()) if err != nil { return nil, fmt.Errorf("failed to get node version info: %w", err) } nodeRootBlockHeight = info.NodeRootBlockHeight } // Add this helper function func supportsNodeVersionInfo(client access.Client) bool { _, err := client.GetNodeVersionInfo(context.Background()) return err == nil }
Line range hint
139-151
: Add more detailed logging in CrossSporkClient methods.While the current implementation includes some logging, consider adding more detailed logs to aid in debugging and monitoring. For example:
- In
getClientForHeight
, log when falling back to the current spork client.- In
GetLatestHeightForSpork
, log the retrieved latest height.- In
ExecuteScriptAtBlockHeight
, log the script execution (maybe hash of the script for privacy).Example for
getClientForHeight
:if !c.IsPastSpork(height) { c.logger.Debug(). Uint64("requested-height", height). Msg("using current spork client") return c.Client, nil }Also applies to: 153-167, 169-179, 181-191, 193-203
Multiple Usages of Experimental Slices Package Identified
The
golang.org/x/exp/slices
package is imported in the following files:
services/evm/cross-spork_client.go
services/logs/filter.go
Using an experimental package across multiple modules can lead to potential instability if the API changes in future updates. Please ensure that this dependency is well-documented and monitor the package for any changes or updates.
🔗 Analysis chain
Line range hint
3-14
: Consider the implications of using the experimental slices package.The code imports
golang.org/x/exp/slices
, which is an experimental package. While it provides useful functionality, be aware that its API may change in the future. Consider documenting this dependency and keeping track of any updates to the package.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Check if there are any other usages of the experimental slices package in the codebase rg --type go 'golang\.org/x/exp/slices'Length of output: 259
Script:
#!/bin/bash # Check if there are any other usages of the experimental slices package in the codebase rg --type go 'golang\.org/x/exp/slices'Length of output: 154
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (3)
go.sum
is excluded by!**/*.sum
tests/go.sum
is excluded by!**/*.sum
tests/web3js/package-lock.json
is excluded by!**/package-lock.json
📒 Files selected for processing (32)
- .gitignore (0 hunks)
- api/api.go (3 hunks)
- bootstrap/bootstrap.go (7 hunks)
- go.mod (2 hunks)
- models/block.go (2 hunks)
- models/block_test.go (2 hunks)
- services/evm/client.go (13 hunks)
- services/evm/cross-spork_client.go (1 hunks)
- services/evm/cross-spork_client_test.go (1 hunks)
- services/evm/executor.go (1 hunks)
- services/evm/kms_key_rotation_signer.go (1 hunks)
- services/evm/pool.go (1 hunks)
- services/evm/remote_ledger.go (3 hunks)
- services/evm/remote_ledger_test.go (1 hunks)
- services/evm/rotation_signer.go (1 hunks)
- services/evm/rotation_signer_test.go (1 hunks)
- services/ingestion/engine_test.go (1 hunks)
- services/ingestion/subscriber.go (3 hunks)
- services/ingestion/subscriber_test.go (6 hunks)
- services/requester/requester_test.go (0 hunks)
- tests/e2e_web3js_test.go (2 hunks)
- tests/fixtures/storage.byte (1 hunks)
- tests/fixtures/storage.sol (4 hunks)
- tests/fixtures/storageABI.json (4 hunks)
- tests/go.mod (1 hunks)
- tests/helpers.go (3 hunks)
- tests/web3js/build_evm_state_test.js (2 hunks)
- tests/web3js/cadence_arch_env_test.js (1 hunks)
- tests/web3js/eth_deploy_contract_and_interact_test.js (2 hunks)
- tests/web3js/eth_filter_endpoints_test.js (2 hunks)
- tests/web3js/eth_revert_reason_test.js (2 hunks)
- tests/web3js/eth_transaction_type_fees_test.js (4 hunks)
💤 Files with no reviewable changes (2)
- .gitignore
- services/requester/requester_test.go
✅ Files skipped from review due to trivial changes (1)
- tests/go.mod
🚧 Files skipped from review as they are similar to previous changes (24)
- api/api.go
- bootstrap/bootstrap.go
- go.mod
- models/block.go
- models/block_test.go
- services/evm/client.go
- services/evm/executor.go
- services/evm/pool.go
- services/evm/remote_ledger.go
- services/evm/remote_ledger_test.go
- services/evm/rotation_signer_test.go
- services/ingestion/engine_test.go
- services/ingestion/subscriber.go
- services/ingestion/subscriber_test.go
- tests/e2e_web3js_test.go
- tests/fixtures/storage.byte
- tests/fixtures/storageABI.json
- tests/helpers.go
- tests/web3js/build_evm_state_test.js
- tests/web3js/cadence_arch_env_test.js
- tests/web3js/eth_deploy_contract_and_interact_test.js
- tests/web3js/eth_filter_endpoints_test.js
- tests/web3js/eth_revert_reason_test.js
- tests/web3js/eth_transaction_type_fees_test.js
🔇 Additional comments (19)
services/evm/rotation_signer.go (3)
Line range hint
1-7
: LGTM: Package change and imports are appropriate.The package change from
requester
toevm
aligns with the PR objectives. The imports are relevant for the implemented functionality.
Line range hint
9-24
: LGTM: Well-designed struct with clear documentation.The
KeyRotationSigner
struct is well-defined with appropriate fields. The documentation clearly explains its purpose and behavior, including its concurrency safety. The implementation of thecrypto.Signer
interface is correctly indicated.
Line range hint
51-61
: LGTM: Thread-safe implementation with correct key rotation.The
Sign
method is well-implemented with proper mutex usage for thread safety. The signing process and key rotation logic are correctly implemented.services/evm/kms_key_rotation_signer.go (3)
Line range hint
1-11
: LGTM: Package declaration and imports are appropriate.The package name change from 'requester' to 'evm' aligns well with the file's location in the 'evm' directory. The imports cover necessary standard library packages and external dependencies required for the implementation.
Line range hint
13-33
: LGTM: Well-designed struct with comprehensive documentation.The
KMSKeyRotationSigner
struct is well-defined with appropriate fields for managing a pool of KMS signers. The documentation clearly explains its purpose, functionality, and benefits, including its concurrency-safety and optimization for transaction submissions. The implementation of thecrypto.Signer
interface is appropriate for the intended use case.
Line range hint
108-122
: LGTM: Thread-safe implementation with potential for future improvement.The
PublicKey
method is correctly implemented and ensures thread-safety by using a read lock.Regarding the TODO comment, it suggests an important improvement for key sequence management. To track this, consider creating an issue in the project's issue tracker. Here's a script to check if an issue already exists for this TODO:
If no relevant issue is found, please create one to track this improvement.
services/evm/cross-spork_client_test.go (3)
Line range hint
17-34
: Test_CrossSporkClient looks good!The test function
Test_CrossSporkClient
is well-structured and comprehensive. It covers various scenarios including:
- Edge cases (first and last heights)
- Values within the range
- Values outside the range (both below and above)
This ensures that the
contains
method of thesporkClient
struct is working correctly for all possible inputs.
Line range hint
1-134
: Overall, the test suite is comprehensive but could benefit from some structural improvements.The test suite for the CrossSporkClient implementation covers a wide range of functionality and scenarios. However, there are a few areas where we can enhance the tests:
- In
Test_CrossSporkClients
, consider adding more edge cases, such as overlapping ranges and boundary conditions.- For
Test_CrossSpork
, refactor the large test into smaller, focused subtests to improve readability and maintainability.- Implement table-driven tests where appropriate to make it easier to add new test cases in the future.
These improvements will make the test suite more robust, easier to maintain, and simpler to extend as the CrossSporkClient functionality evolves.
1-1
: Package name change looks good, but let's verify consistency.The package name change from
requester
toevm
aligns well with the file path. This change improves the organization of the codebase.Let's verify that this change is consistent across the codebase:
✅ Verification successful
Package name change is consistent across the codebase.
The package name has been successfully changed from
requester
toevm
in all relevant files, ensuring consistency and enhancing the organization of the codebase.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for any remaining references to the old package name and verify the new package name usage. # Test 1: Check for any remaining "package requester" declarations echo "Checking for any remaining 'package requester' declarations:" rg --type go "^package requester$" # Test 2: Verify the usage of "package evm" in the evm directory echo "Verifying 'package evm' usage in the evm directory:" rg --type go "^package evm$" services/evm/Length of output: 775
tests/fixtures/storage.sol (5)
9-18
: LGTM: New events are well-structuredThe newly added events are well-defined and follow Solidity best practices. They provide a comprehensive way to log various contract interactions and state changes, which will be useful for off-chain monitoring and analysis.
60-62
: LGTM:emitBlockNumber
function addedThe new
emitBlockNumber
function is a good addition, allowing event-based tracking of block numbers. This can be useful for various off-chain applications that need to monitor block progression.
68-70
: LGTM:emitBlockTime
function addedThe new
emitBlockTime
function is a good addition, allowing event-based tracking of block timestamps. This can be useful for time-sensitive off-chain applications that need to monitor block times.
72-78
: LGTM with suggestion:emitBlockHash
function addedThe new
emitBlockHash
function is a good addition, allowing event-based tracking of block hashes.Please note that the previous review comment about adding input validation for the
num
parameter is still applicable. Consider implementing the suggested input validation to ensurenum
is within the valid range (block.number - 256 <= num < block.number
).
92-94
: LGTM:emitChainID
function addedThe new
emitChainID
function is a good addition, allowing event-based tracking of the chain ID. This can be useful for multi-chain applications or for verifying the correct network context.services/evm/cross-spork_client.go (5)
1-1
: LGTM: Package name change aligns with PR objectives.The package name change from
requester
toevm
better reflects the file's content and purpose, aligning with the PR's goal of implementing state reading and execution through the remote registers API.
Line range hint
16-27
: LGTM: Well-defined sporkClient struct and method.The
sporkClient
struct and itscontains
method are well-implemented. The struct efficiently stores the necessary information for each spork client, and thecontains
method correctly checks if a given height is within the spork's range.
Line range hint
85-101
: LGTM: Well-designed CrossSporkClient struct.The
CrossSporkClient
struct is well-designed to handle cross-spork functionality. It effectively wraps the Flow AN client and provides methods to access different AN APIs based on height boundaries of the sporks.
Line range hint
1-203
: Overall assessment: Well-implemented CrossSporkClient with minor suggestions for improvement.The implementation of the CrossSporkClient in this file effectively addresses the PR objectives of implementing state reading and execution through the remote registers API from the Application Node. The code is well-structured and provides a solid foundation for handling cross-spork functionality.
Key points:
- The package name change and new imports align well with the PR goals.
- The sporkClient and sporkClients types are well-designed and implemented.
- The CrossSporkClient struct and its methods effectively manage multiple spork clients and delegate calls based on height.
Suggestions for improvement:
- Consider the implications of using the experimental slices package.
- Improve error handling in the sporkClients.add method.
- Refine the temporary fix for the Emulator in NewCrossSporkClient.
- Add more detailed logging in some methods to aid debugging and monitoring.
- Verify the implementation of GetLatestHeightForSpork to ensure it always returns a height within the correct spork's range.
While this implementation provides a solid foundation, additional testing may be required to address the scalability concerns mentioned in the linked issue, particularly regarding the speed of register API requests during re-execution.
Line range hint
169-179
: Verify the implementation of GetLatestHeightForSpork.The
GetLatestHeightForSpork
method retrieves the latest height for a given spork. However, it's important to ensure that this method always returns a height within the correct spork's range.#!/bin/bash # Check if there are any tests for GetLatestHeightForSpork rg --type go 'func.*Test.*GetLatestHeightForSpork' # If no tests are found, output a message if [ $? -ne 0 ]; then echo "No tests found for GetLatestHeightForSpork. Consider adding tests to verify its behavior." fi
function emitRandom() public { | ||
emit Random(msg.sender, block.prevrandao); | ||
} |
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.
💡 Codebase verification
Security Issue: Insecure Randomness Source in random
Function
The random
function relies on block.prevrandao
, which can be manipulated by miners and is not suitable for critical operations requiring secure randomness.
- File:
tests/fixtures/storage.sol
- Function:
random()
Recommendation: Use a more secure randomness source, such as Chainlink VRF, to ensure unpredictability and security in critical operations.
🔗 Analysis chain
LGTM with security consideration: emitRandom
function added
The new emitRandom
function is a good addition, allowing event-based tracking of the block's prevrandao value.
Please ensure that this function is not used as the sole source of randomness for critical operations, as it can be manipulated by miners to some extent. Consider using a more secure randomness source for sensitive applications.
To verify the usage of this function, you can run the following script:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for potentially unsafe usage of emitRandom or random functions
# Test: Search for function calls that might be using emitRandom or random for sensitive operations
rg --type solidity -e "emitRandom|random" -C 5
Length of output: 81
Script:
#!/bin/bash
# Description: Check for potentially unsafe usage of emitRandom or random functions
# Test: Search for function calls that might be using emitRandom or random for sensitive operations in Solidity files
rg -g '*.sol' -e "emitRandom|random" -C 5
Length of output: 826
if payload.PrevRandao == gethCommon.HexToHash("0x0") { | ||
hash := payload.Hash.String() | ||
fixedHash = &hash | ||
} |
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 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.
@janezpodhostnik This is a part which is necessary for calculating the hash of blocks, when there are changes to its format (e.g. addition/removal of fields). The hash calculation can only be made on demand, with a function (https://github.com/onflow/flow-go/blob/master/fvm/evm/types/block.go#L54-L63). When testnet
was launched, the block format had certain fields. After some time, we made an HCU to introduce a new field, PrevRandao
. This naturally caused the Hash
function to return different values for past blocks. And this part is basically an approach to mitigate that. We fix the block hash, to the value that was emitted in the EVM.BlockExecuted
event.
Closes: #574
Description
This PR adds state read and execution using remote registers API from the AN.
For contributor use:
master
branchFiles changed
in the Github PR explorerSummary by CodeRabbit
Release Notes
New Features
BlockExecutor
for executing transactions in the EVM context on the Flow blockchain.Refactor
requester
toevm
across multiple services.EVMClient
.Bug Fixes
evm
services.Chores
go.mod
files to ensure compatibility with the latest changes..gitignore
for better file management.