Skip to content

Commit

Permalink
Reduces game entropy from 2 storage updates to 1
Browse files Browse the repository at this point in the history
* previously the entropy and last updated block were stored in two storage slots
* now entropy and last updated block are packed into single storage slot
* this reduces cost of rotating game entropy by ~50% which will be a common call
  • Loading branch information
loothero committed Sep 29, 2023
1 parent afbb47c commit 7af07c1
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 95 deletions.
2 changes: 1 addition & 1 deletion contracts/adventurer/src/bag.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl BagPacking of Packing<Bag> {
}
}

// TODO: add overflow pack protection
// Not used for bag
fn overflow_pack_protection(self: Bag) -> Bag {
self
}
Expand Down
55 changes: 55 additions & 0 deletions contracts/game/src/game/game_entropy.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use pack::{constants::pow, pack::{Packing, rshift_split}};

#[derive(Drop, Copy, Serde)]
struct GameEntropy {
entropy: u128,
last_updated: u64,
}

impl GameEntropyPacking of Packing<GameEntropy> {
fn pack(self: GameEntropy) -> felt252 {
(self.entropy.into()
+ self.last_updated.into() * pow::TWO_POW_128)
.try_into()
.expect('pack GameEntropy')
}

fn unpack(packed: felt252) -> GameEntropy {
let packed = packed.into();
let (packed, entropy) = rshift_split(packed, pow::TWO_POW_128);
let (_, last_updated) = rshift_split(packed, pow::TWO_POW_128);

GameEntropy {
entropy: entropy.try_into().unwrap(), last_updated: last_updated.try_into().unwrap(),
}
}
// Not used for game entropy
fn overflow_pack_protection(self: GameEntropy) -> GameEntropy {
self
}
}

// ---------------------------
// ---------- Tests ----------
// ---------------------------
#[cfg(test)]
mod tests {
use game::game::game_entropy::{GameEntropy, GameEntropyPacking};
use pack::{pack::{Packing}};

#[test]
#[available_gas(3000000)]
fn test_packing_and_unpacking_game_entropy() {
let game_entropy = GameEntropy { entropy: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, last_updated: 0xFFFFFFFFFFFFFFFF };
let unpacked: GameEntropy = Packing::unpack(game_entropy.pack());

assert(unpacked.entropy == game_entropy.entropy, 'wrong entropy max value');
assert(unpacked.last_updated == game_entropy.last_updated, 'wrong last_updated max value');

let game_entropy = GameEntropy { entropy: 0, last_updated: 0 };
let unpacked: GameEntropy = Packing::unpack(game_entropy.pack());

assert(unpacked.entropy == game_entropy.entropy, 'wrong entropy zero');
assert(unpacked.last_updated == game_entropy.last_updated, 'wrong last_updated zero');
}
}
3 changes: 2 additions & 1 deletion contracts/game/src/game/interfaces.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use survivor::{
bag::Bag, adventurer::{Adventurer, Stats}, adventurer_meta::AdventurerMetadata,
item_meta::{ItemSpecials, ItemSpecialsStorage}
};
use game::game::game_entropy::{GameEntropy};


#[starknet::interface]
Expand Down Expand Up @@ -109,5 +110,5 @@ trait IGame<TContractState> {
fn owner_of(self: @TContractState, adventurer_id: u256) -> ContractAddress;
fn get_dao_address(self: @TContractState) -> ContractAddress;
fn get_lords_address(self: @TContractState) -> ContractAddress;
fn get_entropy(self: @TContractState) -> u64;
fn get_game_entropy(self: @TContractState) -> GameEntropy;
}
1 change: 1 addition & 0 deletions contracts/game/src/game/lib.cairo
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod game;
mod constants;
mod interfaces;
mod game_entropy;
Loading

1 comment on commit 7af07c1

@vercel
Copy link

@vercel vercel bot commented on 7af07c1 Sep 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.