Skip to content

Commit

Permalink
Random cards generation
Browse files Browse the repository at this point in the history
  • Loading branch information
Kirill Taran committed Jul 15, 2019
1 parent 2e3760c commit d3ec1c7
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 21 deletions.
14 changes: 6 additions & 8 deletions node/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
# Blockchain Poker Node

After building, run `./heads-up.sh` for running two nodes, one for Alice and one for Bob.

You can check status of launched processes with `./status.sh`.

# Building

Install Rust:

```bash
Expand All @@ -21,11 +15,15 @@ Install required tools:
Build the WebAssembly binary:

```bash
./scripts/build.sh
./scripts/build.sh --release
```

Build all native code:

```bash
cargo build
cargo build --release
```

# Tests

You can run tests with `cargo test --all`
72 changes: 67 additions & 5 deletions node/runtime/src/cards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,80 @@ pub const CLUBS: Suit = 3;
pub const DIAMONDS: Suit = 4;
pub const SPADES: Suit = 1;

#[derive(PartialEq, Eq, Debug)]
pub struct Card {
pub nominal: Nominal,
pub suit: Nominal
pub suit: Suit
}

impl Card {
pub fn validate(&self) -> bool {
debug_assert!(self.nominal >= 1 && self.nominal <= 13);
debug_assert!(self.suit >= 1 && self.suit <= 4);

self.nominal >= 1 && self.nominal <= 13
&& self.suit >= 1 && self.suit <= 4
}
}

pub fn hearts(n: Nominal) -> Card {
Card { nominal: n, suit: HEARTS }
}

pub fn clubs(n: Nominal) -> Card {
Card { nominal: n, suit: CLUBS }
}

pub fn diamonds(n: Nominal) -> Card {
Card { nominal: n, suit: DIAMONDS }
}

pub fn spades(n: Nominal) -> Card {
Card { nominal: n, suit: SPADES }
}

pub fn encode(cards: &[Card]) -> Vec<u8> {
cards.iter()
.map(|c| {
debug_assert!(c.nominal >= 1 && c.nominal <= 13);
debug_assert!(c.suit >= 1 && c.suit <= 4);
vec![c.nominal, c.suit]
.map(|card| {
card.validate();
vec![card.nominal, card.suit]
})
.flatten()
.collect()
}

//a bit unfair random generation, see the test
pub fn from_random(bytes: &[u8]) -> Card {
let card = Card {
nominal: bytes[0] % 13 + 1,
suit: bytes[1] % 4 + 1,
};

card.validate();
card
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn generate_from_random() {
assert!(from_random(&[1, 0]) == spades(2));
assert!(from_random(&[14, 0]) == spades(2));
assert!(from_random(&[142, 6]) == clubs(K));

assert!(from_random(&[0, 7]) == diamonds(A));
assert!(from_random(&[247, 7]) == diamonds(A));
assert!(from_random(&[248, 7]) == diamonds(2));
assert!(from_random(&[255, 7]) == diamonds(9));
//this means that 10, J, Q, K are less frequent

assert!(from_random(&[255, 0]) == spades(9));
assert!(from_random(&[255, 252]) == spades(9));
assert!(from_random(&[255, 253]) == hearts(9));
assert!(from_random(&[255, 254]) == clubs(9));
assert!(from_random(&[255, 255]) == diamonds(9));
//for suits, it is fair
}
}
6 changes: 3 additions & 3 deletions node/runtime/src/naive_rsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ mod tests {
let exponent: U256 = U256::from_little_endian(privkey);
generic_crypter(data, pubkey, exponent)
.map(|mut bytes: Vec<u8>| {
let mut end = bytes.len() - 1;
while end >= 0 && bytes[end] == 0 {
let mut end = bytes.len() as isize - 1;
while end >= 0 && bytes[end as usize] == 0 {
end -= 1;
}
bytes.truncate(end + 1);
bytes.truncate((end + 1) as usize);
bytes
})
}
Expand Down
20 changes: 15 additions & 5 deletions node/runtime/src/poker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ use rstd::prelude::*;
use core::debug_assert;
use runtime_io;

use crate::cards::*;
use runtime_primitives::traits::Hash;
use parity_codec::Encode;

use crate::cards;
use crate::naive_rsa::*;

pub trait Trait: system::Trait + balances::Trait {
Expand Down Expand Up @@ -66,12 +69,19 @@ decl_module! {

runtime_io::print("Dealing cards for a player");

let card1 = Card { nominal: A, suit: SPADES };
let card2 = Card { nominal: 10, suit: CLUBS };
//this is fake random for my proof-of-concept
//in future, it has to be replaced with off-chain random generation
//also it probably can be workarounded with sendind a nonce from the player
let random_bytes: Vec<u8> = (<system::Module<T>>::random_seed(), &who, &key)
.using_encoded(<T as system::Trait>::Hashing::hash)
.using_encoded(|x| x.to_vec()); //32 bytes

let card1 = cards::from_random(&random_bytes[0..2]);
let card2 = cards::from_random(&random_bytes[2..4]);

let cards = encode(&vec![card1, card2][..]);
let cards = cards::encode(&vec![card1, card2][..]);

match encrypt(&cards[..],&key[..]) {
match encrypt(&cards[..], &key[..]) {
Ok(cards) => {
<HandCards<T>>::insert(who, cards);
Ok(())
Expand Down

0 comments on commit d3ec1c7

Please sign in to comment.