Skip to content
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

Warp stapling block context #823

Merged
merged 43 commits into from
Sep 12, 2023
Merged

Conversation

aaronbuchwald
Copy link
Collaborator

Why this should be merged

This PR addresses #735 and #734

How this works

This PR creates a predicate results type to encode the per-transaction predicate results into the block header. This is intended to remove the possibility that predicate verification may fail and require dropping the transaction from the mempool/block, which creates a potential DoS vector as per: https://ethresear.ch/t/dos-vectors-in-account-abstraction-aa-or-validation-generalization-a-case-study-in-geth/7937.

Additionally, this PR adds a BlockHashPayload to allow signing a block hash instead of the existing point-to-point AddressedPayload.

To handle the BlockHashPayload this PR adds a new function getVerifiedWarpBlockHash to read the verified block hash and return it to the caller.

How this was tested

  • Adds new contract execution tests for the block hash payload function
  • Adds new predicate test for combinations of verifying successful/failed warp messages within a single transaction
  • Improve vm warp unit test (add testing of traceBlock)
  • TODO: add unit predicate results serialization tests

How is this documented

TODO: update Warp README

@@ -59,7 +59,7 @@ func (*configurator) MakeConfig() precompileconfig.Config {
// This function is called by the EVM once per precompile contract activation.
// You can use this function to set up your precompile contract's initial state,
// by using the [cfg] config and [state] stateDB.
func (*configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg precompileconfig.Config, state contract.StateDB, blockContext contract.BlockContext) error {
func (*configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg precompileconfig.Config, state contract.StateDB, blockContext contract.ConfigurationBlockContext) error {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be broken into a separate preparation PR if preferred

}

for address, predicates := range predicateArguments {
predicate := rules.Predicates[address]
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: add comment noting that if predicateArguments was populated with this address, then the predicate must be present in rules.Predicates

core/evm.go Show resolved Hide resolved
return fmt.Errorf("predicate %s failed verification for tx %s: %w", address, tx.Hash(), err)
}

predicateArguments[address] = append(predicateArguments[address], predicateutils.HashSliceToBytes(accessTuple.StorageKeys))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we append those instead of directly verify each predicate here and set the result bit set here instead of VerifyPredicate? I feel like we can save at least 2 loops here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was so that the predicate can take in all of the byte slices for the transaction in one call rather than doing it one at a time and return the bit set as a byte slice.

Alternatively, we could switch back to VerifyPredicate taking in a single value and CheckPredicates assembling the bit set from those results. This would make the code a bit simpler at the cost of constraining the precompile predicates to return a true/false value instead of an arbitrary byte array.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like using a single value for VerifyPredicate could be simpler + cleaner (and costs less loops). It would be easier for 3rd party implementations as well.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we make this a follow-on PR to try out the alternative?

This also means that we need to track the indices used by each precompile address to create that bitset, so I'm not sure if it will be cleaner.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created #844

contracts/contracts/interfaces/IWarpMessenger.sol Outdated Show resolved Hide resolved
contracts/contracts/interfaces/IWarpMessenger.sol Outdated Show resolved Hide resolved
func (s *StateDB) GetTxHash() common.Hash {
return s.thash
}

// GetPredicateStorageSlots returns the storage slots associated with a given address, and whether or not
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add index to comments

Copy link
Collaborator Author

@aaronbuchwald aaronbuchwald Sep 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the comment on GetPredicateStorageSlots to include an example and added a comment to GetTxHash

type TxPredicateResults map[common.Address][]byte

// PredicateResults encodes the precompile predicate results included in a block on a per transaction basis.
// PredicateResults is not thread-safe.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't we need this to be thread-safe?

Copy link
Collaborator Author

@aaronbuchwald aaronbuchwald Sep 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We currently only modify this synchronously in the worker and during block verification. It is only read from the EVM when it is either a unique instance or is being used synchronously in the worker. For the APIs that may re-use a block context, they will only perform read operations on an instance that is never modified.

We could make it thread-safe, but I don't think it's necessary atm. Is there a specific case you're concerned about?

if !warpIndex.IsInt64() {
return nil, false
}
warpIndexInt := int(warpIndex.Int64())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

paranoid 🤖: could someone issue a very big int (MaxInt32<x<MaxInt64) and cause this casting to be not lossless (in 32-bit systems)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ya I'll update the input type to uint32 so that we don't have to do this at all.

if !exists {
return nil, false
}
if index >= len(predicates) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we check if index is negative (or simply require uint64 indexes here)?

this is related to the comment about lossless conversion between int<>int64 below.

@aaronbuchwald aaronbuchwald merged commit 077e8ca into master Sep 12, 2023
8 checks passed
@aaronbuchwald aaronbuchwald deleted the warp-stapling-block-context branch September 12, 2023 17:10
ceyonur pushed a commit that referenced this pull request Sep 12, 2023
* Warp stapling block context (#823)

* Add GetPredicateResults to BlockContext

* Serve predicate results from blockContext

* Allow extra data to extend past DynamicFeeWindow post DUpgrade

* Get vm warp unit tests working

* Bump ANR to intermediate version to fix incompatibility with AvalancheGo

* Add kc to EthKeyChain

* Bump avalanchego dep in scripts for CI

* Add block hash payload support

* Use gomocks for precompileconfig and predicater and re-write CheckPredicates with gomocks

* Use gomock for mock accessible state and block context

* Fix existing warp contract tests with mock block context

* Remove unused mockPredicater impl

* x/warp: add contract execution unit tests

* Update NewEVMBlockContext

* Add AppendExtra to syncervm to fix tests

* x/warp: add unit test for multiple predicate results

* core: add unit test for CheckPredicates insufficient gas

* Update receive warp message test to trace block and assert the expected result

* Fix lint

* Update warp solidity contracts

* Fix block context mocks for bench

* Update precompile/precompileconfig/config.go

Co-authored-by: Darioush Jalali <darioush.jalali@avalabs.org>
Signed-off-by: aaronbuchwald <aaron.buchwald56@gmail.com>

* Cleanup

* precompile/results: Add predicate results tests + comments

* nits

* precompile/results: omit tx predicate results if empty

* core: add invariant comment to predicate check

* Address PR comments

* Fix unpackWarpMessage and add unit tests

* Rename OriginChainID -> SourceChainID to match ago warp message type

* nits

* x/warp: set public key in warp predicate unit tests

* Update payload format

* Clarify IWarpMessenger verified message return types

* core/state: improve statedb warp specific comments

* Update input param type to uint32 to avoid potential overflow on conversion

* Update GetPredicateStorageSlots arg type to uint32

* warp/payload: add README for payload serialization (#835)

* Fix merge

* x/warp: add unit test for PrimaryNetwork to Subnet predicate verification (#831)

* precompilebind: add ChainConfig with DUpgrade enabled to precompile chain config verify template
aaronbuchwald pushed a commit that referenced this pull request Sep 13, 2023
* update npm package

* expand allowlist.configure

* add activation func to precompile functions

* move chainconfig to precompileconfig

* use chainconfig in verification

* trim unnecessary changes

* add manager role

* fix tests

* add verify test

* nits

* add mocks

* reviews

* fix linter

* fix benchmarks

* nits

* nits

* fix alow list bind tests & ensure they're being tested (#841)

* simplify can modify check

* fix vm tests

* Add manager allowlist role merge (#850)

* Warp stapling block context (#823)

* Add GetPredicateResults to BlockContext

* Serve predicate results from blockContext

* Allow extra data to extend past DynamicFeeWindow post DUpgrade

* Get vm warp unit tests working

* Bump ANR to intermediate version to fix incompatibility with AvalancheGo

* Add kc to EthKeyChain

* Bump avalanchego dep in scripts for CI

* Add block hash payload support

* Use gomocks for precompileconfig and predicater and re-write CheckPredicates with gomocks

* Use gomock for mock accessible state and block context

* Fix existing warp contract tests with mock block context

* Remove unused mockPredicater impl

* x/warp: add contract execution unit tests

* Update NewEVMBlockContext

* Add AppendExtra to syncervm to fix tests

* x/warp: add unit test for multiple predicate results

* core: add unit test for CheckPredicates insufficient gas

* Update receive warp message test to trace block and assert the expected result

* Fix lint

* Update warp solidity contracts

* Fix block context mocks for bench

* Update precompile/precompileconfig/config.go

Co-authored-by: Darioush Jalali <darioush.jalali@avalabs.org>
Signed-off-by: aaronbuchwald <aaron.buchwald56@gmail.com>

* Cleanup

* precompile/results: Add predicate results tests + comments

* nits

* precompile/results: omit tx predicate results if empty

* core: add invariant comment to predicate check

* Address PR comments

* Fix unpackWarpMessage and add unit tests

* Rename OriginChainID -> SourceChainID to match ago warp message type

* nits

* x/warp: set public key in warp predicate unit tests

* Update payload format

* Clarify IWarpMessenger verified message return types

* core/state: improve statedb warp specific comments

* Update input param type to uint32 to avoid potential overflow on conversion

* Update GetPredicateStorageSlots arg type to uint32

* warp/payload: add README for payload serialization (#835)

* Fix merge

* x/warp: add unit test for PrimaryNetwork to Subnet predicate verification (#831)

* precompilebind: add ChainConfig with DUpgrade enabled to precompile chain config verify template
ceyonur pushed a commit that referenced this pull request Sep 14, 2023
* Add GetPredicateResults to BlockContext

* Serve predicate results from blockContext

* Allow extra data to extend past DynamicFeeWindow post DUpgrade

* Get vm warp unit tests working

* Bump ANR to intermediate version to fix incompatibility with AvalancheGo

* Add kc to EthKeyChain

* Bump avalanchego dep in scripts for CI

* Add block hash payload support

* Use gomocks for precompileconfig and predicater and re-write CheckPredicates with gomocks

* Use gomock for mock accessible state and block context

* Fix existing warp contract tests with mock block context

* Remove unused mockPredicater impl

* x/warp: add contract execution unit tests

* Update NewEVMBlockContext

* Add AppendExtra to syncervm to fix tests

* x/warp: add unit test for multiple predicate results

* core: add unit test for CheckPredicates insufficient gas

* Update receive warp message test to trace block and assert the expected result

* Fix lint

* Update warp solidity contracts

* Fix block context mocks for bench

* Update precompile/precompileconfig/config.go

Co-authored-by: Darioush Jalali <darioush.jalali@avalabs.org>
Signed-off-by: aaronbuchwald <aaron.buchwald56@gmail.com>

* Cleanup

* precompile/results: Add predicate results tests + comments

* nits

* precompile/results: omit tx predicate results if empty

* core: add invariant comment to predicate check

* Address PR comments

* Fix unpackWarpMessage and add unit tests

* Rename OriginChainID -> SourceChainID to match ago warp message type

* nits

* x/warp: set public key in warp predicate unit tests

* Update payload format

* Clarify IWarpMessenger verified message return types

* core/state: improve statedb warp specific comments

* Update input param type to uint32 to avoid potential overflow on conversion

* Update GetPredicateStorageSlots arg type to uint32

* warp/payload: add README for payload serialization (#835)

* Fix merge
ceyonur added a commit that referenced this pull request Sep 14, 2023
* update npm package

* expand allowlist.configure

* add activation func to precompile functions

* move chainconfig to precompileconfig

* use chainconfig in verification

* trim unnecessary changes

* add manager role

* fix tests

* add verify test

* nits

* add mocks

* reviews

* fix linter

* fix benchmarks

* nits

* nits

* fix alow list bind tests & ensure they're being tested (#841)

* simplify can modify check

* fix vm tests

* Add manager allowlist role merge (#850)

* Warp stapling block context (#823)

* Add GetPredicateResults to BlockContext

* Serve predicate results from blockContext

* Allow extra data to extend past DynamicFeeWindow post DUpgrade

* Get vm warp unit tests working

* Bump ANR to intermediate version to fix incompatibility with AvalancheGo

* Add kc to EthKeyChain

* Bump avalanchego dep in scripts for CI

* Add block hash payload support

* Use gomocks for precompileconfig and predicater and re-write CheckPredicates with gomocks

* Use gomock for mock accessible state and block context

* Fix existing warp contract tests with mock block context

* Remove unused mockPredicater impl

* x/warp: add contract execution unit tests

* Update NewEVMBlockContext

* Add AppendExtra to syncervm to fix tests

* x/warp: add unit test for multiple predicate results

* core: add unit test for CheckPredicates insufficient gas

* Update receive warp message test to trace block and assert the expected result

* Fix lint

* Update warp solidity contracts

* Fix block context mocks for bench

* Update precompile/precompileconfig/config.go

Co-authored-by: Darioush Jalali <darioush.jalali@avalabs.org>
Signed-off-by: aaronbuchwald <aaron.buchwald56@gmail.com>

* Cleanup

* precompile/results: Add predicate results tests + comments

* nits

* precompile/results: omit tx predicate results if empty

* core: add invariant comment to predicate check

* Address PR comments

* Fix unpackWarpMessage and add unit tests

* Rename OriginChainID -> SourceChainID to match ago warp message type

* nits

* x/warp: set public key in warp predicate unit tests

* Update payload format

* Clarify IWarpMessenger verified message return types

* core/state: improve statedb warp specific comments

* Update input param type to uint32 to avoid potential overflow on conversion

* Update GetPredicateStorageSlots arg type to uint32

* warp/payload: add README for payload serialization (#835)

* Fix merge

* x/warp: add unit test for PrimaryNetwork to Subnet predicate verification (#831)

* precompilebind: add ChainConfig with DUpgrade enabled to precompile chain config verify template
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Archived in project
Development

Successfully merging this pull request may close these issues.

3 participants