ava-labs/subnet-evm

Add Optional OnAccept Hook to Precompiles

aaronbuchwald opened this issue · 0 comments

Precompiles may trigger some behavior such as sending an Avalanche Warp Message that triggers an action only when the block containing it is accepted (ref: https://github.com/ava-labs/subnet-evm/blob/v0.5.8/x/warp/README.md#flow-of-sending--receiving-a-warp-message-within-the-evm).

This works easily for actions that create an event on the block itself since it is persisted to disk and can be checked when marking the block as accepted to handle that event.

However, we would also like to enable arbitrary hooks that occur only when the block is accepted to support logging that only occurs (or occurs at different levels/with different arguments) when a block is processed vs. accepted. For example, when delivering a message through getVerifiedWarpMessage we may want to emit a log when a block is accepted and marks a message as delivered. However, if this emitted a log at the same level or with identical arguments when a block was processed for the first time as it gets verified or via an API call then it may lead to results that are difficult to interpret and differentiate between the different contexts.

To support this, we would ideally like to augment the interfaces supplied to a precompile so that they can add an arbitrary execution function that will run when the block is accepted.

For example, this may look like updating the current BlockContext code: https://github.com/ava-labs/subnet-evm/blob/v0.5.8/precompile/contract/interfaces.go#L63

type BlockContext interface {
	ConfigurationBlockContext
	// GetResults returns an arbitrary byte array result of verifying the predicates
	// of the given transaction, precompile address pair.
	GetPredicateResults(txHash common.Hash, precompileAddress common.Address) []byte
}

to include an additional function:

type BlockContext interface {
	ConfigurationBlockContext
	// GetResults returns an arbitrary byte array result of verifying the predicates
	// of the given transaction, precompile address pair.
	GetPredicateResults(txHash common.Hash, precompileAddress common.Address) []byte
	// AddAcceptHook adds the function f to the set of functions that will be invoked if/when this block is accepted
	AddAcceptHook(f func())
}