// Copyright 2022 The go-ethereum Authors // This file is part of the go-ethereum library. // // The go-ethereum library is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // The go-ethereum library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . package catalyst import ( "sync" "github.com/ethereum/go-ethereum/core/beacon" ) // maxTrackedPayloads is the maximum number of prepared payloads the execution // engine tracks before evicting old ones. Ideally we should only ever track the // latest one; but have a slight wiggle room for non-ideal conditions. const maxTrackedPayloads = 10 // payloadQueueItem represents an id->payload tuple to store until it's retrieved // or evicted. type payloadQueueItem struct { id beacon.PayloadID payload *beacon.ExecutableDataV1 } // payloadQueue tracks the latest handful of constructed payloads to be retrieved // by the beacon chain if block production is requested. type payloadQueue struct { payloads []*payloadQueueItem lock sync.RWMutex } // newPayloadQueue creates a pre-initialized queue with a fixed number of slots // all containing empty items. func newPayloadQueue() *payloadQueue { return &payloadQueue{ payloads: make([]*payloadQueueItem, maxTrackedPayloads), } } // put inserts a new payload into the queue at the given id. func (q *payloadQueue) put(id beacon.PayloadID, data *beacon.ExecutableDataV1) { q.lock.Lock() defer q.lock.Unlock() copy(q.payloads[1:], q.payloads) q.payloads[0] = &payloadQueueItem{ id: id, payload: data, } } // get retrieves a previously stored payload item or nil if it does not exist. func (q *payloadQueue) get(id beacon.PayloadID) *beacon.ExecutableDataV1 { q.lock.RLock() defer q.lock.RUnlock() for _, item := range q.payloads { if item == nil { return nil // no more items } if item.id == id { return item.payload } } return nil }