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

Add justification to batches, progress on validation pipeline #13

Merged
merged 20 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions arbos/arbostypes/incomingmessage.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/ethereum/go-ethereum/params"

"github.com/offchainlabs/nitro/arbos/util"
"github.com/offchainlabs/nitro/espresso"
"github.com/offchainlabs/nitro/util/arbmath"
)

Expand All @@ -34,13 +35,19 @@ const (

const MaxL2MessageSize = 256 * 1024

type EspressoBlockJustification struct {
Header espresso.Header
Proof espresso.NmtProof
}

type L1IncomingMessageHeader struct {
Kind uint8 `json:"kind"`
Poster common.Address `json:"sender"`
BlockNumber uint64 `json:"blockNumber"`
Timestamp uint64 `json:"timestamp"`
RequestId *common.Hash `json:"requestId" rlp:"nilList"`
L1BaseFee *big.Int `json:"baseFeeL1"`
Kind uint8 `json:"kind"`
Poster common.Address `json:"sender"`
BlockNumber uint64 `json:"blockNumber"`
Timestamp uint64 `json:"timestamp"`
RequestId *common.Hash `json:"requestId" rlp:"nilList"`
L1BaseFee *big.Int `json:"baseFeeL1"`
BlockJustification *EspressoBlockJustification
}

func (h L1IncomingMessageHeader) SeqNum() (uint64, error) {
Expand Down Expand Up @@ -228,6 +235,7 @@ func ParseIncomingL1Message(rd io.Reader, batchFetcher FallibleBatchFetcher) (*L
timestamp,
&requestId,
baseFeeL1.Big(),
nil,
},
data,
nil,
Expand Down
21 changes: 20 additions & 1 deletion arbos/block_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"github.com/offchainlabs/nitro/arbos/arbostypes"
"github.com/offchainlabs/nitro/arbos/l2pricing"
"github.com/offchainlabs/nitro/arbos/util"
"github.com/offchainlabs/nitro/espresso"
"github.com/offchainlabs/nitro/solgen/go/precompilesgen"
"github.com/offchainlabs/nitro/util/arbmath"

Expand Down Expand Up @@ -129,6 +130,7 @@
message *arbostypes.L1IncomingMessage,
delayedMessagesRead uint64,
lastBlockHeader *types.Header,
lastHotShotHeader *espresso.Header,
statedb *state.StateDB,
chainContext core.ChainContext,
chainConfig *params.ChainConfig,
Expand Down Expand Up @@ -158,7 +160,7 @@

hooks := NoopSequencingHooks()
return ProduceBlockAdvanced(
message.Header, txes, delayedMessagesRead, lastBlockHeader, statedb, chainContext, chainConfig, hooks,
message.Header, txes, delayedMessagesRead, lastBlockHeader, lastHotShotHeader, statedb, chainContext, chainConfig, hooks,
)
}

Expand All @@ -168,6 +170,7 @@
txes types.Transactions,
delayedMessagesRead uint64,
lastBlockHeader *types.Header,
lastHotShotHeader *espresso.Header,
nomaxg marked this conversation as resolved.
Show resolved Hide resolved
statedb *state.StateDB,
chainContext core.ChainContext,
chainConfig *params.ChainConfig,
Expand All @@ -191,6 +194,22 @@
l1Timestamp: l1Header.Timestamp,
}

// Espresso-specific validation
if chainConfig.Espresso {

Check failure on line 198 in arbos/block_processor.go

View workflow job for this annotation

GitHub Actions / Go Tests (defaults)

chainConfig.Espresso undefined (type *params.ChainConfig has no field or method Espresso)

Check failure on line 198 in arbos/block_processor.go

View workflow job for this annotation

GitHub Actions / Go Tests (race)

chainConfig.Espresso undefined (type *params.ChainConfig has no field or method Espresso)

Check failure on line 198 in arbos/block_processor.go

View workflow job for this annotation

GitHub Actions / Go Tests (challenge)

chainConfig.Espresso undefined (type *params.ChainConfig has no field or method Espresso)
sveitser marked this conversation as resolved.
Show resolved Hide resolved
hotshotHeader := l1Header.BlockJustification.Header
if lastHotShotHeader != &hotshotHeader {
return nil, nil, errors.New("invalid hotshot header")
}
var roots = []*espresso.NmtRoot{&hotshotHeader.TransactionsRoot}
var proofs = []*espresso.NmtProof{&l1Header.BlockJustification.Proof}
var txs []espresso.Bytes
// TOOD: convert txes
err := espresso.ValidateBatchTransactions(chainConfig.ChainID.Uint64(), roots, proofs, txs)
if err != nil {
return nil, nil, errors.New("failed to validate namespace proof)")
}
}

