Skip to content

Commit

Permalink
Merge dev
Browse files Browse the repository at this point in the history
  • Loading branch information
AntonD3 committed Mar 1, 2021
2 parents 79595c5 + d7f82a4 commit 0f03a4d
Show file tree
Hide file tree
Showing 10 changed files with 222 additions and 129 deletions.
1 change: 1 addition & 0 deletions changelog/core.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ All notable changes to the core components will be documented in this file.

- (`loadtest`): `zksync_fee` has been moved to `[main_wallet]` section from the `[network]` section.
- A special balancer for FeeTicker was replaced with a generic balancer.
- (`api_server`): Make `submit_txs_batch` send only one signature request.

### Added

Expand Down
6 changes: 3 additions & 3 deletions core/bin/zksync_api/src/api_server/rest/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use zksync_types::H160;
use zksync_utils::panic_notify::ThreadPanicNotify;

use self::v01::api_decl::ApiV01;
use crate::{fee_ticker::TickerRequest, signature_checker::VerifyTxSignatureRequest};
use crate::{fee_ticker::TickerRequest, signature_checker::VerifySignatureRequest};

use super::tx_sender::TxSender;
use zksync_config::ZkSyncConfig;
Expand All @@ -20,7 +20,7 @@ pub mod v1;
async fn start_server(
api_v01: ApiV01,
fee_ticker: mpsc::Sender<TickerRequest>,
sign_verifier: mpsc::Sender<VerifyTxSignatureRequest>,
sign_verifier: mpsc::Sender<VerifySignatureRequest>,
bind_to: SocketAddr,
) {
HttpServer::new(move || {
Expand Down Expand Up @@ -63,7 +63,7 @@ pub(super) fn start_server_thread_detached(
contract_address: H160,
panic_notify: mpsc::Sender<bool>,
fee_ticker: mpsc::Sender<TickerRequest>,
sign_verifier: mpsc::Sender<VerifyTxSignatureRequest>,
sign_verifier: mpsc::Sender<VerifySignatureRequest>,
config: ZkSyncConfig,
) {
std::thread::Builder::new()
Expand Down
8 changes: 4 additions & 4 deletions core/bin/zksync_api/src/api_server/rest/v1/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ mod tests {
api_server::helpers::try_parse_tx_hash,
core_api_client::CoreApiClient,
fee_ticker::TickerRequest,
signature_checker::{VerifiedTx, VerifyTxSignatureRequest},
signature_checker::{VerifiedTx, VerifySignatureRequest},
};

use super::super::test_utils::{TestServerConfig, TestTransactions};
Expand Down Expand Up @@ -417,12 +417,12 @@ mod tests {
sender
}

fn dummy_sign_verifier() -> mpsc::Sender<VerifyTxSignatureRequest> {
let (sender, mut receiver) = mpsc::channel::<VerifyTxSignatureRequest>(10);
fn dummy_sign_verifier() -> mpsc::Sender<VerifySignatureRequest> {
let (sender, mut receiver) = mpsc::channel::<VerifySignatureRequest>(10);

actix_rt::spawn(async move {
while let Some(item) = receiver.next().await {
let verified = VerifiedTx::unverified(item.tx);
let verified = VerifiedTx::unverified(item.data.get_tx_variant());
item.response
.send(Ok(verified))
.expect("Unable to send response");
Expand Down
6 changes: 3 additions & 3 deletions core/bin/zksync_api/src/api_server/rpc_server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use zksync_types::{tx::TxHash, Address, BatchFee, BlockNumber, Fee, TokenLike, T
// Local uses
use crate::{
fee_ticker::{TickerRequest, TokenPriceRequestType},
signature_checker::VerifyTxSignatureRequest,
signature_checker::VerifySignatureRequest,
utils::shared_lru_cache::SharedLruCache,
};
use bigdecimal::BigDecimal;
Expand Down Expand Up @@ -55,7 +55,7 @@ pub struct RpcApp {
impl RpcApp {
pub fn new(
connection_pool: ConnectionPool,
sign_verify_request_sender: mpsc::Sender<VerifyTxSignatureRequest>,
sign_verify_request_sender: mpsc::Sender<VerifySignatureRequest>,
ticker_request_sender: mpsc::Sender<TickerRequest>,
config: &ZkSyncConfig,
) -> Self {
Expand Down Expand Up @@ -412,7 +412,7 @@ impl RpcApp {
#[allow(clippy::too_many_arguments)]
pub fn start_rpc_server(
connection_pool: ConnectionPool,
sign_verify_request_sender: mpsc::Sender<VerifyTxSignatureRequest>,
sign_verify_request_sender: mpsc::Sender<VerifySignatureRequest>,
ticker_request_sender: mpsc::Sender<TickerRequest>,
panic_notify: mpsc::Sender<bool>,
config: &ZkSyncConfig,
Expand Down
4 changes: 2 additions & 2 deletions core/bin/zksync_api/src/api_server/rpc_subscriptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::fee_ticker::TickerRequest;
use crate::{
api_server::event_notify::{start_sub_notifier, EventNotifierRequest, EventSubscribeRequest},
api_server::rpc_server::types::{ETHOpInfoResp, ResponseAccountState, TransactionInfoResp},
signature_checker::VerifyTxSignatureRequest,
signature_checker::VerifySignatureRequest,
};
use zksync_config::ZkSyncConfig;
use zksync_utils::panic_notify::ThreadPanicNotify;
Expand Down Expand Up @@ -176,7 +176,7 @@ struct RpcSubApp {
#[allow(clippy::too_many_arguments)]
pub fn start_ws_server(
db_pool: ConnectionPool,
sign_verify_request_sender: mpsc::Sender<VerifyTxSignatureRequest>,
sign_verify_request_sender: mpsc::Sender<VerifySignatureRequest>,
ticker_request_sender: mpsc::Sender<TickerRequest>,
panic_notify: mpsc::Sender<bool>,
config: &ZkSyncConfig,
Expand Down
165 changes: 85 additions & 80 deletions core/bin/zksync_api/src/api_server/tx_sender.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ use crate::api_server::rpc_server::types::TxWithSignature;
use crate::{
core_api_client::CoreApiClient,
fee_ticker::{TickerRequest, TokenPriceRequestType},
signature_checker::{TxVariant, VerifiedTx, VerifyTxSignatureRequest},
signature_checker::{BatchRequest, RequestData, TxRequest, VerifiedTx, VerifySignatureRequest},
tx_error::TxAddError,
utils::token_db_cache::TokenDBCache,
};

#[derive(Clone)]
pub struct TxSender {
pub core_api_client: CoreApiClient,
pub sign_verify_requests: mpsc::Sender<VerifyTxSignatureRequest>,
pub sign_verify_requests: mpsc::Sender<VerifySignatureRequest>,
pub ticker_requests: mpsc::Sender<TickerRequest>,

pub pool: ConnectionPool,
Expand Down Expand Up @@ -105,7 +105,7 @@ macro_rules! internal_error {
impl TxSender {
pub fn new(
connection_pool: ConnectionPool,
sign_verify_request_sender: mpsc::Sender<VerifyTxSignatureRequest>,
sign_verify_request_sender: mpsc::Sender<VerifySignatureRequest>,
ticker_request_sender: mpsc::Sender<TickerRequest>,
config: &ZkSyncConfig,
) -> Self {
Expand All @@ -123,7 +123,7 @@ impl TxSender {
pub(crate) fn with_client(
core_api_client: CoreApiClient,
connection_pool: ConnectionPool,
sign_verify_request_sender: mpsc::Sender<VerifyTxSignatureRequest>,
sign_verify_request_sender: mpsc::Sender<VerifySignatureRequest>,
ticker_request_sender: mpsc::Sender<TickerRequest>,
config: &ZkSyncConfig,
) -> Self {
Expand Down Expand Up @@ -322,15 +322,17 @@ impl TxSender {
let tx_fee_info = tx.tx.get_fee_info();

if let Some((tx_type, token, address, provided_fee)) = tx_fee_info {
// Save the transaction type before moving on to the next one, otherwise
// the total fee won't get affected by it.
transaction_types.push((tx_type, address));

if provided_fee == BigUint::zero() {
continue;
}
let fee_allowed =
Self::token_allowed_for_fees(self.ticker_requests.clone(), token.clone())
.await?;

transaction_types.push((tx_type, address));

// In batches, transactions with non-popular token are allowed to be included, but should not
// used to pay fees. Fees must be covered by some more common token.
if !fee_allowed && provided_fee != 0u64.into() {
Expand Down Expand Up @@ -411,7 +413,7 @@ impl TxSender {
tx_sender_types.push(self.get_tx_sender_type(&tx).await?);
}

if !eth_signatures.is_empty() {
let batch_sign_data = if !eth_signatures.is_empty() {
// User provided at least one signature for the whole batch.
// In this case each sender cannot be CREATE2.
if tx_sender_types
Expand All @@ -429,59 +431,26 @@ impl TxSender {
.map(|((tx, token), sender)| (tx.tx.clone(), token, sender))
.collect::<Vec<_>>();
// Create batch signature data.
let batch_sign_data =
EthBatchSignData::new(_txs, eth_signatures).map_err(SubmitError::other)?;
let (verified_batch, sign_data) = verify_txs_batch_signature(
txs,
tx_senders,
tokens,
tx_sender_types,
batch_sign_data,
messages_to_sign,
self.sign_verify_requests.clone(),
)
.await?
.unwrap_batch();

verified_signatures.extend(sign_data.signatures.into_iter());
verified_txs.extend(verified_batch.into_iter());
Some(EthBatchSignData::new(_txs, eth_signatures).map_err(SubmitError::other)?)
} else {
// Otherwise, we process every transaction in turn.

// This hashset holds addresses that have performed a CREATE2 ChangePubKey
// within this batch, so that we don't check ETH signatures on their transactions
// from this batch. We save the account type to the db later.
let mut create2_senders = HashSet::<H160>::new();

for (tx, sender, token, mut sender_type, msg_to_sign) in
izip!(txs, tx_senders, tokens, tx_sender_types, messages_to_sign)
{
if create2_senders.contains(&sender) {
sender_type = EthAccountType::CREATE2;
}
let verified_tx = verify_tx_info_message_signature(
&tx.tx,
sender,
token,
sender_type,
tx.signature.clone(),
msg_to_sign,
self.sign_verify_requests.clone(),
)
.await?
.unwrap_tx();

if let ZkSyncTx::ChangePubKey(tx) = tx.tx {
if let Some(auth_data) = tx.eth_auth_data {
if auth_data.is_create2() {
create2_senders.insert(sender);
}
}
}

verified_txs.push(verified_tx);
}
None
};
let (verified_batch, sign_data) = verify_txs_batch_signature(
txs,
tx_senders,
tokens,
tx_sender_types,
batch_sign_data,
messages_to_sign,
self.sign_verify_requests.clone(),
)
.await?
.unwrap_batch();
if let Some(sign_data) = sign_data {
verified_signatures.extend(sign_data.signatures.into_iter());
}
verified_txs.extend(verified_batch.into_iter());

let tx_hashes: Vec<TxHash> = verified_txs.iter().map(|tx| tx.tx.hash()).collect();
// Send verified transactions to the mempool.
self.core_api_client
Expand Down Expand Up @@ -668,8 +637,8 @@ impl TxSender {
}

async fn send_verify_request_and_recv(
request: VerifyTxSignatureRequest,
mut req_channel: mpsc::Sender<VerifyTxSignatureRequest>,
request: VerifySignatureRequest,
mut req_channel: mpsc::Sender<VerifySignatureRequest>,
receiver: oneshot::Receiver<Result<VerifiedTx, TxAddError>>,
) -> Result<VerifiedTx, SubmitError> {
// Send the check request.
Expand All @@ -693,7 +662,7 @@ async fn verify_tx_info_message_signature(
account_type: EthAccountType,
signature: Option<TxEthSignature>,
msg_to_sign: Option<Vec<u8>>,
req_channel: mpsc::Sender<VerifyTxSignatureRequest>,
req_channel: mpsc::Sender<VerifySignatureRequest>,
) -> Result<VerifiedTx, SubmitError> {
let eth_sign_data = match msg_to_sign {
Some(message) => match account_type {
Expand All @@ -718,13 +687,15 @@ async fn verify_tx_info_message_signature(

let (sender, receiever) = oneshot::channel();

let request = VerifyTxSignatureRequest {
tx: TxVariant::Tx(SignedZkSyncTx {
tx: tx.clone(),
eth_sign_data,
let request = VerifySignatureRequest {
data: RequestData::Tx(TxRequest {
tx: SignedZkSyncTx {
tx: tx.clone(),
eth_sign_data,
},
sender: tx_sender,
token,
}),
senders: vec![tx_sender],
tokens: vec![token],
response: sender,
};

Expand All @@ -740,24 +711,55 @@ async fn verify_txs_batch_signature(
senders: Vec<Address>,
tokens: Vec<Token>,
sender_types: Vec<EthAccountType>,
batch_sign_data: EthBatchSignData,
batch_sign_data: Option<EthBatchSignData>,
msgs_to_sign: Vec<Option<Vec<u8>>>,
req_channel: mpsc::Sender<VerifyTxSignatureRequest>,
req_channel: mpsc::Sender<VerifySignatureRequest>,
) -> Result<VerifiedTx, SubmitError> {
// This hashset holds addresses that have performed a CREATE2 ChangePubKey
// within this batch, so that we don't check ETH signatures on their transactions
// from this batch. We save the account type to the db later.
let mut create2_senders = HashSet::<H160>::new();
let mut txs = Vec::with_capacity(batch.len());
for (tx, message, sender_type) in izip!(batch, msgs_to_sign, sender_types) {
for (tx, message, sender, mut sender_type) in
izip!(batch, msgs_to_sign, senders.iter(), sender_types)
{
if create2_senders.contains(sender) {
sender_type = EthAccountType::CREATE2;
}
if let ZkSyncTx::ChangePubKey(tx) = &tx.tx {
if let Some(auth_data) = &tx.eth_auth_data {
if auth_data.is_create2() {
create2_senders.insert(*sender);
}
}
}
// If we have more signatures provided than required,
// we will verify those too.
let eth_sign_data = if let (Some(signature), Some(message)) = (tx.signature, message) {
if let EthAccountType::CREATE2 = sender_type {
return Err(SubmitError::IncorrectTx(
"Eth signature from CREATE2 account not expected".to_string(),
));
let eth_sign_data = if let Some(message) = message {
match sender_type {
EthAccountType::CREATE2 => {
if tx.signature.is_some() {
return Err(SubmitError::IncorrectTx(
"Eth signature from CREATE2 account not expected".to_string(),
));
}
None
}
EthAccountType::Owned => {
if batch_sign_data.is_none() && tx.signature.is_none() {
return Err(SubmitError::TxAdd(TxAddError::MissingEthSignature));
}
if let Some(signature) = tx.signature {
Some(EthSignData { signature, message })
} else {
None
}
}
}
Some(EthSignData { signature, message })
} else {
None
};

txs.push(SignedZkSyncTx {
tx: tx.tx,
eth_sign_data,
Expand All @@ -766,10 +768,13 @@ async fn verify_txs_batch_signature(

let (sender, receiver) = oneshot::channel();

let request = VerifyTxSignatureRequest {
tx: TxVariant::Batch(txs, batch_sign_data),
senders,
tokens,
let request = VerifySignatureRequest {
data: RequestData::Batch(BatchRequest {
txs,
batch_sign_data,
senders,
tokens,
}),
response: sender,
};

Expand Down
Loading

0 comments on commit 0f03a4d

Please sign in to comment.