Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dvush/81/new_deposits_exits_node…
Browse files Browse the repository at this point in the history
…' into tymurkhr/76/circuit_refactoring

# Conflicts:
#	js/franklin_lib/scripts/loadtest.ts
  • Loading branch information
TymurKhr committed Sep 19, 2019
2 parents 2c15cc0 + ef64aa8 commit 0b2b637
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 70 deletions.
6 changes: 6 additions & 0 deletions contracts/contracts/Bytes.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ library Bytes {
bts = toBytesFromBytes32(bytes32(uint(self) << 232), 3);
}

// Compies uint32 'self' into a new 'bytes memory'.
// Returns the newly created 'bytes memory'.
function toBytesFromUInt32(uint32 self) internal pure returns (bytes memory bts) {
bts = toBytesFromBytes32(bytes32(uint(self) << 224), 4);
}

// Compies uint128 'self' into a new 'bytes memory'.
// Returns the newly created 'bytes memory'.
function toBytesFromUInt128(uint128 self) internal pure returns (bytes memory bts) {
Expand Down
16 changes: 10 additions & 6 deletions contracts/contracts/Franklin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ contract Franklin {
uint8 constant SIGNATURE_LEN = 64;
// Public key length
uint8 constant PUBKEY_LEN = 32;
// Franklin nonce length
uint8 constant NONCE_LEN = 4;
// Fee coefficient for priority request transaction
uint256 constant FEE_COEFF = 4;
// Base gas cost for transaction
Expand All @@ -53,7 +55,7 @@ contract Franklin {
uint256 constant PARTIAL_EXIT_LENGTH = 6 * 8; // partial exit
uint256 constant CLOSE_ACCOUNT_LENGTH = 1 * 8; // close account
uint256 constant TRANSFER_LENGTH = 2 * 8; // transfer
uint256 constant FULL_EXIT_LENGTH = 14 * 8; // full exit
uint256 constant FULL_EXIT_LENGTH = 15 * 8; // full exit

// MARK: - EVENTS

Expand Down Expand Up @@ -433,7 +435,8 @@ contract Franklin {
function fullExit (
bytes calldata _pubKey,
address _token,
bytes calldata _signature
bytes calldata _signature,
uint32 _nonce
) external payable {
// Fee is:
// fee coeff * (base tx gas cost + remained gas) * gas price
Expand Down Expand Up @@ -467,6 +470,7 @@ contract Franklin {
bytes memory pubData = _pubKey; // franklin id
pubData = Bytes.concat(pubData, Bytes.toBytesFromAddress(msg.sender)); // eth address
pubData = Bytes.concat(pubData, Bytes.toBytesFromUInt16(tokenId)); // token id
pubData = Bytes.concat(pubData, Bytes.toBytesFromUInt32(_nonce)); // token id
pubData = Bytes.concat(pubData, _signature); // signature
addPriorityRequest(OpType.FullExit, fee, pubData);

Expand Down Expand Up @@ -677,9 +681,9 @@ contract Franklin {
}

if (_opType == uint8(OpType.FullExit)) {
bytes memory pubData = Bytes.slice(_publicData, opDataPointer, ACC_NUM_BYTES + ETH_ADDR_BYTES + TOKEN_BYTES + SIGNATURE_LEN + AMOUNT_BYTES);
bytes memory pubData = Bytes.slice(_publicData, opDataPointer, ACC_NUM_BYTES + PUBKEY_LEN + ETH_ADDR_BYTES + TOKEN_BYTES + NONCE_LEN + SIGNATURE_LEN + AMOUNT_BYTES);
require(
pubData.length == ACC_NUM_BYTES + ETH_ADDR_BYTES + TOKEN_BYTES + SIGNATURE_LEN + AMOUNT_BYTES,
pubData.length == ACC_NUM_BYTES + PUBKEY_LEN + ETH_ADDR_BYTES + TOKEN_BYTES + NONCE_LEN + SIGNATURE_LEN + AMOUNT_BYTES,
"fpp13"
); // fpp13 - wrong full exit length
onchainOps[_currentOnchainOp] = OnchainOperation(
Expand Down Expand Up @@ -760,8 +764,8 @@ contract Franklin {
priorityPubData = Bytes.slice(priorityRequests[_priorityRequestId].pubData, ETH_ADDR_BYTES, PUBKEY_HASH_LEN + AMOUNT_BYTES + TOKEN_BYTES);
onchainPubData = _onchainOp.pubData;
} else if (_onchainOp.opType == OpType.FullExit && priorityRequests[_priorityRequestId].opType == OpType.FullExit) {
priorityPubData = Bytes.slice(priorityRequests[_priorityRequestId].pubData, PUBKEY_LEN, ETH_ADDR_BYTES + TOKEN_BYTES + SIGNATURE_LEN);
onchainPubData = Bytes.slice(_onchainOp.pubData, ACC_NUM_BYTES, ETH_ADDR_BYTES + TOKEN_BYTES + SIGNATURE_LEN);
priorityPubData = Bytes.slice(priorityRequests[_priorityRequestId].pubData, 0, PUBKEY_LEN + ETH_ADDR_BYTES + TOKEN_BYTES + NONCE_LEN + SIGNATURE_LEN);
onchainPubData = Bytes.slice(_onchainOp.pubData, ACC_NUM_BYTES, PUBKEY_LEN + ETH_ADDR_BYTES + TOKEN_BYTES + NONCE_LEN + SIGNATURE_LEN);
} else {
revert("fid11"); // fid11 - wrong operation
}
Expand Down
2 changes: 0 additions & 2 deletions core/models/src/merkle_tree/parallel_smt.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
/// Sparse Merkle tree with batch updates
use super::hasher::Hasher;
use crate::primitives::GetBits;
use fnv::FnvHashMap;
use std::fmt::Debug;


fn select<T>(condition: bool, a: T, b: T) -> (T, T) {
if condition {
(a, b)
Expand Down
1 change: 0 additions & 1 deletion core/models/src/merkle_tree/sequential_smt.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/// Sparse Merkle tree with flexible hashing strategy
use super::hasher::Hasher;
use crate::primitives::GetBits;
use std::collections::HashMap;
Expand Down
4 changes: 3 additions & 1 deletion core/models/src/node/operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,18 @@ pub struct FullExitOp {
}

impl FullExitOp {
pub const CHUNKS: usize = 14;
pub const CHUNKS: usize = 15;
const OP_CODE: u8 = 0x06;

fn get_public_data(&self) -> Vec<u8> {
let mut data = Vec::new();
data.push(Self::OP_CODE); // opcode
let (account_id, amount) = self.account_data.clone().unwrap_or_default();
data.extend_from_slice(&account_id.to_be_bytes()[1..]);
data.extend_from_slice(&*self.priority_op.packed_pubkey);
data.extend_from_slice(self.priority_op.eth_address.as_bytes());
data.extend_from_slice(&self.priority_op.token.to_be_bytes());
data.extend_from_slice(&self.priority_op.nonce.to_be_bytes());
data.extend_from_slice(&*self.priority_op.signature_r);
data.extend_from_slice(&*self.priority_op.signature_s);
data.extend_from_slice(&big_decimal_to_u128(&amount).to_be_bytes());
Expand Down
14 changes: 11 additions & 3 deletions core/models/src/node/priority_ops.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::operations::{DepositOp, FullExitOp};
use super::tx::{PackedPublicKey, PackedSignature, TxSignature};
use super::Nonce;
use super::{AccountAddress, TokenId};
use crate::params::FR_ADDRESS_LEN;
use bigdecimal::BigDecimal;
Expand All @@ -24,6 +25,7 @@ pub struct FullExit {
pub packed_pubkey: Box<[u8; 32]>,
pub eth_address: Address,
pub token: TokenId,
pub nonce: Nonce,
pub signature_r: Box<[u8; 32]>,
pub signature_s: Box<[u8; 32]>,
}
Expand All @@ -36,6 +38,7 @@ impl FullExit {
out.extend_from_slice(self.packed_pubkey.as_ref());
out.extend_from_slice(&self.eth_address.as_bytes());
out.extend_from_slice(&self.token.to_be_bytes());
out.extend_from_slice(&self.nonce.to_be_bytes());
out
}

Expand Down Expand Up @@ -95,16 +98,21 @@ impl FranklinPriorityOp {
}))
}
FULLEXIT_OPTYPE_ID => {
ensure!(pub_data.len() == 32 + 20 + 2 + 64, "Pub data len mismatch");
ensure!(
pub_data.len() == 32 + 20 + 2 + 64 + 4,
"Pub data len mismatch"
);
let packed_pubkey = Box::new(pub_data[0..32].try_into().unwrap());
let eth_address = Address::from_slice(&pub_data[32..(32 + 20)]);
let token = u16::from_be_bytes(pub_data[52..(52 + 2)].try_into().unwrap());
let signature_r = Box::new(pub_data[54..(54 + 32)].try_into().unwrap());
let signature_s = Box::new(pub_data[86..(86 + 32)].try_into().unwrap());
let nonce = u32::from_be_bytes(pub_data[54..(54 + 4)].try_into().unwrap());
let signature_r = Box::new(pub_data[58..(58 + 32)].try_into().unwrap());
let signature_s = Box::new(pub_data[90..(90 + 32)].try_into().unwrap());
Ok(Self::FullExit(FullExit {
packed_pubkey,
eth_address,
token,
nonce,
signature_r,
signature_s,
}))
Expand Down
7 changes: 6 additions & 1 deletion core/plasma/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,17 +159,22 @@ impl PlasmaState {

let old_balance = account.get_balance(op.priority_op.token);
let old_nonce = account.nonce;
if old_nonce != op.priority_op.nonce {
return updates;
}
account.sub_balance(op.priority_op.token, &amount);
account.nonce += 1;
let new_balance = account.get_balance(op.priority_op.token);
assert_eq!(new_balance, BigDecimal::from(0));
let new_nonce = account.nonce;

self.insert_account(account_id, account);
updates.push((
account_id,
AccountUpdate::UpdateBalance {
balance_update: (op.priority_op.token, old_balance, new_balance),
old_nonce,
new_nonce: old_nonce,
new_nonce,
},
));

Expand Down
19 changes: 11 additions & 8 deletions core/storage/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ use std::env;
use diesel::sql_types::{BigInt, Nullable, Text, Timestamp};
sql_function!(coalesce, Coalesce, (x: Nullable<BigInt>, y: BigInt) -> BigInt);

use diesel::result::Error;
use itertools::Itertools;
use models::node::AccountAddress;

Expand Down Expand Up @@ -606,15 +607,17 @@ impl StorageProcessor {
}

pub fn get_block_operations(&self, block: BlockNumber) -> QueryResult<Vec<FranklinOp>> {
let executed_txs: Vec<_> = executed_transactions::table
.filter(executed_transactions::block_number.eq(i64::from(block)))
.load::<StoredExecutedTransaction>(self.conn())?;
Ok(executed_txs
let op = self
.load_stored_op_with_block_number(block, ActionType::COMMIT)
.ok_or_else(|| Error::NotFound)?;
let restored_operation = op.into_op(self)?;
Ok(restored_operation
.block
.block_transactions
.into_iter()
.filter_map(|exec_tx| {
exec_tx
.operation
.map(|op| serde_json::from_value(op).expect("stored op"))
.filter_map(|exec| match exec {
ExecutedOperations::PriorityOp(prior_op) => Some(prior_op.op),
ExecutedOperations::Tx(tx) => tx.op,
})
.collect())
}
Expand Down
96 changes: 52 additions & 44 deletions js/franklin_lib/abi/Franklin.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,32 @@
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_pubKey",
"type": "bytes"
},
{
"name": "_token",
"type": "address"
},
{
"name": "_signature",
"type": "bytes"
},
{
"name": "_nonce",
"type": "uint32"
}
],
"name": "fullExit",
"outputs": [],
"payable": true,
"stateMutability": "payable",
"type": "function"
},
{
"constant": true,
"inputs": [],
Expand Down Expand Up @@ -279,28 +305,6 @@
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_pubKey",
"type": "bytes"
},
{
"name": "_token",
"type": "address"
},
{
"name": "_signature",
"type": "bytes"
}
],
"name": "fullExit",
"outputs": [],
"payable": true,
"stateMutability": "payable",
"type": "function"
},
{
"constant": false,
"inputs": [
Expand Down Expand Up @@ -618,6 +622,32 @@
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_pubKey",
"type": "bytes"
},
{
"name": "_token",
"type": "address"
},
{
"name": "_signature",
"type": "bytes"
},
{
"name": "_nonce",
"type": "uint32"
}
],
"name": "fullExit",
"outputs": [],
"payable": true,
"stateMutability": "payable",
"type": "function"
},
{
"constant": true,
"inputs": [],
Expand Down Expand Up @@ -829,28 +859,6 @@
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_pubKey",
"type": "bytes"
},
{
"name": "_token",
"type": "address"
},
{
"name": "_signature",
"type": "bytes"
}
],
"name": "fullExit",
"outputs": [],
"payable": true,
"stateMutability": "payable",
"type": "function"
},
{
"constant": false,
"inputs": [
Expand Down
11 changes: 7 additions & 4 deletions js/franklin_lib/src/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ export interface CloseTx {
export interface FullExitReq {
token: number,
eth_address: String
nonce: number,
}

export class WalletKeys {
Expand Down Expand Up @@ -185,8 +186,9 @@ export class WalletKeys {
let eth_address = Buffer.from(op.eth_address.slice(2),"hex")
let token = Buffer.alloc(2);
token.writeUInt16BE(op.token,0);

let msg = Buffer.concat([type, packed_pubkey, eth_address, token]);
let nonce = Buffer.alloc(4);
nonce.writeUInt32BE(op.nonce, 0);
let msg = Buffer.concat([type, packed_pubkey, eth_address, token, nonce]);
return Buffer.from(musigPedersen(this.privateKey, msg).sign, "hex");
}
}
Expand Down Expand Up @@ -250,8 +252,9 @@ export class Wallet {

async emergencyWithdraw(token: Token) {
const franklinDeployedContract = new Contract(this.provider.contractAddress, franklinContractCode.interface, this.ethWallet);
let signature = this.walletKeys.signFullExit({token: token.id, eth_address: await this.ethWallet.getAddress()});
let tx = await franklinDeployedContract.fullExit(serializePointPacked(this.walletKeys.publicKey), token.address, signature,
let nonce = await this.getNonce();
let signature = this.walletKeys.signFullExit({token: token.id, eth_address: await this.ethWallet.getAddress(), nonce});
let tx = await franklinDeployedContract.fullExit(serializePointPacked(this.walletKeys.publicKey), token.address, signature, nonce,
{gasLimit: bigNumberify("500000"), value: parseEther("0.02")});
return tx.hash;
}
Expand Down

0 comments on commit 0b2b637

Please sign in to comment.