header := createNewHeader(lastBlockHeader, l1Info, state, chainConfig)
signer := types.MakeSigner(chainConfig, header.Number, header.Time)
// Note: blockGasLeft will diverge from the actual gas left during execution in the event of invalid txs,
Expand Down
18 changes: 17 additions & 1 deletion cmd/replay/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/offchainlabs/nitro/arbutil"
"github.com/offchainlabs/nitro/cmd/chaininfo"
"github.com/offchainlabs/nitro/das/dastree"
"github.com/offchainlabs/nitro/espresso"
"github.com/offchainlabs/nitro/gethhook"
"github.com/offchainlabs/nitro/wavmio"
)
Expand All @@ -46,6 +47,19 @@ func getBlockHeaderByHash(hash common.Hash) *types.Header {
return header
}

func getHotShotHeaderByHash(hash common.Hash) *espresso.Header {
nomaxg marked this conversation as resolved.
Show resolved Hide resolved
enc, err := wavmio.ResolveTypedPreimage(arbutil.Keccak256PreimageType, hash)
if err != nil {
return nil
}
var header &espresso.Header
if err := json.Unmarshal(header, &enc); err != nil {
nomaxg marked this conversation as resolved.
Show resolved Hide resolved
panic(fmt.Errorf("Error deserializing espresso header preimage"))
}

return header
}

type WavmChainContext struct{}

