-
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
Astria named forks #59
base: main
Are you sure you want to change the base?
Changes from all commits
43b5a98
a63cd80
a85e7ee
6610cb0
3aae19a
69cc309
5886c66
6bdcf95
b7a6184
1f1aacd
8497d10
17e5dab
14592f0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,7 +24,6 @@ import ( | |
"github.com/ethereum/go-ethereum/log" | ||
"github.com/ethereum/go-ethereum/metrics" | ||
"github.com/ethereum/go-ethereum/miner" | ||
"github.com/ethereum/go-ethereum/params" | ||
codes "google.golang.org/grpc/codes" | ||
status "google.golang.org/grpc/status" | ||
"google.golang.org/protobuf/types/known/timestamppb" | ||
|
@@ -45,11 +44,6 @@ type ExecutionServiceServerV1 struct { | |
|
||
genesisInfoCalled bool | ||
getCommitmentStateCalled bool | ||
|
||
bridgeAddresses map[string]*params.AstriaBridgeAddressConfig // astria bridge addess to config for that bridge account | ||
bridgeAllowedAssets map[string]struct{} // a set of allowed asset IDs structs are left empty | ||
|
||
nextFeeRecipient common.Address // Fee recipient for the next block | ||
} | ||
|
||
var ( | ||
|
@@ -81,74 +75,35 @@ func NewExecutionServiceServerV1(eth *eth.Ethereum) (*ExecutionServiceServerV1, | |
return nil, errors.New("rollup name not set") | ||
} | ||
|
||
if bc.Config().AstriaSequencerInitialHeight == 0 { | ||
fork := bc.Config().GetAstriaForks().GetForkAtHeight(max(bc.CurrentSafeBlock().Number.Uint64(), 1)) | ||
|
||
if fork.Sequencer.ChainID == "" { | ||
return nil, errors.New("sequencer chain ID not set") | ||
} | ||
|
||
if fork.Sequencer.StartHeight == 0 { | ||
return nil, errors.New("sequencer initial height not set") | ||
} | ||
|
||
if bc.Config().AstriaCelestiaInitialHeight == 0 { | ||
return nil, errors.New("celestia initial height not set") | ||
if fork.Celestia.ChainID == "" { | ||
return nil, errors.New("celestia chain ID not set") | ||
} | ||
|
||
if bc.Config().AstriaCelestiaHeightVariance == 0 { | ||
return nil, errors.New("celestia height variance not set") | ||
if fork.Celestia.StartHeight == 0 { | ||
return nil, errors.New("celestia initial height not set") | ||
} | ||
|
||
bridgeAddresses := make(map[string]*params.AstriaBridgeAddressConfig) | ||
bridgeAllowedAssets := make(map[string]struct{}) | ||
if bc.Config().AstriaBridgeAddressConfigs == nil { | ||
log.Warn("bridge addresses not set") | ||
} else { | ||
nativeBridgeSeen := false | ||
for _, cfg := range bc.Config().AstriaBridgeAddressConfigs { | ||
err := cfg.Validate(bc.Config().AstriaSequencerAddressPrefix) | ||
if err != nil { | ||
return nil, fmt.Errorf("invalid bridge address config: %w", err) | ||
} | ||
|
||
if cfg.Erc20Asset == nil { | ||
if nativeBridgeSeen { | ||
return nil, errors.New("only one native bridge address is allowed") | ||
} | ||
nativeBridgeSeen = true | ||
} | ||
|
||
if cfg.Erc20Asset != nil && cfg.SenderAddress == (common.Address{}) { | ||
return nil, errors.New("astria bridge sender address must be set for bridged ERC20 assets") | ||
} | ||
|
||
bridgeCfg := cfg | ||
bridgeAddresses[cfg.BridgeAddress] = &bridgeCfg | ||
bridgeAllowedAssets[cfg.AssetDenom] = struct{}{} | ||
if cfg.Erc20Asset == nil { | ||
log.Info("bridge for sequencer native asset initialized", "bridgeAddress", cfg.BridgeAddress, "assetDenom", cfg.AssetDenom) | ||
} else { | ||
log.Info("bridge for ERC20 asset initialized", "bridgeAddress", cfg.BridgeAddress, "assetDenom", cfg.AssetDenom, "contractAddress", cfg.Erc20Asset.ContractAddress) | ||
} | ||
} | ||
if fork.Celestia.HeightVariance == 0 { | ||
return nil, errors.New("celestia height variance not set") | ||
} | ||
|
||
// To decrease compute cost, we identify the next fee recipient at the start | ||
// and update it as we execute blocks. | ||
nextFeeRecipient := common.Address{} | ||
if bc.Config().AstriaFeeCollectors == nil { | ||
if fork.FeeCollector == (common.Address{}) { | ||
log.Warn("fee asset collectors not set, assets will be burned") | ||
} else { | ||
maxHeightCollectorMatch := uint32(0) | ||
nextBlock := uint32(bc.CurrentBlock().Number.Int64()) + 1 | ||
for height, collector := range bc.Config().AstriaFeeCollectors { | ||
if height <= nextBlock && height > maxHeightCollectorMatch { | ||
maxHeightCollectorMatch = height | ||
nextFeeRecipient = collector | ||
} | ||
} | ||
} | ||
|
||
return &ExecutionServiceServerV1{ | ||
eth: eth, | ||
bc: bc, | ||
bridgeAddresses: bridgeAddresses, | ||
bridgeAllowedAssets: bridgeAllowedAssets, | ||
nextFeeRecipient: nextFeeRecipient, | ||
eth: eth, | ||
bc: bc, | ||
}, nil | ||
} | ||
|
||
|
@@ -159,10 +114,18 @@ func (s *ExecutionServiceServerV1) GetGenesisInfo(ctx context.Context, req *astr | |
rollupHash := sha256.Sum256([]byte(s.bc.Config().AstriaRollupName)) | ||
rollupId := primitivev1.RollupId{Inner: rollupHash[:]} | ||
|
||
fork := s.bc.Config().GetAstriaForks().GetForkAtHeight(s.bc.CurrentSafeBlock().Number.Uint64() + 1) | ||
nextFork := s.bc.Config().GetAstriaForks().GetNextForkAtHeight(s.bc.CurrentSafeBlock().Number.Uint64() + 1) | ||
|
||
res := &astriaPb.GenesisInfo{ | ||
RollupId: &rollupId, | ||
SequencerGenesisBlockHeight: s.bc.Config().AstriaSequencerInitialHeight, | ||
CelestiaBlockVariance: s.bc.Config().AstriaCelestiaHeightVariance, | ||
RollupId: &rollupId, | ||
SequencerChainId: fork.Sequencer.ChainID, | ||
SequencerStartHeight: fork.Sequencer.StartHeight, | ||
CelestiaChainId: fork.Celestia.ChainID, | ||
CelestiaBlockVariance: fork.Celestia.HeightVariance, | ||
RollupStartBlockNumber: fork.Height, | ||
RollupStopBlockNumber: fork.StopHeight, | ||
HaltAtRollupStopNumber: nextFork != nil && nextFork.Halt, | ||
} | ||
|
||
log.Info("GetGenesisInfo completed", "response", res) | ||
|
@@ -242,6 +205,7 @@ func (s *ExecutionServiceServerV1) ExecuteBlock(ctx context.Context, req *astria | |
|
||
s.blockExecutionLock.Lock() | ||
defer s.blockExecutionLock.Unlock() | ||
|
||
// Deliberately called after lock, to more directly measure the time spent executing | ||
executionStart := time.Now() | ||
defer executeBlockTimer.UpdateSince(executionStart) | ||
|
@@ -250,19 +214,26 @@ func (s *ExecutionServiceServerV1) ExecuteBlock(ctx context.Context, req *astria | |
return nil, status.Error(codes.PermissionDenied, "Cannot execute block until GetGenesisInfo && GetCommitmentState methods are called") | ||
} | ||
|
||
// the height that this block will be at | ||
height := s.bc.CurrentBlock().Number.Uint64() + 1 | ||
|
||
fork := s.bc.Config().GetAstriaForks().GetForkAtHeight(height) | ||
|
||
// this fork halts the chain | ||
if fork.Halt { | ||
return nil, status.Error(codes.FailedPrecondition, "Block cannot be created at halted fork") | ||
} | ||
Comment on lines
+222
to
+225
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. how does the chain un-halt? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. manual intervention There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could you link the doc for this? i'm unclear from the code as to how unhalting would work There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes need to get some docs on this but basically the way it would work, such as the case of a sequencer network change, is you would pick some future height to halt at, update genesis to create a new named fork at that future height with |
||
|
||
// Validate block being created has valid previous hash | ||
prevHeadHash := common.BytesToHash(req.PrevBlockHash) | ||
softHash := s.bc.CurrentSafeBlock().Hash() | ||
if prevHeadHash != softHash { | ||
return nil, status.Error(codes.FailedPrecondition, "Block can only be created on top of soft block.") | ||
} | ||
|
||
// the height that this block will be at | ||
height := s.bc.CurrentBlock().Number.Uint64() + 1 | ||
|
||
txsToProcess := types.Transactions{} | ||
for _, tx := range req.Transactions { | ||
unmarshalledTx, err := validateAndUnmarshalSequencerTx(height, tx, s.bridgeAddresses, s.bridgeAllowedAssets) | ||
unmarshalledTx, err := validateAndUnmarshalSequencerTx(height, tx, fork.BridgeAddresses, fork.BridgeAllowedAssets) | ||
if err != nil { | ||
log.Debug("failed to validate sequencer tx, ignoring", "tx", tx, "err", err) | ||
continue | ||
|
@@ -274,12 +245,15 @@ func (s *ExecutionServiceServerV1) ExecuteBlock(ctx context.Context, req *astria | |
// the Miner when building a payload. | ||
s.eth.TxPool().SetAstriaOrdered(txsToProcess) | ||
|
||
// set extra data | ||
s.eth.Miner().SetExtra(s.bc.Config().AstriaExtraData(height)) | ||
|
||
// Build a payload to add to the chain | ||
payloadAttributes := &miner.BuildPayloadArgs{ | ||
Parent: prevHeadHash, | ||
Timestamp: uint64(req.GetTimestamp().GetSeconds()), | ||
Random: common.Hash{}, | ||
FeeRecipient: s.nextFeeRecipient, | ||
FeeRecipient: s.bc.Config().GetAstriaForks().GetForkAtHeight(height).FeeCollector, | ||
} | ||
payload, err := s.eth.Miner().BuildPayload(payloadAttributes) | ||
if err != nil { | ||
|
@@ -312,10 +286,6 @@ func (s *ExecutionServiceServerV1) ExecuteBlock(ctx context.Context, req *astria | |
}, | ||
} | ||
|
||
if next, ok := s.bc.Config().AstriaFeeCollectors[res.Number+1]; ok { | ||
s.nextFeeRecipient = next | ||
} | ||
|
||
log.Info("ExecuteBlock completed", "block_num", res.Number, "timestamp", res.Timestamp) | ||
totalExecutedTxCount.Inc(int64(len(block.Transactions()))) | ||
executeBlockSuccessCount.Inc(1) | ||
|
@@ -340,10 +310,12 @@ func (s *ExecutionServiceServerV1) GetCommitmentState(ctx context.Context, req * | |
|
||
celestiaBlock := s.bc.CurrentBaseCelestiaHeight() | ||
|
||
fork := s.bc.Config().GetAstriaForks().GetForkAtHeight(uint64(softBlock.Number)) | ||
|
||
res := &astriaPb.CommitmentState{ | ||
Soft: softBlock, | ||
Firm: firmBlock, | ||
BaseCelestiaHeight: celestiaBlock, | ||
BaseCelestiaHeight: max(celestiaBlock, fork.Celestia.StartHeight), | ||
} | ||
|
||
log.Info("GetCommitmentState completed", "soft_height", res.Soft.Number, "firm_height", res.Firm.Number, "base_celestia_height", res.BaseCelestiaHeight) | ||
|
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.
is this just used for genesis validation?
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 is a
justfile
in thedev
directory too which is used in our tutorials on running a local rollup. These are the default values needed if you follow the tutorial.