mirror of
https://github.com/alexgo-io/stacks-puppet-node.git
synced 2026-04-27 17:30:30 +08:00
@@ -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]
|
||||
|
||||
|
||||
@@ -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")"
|
||||
|
||||
@@ -195,12 +195,13 @@ 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
|
||||
@@ -208,6 +209,7 @@ easy_token_transfer() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
logln "Generated tx: $TX"
|
||||
printf "$TX"
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 => {
|
||||
@@ -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
|
||||
@@ -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,
|
||||
@@ -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());
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
@@ -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());
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user