Skip to content

Commit 148dbd6

Browse files
authored
Merge pull request #2514 from blockstack/fix/mempool-walk-order
Fix/mempool walk order
2 parents 1cdff84 + 22d4216 commit 148dbd6

File tree

5 files changed

+532
-625
lines changed

5 files changed

+532
-625
lines changed

src/chainstate/stacks/db/headers.rs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -279,23 +279,6 @@ impl StacksChainState {
279279
}
280280
}
281281

282-
/// Get an ancestor block header given an index hash
283-
pub fn get_index_tip_ancestor_conn(
284-
conn: &StacksDBConn,
285-
tip_index_hash: &StacksBlockId,
286-
height: u64,
287-
) -> Result<Option<StacksHeaderInfo>, Error> {
288-
match conn
289-
.get_ancestor_block_hash(height, tip_index_hash)
290-
.map_err(Error::DBError)?
291-
{
292-
Some(bhh) => {
293-
StacksChainState::get_stacks_block_header_info_by_index_block_hash(conn, &bhh)
294-
}
295-
None => Ok(None),
296-
}
297-
}
298-
299282
/// Get a segment of headers from the canonical chain
300283
pub fn get_ancestors_headers(
301284
conn: &Connection,

src/chainstate/stacks/miner.rs

Lines changed: 90 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -437,44 +437,38 @@ impl<'a> StacksMicroblockBuilder<'a> {
437437
let mut bytes_so_far = self.runtime.bytes_so_far;
438438
let mut num_txs = self.runtime.num_mined;
439439

440-
let result = mem_pool.iterate_candidates(
441-
&self.anchor_block_consensus_hash,
442-
&self.anchor_block,
443-
self.anchor_block_height,
444-
&mut self.header_reader,
445-
|micro_txs| {
446-
let mut result = Ok(());
447-
for mempool_tx in micro_txs.into_iter() {
448-
match StacksMicroblockBuilder::mine_next_transaction(
449-
&mut clarity_tx,
450-
mempool_tx.tx.clone(),
451-
mempool_tx.metadata.len,
452-
&mut considered,
453-
bytes_so_far,
454-
) {
455-
Ok(true) => {
456-
bytes_so_far += mempool_tx.metadata.len;
457-
458-
debug!(
459-
"Include tx {} ({}) in microblock",
460-
mempool_tx.tx.txid(),
461-
mempool_tx.tx.payload.name()
462-
);
463-
txs_included.push(mempool_tx.tx);
464-
num_txs += 1;
465-
}
466-
Ok(false) => {
467-
continue;
468-
}
469-
Err(e) => {
470-
result = Err(e);
471-
break;
472-
}
440+
let result = mem_pool.iterate_candidates(self.anchor_block_height, |micro_txs| {
441+
let mut result = Ok(());
442+
for mempool_tx in micro_txs.into_iter() {
443+
match StacksMicroblockBuilder::mine_next_transaction(
444+
&mut clarity_tx,
445+
mempool_tx.tx.clone(),
446+
mempool_tx.metadata.len,
447+
&mut considered,
448+
bytes_so_far,
449+
) {
450+
Ok(true) => {
451+
bytes_so_far += mempool_tx.metadata.len;
452+
453+
debug!(
454+
"Include tx {} ({}) in microblock",
455+
mempool_tx.tx.txid(),
456+
mempool_tx.tx.payload.name()
457+
);
458+
txs_included.push(mempool_tx.tx);
459+
num_txs += 1;
460+
}
461+
Ok(false) => {
462+
continue;
463+
}
464+
Err(e) => {
465+
result = Err(e);
466+
break;
473467
}
474468
}
475-
result
476-
},
477-
);
469+
}
470+
result
471+
});
478472

479473
// do fault injection
480474
if self.runtime.disable_bytes_check {
@@ -1389,7 +1383,6 @@ impl StacksBlockBuilder {
13891383
&tip_consensus_hash, &tip_block_hash, tip_height, execution_budget
13901384
);
13911385

1392-
let (mut header_reader_chainstate, _) = chainstate_handle.reopen()?; // used for reading block headers during an epoch
13931386
let (mut chainstate, _) = chainstate_handle.reopen_limited(execution_budget)?; // used for processing a block up to the given limit
13941387

13951388
let mut builder = StacksBlockBuilder::make_block_builder(
@@ -1413,86 +1406,80 @@ impl StacksBlockBuilder {
14131406

14141407
let mut block_limit_hit = BlockLimitFunction::NO_LIMIT_HIT;
14151408

1416-
let result = mempool.iterate_candidates(
1417-
&tip_consensus_hash,
1418-
&tip_block_hash,
1419-
tip_height,
1420-
&mut header_reader_chainstate,
1421-
|available_txs| {
1422-
if block_limit_hit == BlockLimitFunction::LIMIT_REACHED {
1423-
return Ok(());
1424-
}
1409+
let result = mempool.iterate_candidates(tip_height, |available_txs| {
1410+
if block_limit_hit == BlockLimitFunction::LIMIT_REACHED {
1411+
return Ok(());
1412+
}
14251413

1426-
for txinfo in available_txs.into_iter() {
1427-
// skip transactions early if we can
1428-
if considered.contains(&txinfo.tx.txid()) {
1414+
for txinfo in available_txs.into_iter() {
1415+
// skip transactions early if we can
1416+
if considered.contains(&txinfo.tx.txid()) {
1417+
continue;
1418+
}
1419+
if let Some(nonce) = mined_origin_nonces.get(&txinfo.tx.origin_address()) {
1420+
if *nonce >= txinfo.tx.get_origin_nonce() {
14291421
continue;
14301422
}
1431-
if let Some(nonce) = mined_origin_nonces.get(&txinfo.tx.origin_address()) {
1432-
if *nonce >= txinfo.tx.get_origin_nonce() {
1433-
continue;
1434-
}
1435-
}
1436-
if let Some(sponsor_addr) = txinfo.tx.sponsor_address() {
1437-
if let Some(nonce) = mined_sponsor_nonces.get(&sponsor_addr) {
1438-
if let Some(sponsor_nonce) = txinfo.tx.get_sponsor_nonce() {
1439-
if *nonce >= sponsor_nonce {
1440-
continue;
1441-
}
1423+
}
1424+
if let Some(sponsor_addr) = txinfo.tx.sponsor_address() {
1425+
if let Some(nonce) = mined_sponsor_nonces.get(&sponsor_addr) {
1426+
if let Some(sponsor_nonce) = txinfo.tx.get_sponsor_nonce() {
1427+
if *nonce >= sponsor_nonce {
1428+
continue;
14421429
}
14431430
}
14441431
}
1432+
}
14451433

1446-
considered.insert(txinfo.tx.txid());
1447-
1448-
match builder.try_mine_tx_with_len(
1449-
&mut epoch_tx,
1450-
&txinfo.tx,
1451-
txinfo.metadata.len,
1452-
&block_limit_hit,
1453-
) {
1454-
Ok(_) => {}
1455-
Err(Error::BlockTooBigError) => {
1456-
// done mining -- our execution budget is exceeded.
1457-
// Make the block from the transactions we did manage to get
1458-
debug!("Block budget exceeded on tx {}", &txinfo.tx.txid());
1459-
if block_limit_hit == BlockLimitFunction::NO_LIMIT_HIT {
1460-
block_limit_hit = BlockLimitFunction::CONTRACT_LIMIT_HIT;
1461-
continue;
1462-
} else if block_limit_hit == BlockLimitFunction::CONTRACT_LIMIT_HIT {
1463-
block_limit_hit = BlockLimitFunction::LIMIT_REACHED;
1464-
}
1465-
}
1466-
Err(Error::TransactionTooBigError) => {
1467-
invalidated_txs.push(txinfo.metadata.txid);
1468-
if block_limit_hit == BlockLimitFunction::NO_LIMIT_HIT {
1469-
block_limit_hit = BlockLimitFunction::CONTRACT_LIMIT_HIT;
1470-
continue;
1471-
} else if block_limit_hit == BlockLimitFunction::CONTRACT_LIMIT_HIT {
1472-
block_limit_hit = BlockLimitFunction::LIMIT_REACHED;
1473-
}
1474-
}
1475-
Err(Error::InvalidStacksTransaction(_, true)) => {
1476-
// if we have an invalid transaction that was quietly ignored, don't warn here either
1434+
considered.insert(txinfo.tx.txid());
1435+
1436+
match builder.try_mine_tx_with_len(
1437+
&mut epoch_tx,
1438+
&txinfo.tx,
1439+
txinfo.metadata.len,
1440+
&block_limit_hit,
1441+
) {
1442+
Ok(_) => {}
1443+
Err(Error::BlockTooBigError) => {
1444+
// done mining -- our execution budget is exceeded.
1445+
// Make the block from the transactions we did manage to get
1446+
debug!("Block budget exceeded on tx {}", &txinfo.tx.txid());
1447+
if block_limit_hit == BlockLimitFunction::NO_LIMIT_HIT {
1448+
block_limit_hit = BlockLimitFunction::CONTRACT_LIMIT_HIT;
14771449
continue;
1450+
} else if block_limit_hit == BlockLimitFunction::CONTRACT_LIMIT_HIT {
1451+
block_limit_hit = BlockLimitFunction::LIMIT_REACHED;
14781452
}
1479-
Err(e) => {
1480-
warn!("Failed to apply tx {}: {:?}", &txinfo.tx.txid(), &e);
1453+
}
1454+
Err(Error::TransactionTooBigError) => {
1455+
invalidated_txs.push(txinfo.metadata.txid);
1456+
if block_limit_hit == BlockLimitFunction::NO_LIMIT_HIT {
1457+
block_limit_hit = BlockLimitFunction::CONTRACT_LIMIT_HIT;
14811458
continue;
1459+
} else if block_limit_hit == BlockLimitFunction::CONTRACT_LIMIT_HIT {
1460+
block_limit_hit = BlockLimitFunction::LIMIT_REACHED;
14821461
}
14831462
}
1484-
1485-
mined_origin_nonces
1486-
.insert(txinfo.tx.origin_address(), txinfo.tx.get_origin_nonce());
1487-
if let (Some(sponsor_addr), Some(sponsor_nonce)) =
1488-
(txinfo.tx.sponsor_address(), txinfo.tx.get_sponsor_nonce())
1489-
{
1490-
mined_sponsor_nonces.insert(sponsor_addr, sponsor_nonce);
1463+
Err(Error::InvalidStacksTransaction(_, true)) => {
1464+
// if we have an invalid transaction that was quietly ignored, don't warn here either
1465+
continue;
1466+
}
1467+
Err(e) => {
1468+
warn!("Failed to apply tx {}: {:?}", &txinfo.tx.txid(), &e);
1469+
continue;
14911470
}
14921471
}
1493-
Ok(())
1494-
},
1495-
);
1472+
1473+
mined_origin_nonces
1474+
.insert(txinfo.tx.origin_address(), txinfo.tx.get_origin_nonce());
1475+
if let (Some(sponsor_addr), Some(sponsor_nonce)) =
1476+
(txinfo.tx.sponsor_address(), txinfo.tx.get_sponsor_nonce())
1477+
{
1478+
mined_sponsor_nonces.insert(sponsor_addr, sponsor_nonce);
1479+
}
1480+
}
1481+
Ok(())
1482+
});
14961483

14971484
mempool.drop_txs(&invalidated_txs)?;
14981485
if let Some(observer) = event_observer {

0 commit comments

Comments
 (0)