Skip to content

Commit

Permalink
Merge pull request #2670 from blockstack/fix/2667
Browse files Browse the repository at this point in the history
Fix/2667
  • Loading branch information
jcnelson committed May 27, 2021
2 parents 7801c47 + c0367ef commit 272c839
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 19 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ This release's chainstate directory is compatible with chainstate directories fr
- Fix trait rpc lookups for implicitly implemented traits (#2602).
- Fix `v2/pox` endpoint, broken on Mocknet (#2634).
- Align cost limits on mocknet, testnet and mainnet (#2660).
- Log peer addresses in the HTTP server (#2667)
- Mine microblocks if there are no recent unprocessed Stacks blocks

## [2.0.11.0.0]

Expand Down
5 changes: 3 additions & 2 deletions net-test/tests/test_2_nat_miners_microblocks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,9 @@ with_miner_1
RC=$?
if [ $RC -ne 0 ]; then
logln "Failed to make a token transfer to $STX_DEST_ADDR at attempt $i: rc $RC"
DONE=1
break

# keep trying
continue
fi

TXID="$(echo "$TX" | send_tx "http://localhost:21443")"
Expand Down
6 changes: 4 additions & 2 deletions net-test/tests/testlib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -195,19 +195,21 @@ easy_token_transfer() {
local ADDR="$(blockstack-cli --testnet addresses "$PRIVKEY" | jq -r '.STX')"
local NONCE="$(get_unconfirmed_account_nonce "$STACKS_NODE_URL" "$ADDR")"
local RC=$?
if [ $RC -ne 0 ]; then
logln "Failed to query unconfirmed account nonce: rc $RC"
if [ $RC -ne 0 ] || [ -z "$NONCE" ]; then
logln "Failed to query unconfirmed account nonce: rc '$RC' nonce '$NONCE'"
return 1
fi

local MEMO="test $NONCE"
logln "blockstack-cli --testnet token-transfer '$PRIVKEY' '$FEE_RATE' '$NONCE' '$DEST' '$AMOUNT' '$MEMO' '$OPTS'"
local TX="$(blockstack-cli --testnet token-transfer "$PRIVKEY" "$FEE_RATE" "$NONCE" "$DEST" "$AMOUNT" "$MEMO" "$OPTS" 2>&1)"
RC=$?
if [ $RC -ne 0 ]; then
logln "Failed to generate tx: blockstack-cli --testnet token-transfer $PRIVKEY $FEE_RATE $NONCE $DEST $AMOUNT \"$MEMO\""
return 1
fi

logln "Generated tx: $TX"
printf "$TX"
return 0
}
5 changes: 5 additions & 0 deletions src/chainstate/stacks/db/unconfirmed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,11 @@ impl UnconfirmedState {
self.last_mblock.is_some()
}

/// Does the unconfirmed microblock state represent any transactions?
pub fn num_mined_txs(&self) -> usize {
self.mined_txs.len()
}

/// Get information about an unconfirmed transaction
pub fn get_unconfirmed_transaction(
&self,
Expand Down
25 changes: 15 additions & 10 deletions src/net/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1568,7 +1568,7 @@ impl HttpRequestType {
} else {
"".to_string()
};
info!("Handle {} {}{}", verb, decoded_path, query);
info!("Handle HTTPRequest"; "verb" => %verb, "peer_addr" => %protocol.peer_addr, "path" => %decoded_path, "query" => %query);
return Ok(request);
}
None => {
Expand Down Expand Up @@ -3964,6 +3964,8 @@ struct HttpReplyData {
/// There can be at most one HTTP request in-flight (i.e. we don't do pipelining)
#[derive(Debug, Clone, PartialEq)]
pub struct StacksHttp {
/// Address of peer
peer_addr: SocketAddr,
/// Version of client
request_version: Option<HttpVersion>,
/// Path we requested
Expand All @@ -3977,8 +3979,9 @@ pub struct StacksHttp {
}

impl StacksHttp {
pub fn new() -> StacksHttp {
pub fn new(peer_addr: SocketAddr) -> StacksHttp {
StacksHttp {
peer_addr,
reply: None,
request_version: None,
request_path: None,
Expand Down Expand Up @@ -4084,19 +4087,21 @@ impl StacksHttp {
}

/// Given a HTTP request, serialize it out
#[cfg(test)]
pub fn serialize_request(req: &HttpRequestType) -> Result<Vec<u8>, net_error> {
let mut http = StacksHttp::new();
let mut http = StacksHttp::new("127.0.0.1:20443".parse().unwrap());
let mut ret = vec![];
req.send(&mut http, &mut ret)?;
Ok(ret)
}

/// Given a fully-formed single HTTP response, parse it (used by clients).
#[cfg(test)]
pub fn parse_response(
request_path: &str,
response_buf: &[u8],
) -> Result<StacksHttpMessage, net_error> {
let mut http = StacksHttp::new();
let mut http = StacksHttp::new("127.0.0.1:20443".parse().unwrap());
http.reset();
http.begin_request(HttpVersion::Http11, request_path.to_string());

Expand Down Expand Up @@ -5437,7 +5442,7 @@ mod test {
expected_bytes.append(&mut expected_http_body.clone());

let mut bytes = vec![];
let mut http = StacksHttp::new();
let mut http = StacksHttp::new("127.0.0.1:20443".parse().unwrap());
http.write_message(&mut bytes, &StacksHttpMessage::Request(test.clone()))
.unwrap();

Expand All @@ -5454,7 +5459,7 @@ mod test {
"POST /v2/transactions HTTP/1.1\r\nUser-Agent: stacks/2.0\r\nHost: bad:123\r\nContent-Length: 0\r\n\r\n",
];
for bad_content_length in bad_content_lengths {
let mut http = StacksHttp::new();
let mut http = StacksHttp::new("127.0.0.1:20443".parse().unwrap());
let (preamble, offset) = http.read_preamble(bad_content_length.as_bytes()).unwrap();
let e = http.read_payload(&preamble, &bad_content_length.as_bytes()[offset..]);
let estr = format!("{:?}", &e);
Expand All @@ -5473,7 +5478,7 @@ mod test {
"POST /v2/transactions HTTP/1.1\r\nUser-Agent: stacks/2.0\r\nHost: bad:123\r\nContent-Length: 1\r\n\r\nb",
];
for bad_content_type in bad_content_types {
let mut http = StacksHttp::new();
let mut http = StacksHttp::new("127.0.0.1:20443".parse().unwrap());
let (preamble, offset) = http.read_preamble(bad_content_type.as_bytes()).unwrap();
let e = http.read_payload(&preamble, &bad_content_type.as_bytes()[offset..]);
assert!(e.is_err());
Expand Down Expand Up @@ -5871,7 +5876,7 @@ mod test {
.zip(expected_http_bodies.iter()),
)
{
let mut http = StacksHttp::new();
let mut http = StacksHttp::new("127.0.0.1:20443".parse().unwrap());
let mut bytes = vec![];
test_debug!("write body:\n{:?}\n", test);

Expand Down Expand Up @@ -5963,7 +5968,7 @@ mod test {
expected_error
);

let mut http = StacksHttp::new();
let mut http = StacksHttp::new("127.0.0.1:20443".parse().unwrap());
http.begin_request(HttpVersion::Http11, request_path.to_string());

let (preamble, offset) = http.read_preamble(test.as_bytes()).unwrap();
Expand Down Expand Up @@ -6084,7 +6089,7 @@ mod test {
let invalid_neighbors_response = "HTTP/1.1 200 OK\r\nServer: stacks/v2.0\r\nX-Request-Id: 123\r\nContent-Type: application/json\r\nTransfer-Encoding: chunked\r\n\r\n10\r\nxxxxxxxxxxxxxxxx\r\n0\r\n\r\n";
let invalid_chunked_response = "HTTP/1.1 200 OK\r\nServer: stacks/v2.0\r\nX-Request-Id: 123\r\nContent-Type: application/json\r\nTransfer-Encoding: chunked\r\n\r\n29\r\n{\"sample\":[],\"inbound\":[],\"outbound\":[]}\r\n0\r\n\r\n";

let mut http = StacksHttp::new();
let mut http = StacksHttp::new("127.0.0.1:20443".parse().unwrap());

http.begin_request(HttpVersion::Http11, "/v2/neighbors".to_string());
let (preamble, offset) = http
Expand Down
4 changes: 2 additions & 2 deletions src/net/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ impl RPCPeerInfoData {
let stacks_tip_height = burnchain_tip.canonical_stacks_tip_height;
let (unconfirmed_tip, unconfirmed_seq) = match chainstate.unconfirmed_state {
Some(ref unconfirmed) => {
if unconfirmed.is_readable() {
if unconfirmed.num_mined_txs() > 0 {
(
unconfirmed.unconfirmed_chain_tip.clone(),
unconfirmed.last_mblock_seq,
Expand Down Expand Up @@ -481,7 +481,7 @@ impl ConversationHttp {
conn_opts: &ConnectionOptions,
conn_id: usize,
) -> ConversationHttp {
let mut stacks_http = StacksHttp::new();
let mut stacks_http = StacksHttp::new(peer_addr.clone());
stacks_http.maximum_call_argument_size = conn_opts.maximum_call_argument_size;
ConversationHttp {
network_id: network_id,
Expand Down
12 changes: 9 additions & 3 deletions testnet/stacks-node/src/neon_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,9 +436,13 @@ fn try_mine_microblock(
if microblock_miner.last_mined + (microblock_miner.frequency as u128)
< get_epoch_time_ms()
{
// opportunistically try and mine, but only if there's no attachable blocks
let num_attachable =
StacksChainState::count_attachable_staging_blocks(chainstate.db(), 1, 0)?;
// opportunistically try and mine, but only if there are no attachable blocks in
// recent history (i.e. in the last 10 minutes)
let num_attachable = StacksChainState::count_attachable_staging_blocks(
chainstate.db(),
1,
get_epoch_time_secs() - 600,
)?;
if num_attachable == 0 {
match mine_one_microblock(&mut microblock_miner, sortdb, chainstate, &mem_pool)
{
Expand All @@ -453,6 +457,8 @@ fn try_mine_microblock(
warn!("Failed to mine one microblock: {:?}", &e);
}
}
} else {
debug!("Will not mine microblocks yet -- have {} attachable blocks that arrived in the last 10 minutes", num_attachable);
}
}
microblock_miner.last_mined = get_epoch_time_ms();
Expand Down

0 comments on commit 272c839

Please sign in to comment.