Skip to content

Commit

Permalink
fixes #21: use merkelize in getRootHash (#24)
Browse files Browse the repository at this point in the history
* use merkle tree for root hash

* other fixes

* chore: changes

---------

Co-authored-by: Aashutosh Rathi <[email protected]>
  • Loading branch information
eshaan7 and aashutoshrathi authored Aug 3, 2024
1 parent 8108f5c commit 0cde2dc
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 31 deletions.
16 changes: 8 additions & 8 deletions rollup/stackr/machine.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { State, StateMachine } from "@stackr/sdk/machine";
import { solidityPackedKeccak256 } from "ethers";
import { merklize } from "@stackr/sdk";
import { solidityPacked } from "ethers";
import genesisState from "../genesis-state.json";
import { transitions } from "./transitions";

Expand All @@ -24,14 +25,13 @@ export class AppState extends State<RawState, WrappedState> {
transformer() {
return {
wrap: () => {
const games = this.state.games.reduce((acc, game) => {
const games = this.state.games.reduce<WrappedState['games']>((acc, game) => {
const { id, ...rest } = game;
acc[id] = { ...rest };
return acc;
}, {});
return { games };
},

unwrap: (wrappedState: WrappedState) => {
const games = Object.keys(wrappedState.games).map((id) => ({
id,
Expand All @@ -43,12 +43,12 @@ export class AppState extends State<RawState, WrappedState> {
};
}

// TODO: change this to MerkleTree
getRootHash() {
return solidityPackedKeccak256(
["string"],
[JSON.stringify(this.state.games)]
getRootHash(): string {
const leaves = this.state.games.map(
({ id, player, score }) =>
solidityPacked(["string", "address", "uint256"], [id, player, score])
);
return merklize(leaves);
}
}

Expand Down
40 changes: 17 additions & 23 deletions rollup/stackr/transitions.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
import { STF, Transitions } from "@stackr/sdk/machine";
import { REQUIRE, STF, Transitions } from "@stackr/sdk/machine";
import { hashMessage } from "ethers";
import { ACTIONS, GameMode } from "../../client/game/gameMode";
import { World } from "../../client/game/world";
import { AppState } from "./machine";

export type CreateGame = {
export type StartGameInput = {
timestamp: number;
};

export type ValidateGameInput = {
gameId: number;
export type EndGameInput = {
gameId: string;
timestamp: number;
score: number;
gameInputs: string;
};

const startGame: STF<AppState, ValidateGameInput> = {
const startGame: STF<AppState, StartGameInput> = {
handler: ({ state, msgSender, block, emit }) => {
const gameId = hashMessage(
`${msgSender}::${block.timestamp}::${Object.keys(state.games).length}`
);

state.games[gameId] = {
id: gameId,
score: 0,
player: msgSender,
player: String(msgSender),
};

emit({
Expand All @@ -34,22 +34,15 @@ const startGame: STF<AppState, ValidateGameInput> = {
},
};

const endGame: STF<AppState, ValidateGameInput> = {
const endGame: STF<AppState, EndGameInput> = {
handler: ({ state, inputs, msgSender }) => {
const { gameInputs, gameId, score } = inputs;
const { games } = state;
if (!games[gameId]) {
throw new Error("Game not found");
}

if (games[gameId].score > 0) {
throw new Error("Game already ended");
}

if (games[gameId].player !== msgSender) {
throw new Error("Unauthorized to end game");
}

// validation checks
REQUIRE(!!games[gameId], "GAME_NOT_FOUND");
REQUIRE(games[gameId].score === 0, "GAME_ALREADY_ENDED");
REQUIRE(games[gameId].player === String(msgSender), "UNAUTHORIZED");
// rerun game loop
const world = new World();
const gameMode = new GameMode(world, { gameId });
const ticks = gameInputs
Expand All @@ -60,9 +53,10 @@ const endGame: STF<AppState, ValidateGameInput> = {
gameMode.deserializeAndUpdate(1 / 60, ticks[i]);
}

if (world.score !== score) {
throw new Error(`Failed to replay: ${world.score} !== ${score}`);
}
REQUIRE(
world.score === score,
`FAILED_TO_REPLAY: ${world.score} !== ${score}`
);

games[gameId].score = score;

Expand Down

0 comments on commit 0cde2dc

Please sign in to comment.