Skip to content

Commit

Permalink
feat: use query tx version for fee estimation (#470)
Browse files Browse the repository at this point in the history
  • Loading branch information
xJonathanLEI authored Sep 5, 2023
1 parent cecb6d0 commit a5e23d0
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 42 deletions.
67 changes: 50 additions & 17 deletions starknet-accounts/src/account/declaration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,22 @@ const PREFIX_DECLARE: FieldElement = FieldElement::from_mont([
191557713328401194,
]);

/// 2 ^ 128 + 1
const QUERY_VERSION_ONE: FieldElement = FieldElement::from_mont([
18446744073700081633,
17407,
18446744073709551584,
576460752142433776,
]);

/// 2 ^ 128 + 2
const QUERY_VERSION_TWO: FieldElement = FieldElement::from_mont([
18446744073700081601,
17407,
18446744073709551584,
576460752142433232,
]);

impl<'a, A> Declaration<'a, A> {
pub fn new(
contract_class: Arc<FlattenedSierraClass>,
Expand Down Expand Up @@ -157,7 +173,7 @@ where
max_fee: FieldElement::ZERO,
},
};
let declare = prepared.get_declare_request().await?;
let declare = prepared.get_declare_request(true).await?;

self.account
.provider()
Expand Down Expand Up @@ -296,7 +312,7 @@ where
max_fee: FieldElement::ZERO,
},
};
let declare = prepared.get_declare_request().await?;
let declare = prepared.get_declare_request(true).await?;

self.account
.provider()
Expand All @@ -310,10 +326,19 @@ where
}

