Fix issue in polling for transaction signatures (#4923)

- Specifically if multiple confirmation for the signature is requested
This commit is contained in:
Pankaj Garg
2019-07-02 20:56:10 -07:00
committed by GitHub
parent 55b8ff72d0
commit f551b34725
4 changed files with 37 additions and 28 deletions

View File

@@ -203,26 +203,38 @@ impl ThinClient {
keypairs: &[&Keypair],
transaction: &mut Transaction,
tries: usize,
min_confirmed_blocks: usize,
pending_confirmations: usize,
) -> io::Result<Signature> {
for x in 0..tries {
let now = Instant::now();
let mut buf = vec![0; serialized_size(&transaction).unwrap() as usize];
let mut wr = std::io::Cursor::new(&mut buf[..]);
let mut num_confirmed = 0;
let mut wait_time = MAX_PROCESSING_AGE;
serialize_into(&mut wr, &transaction)
.expect("serialize Transaction in pub fn transfer_signed");
// resend the same transaction until the transaction has no chance of succeeding
while now.elapsed().as_secs() < MAX_PROCESSING_AGE as u64 {
self.transactions_socket
.send_to(&buf[..], &self.transactions_addr())?;
if self
.poll_for_signature_confirmation(
&transaction.signatures[0],
min_confirmed_blocks,
)
.is_ok()
{
return Ok(transaction.signatures[0]);
while now.elapsed().as_secs() < wait_time as u64 {
if num_confirmed == 0 {
// Send the transaction if there has been no confirmation (e.g. the first time)
self.transactions_socket
.send_to(&buf[..], &self.transactions_addr())?;
}
if let Ok(confirmed_blocks) = self.poll_for_signature_confirmation(
&transaction.signatures[0],
pending_confirmations,
) {
num_confirmed = confirmed_blocks;
if confirmed_blocks >= pending_confirmations {
return Ok(transaction.signatures[0]);
}
// Since network has seen the transaction, wait longer to receive
// all pending confirmations. Resending the transaction could result into
// extra transaction fees
wait_time = wait_time.max(
MAX_PROCESSING_AGE * pending_confirmations.saturating_sub(num_confirmed),
);
}
}
info!(
@@ -385,7 +397,7 @@ impl SyncClient for ThinClient {
&self,
signature: &Signature,
min_confirmed_blocks: usize,
) -> TransportResult<()> {
) -> TransportResult<usize> {
Ok(self
.rpc_client()
.poll_for_signature_confirmation(signature, min_confirmed_blocks)?)