Commit b59b8710 authored by clabby's avatar clabby

Add error to `StateWitness::StateHash`

parent c04d3959
......@@ -330,12 +330,18 @@ func Run(ctx *cli.Context) error {
}
if proofAt(state) {
preStateHash := state.EncodeWitness().StateHash()
preStateHash, err := state.EncodeWitness().StateHash()
if err != nil {
return fmt.Errorf("failed to hash prestate witness: %w", err)
}
witness, err := stepFn(true)
if err != nil {
return fmt.Errorf("failed at proof-gen step %d (PC: %08x): %w", step, state.PC, err)
}
postStateHash := state.EncodeWitness().StateHash()
postStateHash, err := state.EncodeWitness().StateHash()
if err != nil {
return fmt.Errorf("failed to hash poststate witness: %w", err)
}
proof := &Proof{
Step: step,
Pre: preStateHash,
......
......@@ -30,7 +30,10 @@ func Witness(ctx *cli.Context) error {
return fmt.Errorf("invalid input state (%v): %w", input, err)
}
witness := state.EncodeWitness()
h := witness.StateHash()
h, err := witness.StateHash()
if err != nil {
return fmt.Errorf("failed to compute witness hash: %w", err)
}
if output != "" {
if err := os.WriteFile(output, witness, 0755); err != nil {
return fmt.Errorf("writing output to %v: %w", output, err)
......
......@@ -92,7 +92,8 @@ func (m *MIPSEVM) Step(t *testing.T, stepWitness *StepWitness) []byte {
require.Equal(t, 1, len(logs), "expecting a log with post-state")
evmPost := logs[0].Data
stateHash := StateWitness(evmPost).StateHash()
stateHash, err := StateWitness(evmPost).StateHash()
require.NoError(t, err, "state hash could not be computed")
require.Equal(t, stateHash, postHash, "logged state must be accurate")
m.env.StateDB.RevertToSnapshot(snap)
......
......@@ -2,12 +2,16 @@ package mipsevm
import (
"encoding/binary"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
)
// StateWitnessSize is the size of the state witness encoding in bytes.
var StateWitnessSize = 226
type State struct {
Memory *Memory `json:"memory"`
......@@ -75,18 +79,26 @@ const (
VMStatusUnfinished = 3
)
func (sw StateWitness) StateHash() common.Hash {
func (sw StateWitness) StateHash() (common.Hash, error) {
hash := crypto.Keccak256Hash(sw)
offset := 32*2 + 4*6
if len(sw) != 226 {
return common.Hash{}, fmt.Errorf("Invalid witness length. Got %d, expected at least 88", len(sw))
}
exitCode := sw[offset]
exited := sw[offset+1]
status := vmStatus(exited == 1, exitCode)
hash[0] = status
return hash
return hash, nil
}
func vmStatus(exited bool, exitCode uint8) uint8 {
if exited {
if !exited {
return VMStatusUnfinished
}
switch exitCode {
case 0:
return VMStatusValid
......@@ -95,7 +107,4 @@ func vmStatus(exited bool, exitCode uint8) uint8 {
default:
return VMStatusPanic
}
} else {
return VMStatusUnfinished
}
}
......@@ -128,7 +128,11 @@ func (p *CannonTraceProvider) AbsolutePreStateCommitment(ctx context.Context) (c
if err != nil {
return common.Hash{}, fmt.Errorf("cannot load absolute pre-state: %w", err)
}
return mipsevm.StateWitness(state).StateHash(), nil
hash, err := mipsevm.StateWitness(state).StateHash()
if err != nil {
return common.Hash{}, fmt.Errorf("cannot hash absolute pre-state: %w", err)
}
return hash, nil
}
// loadProof will attempt to load or generate the proof data at the specified index
......@@ -160,8 +164,12 @@ func (p *CannonTraceProvider) loadProof(ctx context.Context, i uint64) (*proofDa
// Extend the trace out to the full length using a no-op instruction that doesn't change any state
// No execution is done, so no proof-data or oracle values are required.
witness := state.EncodeWitness()
witnessHash, err := mipsevm.StateWitness(witness).StateHash()
if err != nil {
return nil, fmt.Errorf("cannot hash witness: %w", err)
}
proof := &proofData{
ClaimValue: witness.StateHash(),
ClaimValue: witnessHash,
StateData: hexutil.Bytes(witness),
ProofData: []byte{},
OracleKey: nil,
......@@ -188,5 +196,9 @@ func (p *CannonTraceProvider) loadProof(ctx context.Context, i uint64) (*proofDa
}
func (p *CannonTraceProvider) StateHash(ctx context.Context, state []byte) (common.Hash, error) {
return mipsevm.StateWitness(state).StateHash(), nil
hash, err := mipsevm.StateWitness(state).StateHash()
if err != nil {
return common.Hash{}, fmt.Errorf("cannot hash state: %w", err)
}
return hash, nil
}
......@@ -633,13 +633,7 @@ contract OneVsOne_Arena is FaultDisputeGame_Init {
/// @dev The challenger.
GamePlayer internal challenger;
function init(
GamePlayer _defender,
GamePlayer _challenger,
uint256 _finalTraceIndex
)
public
{
function init(GamePlayer _defender, GamePlayer _challenger, uint256 _finalTraceIndex) public {
Claim rootClaim = _defender.claimAt(_finalTraceIndex);
super.init(rootClaim, ABSOLUTE_PRESTATE_CLAIM);
defender = _defender;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment