| 
 | 1 | +package arbnode  | 
 | 2 | + | 
 | 3 | +import (  | 
 | 4 | +	"context"  | 
 | 5 | +	"fmt"  | 
 | 6 | +	"math/big"  | 
 | 7 | + | 
 | 8 | +	"github.com/ethereum/go-ethereum/accounts/abi/bind"  | 
 | 9 | +	"github.com/ethereum/go-ethereum/ethclient"  | 
 | 10 | +	"github.com/ethereum/go-ethereum/log"  | 
 | 11 | + | 
 | 12 | +	"github.com/offchainlabs/nitro/arbutil"  | 
 | 13 | +	"github.com/offchainlabs/nitro/espressotee"  | 
 | 14 | +	"github.com/offchainlabs/nitro/solgen/go/espressogen"  | 
 | 15 | +)  | 
 | 16 | + | 
 | 17 | +// Reads state from external sources and resets the espresso streamer to start producing  | 
 | 18 | +// messages from hotshot based on the source of truth on the parent chain  | 
 | 19 | +func (b *BatchPoster) resetStreamerToParentChainOrConfigHotshotBlock(messageCount arbutil.MessageIndex, ctx context.Context) {  | 
 | 20 | +	hotshotBlock := b.fetchHotshotBlockFromLastCheckpoint(ctx)  | 
 | 21 | +	if hotshotBlock == 0 {  | 
 | 22 | +		// if there hasn't been a batch posted, or we encountered an error, start reading from the configured hotshot block number.  | 
 | 23 | +		hotshotBlock = b.config().HotShotBlock  | 
 | 24 | +	}  | 
 | 25 | +	b.espressoStreamer.Reset(uint64(messageCount), hotshotBlock)  | 
 | 26 | +}  | 
 | 27 | + | 
 | 28 | +// fetchHotshotBlockFromLastCheckpoint:  | 
 | 29 | +// This function uses the sequencer inbox bridgegen contract to filter for logs related to the TEESignatureVerified events  | 
 | 30 | +// If any of these events are encountered, it checks the log iterator for the data about this event.  | 
 | 31 | +// Return:  | 
 | 32 | +// returns the Hotshot height of the last event in the iterator returned from FilterTEESignatureVerified()  | 
 | 33 | +// representing the most recently emitted hotshotblock height. Any errors encountered will result in 0 being returned.  | 
 | 34 | +func (b *BatchPoster) fetchHotshotBlockFromLastCheckpoint(ctx context.Context) uint64 {  | 
 | 35 | +	pollingStep := b.config().EspressoEventPollingStep  | 
 | 36 | +	header, err := b.l1Reader.LastHeader(ctx)  | 
 | 37 | +	if err != nil {  | 
 | 38 | +		log.Error("Failed to fetch last header from parent chain", "err", err)  | 
 | 39 | +		return 0  | 
 | 40 | +	}  | 
 | 41 | + | 
 | 42 | +	var lastHotshotHeight uint64 = 0  | 
 | 43 | +	// Prevent unsigned integer underflow: in Go, subtracting a larger value  | 
 | 44 | +	// from a smaller uint64 will wrap around to a very large number.  | 
 | 45 | +	for i := header.Number.Uint64(); i >= b.config().HotShotFirstPostingBlock; i -= min(i, pollingStep) {  | 
 | 46 | +		start := i - min(i, pollingStep)  | 
 | 47 | +		if start < b.config().HotShotFirstPostingBlock {  | 
 | 48 | +			start = b.config().HotShotFirstPostingBlock  | 
 | 49 | +		}  | 
 | 50 | +		filterOpts := bind.FilterOpts{  | 
 | 51 | +			Start:   start,  | 
 | 52 | +			End:     &i,  | 
 | 53 | +			Context: ctx,  | 
 | 54 | +		}  | 
 | 55 | + | 
 | 56 | +		logIterator, err := b.seqInbox.FilterTEESignatureVerified(&filterOpts, []*big.Int{}, []*big.Int{})  | 
 | 57 | +		if err != nil {  | 
 | 58 | +			log.Error("Failed to obtain iterator for logs for block", "blockNumber", i, "err", err)  | 
 | 59 | +			continue  | 
 | 60 | +		}  | 
 | 61 | + | 
 | 62 | +		if logIterator == nil {  | 
 | 63 | +			continue  | 
 | 64 | +		}  | 
 | 65 | + | 
 | 66 | +		for logIterator.Next() {  | 
 | 67 | +			lastHotshotHeight = logIterator.Event.HotshotHeight.Uint64()  | 
 | 68 | +		}  | 
 | 69 | + | 
 | 70 | +		if lastHotshotHeight > 0 {  | 
 | 71 | +			return lastHotshotHeight  | 
 | 72 | +		}  | 
 | 73 | +	}  | 
 | 74 | + | 
 | 75 | +	log.Warn("No logs found for Hotshot block")  | 
 | 76 | +	return 0  | 
 | 77 | +}  | 
 | 78 | + | 
 | 79 | +func setupNitroVerifier(teeVerifier *espressogen.IEspressoTEEVerifier, l1Client *ethclient.Client) (espressotee.EspressoNitroTEEVerifierInterface, error) {  | 
 | 80 | +	// Setup nitro contract interface  | 
 | 81 | +	nitroAddr, err := teeVerifier.EspressoNitroTEEVerifier(&bind.CallOpts{})  | 
 | 82 | +	if err != nil {  | 
 | 83 | +		return nil, fmt.Errorf("failed to get nitro tee verifier address from caller: %w", err)  | 
 | 84 | +	}  | 
 | 85 | +	log.Info("successfully retrieved nitro contract verifier address", "address", nitroAddr)  | 
 | 86 | + | 
 | 87 | +	nitroVerifierBindings, err := espressogen.NewIEspressoNitroTEEVerifier(  | 
 | 88 | +		nitroAddr,  | 
 | 89 | +		l1Client)  | 
 | 90 | +	if err != nil {  | 
 | 91 | +		return nil, err  | 
 | 92 | +	}  | 
 | 93 | +	nitroVerifier := espressotee.NewEspressoNitroTEEVerifier(nitroVerifierBindings, l1Client, nitroAddr)  | 
 | 94 | +	return nitroVerifier, nil  | 
 | 95 | +}  | 
0 commit comments