Skip to content

Commit dd19e5f

Browse files
feat: make signing eip 712 compliant (#916)
Co-authored-by: Urix <[email protected]>
1 parent 55109ad commit dd19e5f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+531
-159
lines changed

.gitmodules

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,9 @@
1616
[submodule "examples/validating-public-input/contracts/lib/forge-std"]
1717
path = examples/validating-public-input/contracts/lib/forge-std
1818
url = https://github.com/foundry-rs/forge-std
19+
[submodule "contracts/lib/openzeppelin-contracts"]
20+
path = contracts/lib/openzeppelin-contracts
21+
url = https://github.com/OpenZeppelin/openzeppelin-contracts
22+
[submodule "contracts/lib/openzeppelin-contracts-upgradeable"]
23+
path = contracts/lib/openzeppelin-contracts-upgradeable
24+
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable

Makefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ anvil_upgrade_aligned_contracts:
5555
@echo "Upgrading Aligned Contracts..."
5656
. contracts/scripts/anvil/upgrade_aligned_contracts.sh
5757

58+
anvil_upgrade_batcher_payment_service:
59+
@echo "Upgrading BatcherPayments contract..."
60+
. contracts/scripts/anvil/upgrade_batcher_payment_service.sh
61+
5862
anvil_upgrade_registry_coordinator:
5963
@echo "Upgrading Registry Coordinator Contracts..."
6064
. contracts/scripts/anvil/upgrade_registry_coordinator.sh
@@ -75,6 +79,10 @@ anvil_upgrade_add_aggregator:
7579
@echo "Adding Aggregator to Aligned Contracts..."
7680
. contracts/scripts/anvil/upgrade_add_aggregator_to_service_manager.sh
7781

82+
anvil_add_type_hash_to_batcher_payment_service:
83+
@echo "Adding Type Hash to Batcher Payment Service..."
84+
. contracts/scripts/anvil/upgrade_add_type_hash_to_batcher_payment_service.sh
85+
7886
lint_contracts:
7987
@cd contracts && npm run lint:sol
8088

@@ -437,6 +445,10 @@ upgrade_add_aggregator: ## Add Aggregator to Aligned Contracts
437445
@echo "Adding Aggregator to Aligned Contracts..."
438446
@. contracts/scripts/.env && . contracts/scripts/upgrade_add_aggregator_to_service_manager.sh
439447

448+
upgrade_batcher_payments_add_type_hash: ## Add Type Hash to Batcher Payment Service
449+
@echo "Adding Type Hash to Batcher Payment Service..."
450+
@. contracts/scripts/.env && . contracts/scripts/upgrade_add_type_hash_to_batcher_payment_service.sh
451+
440452
deploy_verify_batch_inclusion_caller:
441453
@echo "Deploying VerifyBatchInclusionCaller contract..."
442454
@. examples/verify/.env && . examples/verify/scripts/deploy_verify_batch_inclusion_caller.sh

batcher/aligned-batcher/src/lib.rs

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,7 @@ impl BatchState {
103103
self.batch_queue
104104
.iter()
105105
.map(|(entry, _)| entry)
106-
.find(|entry| {
107-
entry.sender == sender
108-
&& U256::from_big_endian(entry.nonced_verification_data.nonce.as_slice())
109-
== nonce
110-
})
106+
.find(|entry| entry.sender == sender && entry.nonced_verification_data.nonce == nonce)
111107
}
112108

113109
/// Checks if the entry is valid
@@ -122,8 +118,7 @@ impl BatchState {
122118
replacement_entry: BatchQueueEntry,
123119
) -> Option<ValidityResponseMessage> {
124120
let replacement_max_fee = replacement_entry.nonced_verification_data.max_fee;
125-
let nonce =
126-
U256::from_big_endian(replacement_entry.nonced_verification_data.nonce.as_slice());
121+
let nonce = replacement_entry.nonced_verification_data.nonce;
127122
let sender = replacement_entry.sender;
128123

129124
debug!(
@@ -134,7 +129,7 @@ impl BatchState {
134129
// it is a valid entry only if there is no entry with the same sender, lower nonce and a lower fee
135130
let is_valid = !self.batch_queue.iter().any(|(entry, _)| {
136131
entry.sender == sender
137-
&& U256::from_big_endian(entry.nonced_verification_data.nonce.as_slice()) < nonce
132+
&& entry.nonced_verification_data.nonce < nonce
138133
&& entry.nonced_verification_data.max_fee < replacement_max_fee
139134
});
140135

@@ -439,7 +434,7 @@ impl Batcher {
439434

440435
info!(
441436
"Received message with nonce: {}",
442-
U256::from_big_endian(client_msg.verification_data.nonce.as_slice())
437+
client_msg.verification_data.nonce
443438
);
444439

445440
if client_msg.verification_data.chain_id != self.chain_id {
@@ -495,7 +490,7 @@ impl Batcher {
495490
}
496491

497492
// Nonce and max fee verification
498-
let nonce = U256::from_big_endian(nonced_verification_data.nonce.as_slice());
493+
let nonce = nonced_verification_data.nonce;
499494
let max_fee = nonced_verification_data.max_fee;
500495

501496
if max_fee < U256::from(MIN_FEE_PER_PROOF) {
@@ -644,7 +639,7 @@ impl Batcher {
644639
return false;
645640
}
646641

647-
let nonce = U256::from_big_endian(&nonced_verification_data.nonce);
642+
let nonce = nonced_verification_data.nonce;
648643

649644
batch_state.user_nonces.insert(addr, nonce + U256::one());
650645
batch_state.user_min_fee.insert(addr, max_fee);
@@ -678,7 +673,7 @@ impl Batcher {
678673
expected_user_nonce: U256,
679674
) -> bool {
680675
let replacement_max_fee = nonced_verification_data.max_fee;
681-
let nonce = U256::from_big_endian(&nonced_verification_data.nonce);
676+
let nonce = nonced_verification_data.nonce;
682677

683678
let mut replacement_entry = match batch_state.get_entry(addr, nonce) {
684679
Some(entry) => {
@@ -761,7 +756,7 @@ impl Batcher {
761756
info!("Adding verification data to batch...");
762757

763758
let max_fee = verification_data.max_fee;
764-
let nonce = U256::from_big_endian(verification_data.nonce.as_slice());
759+
let nonce = verification_data.nonce;
765760

766761
batch_state.batch_queue.push(
767762
BatchQueueEntry::new(
@@ -1254,24 +1249,26 @@ impl Batcher {
12541249
}
12551250
};
12561251

1257-
debug!("non paying nonce: {:?}", nonpaying_nonce);
1252+
info!("non paying nonce: {:?}", nonpaying_nonce);
1253+
1254+
let nonce_value = *nonpaying_nonce;
12581255

1259-
let mut nonce_bytes = [0u8; 32];
1260-
nonpaying_nonce.to_big_endian(&mut nonce_bytes);
12611256
*nonpaying_nonce += U256::one();
12621257

12631258
NoncedVerificationData::new(
12641259
client_msg.verification_data.verification_data.clone(),
1265-
nonce_bytes,
1260+
nonce_value,
12661261
DEFAULT_MAX_FEE_PER_PROOF.into(), // 13_000 gas per proof * 100 gwei gas price (upper bound)
12671262
self.chain_id,
1263+
self.payment_service.address(),
12681264
)
12691265
};
12701266

12711267
let client_msg = ClientMessage::new(
12721268
nonced_verification_data.clone(),
12731269
non_paying_config.replacement.clone(),
1274-
);
1270+
)
1271+
.await;
12751272

12761273
let batch_state = self.batch_state.lock().await;
12771274
self.clone()

batcher/aligned-sdk/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ version = "0.1.0"
44
edition = "2021"
55

66
[dependencies]
7-
ethers = { tag = "v2.0.15-fix-reconnections", features = ["ws", "rustls"], git = "https://github.com/yetanotherco/ethers-rs.git" }
7+
ethers = { tag = "v2.0.15-fix-reconnections", features = ["ws", "rustls", "eip712"], git = "https://github.com/yetanotherco/ethers-rs.git" }
88
log = { version = "0.4.21"}
99
serde_json = "1.0.117"
1010
tokio-tungstenite = { version = "0.23.1", features = ["native-tls"] }

batcher/aligned-sdk/src/communication/messaging.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use ethers::signers::Signer;
2+
use ethers::types::Address;
23
use futures_util::{stream::SplitStream, SinkExt, StreamExt};
34
use log::{debug, error, info};
45
use std::sync::Arc;
@@ -30,6 +31,7 @@ pub type ResponseStream = TryFilter<
3031
pub async fn send_messages(
3132
response_stream: Arc<Mutex<ResponseStream>>,
3233
ws_write: Arc<Mutex<SplitSink<WebSocketStream<MaybeTlsStream<TcpStream>>, Message>>>,
34+
payment_service_addr: Address,
3335
verification_data: &[VerificationData],
3436
max_fees: &[U256],
3537
wallet: Wallet<SigningKey>,
@@ -39,25 +41,22 @@ pub async fn send_messages(
3941

4042
let mut ws_write = ws_write.lock().await;
4143

42-
let mut nonce_bytes = [0u8; 32];
43-
4444
let mut response_stream = response_stream.lock().await;
4545

4646
let chain_id = U256::from(wallet.chain_id());
4747

4848
for (idx, verification_data) in verification_data.iter().enumerate() {
49-
nonce.to_big_endian(&mut nonce_bytes);
50-
5149
let verification_data = NoncedVerificationData::new(
5250
verification_data.clone(),
53-
nonce_bytes,
51+
nonce,
5452
max_fees[idx],
5553
chain_id,
54+
payment_service_addr,
5655
);
5756

5857
nonce += U256::one();
5958

60-
let msg = ClientMessage::new(verification_data.clone(), wallet.clone());
59+
let msg = ClientMessage::new(verification_data.clone(), wallet.clone()).await;
6160
let msg_bin = cbor_serialize(&msg).map_err(SubmitError::SerializationError)?;
6261
ws_write
6362
.send(Message::Binary(msg_bin.clone()))

batcher/aligned-sdk/src/communication/protocol.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::core::{errors::SubmitError, types::ResponseMessage};
66

77
use super::serialization::cbor_deserialize;
88

9-
pub const EXPECTED_PROTOCOL_VERSION: u16 = 3;
9+
pub const EXPECTED_PROTOCOL_VERSION: u16 = 4;
1010

1111
pub async fn check_protocol_version(
1212
ws_read: &mut SplitStream<WebSocketStream<MaybeTlsStream<TcpStream>>>,

batcher/aligned-sdk/src/core/errors.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use core::fmt;
22
use ethers::providers::ProviderError;
33
use ethers::signers::WalletError;
4+
use ethers::types::transaction::eip712::Eip712Error;
5+
use ethers::types::SignatureError;
46
use std::io;
57
use std::path::PathBuf;
68
use tokio_tungstenite::tungstenite::protocol::CloseFrame;
@@ -233,3 +235,32 @@ impl fmt::Display for ChainIdError {
233235
}
234236
}
235237
}
238+
239+
#[derive(Debug)]
240+
pub enum VerifySignatureError {
241+
RecoverTypedDataError(SignatureError),
242+
EncodeError(Eip712Error),
243+
}
244+
245+
impl From<SignatureError> for VerifySignatureError {
246+
fn from(e: SignatureError) -> Self {
247+
VerifySignatureError::RecoverTypedDataError(e)
248+
}
249+
}
250+
251+
impl From<Eip712Error> for VerifySignatureError {
252+
fn from(e: Eip712Error) -> Self {
253+
VerifySignatureError::EncodeError(e)
254+
}
255+
}
256+
257+
impl fmt::Display for VerifySignatureError {
258+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
259+
match self {
260+
VerifySignatureError::RecoverTypedDataError(e) => {
261+
write!(f, "Recover typed data error: {}", e)
262+
}
263+
VerifySignatureError::EncodeError(e) => write!(f, "Encode error: {}", e),
264+
}
265+
}
266+
}

0 commit comments

Comments
 (0)