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

Remove the global state for HotShot height #210

Merged
merged 9 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
2 changes: 1 addition & 1 deletion .github/workflows/espresso-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:

steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
submodules: true

Expand Down
5 changes: 2 additions & 3 deletions arbitrator/jit/src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ pub struct WasmEnv {
/// Go's general runtime state
pub go_state: GoRuntimeState,
/// An ordered list of the 8-byte globals
pub small_globals: [u64; 3],
pub small_globals: [u64; 2],
/// An ordered list of the 32-byte globals
pub large_globals: [Bytes32; 2],
/// An oracle allowing the prover to reverse keccak256
Expand Down Expand Up @@ -288,7 +288,7 @@ impl WasmEnv {

let last_block_hash = parse_hex(&opts.last_block_hash, "--last-block-hash")?;
let last_send_root = parse_hex(&opts.last_send_root, "--last-send-root")?;
env.small_globals = [opts.inbox_position, opts.position_within_message, 0];
env.small_globals = [opts.inbox_position, opts.position_within_message];
env.large_globals = [last_block_hash, last_send_root];
Ok(env)
}
Expand Down Expand Up @@ -318,7 +318,6 @@ impl WasmEnv {
check!(socket::write_u8(writer, socket::SUCCESS));
check!(socket::write_u64(writer, self.small_globals[0]));
check!(socket::write_u64(writer, self.small_globals[1]));
check!(socket::write_u64(writer, self.small_globals[2]));
check!(socket::write_bytes32(writer, &self.large_globals[0]));
check!(socket::write_bytes32(writer, &self.large_globals[1]));
check!(socket::write_u64(writer, memory_used.bytes().0 as u64));
Expand Down
7 changes: 1 addition & 6 deletions arbitrator/jit/src/wavmio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,16 +298,11 @@ fn ready_hostio(env: &mut WasmEnv) -> MaybeEscape {
let position_within_message = socket::read_u64(stream)?;
let last_block_hash = socket::read_bytes32(stream)?;
let last_send_root = socket::read_bytes32(stream)?;
let validated_hotshot_height = socket::read_u64(stream)?;
let hotshot_comm = socket::read_bytes32(stream)?;
let block_height = socket::read_u64(stream)?;
let hotshot_liveness = socket::read_u8(stream)?;

env.small_globals = [
inbox_position,
position_within_message,
validated_hotshot_height,
];
env.small_globals = [inbox_position, position_within_message];
env.large_globals = [last_block_hash, last_send_root];
if hotshot_liveness > 0 {
// HotShot is up
Expand Down
2 changes: 1 addition & 1 deletion arbitrator/prover/src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ impl From<Function> for FunctionSerdeAll {
// uint64 - position_within_message
// uint64 - espresso hotshot height
pub const GLOBAL_STATE_BYTES32_NUM: usize = 2;
pub const GLOBAL_STATE_U64_NUM: usize = 3;
pub const GLOBAL_STATE_U64_NUM: usize = 2;

#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[repr(C)]
Expand Down
8 changes: 1 addition & 7 deletions arbitrator/prover/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,6 @@ struct Opts {
skip_until_host_io: bool,
#[structopt(long)]
max_steps: Option<u64>,
#[structopt(long, default_value = "0")]
hotshot_height: u64,
}

fn file_with_stub_header(path: &Path, headerlength: usize) -> Result<Vec<u8>> {
Expand Down Expand Up @@ -186,11 +184,7 @@ fn main() -> Result<()> {
let last_send_root = decode_hex_arg(&opts.last_send_root, "--last-send-root")?;

let global_state = GlobalState {
u64_vals: [
opts.inbox_position,
opts.position_within_message,
opts.hotshot_height,
],
u64_vals: [opts.inbox_position, opts.position_within_message],
bytes32_vals: [last_block_hash, last_send_root],
};

Expand Down
4 changes: 2 additions & 2 deletions cmd/replay/espresso_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"fmt"

"github.com/offchainlabs/nitro/arbos"
"github.com/offchainlabs/nitro/arbos/arbostypes"
"github.com/offchainlabs/nitro/wavmio"
Expand All @@ -21,10 +22,9 @@ import (
func handleEspressoPreConditions(message *arbostypes.MessageWithMetadata, isEnabled bool) (bool, func()) {
// calculate and cache all values needed to determine if the preconditions are met to enter the Espresso STF logic
isNonEspressoMessage := arbos.IsL2NonEspressoMsg(message.Message)
hotshotHeight := wavmio.GetEspressoHeight()

validatingEspressoLivenessFailure := isNonEspressoMessage && isEnabled
validatingEspressoHeightFailure := isNonEspressoMessage && hotshotHeight != 0
validatingEspressoHeightFailure := isNonEspressoMessage && isEnabled
sveitser marked this conversation as resolved.
Show resolved Hide resolved
validatingAgainstEspresso := arbos.IsEspressoMsg(message.Message) && isEnabled

if validatingEspressoLivenessFailure {
Expand Down
13 changes: 0 additions & 13 deletions cmd/replay/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,19 +300,6 @@ func main() {
hotshotHeader := jst.Header
height := hotshotHeader.Height

// Check the continuity of the hotshot block if we are not running the sovereign sequencer.
if !arbos.IsEspressoSovereignMsg(message.Message) {
validatedHeight := wavmio.GetEspressoHeight()
if validatedHeight == 0 {
// Validators can choose their own trusted starting point to start their validation.
// TODO: Check the starting point is greater than the first valid hotshot block number.
wavmio.SetEspressoHeight(height)
} else if validatedHeight+1 == height {
wavmio.SetEspressoHeight(height)
} else {
panic(fmt.Sprintf("invalid hotshot block height: %v, got: %v", height, validatedHeight+1))
}
}
if jst.BlockMerkleJustification == nil {
panic("block merkle justification missing")
}
Expand Down
12 changes: 4 additions & 8 deletions staker/block_challenge_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,10 @@ func (b *BlockChallengeBackend) FindGlobalStateFromMessageCount(count arbutil.Me
}

return validator.GoGlobalState{
BlockHash: res.BlockHash,
SendRoot: res.SendRoot,
Batch: batch,
PosInBatch: uint64(count - prevBatchMsgCount),
HotShotHeight: res.HotShotHeight,
BlockHash: res.BlockHash,
SendRoot: res.SendRoot,
Batch: batch,
PosInBatch: uint64(count - prevBatchMsgCount),
}, nil
}

Expand All @@ -156,9 +155,6 @@ func (b *BlockChallengeBackend) GetInfoAtStep(step uint64) (validator.GoGlobalSt
if err != nil {
return validator.GoGlobalState{}, 0, err
}
if b.EspressoDebugging(globalState.HotShotHeight) {
globalState.BlockHash = mockHash(globalState.HotShotHeight)
}
return globalState, StatusFinished, nil
}

Expand Down
14 changes: 6 additions & 8 deletions staker/block_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -571,9 +571,8 @@ func (v *BlockValidator) createNextValidationEntry(ctx context.Context) (bool, e
v.nextCreateBatchReread = false
}
endGS := validator.GoGlobalState{
BlockHash: endRes.BlockHash,
SendRoot: endRes.SendRoot,
HotShotHeight: endRes.HotShotHeight,
BlockHash: endRes.BlockHash,
SendRoot: endRes.SendRoot,
}
if pos+1 < v.nextCreateBatchMsgCount {
endGS.Batch = v.nextCreateStartGS.Batch
Expand Down Expand Up @@ -1188,11 +1187,10 @@ func (v *BlockValidator) checkLegacyValid() error {
return fmt.Errorf("legacy validated blockHash does not fit chain")
}
validGS := validator.GoGlobalState{
BlockHash: result.BlockHash,
SendRoot: result.SendRoot,
Batch: v.legacyValidInfo.AfterPosition.BatchNumber,
PosInBatch: v.legacyValidInfo.AfterPosition.PosInBatch,
HotShotHeight: result.HotShotHeight,
BlockHash: result.BlockHash,
SendRoot: result.SendRoot,
Batch: v.legacyValidInfo.AfterPosition.BatchNumber,
PosInBatch: v.legacyValidInfo.AfterPosition.PosInBatch,
}
err = v.writeLastValidated(validGS, nil)
if err == nil {
Expand Down
4 changes: 0 additions & 4 deletions staker/challenge_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -509,10 +509,6 @@ func (m *ChallengeManager) createExecutionBackend(ctx context.Context, step uint
if err != nil {
return fmt.Errorf("error getting execution challenge final state: %w", err)
}
if m.blockChallengeBackend.EspressoDebugging(computedState.HotShotHeight) {
computedState.BlockHash = mockHash(computedState.HotShotHeight)
computedStatus = expectedStatus
}
if expectedStatus != computedStatus {
return fmt.Errorf("after msg %v expected status %v but got %v", initialCount, expectedStatus, computedStatus)
}
Expand Down
12 changes: 0 additions & 12 deletions staker/l1_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,10 +265,6 @@ func (v *L1Validator) generateNodeAction(
}

caughtUp, startCount, err := GlobalStateToMsgCount(v.inboxTracker, v.txStreamer, startState.GlobalState)
if v.blockValidator != nil && v.blockValidator.EspressoDebugging(startState.GlobalState.HotShotHeight) {
caughtUp = true
err = nil
}
if err != nil {
return nil, false, fmt.Errorf("start state not in chain: %w", err)
}
Expand Down Expand Up @@ -427,10 +423,6 @@ func (v *L1Validator) generateNodeAction(
log.Error("Found incorrect assertion: Machine status not finished", "node", nd.NodeNum, "machineStatus", nd.Assertion.AfterState.MachineStatus)
continue
}
if v.blockValidator != nil && v.blockValidator.EspressoDebugging(afterGS.HotShotHeight) {
log.Error("Mocking wrong global state")
afterGS.BlockHash = mockHash(afterGS.HotShotHeight)
}
caughtUp, nodeMsgCount, err := GlobalStateToMsgCount(v.inboxTracker, v.txStreamer, afterGS)
if errors.Is(err, ErrGlobalStateNotInChain) {
wrongNodesExist = true
Expand All @@ -455,10 +447,6 @@ func (v *L1Validator) generateNodeAction(
}
}

if v.blockValidator != nil && v.blockValidator.EspressoDebugging(validatedGlobalState.HotShotHeight) {
validatedGlobalState.BlockHash = mockHash(validatedGlobalState.HotShotHeight)
}

if correctNode != nil || strategy == WatchtowerStrategy {
return correctNode, wrongNodesExist, nil
}
Expand Down
9 changes: 4 additions & 5 deletions staker/stateless_block_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,11 +335,10 @@ func (v *StatelessBlockValidator) ValidationEntryRecord(ctx context.Context, e *

func buildGlobalState(res execution.MessageResult, pos GlobalStatePosition) validator.GoGlobalState {
return validator.GoGlobalState{
BlockHash: res.BlockHash,
SendRoot: res.SendRoot,
Batch: pos.BatchNumber,
PosInBatch: pos.PosInBatch,
HotShotHeight: res.HotShotHeight,
BlockHash: res.BlockHash,
SendRoot: res.SendRoot,
Batch: pos.BatchNumber,
PosInBatch: pos.PosInBatch,
}
}

Expand Down
102 changes: 0 additions & 102 deletions system_tests/espresso_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@ import (
"encoding/json"
"fmt"
"math/big"
"os"
"os/exec"
"strings"
"testing"
"time"

lightclientmock "github.com/EspressoSystems/espresso-sequencer-go/light-client-mock"
espressoTypes "github.com/EspressoSystems/espresso-sequencer-go/types"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
Expand Down Expand Up @@ -515,106 +513,6 @@ func TestEspressoE2E(t *testing.T) {
return condition
})
Require(t, err)

// The following tests are very time-consuming and, given that the related code
// does not change often, it's not necessary to run them every time.
// Note: If you are modifying the smart contracts, staker-related code or doing overhaul,
// set the E2E_CHECK_STAKER env variable to any non-empty string to run the check.

checkStaker := os.Getenv("E2E_CHECK_STAKER")
if checkStaker == "" {
log.Info("Checking the escape hatch")
// Start to check the escape hatch
address := common.HexToAddress(lightClientAddress)

txOpts := builder.L1Info.GetDefaultTransactOpts("Faucet", ctx)
// Freeze the l1 height
err := lightclientmock.FreezeL1Height(t, builder.L1.Client, address, &txOpts)
Require(t, err)

err = waitForWith(t, ctx, 1*time.Minute, 1*time.Second, func() bool {
isLive, err := lightclientmock.IsHotShotLive(t, builder.L1.Client, address, uint64(delayThreshold))
if err != nil {
return false
}
return !isLive
})
Require(t, err)

// Wait for the switch to be totally finished
currMsg, err := node.ConsensusNode.TxStreamer.GetMessageCount()
Require(t, err)
var validatedMsg arbutil.MessageIndex
err = waitForWith(t, ctx, 6*time.Minute, 60*time.Second, func() bool {

validatedCnt := node.ConsensusNode.BlockValidator.Validated(t)
if validatedCnt >= currMsg {
validatedMsg = validatedCnt
return true
}
return false
})
Require(t, err)

err = checkTransferTxOnL2(t, ctx, l2Node, "User12", l2Info)
Require(t, err)
err = checkTransferTxOnL2(t, ctx, l2Node, "User13", l2Info)
Require(t, err)

err = waitForWith(t, ctx, 3*time.Minute, 20*time.Second, func() bool {
validated := node.ConsensusNode.BlockValidator.Validated(t)
return validated >= validatedMsg
})
Require(t, err)

// Unfreeze the l1 height
err = lightclientmock.UnfreezeL1Height(t, builder.L1.Client, address, &txOpts)
Require(t, err)

// Check if the validated count is increasing
err = waitForWith(t, ctx, 3*time.Minute, 20*time.Second, func() bool {
validated := node.ConsensusNode.BlockValidator.Validated(t)
return validated >= validatedMsg+10
})
Require(t, err)

return
}
err = waitForWith(
t,
ctx,
time.Minute*20,
time.Second*5,
func() bool {
log.Info("good staker acts", "step", i)
txA, err := goodStaker.Act(ctx)
if err != nil {
return false
}
if txA != nil {
_, err = builder.L1.EnsureTxSucceeded(txA)
Require(t, err)
}

log.Info("bad staker acts", "step", i)
txB, err := badStaker1.Act(ctx)
if txB != nil && err == nil {
_, err = builder.L1.EnsureTxSucceeded(txB)
Require(t, err)
} else if err != nil {
ok := strings.Contains(err.Error(), "ERROR_HOTSHOT_COMMITMENT")
if ok {
return true
} else {
fmt.Println(err.Error())
t.Fatal("unexpected err")
}
}
i += 1
return false

})
Require(t, err)
}

func checkTransferTxOnL2(
Expand Down
4 changes: 2 additions & 2 deletions system_tests/full_challenge_impl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,11 @@ func CreateChallenge(
[2]mocksgen.GlobalState{
{
Bytes32Vals: [2][32]byte{startGlobalState.BlockHash, startGlobalState.SendRoot},
U64Vals: [3]uint64{startGlobalState.Batch, startGlobalState.PosInBatch},
U64Vals: [2]uint64{startGlobalState.Batch, startGlobalState.PosInBatch},
},
{
Bytes32Vals: [2][32]byte{endGlobalState.BlockHash, endGlobalState.SendRoot},
U64Vals: [3]uint64{endGlobalState.Batch, endGlobalState.PosInBatch},
U64Vals: [2]uint64{endGlobalState.Batch, endGlobalState.PosInBatch},
},
},
numBlocks,
Expand Down
Loading
Loading