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 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 /// Helper for filling a transaction's nonce using the wallet
async fn fill_transaction( async fn fill_transaction(
&self, &self,

View File

@ -315,7 +315,7 @@ pub trait Middleware: Sync + Send + Debug {
r r
}) })
.map(|req| async move { .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 .await
.map(|sig| req.rlp_signed(chain_id, &sig)) .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) 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 ////// Contract state
async fn get_logs(&self, filter: &Filter) -> Result<Vec<Log>, Self::Error> { async fn get_logs(&self, filter: &Filter) -> Result<Vec<Log>, Self::Error> {

View File

@ -140,12 +140,19 @@ macro_rules! poll_broadcast_fut {
check_all_receipts!($cx, $this); check_all_receipts!($cx, $this);
} }
Poll::Ready(Err(e)) => { Poll::Ready(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!( tracing::error!(
error = ?e, error = ?e,
"Error during transaction broadcast" "Error during transaction broadcast"
); );
completed!($this, Err(e)); completed!($this, Err(e));
} }
}
Poll::Pending => return Poll::Pending, Poll::Pending => return Poll::Pending,
} }
}; };

View File

@ -125,6 +125,9 @@ pub enum ProviderError {
#[error("unsupported node client")] #[error("unsupported node client")]
UnsupportedNodeClient, 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. /// 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()))?) .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 ////// Contract state
/// Returns an array (possibly empty) of logs that match the filter /// Returns an array (possibly empty) of logs that match the filter