impl RawDeclaration {
pub fn transaction_hash(&self, chain_id: FieldElement, address: FieldElement) -> FieldElement {
pub fn transaction_hash(
&self,
chain_id: FieldElement,
address: FieldElement,
query_only: bool,
) -> FieldElement {
compute_hash_on_elements(&[
PREFIX_DECLARE,
FieldElement::TWO, // version
if query_only {
QUERY_VERSION_TWO
} else {
FieldElement::TWO
}, // version
address,
FieldElement::ZERO, // entry_point_selector
compute_hash_on_elements(&[self.contract_class.class_hash()]),
Expand All @@ -330,10 +355,15 @@ impl RawLegacyDeclaration {
&self,
chain_id: FieldElement,
address: FieldElement,
query_only: bool,
) -> Result<FieldElement, ComputeClassHashError> {
Ok(compute_hash_on_elements(&[
PREFIX_DECLARE,
FieldElement::ONE, // version
if query_only {
QUERY_VERSION_ONE
} else {
FieldElement::ONE
}, // version
address,
FieldElement::ZERO, // entry_point_selector
compute_hash_on_elements(&[self.contract_class.class_hash()?]),
Expand All @@ -350,9 +380,9 @@ where
{
/// Locally calculates the hash of the transaction to be sent from this declaration given the
/// parameters.
pub fn transaction_hash(&self) -> FieldElement {
pub fn transaction_hash(&self, query_only: bool) -> FieldElement {
self.inner
.transaction_hash(self.account.chain_id(), self.account.address())
.transaction_hash(self.account.chain_id(), self.account.address(), query_only)
}
}

Expand All @@ -366,7 +396,7 @@ where
DeclareTransactionResult,
AccountError<A::SignError, <A::Provider as Provider>::Error>,
> {
let tx_request = self.get_declare_request().await?;
let tx_request = self.get_declare_request(false).await?;
self.account
.provider()
.add_declare_transaction(BroadcastedDeclareTransaction::V2(tx_request))
Expand All @@ -376,13 +406,14 @@ where

pub async fn get_declare_request(
&self,
query_only: bool,
) -> Result<
BroadcastedDeclareTransactionV2,
AccountError<A::SignError, <A::Provider as Provider>::Error>,
> {
let signature = self
.account
.sign_declaration(&self.inner)
.sign_declaration(&self.inner, query_only)
.await
.map_err(AccountError::Signing)?;

Expand All @@ -393,8 +424,7 @@ where
contract_class: self.inner.contract_class.clone(),
compiled_class_hash: self.inner.compiled_class_hash,
sender_address: self.account.address(),
// TODO: make use of query version tx for estimating fees
is_query: false,
is_query: query_only,
})
}
}
Expand All @@ -405,9 +435,12 @@ where
{
/// Locally calculates the hash of the transaction to be sent from this declaration given the
/// parameters.
pub fn transaction_hash(&self) -> Result<FieldElement, ComputeClassHashError> {
pub fn transaction_hash(
&self,
query_only: bool,
) -> Result<FieldElement, ComputeClassHashError> {
self.inner
.transaction_hash(self.account.chain_id(), self.account.address())
.transaction_hash(self.account.chain_id(), self.account.address(), query_only)
}
}

Expand All @@ -421,7 +454,7 @@ where
DeclareTransactionResult,
AccountError<A::SignError, <A::Provider as Provider>::Error>,
> {
let tx_request = self.get_declare_request().await?;
let tx_request = self.get_declare_request(false).await?;
self.account
.provider()
.add_declare_transaction(BroadcastedDeclareTransaction::V1(tx_request))
Expand All @@ -431,13 +464,14 @@ where

pub async fn get_declare_request(
&self,
query_only: bool,
) -> Result<
BroadcastedDeclareTransactionV1,
AccountError<A::SignError, <A::Provider as Provider>::Error>,
> {
let signature = self
.account
.sign_legacy_declaration(&self.inner)
.sign_legacy_declaration(&self.inner, query_only)
.await
.map_err(AccountError::Signing)?;

Expand All @@ -449,8 +483,7 @@ where
nonce: self.inner.nonce,
contract_class: Arc::new(compressed_class),
sender_address: self.account.address(),
// TODO: make use of query version tx for estimating fees
is_query: false,
is_query: query_only,
})
}
}
32 changes: 24 additions & 8 deletions starknet-accounts/src/account/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ const PREFIX_INVOKE: FieldElement = FieldElement::from_mont([
513398556346534256,
]);

/// 2 ^ 128 + 1
const QUERY_VERSION_ONE: FieldElement = FieldElement::from_mont([
18446744073700081633,
17407,
18446744073709551584,
576460752142433776,
]);

impl<'a, A> Execution<'a, A> {
pub fn new(calls: Vec<Call>, account: &'a A) -> Self {
Self {
Expand Down Expand Up @@ -148,7 +156,7 @@ where
},
};
let invoke = prepared
.get_invoke_request()
.get_invoke_request(true)
.await
.map_err(AccountError::Signing)?;

Expand All @@ -168,14 +176,19 @@ impl RawExecution {
&self,
chain_id: FieldElement,
address: FieldElement,
query_only: bool,
encoder: E,
) -> FieldElement
where
E: ExecutionEncoder,
{
compute_hash_on_elements(&[
PREFIX_INVOKE,
FieldElement::ONE, // version
if query_only {
QUERY_VERSION_ONE
} else {
FieldElement::ONE
}, // version
address,
FieldElement::ZERO, // entry_point_selector
compute_hash_on_elements(&encoder.encode_calls(&self.calls)),
Expand All @@ -192,10 +205,11 @@ where
{
/// Locally calculates the hash of the transaction to be sent from this execution given the
/// parameters.
pub fn transaction_hash(&self) -> FieldElement {
pub fn transaction_hash(&self, query_only: bool) -> FieldElement {
self.inner.transaction_hash(
self.account.chain_id(),
self.account.address(),
query_only,
self.account,
)
}
Expand All @@ -210,7 +224,7 @@ where
) -> Result<InvokeTransactionResult, AccountError<A::SignError, <A::Provider as Provider>::Error>>
{
let tx_request = self
.get_invoke_request()
.get_invoke_request(false)
.await
.map_err(AccountError::Signing)?;
self.account
Expand All @@ -223,17 +237,19 @@ where
// The `simulate` function is temporarily removed until it's supported in [Provider]
// TODO: add `simulate` back once transaction simulation in supported

pub async fn get_invoke_request(&self) -> Result<BroadcastedInvokeTransaction, A::SignError> {
let signature = self.account.sign_execution(&self.inner).await?;
pub async fn get_invoke_request(
&self,
query_only: bool,
) -> Result<BroadcastedInvokeTransaction, A::SignError> {
let signature = self.account.sign_execution(&self.inner, query_only).await?;

Ok(BroadcastedInvokeTransaction {
max_fee: self.inner.max_fee,
signature,
nonce: self.inner.nonce,
sender_address: self.account.address(),
calldata: self.account.encode_calls(&self.inner.calls),
// TODO: make use of query version tx for estimating fees
is_query: false,
is_query: query_only,
})
}
}
36 changes: 27 additions & 9 deletions starknet-accounts/src/account/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,19 @@ pub trait Account: ExecutionEncoder + Sized {
async fn sign_execution(
&self,
execution: &RawExecution,
query_only: bool,
) -> Result<Vec<FieldElement>, Self::SignError>;

async fn sign_declaration(
&self,
declaration: &RawDeclaration,
query_only: bool,
) -> Result<Vec<FieldElement>, Self::SignError>;

async fn sign_legacy_declaration(
&self,
legacy_declaration: &RawLegacyDeclaration,
query_only: bool,
) -> Result<Vec<FieldElement>, Self::SignError>;

fn execute(&self, calls: Vec<Call>) -> Execution<Self> {
Expand Down Expand Up @@ -197,22 +200,27 @@ where
async fn sign_execution(
&self,
execution: &RawExecution,
query_only: bool,
) -> Result<Vec<FieldElement>, Self::SignError> {
(*self).sign_execution(execution).await
(*self).sign_execution(execution, query_only).await
}

async fn sign_declaration(
&self,
declaration: &RawDeclaration,
query_only: bool,
) -> Result<Vec<FieldElement>, Self::SignError> {
(*self).sign_declaration(declaration).await
(*self).sign_declaration(declaration, query_only).await
}

async fn sign_legacy_declaration(
&self,
legacy_declaration: &RawLegacyDeclaration,
query_only: bool,
) -> Result<Vec<FieldElement>, Self::SignError> {
(*self).sign_legacy_declaration(legacy_declaration).await
(*self)
.sign_legacy_declaration(legacy_declaration, query_only)
.await
}
}

Expand All @@ -235,23 +243,28 @@ where
async fn sign_execution(
&self,
execution: &RawExecution,
query_only: bool,
) -> Result<Vec<FieldElement>, Self::SignError> {
self.as_ref().sign_execution(execution).await
self.as_ref().sign_execution(execution, query_only).await
}

async fn sign_declaration(
&self,
declaration: &RawDeclaration,
query_only: bool,
) -> Result<Vec<FieldElement>, Self::SignError> {
self.as_ref().sign_declaration(declaration).await
self.as_ref()
.sign_declaration(declaration, query_only)
.await
}

async fn sign_legacy_declaration(
&self,
legacy_declaration: &RawLegacyDeclaration,
query_only: bool,
) -> Result<Vec<FieldElement>, Self::SignError> {
self.as_ref()
.sign_legacy_declaration(legacy_declaration)
.sign_legacy_declaration(legacy_declaration, query_only)
.await
}
}
Expand All @@ -275,23 +288,28 @@ where
async fn sign_execution(
&self,
execution: &RawExecution,
query_only: bool,
) -> Result<Vec<FieldElement>, Self::SignError> {
self.as_ref().sign_execution(execution).await
self.as_ref().sign_execution(execution, query_only).await
}

async fn sign_declaration(
&self,
declaration: &RawDeclaration,
query_only: bool,
) -> Result<Vec<FieldElement>, Self::SignError> {
self.as_ref().sign_declaration(declaration).await
self.as_ref()
.sign_declaration(declaration, query_only)
.await
}

async fn sign_legacy_declaration(
&self,
legacy_declaration: &RawLegacyDeclaration,
query_only: bool,
) -> Result<Vec<FieldElement>, Self::SignError> {
self.as_ref()
.sign_legacy_declaration(legacy_declaration)
.sign_legacy_declaration(legacy_declaration, query_only)
.await
}
}
Expand Down
Loading

0 comments on commit a5e23d0

Please sign in to comment.