Skip to content

Commit

Permalink
Merge pull request #34 from astriaorg/bharath/ignore-allocation-befor…
Browse files Browse the repository at this point in the history
…e-first-auctioneer-address

feat: Trusted Auctioneer: ignore allocations before first auctioneer address is active
  • Loading branch information
bharath-123 authored Jan 14, 2025
2 parents 0e1b4a1 + 805e73c commit ff39ee3
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 34 deletions.
6 changes: 5 additions & 1 deletion grpc/execution/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func (s *ExecutionServiceServerV1) ExecuteBlock(ctx context.Context, req *astria

addressPrefix := s.Bc().Config().AstriaSequencerAddressPrefix

txsToProcess := shared.UnbundleRollupDataTransactions(req.Transactions, height, s.BridgeAddresses(), s.BridgeAllowedAssets(), prevHeadHash.Bytes(), s.AuctioneerAddress(), addressPrefix)
txsToProcess := shared.UnbundleRollupDataTransactions(req.Transactions, height, s.BridgeAddresses(), s.BridgeAllowedAssets(), prevHeadHash.Bytes(), s.AuctioneerAddress(), s.AuctioneerStartHeight(), addressPrefix)

// This set of ordered TXs on the TxPool is has been configured to be used by
// the Miner when building a payload.
Expand Down Expand Up @@ -448,3 +448,7 @@ func (s *ExecutionServiceServerV1) AuctioneerAddress() string {
func (s *ExecutionServiceServerV1) SetAuctioneerAddress(auctioneerAddress string) {
s.sharedServiceContainer.SetAuctioneerAddress(auctioneerAddress)
}

func (s *ExecutionServiceServerV1) AuctioneerStartHeight() uint64 {
return s.sharedServiceContainer.AuctioneerStartHeight()
}
22 changes: 13 additions & 9 deletions grpc/optimistic/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ func (o *OptimisticServiceV1Alpha1) ExecuteOptimisticBlock(ctx context.Context,

addressPrefix := o.Bc().Config().AstriaSequencerAddressPrefix

txsToProcess := shared.UnbundleRollupDataTransactions(req.Transactions, height, o.BridgeAddresses(), o.BridgeAllowedAssets(), softBlock.Hash().Bytes(), o.AuctioneerAddress(), addressPrefix)
txsToProcess := shared.UnbundleRollupDataTransactions(req.Transactions, height, o.BridgeAddresses(), o.BridgeAllowedAssets(), softBlock.Hash().Bytes(), o.AuctioneerAddress(), o.AuctioneerStartHeight(), addressPrefix)

// Build a payload to add to the chain
payloadAttributes := &miner.BuildPayloadArgs{
Expand Down Expand Up @@ -286,18 +286,22 @@ func (o *OptimisticServiceV1Alpha1) SetNextFeeRecipient(feeRecipient common.Addr
o.sharedServiceContainer.SetNextFeeRecipient(feeRecipient)
}

func (s *OptimisticServiceV1Alpha1) BridgeAddresses() map[string]*params.AstriaBridgeAddressConfig {
return s.sharedServiceContainer.BridgeAddresses()
func (o *OptimisticServiceV1Alpha1) BridgeAddresses() map[string]*params.AstriaBridgeAddressConfig {
return o.sharedServiceContainer.BridgeAddresses()
}

func (s *OptimisticServiceV1Alpha1) BridgeAllowedAssets() map[string]struct{} {
return s.sharedServiceContainer.BridgeAllowedAssets()
func (o *OptimisticServiceV1Alpha1) BridgeAllowedAssets() map[string]struct{} {
return o.sharedServiceContainer.BridgeAllowedAssets()
}

func (s *OptimisticServiceV1Alpha1) SyncMethodsCalled() bool {
return s.sharedServiceContainer.SyncMethodsCalled()
func (o *OptimisticServiceV1Alpha1) SyncMethodsCalled() bool {
return o.sharedServiceContainer.SyncMethodsCalled()
}

func (s *OptimisticServiceV1Alpha1) AuctioneerAddress() string {
return s.sharedServiceContainer.AuctioneerAddress()
func (o *OptimisticServiceV1Alpha1) AuctioneerAddress() string {
return o.sharedServiceContainer.AuctioneerAddress()
}

func (o *OptimisticServiceV1Alpha1) AuctioneerStartHeight() uint64 {
return o.sharedServiceContainer.AuctioneerStartHeight()
}
25 changes: 21 additions & 4 deletions grpc/shared/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ type SharedServiceContainer struct {

// auctioneer address is a bech32m address
auctioneerAddress atomic.Pointer[string]
// this is set to the height at which the first auctioneer address is activated.
// before `auctioneerStartHeight` any incoming `Allocations` will be ignored
auctioneerStartHeight uint64

nextFeeRecipient atomic.Pointer[common.Address] // Fee recipient for the next block
}
Expand Down Expand Up @@ -109,6 +112,7 @@ func NewSharedServiceContainer(eth *eth.Ethereum) (*SharedServiceContainer, erro
for height, address := range auctioneerAddressesBlockMap {
if height <= nextBlock && height > maxHeightCollectorMatch {
maxHeightCollectorMatch = height

if err := ValidateBech32mAddress(address, bc.Config().AstriaSequencerAddressPrefix); err != nil {
return nil, errors.Wrapf(err, "auctioneer address %s at height %d is invalid", address, height)
}
Expand All @@ -117,11 +121,20 @@ func NewSharedServiceContainer(eth *eth.Ethereum) (*SharedServiceContainer, erro
}
}

// the height at which the first auctioneer address is activated
auctioneerStartHeight := ^uint64(0)
for height := range auctioneerAddressesBlockMap {
if uint64(height) < auctioneerStartHeight {
auctioneerStartHeight = uint64(height)
}
}

sharedServiceContainer := &SharedServiceContainer{
eth: eth,
bc: bc,
bridgeAddresses: bridgeAddresses,
bridgeAllowedAssets: bridgeAllowedAssets,
eth: eth,
bc: bc,
bridgeAddresses: bridgeAddresses,
bridgeAllowedAssets: bridgeAllowedAssets,
auctioneerStartHeight: auctioneerStartHeight,
}

sharedServiceContainer.SetAuctioneerAddress(auctioneerAddress)
Expand Down Expand Up @@ -183,6 +196,10 @@ func (s *SharedServiceContainer) BridgeAllowedAssets() map[string]struct{} {
return s.bridgeAllowedAssets
}

func (s *SharedServiceContainer) AuctioneerStartHeight() uint64 {
return s.auctioneerStartHeight
}

func (s *SharedServiceContainer) AuctioneerAddress() string {
return *s.auctioneerAddress.Load()
}
Expand Down
38 changes: 21 additions & 17 deletions grpc/shared/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,15 +193,17 @@ func unmarshallAllocationTxs(allocation *auctionv1alpha1.Allocation, prevBlockHa

}

// `UnbundleRollupDataTransactions` takes in a list of rollup data transactions and returns a list of Ethereum transactions.
// TODO - this function has become too big. we should start breaking it down
// `UnbundleRollupDataTransactions` takes in a list of rollup data transactions and returns the corresponding
// list of Ethereum transactions. It also returns an allocation transaction if it finds one in the rollup data.
// The allocation transaction is placed at the beginning of the returned list of transactions.
func UnbundleRollupDataTransactions(txs []*sequencerblockv1.RollupData, height uint64, bridgeAddresses map[string]*params.AstriaBridgeAddressConfig,
bridgeAllowedAssets map[string]struct{}, prevBlockHash []byte, auctioneerBech32Address string, addressPrefix string) types.Transactions {
bridgeAllowedAssets map[string]struct{}, prevBlockHash []byte, auctioneerBech32Address string, auctioneerStartHeight uint64, addressPrefix string) types.Transactions {

processedTxs := types.Transactions{}
allocationTxs := types.Transactions{}
// we just return the allocation here and do not unmarshall the transactions in the bid if we find it

var allocation *auctionv1alpha1.Allocation

for _, tx := range txs {
if deposit := tx.GetDeposit(); deposit != nil {
depositTx, err := validateAndUnmarshalDepositTx(deposit, height, bridgeAddresses, bridgeAllowedAssets)
Expand All @@ -213,27 +215,29 @@ func UnbundleRollupDataTransactions(txs []*sequencerblockv1.RollupData, height u
processedTxs = append(processedTxs, depositTx)
} else {
sequenceData := tx.GetSequencedData()
// check if sequence data is of type Allocation
if allocation == nil {
// TODO - check if we can avoid a temp value
tempAllocation := &auctionv1alpha1.Allocation{}
err := proto.Unmarshal(sequenceData, tempAllocation)
if err == nil {
// check if sequence data is of type Allocation.
// we should expect only one valid allocation per block. duplicate allocations should be ignored.

tempAllocation := &auctionv1alpha1.Allocation{}
err := proto.Unmarshal(sequenceData, tempAllocation)
if err == nil {
if allocation != nil {
log.Debug("ignoring allocation tx as it is a duplicate", "height", height)
} else {
if height < auctioneerStartHeight {
log.Debug("ignoring allocation tx as it is before the auctioneer start height", "height", height, "auctioneerStartHeight", auctioneerStartHeight)
continue
}

unmarshalledAllocationTxs, err := unmarshallAllocationTxs(tempAllocation, prevBlockHash, auctioneerBech32Address, addressPrefix)
if err != nil {
log.Error("failed to unmarshall allocation transactions", "error", err)
continue
}

// we found the valid allocation, we should ignore all future allocations in this block
allocation = tempAllocation
allocationTxs = unmarshalledAllocationTxs
} else {
ethtx, err := validateAndUnmarshallSequenceAction(tx)
if err != nil {
log.Error("failed to unmarshall sequence action", "error", err)
continue
}
processedTxs = append(processedTxs, ethtx)
}
} else {
ethtx, err := validateAndUnmarshallSequenceAction(tx)
Expand Down
6 changes: 3 additions & 3 deletions grpc/shared/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ func TestUnbundleRollupData(t *testing.T) {

finalTxs := []*sequencerblockv1.RollupData{seqData1, seqData2, allocationSequenceData, depositTx}

txsToProcess := UnbundleRollupDataTransactions(finalTxs, 2, serviceV1Alpha1.BridgeAddresses(), serviceV1Alpha1.BridgeAllowedAssets(), prevRollupBlockHash, serviceV1Alpha1.AuctioneerAddress(), addressPrefix)
txsToProcess := UnbundleRollupDataTransactions(finalTxs, 2, serviceV1Alpha1.BridgeAddresses(), serviceV1Alpha1.BridgeAllowedAssets(), prevRollupBlockHash, serviceV1Alpha1.AuctioneerAddress(), serviceV1Alpha1.AuctioneerStartHeight(), addressPrefix)

require.Equal(t, txsToProcess.Len(), 6, "expected 6 txs to process")

Expand Down Expand Up @@ -589,7 +589,7 @@ func TestUnbundleRollupDataWithDuplicateAllocations(t *testing.T) {

finalTxs := []*sequencerblockv1.RollupData{seqData1, seqData2, allocationSequenceData, allocationSequenceData2, depositTx}

txsToProcess := UnbundleRollupDataTransactions(finalTxs, 2, serviceV1Alpha1.BridgeAddresses(), serviceV1Alpha1.BridgeAllowedAssets(), prevRollupBlockHash, serviceV1Alpha1.AuctioneerAddress(), addressPrefix)
txsToProcess := UnbundleRollupDataTransactions(finalTxs, 2, serviceV1Alpha1.BridgeAddresses(), serviceV1Alpha1.BridgeAllowedAssets(), prevRollupBlockHash, serviceV1Alpha1.AuctioneerAddress(), serviceV1Alpha1.AuctioneerStartHeight(), addressPrefix)

require.Equal(t, txsToProcess.Len(), 6, "expected 6 txs to process")

Expand Down Expand Up @@ -734,7 +734,7 @@ func TestUnbundleRollupDataWithDuplicateInvalidAllocations(t *testing.T) {

finalTxs := []*sequencerblockv1.RollupData{seqData1, seqData2, allocationSequenceData, invalidAllocationSequenceData, depositTx}

txsToProcess := UnbundleRollupDataTransactions(finalTxs, 2, serviceV1Alpha1.BridgeAddresses(), serviceV1Alpha1.BridgeAllowedAssets(), prevRollupBlockHash, serviceV1Alpha1.AuctioneerAddress(), addressPrefix)
txsToProcess := UnbundleRollupDataTransactions(finalTxs, 2, serviceV1Alpha1.BridgeAddresses(), serviceV1Alpha1.BridgeAllowedAssets(), prevRollupBlockHash, serviceV1Alpha1.AuctioneerAddress(), serviceV1Alpha1.AuctioneerStartHeight(), addressPrefix)

require.Equal(t, txsToProcess.Len(), 6, "expected 6 txs to process")

Expand Down

0 comments on commit ff39ee3

Please sign in to comment.