Prestwich/escalator fixes (#581)

* refactor: handle nonce-too-low cases indicating previous conf.

* feature: add sign_transaction to Middleware trait and fix escalation signing
This commit is contained in:
James Prestwich 2021-11-14 04:26:02 -08:00 committed by GitHub
parent 2723e46044
commit 0f22afeb49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 6 deletions

View File

@ -167,6 +167,14 @@ where
true
}
async fn sign_transaction(
&self,
tx: &TypedTransaction,
_: Address,
) -> Result<Signature, Self::Error> {
Ok(self.signer.sign_transaction(tx).await.map_err(SignerMiddlewareError::SignerError)?)
}
/// Helper for filling a transaction's nonce using the wallet
async fn fill_transaction(
&self,

View File

@ -315,7 +315,7 @@ pub trait Middleware: Sync + Send + Debug {
r
})
.map(|req| async move {
self.sign(req.rlp(chain_id), &self.default_sender().unwrap_or_default())
self.sign_transaction(&req, self.default_sender().unwrap_or_default())
.await
.map(|sig| req.rlp_signed(chain_id, &sig))
})
@ -456,6 +456,15 @@ pub trait Middleware: Sync + Send + Debug {
self.inner().sign(data, from).await.map_err(FromErr::from)
}
/// Sign a transaction via RPC call
async fn sign_transaction(
&self,
tx: &TypedTransaction,
from: Address,
) -> Result<Signature, Self::Error> {
self.inner().sign_transaction(tx, from).await.map_err(FromErr::from)
}
////// Contract state
async fn get_logs(&self, filter: &Filter) -> Result<Vec<Log>, Self::Error> {

View File

@ -140,11 +140,18 @@ macro_rules! poll_broadcast_fut {
check_all_receipts!($cx, $this);
}
Poll::Ready(Err(e)) => {
tracing::error!(
error = ?e,
"Error during transaction broadcast"
);
completed!($this, Err(e));
// kludge. Prevents erroring on "nonce too low" which indicates
// a previous escalation confirmed during this broadcast attempt
if format!("{}", e).contains("nonce too low") {
check_all_receipts!($cx, $this);
} else {
tracing::error!(
error = ?e,
"Error during transaction broadcast"
);
completed!($this, Err(e));
}
}
Poll::Pending => return Poll::Pending,
}

View File

@ -125,6 +125,9 @@ pub enum ProviderError {
#[error("unsupported node client")]
UnsupportedNodeClient,
#[error("Attempted to sign a transaction with no available signer. Hint: did you mean to use a SignerMiddleware?")]
SignerUnavailable,
}
/// Types of filters supported by the JSON-RPC.
@ -517,6 +520,15 @@ impl<P: JsonRpcClient> Middleware for Provider<P> {
.map_err(|e| ProviderError::CustomError(e.to_string()))?)
}
/// Sign a transaction via RPC call
async fn sign_transaction(
&self,
_tx: &TypedTransaction,
_from: Address,
) -> Result<Signature, Self::Error> {
Err(ProviderError::SignerUnavailable).map_err(FromErr::from)
}
////// Contract state
/// Returns an array (possibly empty) of logs that match the filter