Skip to content

Commit

Permalink
partial refactor tests
Browse files Browse the repository at this point in the history
  • Loading branch information
StanislavBreadless committed Dec 3, 2021
1 parent 8f2d96a commit 469c775
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 109 deletions.
7 changes: 0 additions & 7 deletions core/bin/zksync_api/src/api_server/rpc_server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,14 +183,10 @@ async fn insert_ip(body: hyper::Body, ip: String) -> hyper::Result<Vec<u8>> {

if let Ok(s) = body_str {
let call: std::result::Result<jsonrpc_core::MethodCall, _> = serde_json::from_str(&s); //.map_err(|e| hyper::Error)

dbg!(s);

if let Ok(call) = call {
let new_call = get_call_with_ip_if_needed(call, ip);
let new_body_bytes = serde_json::to_string(&new_call);
if let Ok(s) = new_body_bytes {
dbg!(s.clone());
body_bytes = s.as_bytes().to_owned();
}
};
Expand All @@ -204,7 +200,6 @@ impl RequestMiddleware for IpInsertMiddleWare {
let (parts, body) = request.into_parts();
let cloudflare_sent_ip = "CF-Connecting-IP";

// DONT MERGE IF THE FOLLOWING IS STILL COMMENTED OUT
let remote_ip = match parts.headers.get(cloudflare_sent_ip) {
Some(ip) => ip.to_str(),
None => {
Expand All @@ -223,8 +218,6 @@ impl RequestMiddleware for IpInsertMiddleWare {
} else {
remote_ip.unwrap()
};
dbg!(remote_ip.clone());
//let remote_ip = "localhost";

let body_bytes = insert_ip(body, remote_ip.to_owned()).into_stream();
let body = hyper::Body::wrap_stream(body_bytes);
Expand Down
11 changes: 0 additions & 11 deletions core/bin/zksync_api/src/api_server/rpc_server/rpc_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,6 @@ impl RpcApp {
ip: Option<String>,
) -> Result<TxHash> {
let start = Instant::now();

if let Some(ip) = ip.clone() {
dbg!("IPPPPPPPPPPPPPPP");
dbg!(ip);
}

let is_subsidized_ip = self.should_subsidie_cpk(ip);

let result = self
Expand Down Expand Up @@ -255,7 +249,6 @@ impl RpcApp {
token: TokenLike,
ip: Option<String>,
) -> Result<Fee> {
dbg!(ip.clone());
let start = Instant::now();
let ticker = self.tx_sender.ticker_requests.clone();
let token_allowed = Self::token_allowed_for_fees(ticker.clone(), token.clone()).await?;
Expand All @@ -273,7 +266,6 @@ impl RpcApp {
.can_subsidize(result.subsidy_size_usd.clone())
.await
.map_err(SubmitError::Internal)?;
dbg!(can);

let fee = if is_subsidized_ip
&& result.subsidized_fee.total_fee < result.normal_fee.total_fee
Expand All @@ -283,14 +275,11 @@ impl RpcApp {
.await
.map_err(SubmitError::Internal)?
{
dbg!("YES!!!");
result.subsidized_fee
} else {
result.normal_fee
};

dbg!(is_subsidized_ip);

metrics::histogram!("api.rpc.get_tx_fee", start.elapsed());
Ok(fee)
}
Expand Down
5 changes: 2 additions & 3 deletions core/bin/zksync_api/src/api_server/tx_sender.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use zksync_types::{
};
use zksync_utils::{
big_decimal_to_ratio, biguint_to_big_decimal, ratio_to_scaled_u64, ratio_to_u64,
scaled_big_decimal_to_ratio,
};

// Local uses
Expand Down Expand Up @@ -395,9 +396,7 @@ impl TxSender {
.misc_schema()
.get_total_used_subsidy_for_type(self.current_subsidy_type.clone())
.await?;
let subsidized_already = big_decimal_to_ratio(&subsidized_already)?;

//dbg!(subsidized_already.clone());
let subsidized_already = scaled_big_decimal_to_ratio(subsidized_already)?;

let result = if self.max_subsidy_usd > subsidized_already {
&self.max_subsidy_usd - subsidized_already >= new_subsidy_usd
Expand Down
23 changes: 0 additions & 23 deletions core/bin/zksync_api/src/fee_ticker/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,23 +258,6 @@ const CPK_CREATE2_FEE_TYPE: OutputFeeType = OutputFeeType::ChangePubKey(
ChangePubKeyFeeTypeArg::ContractsV4Version(ChangePubKeyType::CREATE2),
);

// async fn get_left_subsidy_usd_cents(
// config: &ZkSyncConfig,
// db_pool: &ConnectionPool,
// ) -> Result<Ratio<BigUint>> {
// let max_subsidy = config.ticker.max_subsidy_usd_cents;
// let subsidy_name = config.ticker.subsidy_name.clone();

// let get_used_subsidy = db_pool
// .access_storage()
// .await?
// .misc_schema()
// .get_total_used_subsidy_for_type(subsidy_name)
// .await?;

// big_decimal_to_ratio(&get_used_subsidy)
// }

#[must_use]
pub fn run_ticker_task(
db_pool: ConnectionPool,
Expand Down Expand Up @@ -532,13 +515,7 @@ impl<API: FeeTickerAPI, INFO: FeeTickerInfo, WATCHER: TokenWatcher> FeeTicker<AP
// It is safe to do unwrap in the next two lines, because token being acceptable for fees
// assumes that the token's price is > 0
let token_price = big_decimal_to_ratio(&token_price).unwrap();
// dbg!("ABA");
// dbg!(subsidized_fee_usd.clone());
// dbg!(token_price.clone());
// dbg!("CABA");
let full_amount = subsidized_fee_usd.checked_div(&token_price).unwrap();
// dbg!(full_amount.clone());
// dbg!(full_amount.clone() * token_price.clone());

let subsidized_fee = Fee::new(
fee_type,
Expand Down
12 changes: 10 additions & 2 deletions core/lib/utils/src/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ pub fn ratio_to_u64(num: Ratio<BigUint>) -> u64 {
const SUBSIDY_USD_AMOUNTS_SCALE: u64 = 1_000_000;

pub fn ratio_to_scaled_u64(num: Ratio<BigUint>) -> u64 {
let ten_pow = BigUint::from(SUBSIDY_USD_AMOUNTS_SCALE);
let scaled_num = num * ten_pow;
let scale = BigUint::from(SUBSIDY_USD_AMOUNTS_SCALE);
let scaled_num = num * scale;

ratio_to_u64(scaled_num)
}
Expand All @@ -59,6 +59,14 @@ pub fn scaled_u64_to_ratio(num: u64) -> Ratio<BigUint> {
Ratio::from(BigUint::from(num)) / BigUint::from(SUBSIDY_USD_AMOUNTS_SCALE)
}

pub fn scaled_big_decimal_to_ratio(num: BigDecimal) -> Result<Ratio<BigUint>, anyhow::Error> {
let scale = BigDecimal::from(SUBSIDY_USD_AMOUNTS_SCALE);

let unscaled = num / scale;

big_decimal_to_ratio(&unscaled)
}

#[cfg(test)]
mod test {
use super::*;
Expand Down
113 changes: 50 additions & 63 deletions core/tests/ts-tests/tests/misc.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Tester } from './tester';
import { expectThrow, Tester } from './tester';
import { expect } from 'chai';
import { Wallet, types, Create2WalletSigner } from 'zksync';
import { BigNumber, ethers } from 'ethers';
import { SignedTransaction, TxEthSignature } from 'zksync/build/types';
import { submitSignedTransactionsBatch } from 'zksync/build/wallet';
import { MAX_TIMESTAMP } from 'zksync/build/utils';
import { Transaction } from 'zksync';
import { Transfer, Withdraw } from 'zksync/build/types';
import {
serializeAccountId,
Expand Down Expand Up @@ -285,7 +286,12 @@ Tester.prototype.testBackwardCompatibleEthMessages = async function (
this.runningFee = this.runningFee.add(totalFee);
};

// This function is needed to emulate the CF-Connecting-IP header being set by the
// Unfortunately due to different rounds and precix sion lost
// the price might differ from the expected one
const SUBSIDY_ACCEPTED_SCALED_DIFFERENCE = 100; // 0.0001 USD
const SUBSIDY_SCALE = 1000000;

// This function is needed to emulate the CF-Connecting-IP header being set by the
// Cloudflare Proxy. In production, this header is set by Cloudflare Proxy and can not be manually
// set by the client.
const subsidyAxiosConfig = () => {
Expand All @@ -297,18 +303,14 @@ const subsidyAxiosConfig = () => {
}
};
return config;
}
};

Tester.prototype.testSubsidyForCREATE2ChangePubKey = async function (create2Wallet: Wallet, token: TokenLike) {
// Unfortunately due to different rounds and precision lost
// the price might differ from the expected one
const ACCEPTED_SCALED_DIFFERENCE = 10; // 10^-5 USD

const subsidizedCpkPriceScaled = BigNumber.from(process.env.FEE_TICKER_SUBSIDY_CPK_PRICE_USD_SCALED)!;

const transport = new HTTPTransport('http://127.0.0.1:3030');
const weiInEth = BigNumber.from(10).pow(18);
const scaledTokenPrice = BigNumber.from(Math.round(1000000 * (await this.syncProvider.getTokenPrice(token))));
const unitsInOneToken = BigNumber.from(10).pow(this.syncProvider.tokenSet.resolveTokenDecimals(token));
const scaledTokenPrice = BigNumber.from(Math.round(SUBSIDY_SCALE * (await this.syncProvider.getTokenPrice(token))));

// Check that the subsidized fee is returned when requested with appropriate headers
const transactionFee = await transport.request(
Expand All @@ -323,26 +325,25 @@ Tester.prototype.testSubsidyForCREATE2ChangePubKey = async function (create2Wall
subsidyAxiosConfig()
);
const totalFee = BigNumber.from(transactionFee.totalFee);
const totalFeeUSDScaled = totalFee.mul(scaledTokenPrice).div(weiInEth);
expect(totalFeeUSDScaled.sub(subsidizedCpkPriceScaled).abs().lte(ACCEPTED_SCALED_DIFFERENCE)).to.be.true;
const totalFeeUSDScaled = totalFee.mul(scaledTokenPrice).div(unitsInOneToken);
expect(totalFeeUSDScaled.sub(subsidizedCpkPriceScaled).abs().lte(SUBSIDY_ACCEPTED_SCALED_DIFFERENCE)).to.be.true;

// However, without the necessary headers, the API should return the normal fee
const normaltransactionFee = await transport.request('get_tx_fee', [
{
ChangePubKey: 'CREATE2'
},
{ ChangePubKey: 'CREATE2' },
ethers.constants.AddressZero,
token
]);
const normalTotalFee = BigNumber.from(normaltransactionFee.totalFee);
const normalTotalFeeUSDScaled = normalTotalFee.mul(scaledTokenPrice).div(weiInEth);
const normalTotalFeeUSDScaled = BigNumber.from(normaltransactionFee.totalFee)
.mul(scaledTokenPrice)
.div(unitsInOneToken);

// The difference is huge (at least 5x times tolerated difference)
expect(
normalTotalFeeUSDScaled
.sub(subsidizedCpkPriceScaled)
.abs()
.gte(5 * ACCEPTED_SCALED_DIFFERENCE)
.gte(5 * SUBSIDY_ACCEPTED_SCALED_DIFFERENCE)
).to.be.true;

// Now we submit the CREATE2 ChangePubKey
Expand All @@ -358,34 +359,28 @@ Tester.prototype.testSubsidyForCREATE2ChangePubKey = async function (create2Wall
...create2data
}
});
let failed = false;
try {
await transport.request('tx_submit', [cpkTx, null]);
} catch (e) {
failed = true;
}
expect(failed).to.be.true;
await expect(transport.request('tx_submit', [cpkTx, null])).to.be.rejected;

// The transaction is submitted successfully
await transport.request('tx_submit', [cpkTx, null], subsidyAxiosConfig());
const hash = await transport.request('tx_submit', [cpkTx, null], subsidyAxiosConfig());
await new Transaction(cpkTx, hash, this.syncProvider).awaitReceipt();

this.runningFee = this.runningFee.add(totalFee);
};

Tester.prototype.testSubsidyForBatch = async function (create2Wallet: Wallet, token: TokenLike) {
// Unfortunately due to different rounds and precision lost
// the price might differ from the expected one
const ACCEPTED_SCALED_DIFFERENCE = 10; // 10^-5 USD

const subsidizedCpkPriceScaled = BigNumber.from(process.env.FEE_TICKER_SUBSIDY_CPK_PRICE_USD_SCALED)!;
const subsidizedCpkFeeUsdScaled = BigNumber.from(process.env.FEE_TICKER_SUBSIDY_CPK_PRICE_USD_SCALED)!;

const transport = new HTTPTransport('http://127.0.0.1:3030');
const weiInEth = BigNumber.from(10).pow(18);
const scaledTokenPrice = BigNumber.from(Math.round(1000000 * (await this.syncProvider.getTokenPrice(token))));

// Check that the subsidized fee is returned when requested with appropriate headers
const unitsInOneToken = BigNumber.from(10).pow(this.syncProvider.tokenSet.resolveTokenDecimals(token));
const tokenPrice = await this.syncProvider.getTokenPrice(token);
const scaledTokenPrice = BigNumber.from(Math.round(SUBSIDY_SCALE * tokenPrice));

const transferFee = (await this.syncProvider.getTransactionFee('Transfer', create2Wallet.address(), token)).totalFee;
const transferFeeUsdScaled = transferFee.mul(scaledTokenPrice).div(weiInEth);
const transferFee = (await this.syncProvider.getTransactionFee('Transfer', create2Wallet.address(), token))
.totalFee;
const transferFeeUsdScaled = transferFee.mul(scaledTokenPrice).div(unitsInOneToken);

// Check that the subsidized fee is returned when requested with appropriate headers
const subsidyFee = await transport.request(
'get_txs_batch_fee_in_wei',
[
Expand All @@ -395,17 +390,16 @@ Tester.prototype.testSubsidyForBatch = async function (create2Wallet: Wallet, to
},
'Transfer'
],
[
create2Wallet.address(),
create2Wallet.address(),
],
token,
[create2Wallet.address(), create2Wallet.address()],
token
],
subsidyAxiosConfig()
);
const totalFee = BigNumber.from(subsidyFee.totalFee);
const totalFeeUSDScaled = totalFee.mul(scaledTokenPrice).div(weiInEth);
expect(totalFeeUSDScaled.sub(subsidizedCpkPriceScaled).sub(transferFeeUsdScaled).abs().lte(ACCEPTED_SCALED_DIFFERENCE)).to.be.true;
const totalFeeUSDScaled = totalFee.mul(scaledTokenPrice).div(unitsInOneToken);

const expectedBatchFeeUsdScaled = subsidizedCpkFeeUsdScaled.add(transferFeeUsdScaled);
expect(totalFeeUSDScaled.sub(expectedBatchFeeUsdScaled).abs().lte(SUBSIDY_ACCEPTED_SCALED_DIFFERENCE)).to.be.true;

// However, without the necessary headers, the API should return the normal fee
const normalFee = await transport.request('get_txs_batch_fee_in_wei', [
Expand All @@ -415,24 +409,20 @@ Tester.prototype.testSubsidyForBatch = async function (create2Wallet: Wallet, to
},
'Transfer'
],
[
create2Wallet.address(),
create2Wallet.address(),
],
token,
[create2Wallet.address(), create2Wallet.address()],
token
]);
const normalTotalFee = BigNumber.from(normalFee.totalFee);
const normalTotalFeeUSDScaled = normalTotalFee.mul(scaledTokenPrice).div(weiInEth);
const normalTotalFeeUSDScaled = normalTotalFee.mul(scaledTokenPrice).div(unitsInOneToken);

// The difference is huge (at least 5x times tolerated difference)
expect(
normalTotalFeeUSDScaled
.sub(subsidizedCpkPriceScaled)
.sub(subsidizedCpkFeeUsdScaled)
.abs()
.gte(5 * ACCEPTED_SCALED_DIFFERENCE)
.gte(5 * SUBSIDY_ACCEPTED_SCALED_DIFFERENCE)
).to.be.true;

// Now we submit the CREATE2 ChangePubKey
const create2data = (create2Wallet.ethSigner as Create2WalletSigner).create2WalletData;
const cpkTx = await create2Wallet.getChangePubKey({
feeToken: token,
Expand All @@ -448,23 +438,20 @@ Tester.prototype.testSubsidyForBatch = async function (create2Wallet: Wallet, to
const transferTx = await create2Wallet.getTransfer({
token,
fee: totalFee,
nonce: 0,
nonce: 1,
validFrom: 0,
validUntil: MAX_TIMESTAMP,
amount: BigNumber.from('1'),
to: create2Wallet.address(),
to: create2Wallet.address()
});
const txs = [{ tx: cpkTx }, { tx: transferTx }];

let failed = false;
try {
await transport.request('submit_txs_batch', [txs, []]);
} catch (e) {
failed = true;
}
expect(failed).to.be.true;

await transport.request('submit_txs_batch', [txs, []], subsidyAxiosConfig());
await expect(transport.request('submit_txs_batch', [txs, []]), 'Submitted transaction with the wrong fee').to.be
.rejected;

const hashes = await transport.request('submit_txs_batch', [txs, []], subsidyAxiosConfig());
await new Transaction(txs[0].tx, hashes[0], this.syncProvider).awaitReceipt();
this.runningFee = this.runningFee.add(totalFee);
};

export function serializeOldTransfer(transfer: Transfer): Uint8Array {
Expand Down

0 comments on commit 469c775

Please sign in to comment.