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

Block hash publisher #54

Draft
wants to merge 27 commits into
base: main
Choose a base branch
from
Draft

Block hash publisher #54

wants to merge 27 commits into from

Conversation

cam-schultz
Copy link
Collaborator

@cam-schultz cam-schultz commented Oct 5, 2023

Why this should be merged

Adds relayer support for publishing verified block hashes from subnets. See ava-labs/subnet-evm#734 for more details on the subnet-evm feature and use cases. Also includes architecture and interface changes to better support one-to-many Warp message relaying for future anycast protocols.

How this works

Adds EVM_BLOCKHASH VM type, and BLOCK_HASH_PUBLISHER message protocol. EVM_BLOCKHASH subscribes to all new blocks from the configured source, and passes it to the message relayer. BLOCK_HASH_PUBLISHER then creates a single aggregate signature and publishes the block hash on each of the configured destinations via BlockHashReceiver.sol, added here: ava-labs/teleporter#51.

Some notes:

  • Processing of historical blocks is NOT included in this PR to limit this PRs scope.
  • Publishing block hashes from the primary network is also NOT included in this PR. In that case, we need to create a separate aggregate signature for each destination, which I also elected to skip to limit this PRs scope.

How this was tested

  • E2E test
  • Expand E2E to two destination chains
  • block_hash_publisher/config tests
  • block_hash_publisher/message_manager tests
  • evm_block_hash/contract_message tests

How is this documented

Code comments

Copy link
Contributor

@bernard-avalabs bernard-avalabs left a comment

Choose a reason for hiding this comment

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

Generally makes sense to me. I've left a few comments.

@@ -232,6 +237,8 @@ func (s *SourceSubnet) Validate() error {
return fmt.Errorf("invalid message contract address in EVM source subnet: %s", messageContractAddress)
}
}
case EVM_BLOCKHASH:
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems odd that Blockhash is considered its own VM type. Are we overloading the term "VM" here?

)

const (
publishBlockHashGasLimit = 275000
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this temporary, or do we know if this will be enough?

return nil, err
}
var messageConfig Config
if err := json.Unmarshal(data, &messageConfig); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure I understand why we are marshalling and then immediately unmarshalling the data here.

useTimeInterval: destination.useTimeInterval,
timeIntervalSeconds: destination.timeIntervalSeconds,
blockInterval: destination.blockInterval,
address: common.HexToAddress(destination.Address),
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you confirm that destination.Address has already been verified so HexToAddress should never fail?

Comment on lines +39 to +43
addr = strings.TrimPrefix(addr, "0x")
_, err := hex.DecodeString(addr)
if err != nil {
return errors.Wrap(err, fmt.Sprintf("invalid address in block hash publisher configuration. Provided address: %s", destinationInfo.Address))
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we able to check that this is a valid address, and not just a valid hex string?

Comment on lines +78 to +80
if err != nil || intValue < 0 {
return 0, false, err
}
Copy link
Contributor

Choose a reason for hiding this comment

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

We should probably separate these cases. Right now if intValue < 0 we return a nil error.

func (d *destinationSenderInfo) shouldSend(blockTimestamp uint64, blockNumber uint64) bool {
if d.useTimeInterval {
interval := d.timeIntervalSeconds
if time.Unix(int64(blockTimestamp), 0).Sub(time.Unix(int64(d.lastTimeSent), 0)) < (time.Duration(interval) * time.Second) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to convert both of these to unix times?

Comment on lines +49 to +55
cmd := exec.Command(
"cast",
"send",
"--rpc-url", teleporterTestUtils.HttpToRPCURI(subnetInfo.ChainNodeURIs[0], subnetInfo.BlockchainID.String()),
"--private-key", hexutil.Encode(fundedKey.D.Bytes()),
"--create", blockHashReceiverByteCode,
)
Copy link
Contributor

Choose a reason for hiding this comment

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

We should probably replace this with bind.DeployContract so we're not relying on cast. It also cuts out all the scanner boilderplate below.

newHeads chan *types.Header,
subnetInfo teleporterTestUtils.SubnetTestInfo,
blockHashABI *abi.ABI, expectedHashes []common.Hash) {
newHead := <-newHeads
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Can we put a newline here? this is hard to read.

@@ -9,12 +9,15 @@ type VM int
const (
UNKNOWN_VM VM = iota
EVM
EVM_BLOCKHASH
Copy link
Contributor

Choose a reason for hiding this comment

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

I might be misunderstanding something, but this doesn't feel like it should be a distinct VM, I think it would make more sense as a flag? I also don't really understand how we're using it right now - Does an EVM_BLOCKHASH subscriber perform a superset of the actions performed byan EVM subscriber?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

3 participants