func (c WavmChainContext) Engine() consensus.Engine {
Expand Down Expand Up @@ -152,6 +166,8 @@ func main() {
db := state.NewDatabase(raw)

lastBlockHash := wavmio.GetLastBlockHash()
lastHotShotHeaderHash := wavmio.GetLastHotShotHeaderHash()
lastHotShotHeader := getHotShotHeaderByHash(lastHotShotHeaderHash)
nomaxg marked this conversation as resolved.
Show resolved Hide resolved

var lastBlockHeader *types.Header
var lastBlockStateRoot common.Hash
Expand Down Expand Up @@ -238,7 +254,7 @@ func main() {
batchFetcher := func(batchNum uint64) ([]byte, error) {
return wavmio.ReadInboxMessage(batchNum), nil
}
newBlock, _, err = arbos.ProduceBlock(message.Message, message.DelayedMessagesRead, lastBlockHeader, statedb, chainContext, chainConfig, batchFetcher)
newBlock, _, err = arbos.ProduceBlock(message.Message, message.DelayedMessagesRead, lastBlockHeader, lastHotShotHeader, statedb, chainContext, chainConfig, batchFetcher)
if err != nil {
panic(err)
}
Expand Down
1 change: 1 addition & 0 deletions execution/gethexec/block_recorder.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ func (r *BlockRecorder) RecordBlockCreation(
msg.Message,
msg.DelayedMessagesRead,
prevHeader,
nil,
recordingdb,
chaincontext,
chainConfig,
Expand Down
5 changes: 4 additions & 1 deletion execution/gethexec/espresso_sequencer.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,10 @@ func (s *EspressoSequencer) createBlock(ctx context.Context) (returnValue bool)
Timestamp: header.Timestamp,
RequestId: nil,
L1BaseFee: nil,
// TODO: add justification https://github.com/EspressoSystems/espresso-sequencer/issues/733
BlockJustification: &arbostypes.EspressoBlockJustification{
Header: header,
Proof: arbTxns.Proof,
},
}

hooks := s.makeSequencingHooks()
Expand Down
2 changes: 2 additions & 0 deletions execution/gethexec/executionengine.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ func (s *ExecutionEngine) sequenceTransactionsWithBlockMutex(header *arbostypes.
txes,
delayedMessagesRead,
lastBlockHeader,
&header.BlockJustification.Header,
statedb,
s.bc,
s.bc.Config(),
Expand Down Expand Up @@ -446,6 +447,7 @@ func (s *ExecutionEngine) createBlockFromNextMessage(msg *arbostypes.MessageWith
msg.Message,
msg.DelayedMessagesRead,
currentHeader,
&msg.Message.Header.BlockJustification.Header,
statedb,
s.bc,
s.bc.Config(),
Expand Down
3 changes: 3 additions & 0 deletions staker/block_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ type BlockValidatorConfig struct {
PendingUpgradeModuleRoot string `koanf:"pending-upgrade-module-root"` // TODO(magic) requires StatelessBlockValidator recreation on hot reload
FailureIsFatal bool `koanf:"failure-is-fatal" reload:"hot"`
Dangerous BlockValidatorDangerousConfig `koanf:"dangerous"`
// Espresso specific flags
Espresso bool `koanf:"espresso"`
}

func (c *BlockValidatorConfig) Validate() error {
Expand All @@ -107,6 +109,7 @@ func BlockValidatorConfigAddOptions(prefix string, f *flag.FlagSet) {
f.String(prefix+".current-module-root", DefaultBlockValidatorConfig.CurrentModuleRoot, "current wasm module root ('current' read from chain, 'latest' from machines/latest dir, or provide hash)")
f.String(prefix+".pending-upgrade-module-root", DefaultBlockValidatorConfig.PendingUpgradeModuleRoot, "pending upgrade wasm module root to additionally validate (hash, 'latest' or empty)")
f.Bool(prefix+".failure-is-fatal", DefaultBlockValidatorConfig.FailureIsFatal, "failing a validation is treated as a fatal error")
f.Bool(prefix+".espresso", DefaultBlockValidatorConfig.Espresso, "if true, hotshot header preimages will be added to validation entries to verify that transactions have been sequenced by espresso")
BlockValidatorDangerousConfigAddOptions(prefix+".dangerous", f)
}

Expand Down
10 changes: 10 additions & 0 deletions staker/stateless_block_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"sync"
"testing"

"github.com/offchainlabs/nitro/espresso"
"github.com/offchainlabs/nitro/execution"
"github.com/offchainlabs/nitro/util/rpcclient"
"github.com/offchainlabs/nitro/validator/server_api"
Expand Down Expand Up @@ -69,6 +70,7 @@ type TransactionStreamerInterface interface {

type InboxReaderInterface interface {
GetSequencerMessageBytes(ctx context.Context, seqNum uint64) ([]byte, error)
FetchHotShotCommitment(blockHeight uint64) (espresso.Commitment, error)
nomaxg marked this conversation as resolved.
Show resolved Hide resolved
}

type L1ReaderInterface interface {
Expand Down Expand Up @@ -259,6 +261,7 @@ func (v *StatelessBlockValidator) GetModuleRootsToValidate() []common.Hash {
}

func (v *StatelessBlockValidator) ValidationEntryRecord(ctx context.Context, e *validationEntry) error {
usingEspresso := v.config.Espresso
if e.Stage != ReadyForRecord {
return fmt.Errorf("validation entry should be ReadyForRecord, is: %v", e.Stage)
}
Expand Down Expand Up @@ -305,6 +308,13 @@ func (v *StatelessBlockValidator) ValidationEntryRecord(ctx context.Context, e *
return err
}
}
if usingEspresso {
nomaxg marked this conversation as resolved.
Show resolved Hide resolved
_, err := v.inboxReader.FetchHotShotCommitment(batch.Number)
if err != nil {
return fmt.Errorf("failed to fetch hotshot commitment for batch number %d", batch.Number)
}
// TODO construct preimage here and add to validation entry
}
}

e.msg = nil // no longer needed
Expand Down
21 changes: 13 additions & 8 deletions wavmio/stub.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@ func (i *arrayFlags) Set(value string) error {
}

var (
seqMsg []byte
seqMsgPos uint64
posWithinMsg uint64
delayedMsgs [][]byte
delayedMsgFirstPos uint64
lastBlockHash common.Hash
preimages map[common.Hash][]byte
seqAdvanced uint64
seqMsg []byte
seqMsgPos uint64
posWithinMsg uint64
delayedMsgs [][]byte
delayedMsgFirstPos uint64
lastBlockHash common.Hash
lastHotShotHeaderHash common.Hash
preimages map[common.Hash][]byte
seqAdvanced uint64
)

func parsePreimageBytes(path string) {
Expand Down Expand Up @@ -117,6 +118,10 @@ func GetLastBlockHash() (hash common.Hash) {
return lastBlockHash
}

func GetLastHotShotHeaderHash() (hash common.Hash) {
return lastHotShotHeaderHash
}

func ReadInboxMessage(msgNum uint64) []byte {
if msgNum != seqMsgPos {
panic(fmt.Sprintf("trying to read bad msg %d", msgNum))
Expand Down
Loading