mirror of
https://github.com/alexgo-io/stacks-puppet-node.git
synced 2026-04-24 03:45:38 +08:00
Removed mentions of use_latest_tip parameter, returning a NotFound http response if the chain tip can't be loaded for an rpc request
This commit is contained in:
@@ -73,15 +73,8 @@ paths:
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
description: The Stacks chain tip to query from
|
||||
- name: use_latest_tip
|
||||
in: query
|
||||
schema:
|
||||
type: boolean
|
||||
description: |
|
||||
If use_latest_tip == true, the query will be run from the latest known tip (includes unconfirmed state).
|
||||
If use_latest_tip == false or is unspecified, the tip is selected as usual (first checking value of the
|
||||
tip parameter, otherwise taking the stacks chain tip).
|
||||
description: The Stacks chain tip to query from. If tip == latest, the query will be run from the latest
|
||||
known tip (includes unconfirmed state).
|
||||
/v2/map_entry/{contract_address}/{contract_name}/{map_name}:
|
||||
post:
|
||||
summary: Get specific data-map inside a contract
|
||||
@@ -133,15 +126,8 @@ paths:
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
description: The Stacks chain tip to query from
|
||||
- name: use_latest_tip
|
||||
in: query
|
||||
schema:
|
||||
type: boolean
|
||||
description: |
|
||||
If use_latest_tip == true, the query will be run from the latest known tip (includes unconfirmed state).
|
||||
If use_latest_tip == false or is unspecified, the tip is selected as usual (first checking value of the
|
||||
tip parameter, otherwise taking the stacks chain tip).
|
||||
description: The Stacks chain tip to query from. If tip == latest, the query will be run from the latest
|
||||
known tip (includes unconfirmed state).
|
||||
x-codegen-request-body-name: key
|
||||
requestBody:
|
||||
description: Hex string serialization of the lookup key (which should be a Clarity value)
|
||||
@@ -189,16 +175,9 @@ paths:
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
description: The Stacks chain tip to query from
|
||||
description: The Stacks chain tip to query from. If tip == latest, the query will be run from the latest
|
||||
known tip (includes unconfirmed state).
|
||||
required: false
|
||||
- name: use_latest_tip
|
||||
in: query
|
||||
schema:
|
||||
type: boolean
|
||||
description: |
|
||||
If use_latest_tip == true, the query will be run from the latest known tip (includes unconfirmed state).
|
||||
If use_latest_tip == false or is unspecified, the tip is selected as usual (first checking value of the
|
||||
tip parameter, otherwise taking the stacks chain tip).
|
||||
|
||||
/v2/contracts/call-read/{contract_address}/{contract_name}/{function_name}:
|
||||
post:
|
||||
@@ -245,16 +224,9 @@ paths:
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
description: The Stacks chain tip to query from
|
||||
description: The Stacks chain tip to query from. If tip == latest, the query will be run from the latest
|
||||
known tip (includes unconfirmed state).
|
||||
required: false
|
||||
- name: use_latest_tip
|
||||
in: query
|
||||
schema:
|
||||
type: boolean
|
||||
description: |
|
||||
If use_latest_tip == true, the query will be run from the latest known tip (includes unconfirmed state).
|
||||
If use_latest_tip == false or is unspecified, the tip is selected as usual (first checking value of the
|
||||
tip parameter, otherwise taking the stacks chain tip).
|
||||
requestBody:
|
||||
description: map of arguments and the simulated tx-sender where sender is either a Contract identifier or a normal Stacks address, and arguments is an array of hex serialized Clarity values.
|
||||
required: true
|
||||
@@ -296,15 +268,8 @@ paths:
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
description: The Stacks chain tip to query from
|
||||
- name: use_latest_tip
|
||||
in: query
|
||||
schema:
|
||||
type: boolean
|
||||
description: |
|
||||
If use_latest_tip == true, the query will be run from the latest known tip (includes unconfirmed state).
|
||||
If use_latest_tip == false or is unspecified, the tip is selected as usual (first checking value of the
|
||||
tip parameter, otherwise taking the stacks chain tip).
|
||||
description: The Stacks chain tip to query from. If tip == latest, the query will be run from the latest
|
||||
known tip (includes unconfirmed state).
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
@@ -460,15 +425,8 @@ paths:
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
description: The Stacks chain tip to query from
|
||||
- name: use_latest_tip
|
||||
in: query
|
||||
schema:
|
||||
type: boolean
|
||||
description: |
|
||||
If use_latest_tip == true, the query will be run from the latest known tip (includes unconfirmed state).
|
||||
If use_latest_tip == false or is unspecified, the tip is selected as usual (first checking value of the
|
||||
tip parameter, otherwise taking the stacks chain tip).
|
||||
description: The Stacks chain tip to query from. If tip == latest, the query will be run from the latest
|
||||
known tip (includes unconfirmed state).
|
||||
|
||||
/v2/traits/{contract_address}/{contract_name}/{trait_contract_address}/{trait_ contract_name}/{trait_name}:
|
||||
get:
|
||||
|
||||
@@ -383,6 +383,35 @@ impl UnconfirmedState {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
/// Try returning the unconfirmed chain tip. Only return the tip if the underlying MARF trie
|
||||
/// exists, otherwise return None.
|
||||
pub fn get_unconfirmed_state_if_exists(&mut self) -> Result<Option<StacksBlockId>, String> {
|
||||
if self.is_readable() {
|
||||
let trie_exists = match self
|
||||
.clarity_inst
|
||||
.trie_exists_for_block(&self.unconfirmed_chain_tip)
|
||||
{
|
||||
Ok(res) => res,
|
||||
Err(e) => {
|
||||
let err_str = format!(
|
||||
"Failed to load Stacks chain tip; error checking underlying trie: {}",
|
||||
e
|
||||
);
|
||||
warn!("{}", err_str);
|
||||
return Err(err_str);
|
||||
}
|
||||
};
|
||||
|
||||
if trie_exists {
|
||||
Ok(Some(self.unconfirmed_chain_tip))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StacksChainState {
|
||||
|
||||
@@ -2533,10 +2533,7 @@ impl HttpRequestType {
|
||||
fn make_query_string(tip_req: &TipRequest, with_proof: bool) -> String {
|
||||
match tip_req {
|
||||
TipRequest::UseLatestUnconfirmedTip => {
|
||||
format!(
|
||||
"?use_latest_tip=true{}",
|
||||
if with_proof { "" } else { "&proof=0" }
|
||||
)
|
||||
format!("?tip=latest{}", if with_proof { "" } else { "&proof=0" })
|
||||
}
|
||||
TipRequest::SpecificTip(tip) => {
|
||||
format!("?tip={}{}", tip, if with_proof { "" } else { "&proof=0" })
|
||||
|
||||
118
src/net/rpc.rs
118
src/net/rpc.rs
@@ -1555,31 +1555,13 @@ impl ConversationHttp {
|
||||
TipRequest::UseLatestUnconfirmedTip => {
|
||||
let unconfirmed_chain_tip_opt = match &mut chainstate.unconfirmed_state {
|
||||
Some(unconfirmed_state) => {
|
||||
if unconfirmed_state.is_readable() {
|
||||
// Check if underlying MARF trie exists before returning unconfirmed chain tip
|
||||
let trie_exists = match unconfirmed_state
|
||||
.clarity_inst
|
||||
.trie_exists_for_block(&unconfirmed_state.unconfirmed_chain_tip)
|
||||
{
|
||||
Ok(res) => res,
|
||||
Err(e) => {
|
||||
let response_metadata = HttpResponseMetadata::from(req);
|
||||
warn!("Failed to load Stacks chain tip; error checking underlying trie");
|
||||
let response = HttpResponseType::ServerError(
|
||||
response_metadata,
|
||||
format!("Failed to load Stacks chain tip: {:?}", e),
|
||||
);
|
||||
return response.send(http, fd).and_then(|_| Ok(None));
|
||||
}
|
||||
};
|
||||
|
||||
if trie_exists {
|
||||
Some(unconfirmed_state.unconfirmed_chain_tip)
|
||||
} else {
|
||||
None
|
||||
match unconfirmed_state.get_unconfirmed_state_if_exists() {
|
||||
Ok(res) => res,
|
||||
Err(msg) => {
|
||||
let response_metadata = HttpResponseMetadata::from(req);
|
||||
let response = HttpResponseType::NotFound(response_metadata, msg);
|
||||
return response.send(http, fd).and_then(|_| Ok(None));
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
@@ -1596,7 +1578,7 @@ impl ConversationHttp {
|
||||
None => {
|
||||
let response_metadata = HttpResponseMetadata::from(req);
|
||||
warn!("Failed to load Stacks chain tip");
|
||||
let response = HttpResponseType::ServerError(
|
||||
let response = HttpResponseType::NotFound(
|
||||
response_metadata,
|
||||
format!("Failed to load Stacks chain tip"),
|
||||
);
|
||||
@@ -1629,7 +1611,6 @@ impl ConversationHttp {
|
||||
fd: &mut W,
|
||||
req: &HttpRequestType,
|
||||
tip: StacksBlockId,
|
||||
sortdb: &SortitionDB,
|
||||
chainstate: &StacksChainState,
|
||||
) -> Result<Option<(ConsensusHash, BlockHeaderHash)>, net_error> {
|
||||
match chainstate.get_block_header_hashes(&tip)? {
|
||||
@@ -2344,7 +2325,6 @@ impl ConversationHttp {
|
||||
&mut reply,
|
||||
&req,
|
||||
tip,
|
||||
sortdb,
|
||||
chainstate,
|
||||
)?
|
||||
{
|
||||
@@ -3539,9 +3519,9 @@ mod test {
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_rpc_getpoxinfo() {
|
||||
/// Test v2/pox (aka GetPoxInfo) endpoint.
|
||||
/// In this test, `tip_req` is set to UseLatestAnchoredTip.
|
||||
/// Thus, the query for pox info will be against the canonical Stacks tip, which we expect to succeed.
|
||||
// Test v2/pox (aka GetPoxInfo) endpoint.
|
||||
// In this test, `tip_req` is set to UseLatestAnchoredTip.
|
||||
// Thus, the query for pox info will be against the canonical Stacks tip, which we expect to succeed.
|
||||
let pox_server_info = RefCell::new(None);
|
||||
test_rpc(
|
||||
"test_rpc_getpoxinfo",
|
||||
@@ -3592,9 +3572,9 @@ mod test {
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_rpc_getpoxinfo_use_latest_tip() {
|
||||
/// Test v2/pox (aka GetPoxInfo) endpoint.
|
||||
/// In this test, we set `tip_req` to UseLatestUnconfirmedTip, and we expect that querying for pox
|
||||
/// info against the unconfirmed state will succeed.
|
||||
// Test v2/pox (aka GetPoxInfo) endpoint.
|
||||
// In this test, we set `tip_req` to UseLatestUnconfirmedTip, and we expect that querying for pox
|
||||
// info against the unconfirmed state will succeed.
|
||||
let pox_server_info = RefCell::new(None);
|
||||
test_rpc(
|
||||
"test_rpc_getpoxinfo_use_latest_tip",
|
||||
@@ -4325,11 +4305,11 @@ mod test {
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_rpc_get_contract_src() {
|
||||
/// Test v2/contracts/source (aka GetContractSrc) endpoint.
|
||||
/// In this test, we don't set any tip parameters, and allow the endpoint to execute against
|
||||
/// the canonical Stacks tip.
|
||||
/// The contract source we are querying for exists in the anchored state, so we expect the
|
||||
/// query to succeed.
|
||||
// Test v2/contracts/source (aka GetContractSrc) endpoint.
|
||||
// In this test, we don't set any tip parameters, and allow the endpoint to execute against
|
||||
// the canonical Stacks tip.
|
||||
// The contract source we are querying for exists in the anchored state, so we expect the
|
||||
// query to succeed.
|
||||
test_rpc(
|
||||
"test_rpc_get_contract_src",
|
||||
40090,
|
||||
@@ -4368,11 +4348,11 @@ mod test {
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_rpc_get_contract_src_unconfirmed_with_canonical_tip() {
|
||||
/// Test v2/contracts/source (aka GetContractSrc) endpoint.
|
||||
/// In this test, we don't set any tip parameters, and allow the endpoint to execute against
|
||||
/// the canonical Stacks tip.
|
||||
/// The contract source we are querying for only exists in the unconfirmed state, so we
|
||||
/// expect the query to fail.
|
||||
// Test v2/contracts/source (aka GetContractSrc) endpoint.
|
||||
// In this test, we don't set any tip parameters, and allow the endpoint to execute against
|
||||
// the canonical Stacks tip.
|
||||
// The contract source we are querying for only exists in the unconfirmed state, so we
|
||||
// expect the query to fail.
|
||||
test_rpc(
|
||||
"test_rpc_get_contract_src_unconfirmed_with_canonical_tip",
|
||||
40100,
|
||||
@@ -4411,10 +4391,10 @@ mod test {
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_rpc_get_contract_src_with_unconfirmed_tip() {
|
||||
/// Test v2/contracts/source (aka GetContractSrc) endpoint.
|
||||
/// In this test, we set `tip_req` to be the unconfirmed chain tip.
|
||||
/// The contract source we are querying for exists in the unconfirmed state, so we expect
|
||||
/// the query to succeed.
|
||||
// Test v2/contracts/source (aka GetContractSrc) endpoint.
|
||||
// In this test, we set `tip_req` to be the unconfirmed chain tip.
|
||||
// The contract source we are querying for exists in the unconfirmed state, so we expect
|
||||
// the query to succeed.
|
||||
test_rpc(
|
||||
"test_rpc_get_contract_src_with_unconfirmed_tip",
|
||||
40102,
|
||||
@@ -4460,10 +4440,10 @@ mod test {
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_rpc_get_contract_src_use_latest_tip() {
|
||||
/// Test v2/contracts/source (aka GetContractSrc) endpoint.
|
||||
/// In this test, we set `tip_req` to UseLatestUnconfirmedTip.
|
||||
/// The contract source we are querying for exists in the unconfirmed state, so we expect
|
||||
/// the query to succeed.
|
||||
// Test v2/contracts/source (aka GetContractSrc) endpoint.
|
||||
// In this test, we set `tip_req` to UseLatestUnconfirmedTip.
|
||||
// The contract source we are querying for exists in the unconfirmed state, so we expect
|
||||
// the query to succeed.
|
||||
test_rpc(
|
||||
"test_rpc_get_contract_src_use_latest_tip",
|
||||
40104,
|
||||
@@ -4676,9 +4656,9 @@ mod test {
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_rpc_get_map_entry() {
|
||||
/// Test v2/map_entry (aka GetMapEntry) endpoint.
|
||||
/// In this test, we don't set any tip parameters, and we expect that querying for map data
|
||||
/// against the canonical Stacks tip will succeed.
|
||||
// Test v2/map_entry (aka GetMapEntry) endpoint.
|
||||
// In this test, we don't set any tip parameters, and we expect that querying for map data
|
||||
// against the canonical Stacks tip will succeed.
|
||||
test_rpc(
|
||||
"test_rpc_get_map_entry",
|
||||
40130,
|
||||
@@ -4733,9 +4713,9 @@ mod test {
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_rpc_get_map_entry_unconfirmed() {
|
||||
/// Test v2/map_entry (aka GetMapEntry) endpoint.
|
||||
/// In this test, we set `tip_req` to UseLatestUnconfirmedTip, and we expect that querying for map data
|
||||
/// against the unconfirmed state will succeed.
|
||||
// Test v2/map_entry (aka GetMapEntry) endpoint.
|
||||
// In this test, we set `tip_req` to UseLatestUnconfirmedTip, and we expect that querying for map data
|
||||
// against the unconfirmed state will succeed.
|
||||
test_rpc(
|
||||
"test_rpc_get_map_entry_unconfirmed",
|
||||
40140,
|
||||
@@ -4851,9 +4831,9 @@ mod test {
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_rpc_get_contract_abi() {
|
||||
/// Test /v2/contracts/interface (aka GetContractABI) endpoint.
|
||||
/// In this test, we don't set any tip parameters, and we expect that querying
|
||||
/// against the canonical Stacks tip will succeed.
|
||||
// Test /v2/contracts/interface (aka GetContractABI) endpoint.
|
||||
// In this test, we don't set any tip parameters, and we expect that querying
|
||||
// against the canonical Stacks tip will succeed.
|
||||
test_rpc(
|
||||
"test_rpc_get_contract_abi",
|
||||
40150,
|
||||
@@ -4891,9 +4871,9 @@ mod test {
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_rpc_get_contract_abi_unconfirmed() {
|
||||
/// Test /v2/contracts/interface (aka GetContractABI) endpoint.
|
||||
/// In this test, we set `tip_req` to UseLatestUnconfirmedTip, and we expect that querying
|
||||
/// against the unconfirmed state will succeed.
|
||||
// Test /v2/contracts/interface (aka GetContractABI) endpoint.
|
||||
// In this test, we set `tip_req` to UseLatestUnconfirmedTip, and we expect that querying
|
||||
// against the unconfirmed state will succeed.
|
||||
test_rpc(
|
||||
"test_rpc_get_contract_abi_unconfirmed",
|
||||
40152,
|
||||
@@ -4969,9 +4949,9 @@ mod test {
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_rpc_call_read_only() {
|
||||
/// Test /v2/contracts/call-read (aka CallReadOnlyFunction) endpoint.
|
||||
/// In this test, we don't set any tip parameters, and we expect that querying
|
||||
/// against the canonical Stacks tip will succeed.
|
||||
// Test /v2/contracts/call-read (aka CallReadOnlyFunction) endpoint.
|
||||
// In this test, we don't set any tip parameters, and we expect that querying
|
||||
// against the canonical Stacks tip will succeed.
|
||||
test_rpc(
|
||||
"test_rpc_call_read_only",
|
||||
40170,
|
||||
@@ -5017,9 +4997,9 @@ mod test {
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_rpc_call_read_only_use_latest_tip() {
|
||||
/// Test /v2/contracts/call-read (aka CallReadOnlyFunction) endpoint.
|
||||
/// In this test, we set `tip_req` to UseLatestUnconfirmedTip, and we expect that querying
|
||||
/// against the unconfirmed state will succeed.
|
||||
// Test /v2/contracts/call-read (aka CallReadOnlyFunction) endpoint.
|
||||
// In this test, we set `tip_req` to UseLatestUnconfirmedTip, and we expect that querying
|
||||
// against the unconfirmed state will succeed.
|
||||
test_rpc(
|
||||
"test_rpc_call_read_only_use_latest_tip",
|
||||
40172,
|
||||
|
||||
@@ -710,9 +710,9 @@ fn get_contract_src(
|
||||
) -> Result<String, String> {
|
||||
let client = reqwest::blocking::Client::new();
|
||||
let query_string = if use_latest_tip {
|
||||
"?use_latest_tip=true".to_string()
|
||||
"?tip=latest".to_string()
|
||||
} else {
|
||||
"?use_latest_tip=false".to_string()
|
||||
"".to_string()
|
||||
};
|
||||
let path = format!(
|
||||
"{}/v2/contracts/source/{}/{}{}",
|
||||
@@ -5883,16 +5883,16 @@ fn atlas_stress_integration_test() {
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn use_latest_tip_integration_test() {
|
||||
// The purpose of this test is to check if the `use_latest_tip` query parameter is working
|
||||
// The purpose of this test is to check if setting the query parameter `tip` to `latest` is working
|
||||
// as expected. Multiple endpoints accept this parameter, and in this test, we are using the
|
||||
// GetContractSrc method to test it.
|
||||
//
|
||||
// The following scenarios are tested here:
|
||||
// - The caller passes use_latest_tip=0, and the canonical chain tip is used regardless of the
|
||||
// - The caller does not specify the tip paramater, and the canonical chain tip is used regardless of the
|
||||
// state of the unconfirmed microblock stream.
|
||||
// - The caller passes use_latest_tip=1 with an existing unconfirmed microblock stream, and
|
||||
// - The caller passes tip=latest with an existing unconfirmed microblock stream, and
|
||||
// Clarity state from the unconfirmed microblock stream is successfully loaded.
|
||||
// - The caller passes use_latest_tip=1 with an empty unconfirmed microblock stream, and
|
||||
// - The caller passes tip=latest with an empty unconfirmed microblock stream, and
|
||||
// Clarity state from the canonical chain tip is successfully loaded (i.e. you don't
|
||||
// get a 404 even though the unconfirmed chain tip points to a nonexistent MARF trie).
|
||||
//
|
||||
@@ -6060,7 +6060,7 @@ fn use_latest_tip_integration_test() {
|
||||
let microblock_events = test_observer::get_microblocks();
|
||||
assert_eq!(microblock_events.len(), 1);
|
||||
|
||||
// Set use_latest_tip=0, and ask for the source of the contract we just defined in a microblock.
|
||||
// Don't set the tip parameter, and ask for the source of the contract we just defined in a microblock.
|
||||
// This should fail because the anchored tip would be unaware of this contract.
|
||||
let err_opt = get_contract_src(
|
||||
&http_origin,
|
||||
@@ -6072,17 +6072,17 @@ fn use_latest_tip_integration_test() {
|
||||
Ok(_) => {
|
||||
panic!(
|
||||
"Asking for the contract source off the anchored tip for a contract published \
|
||||
only in unconfirmed state should panic."
|
||||
only in unconfirmed state should error."
|
||||
);
|
||||
}
|
||||
// Expect to get "NoSuchContract" because the function we are attempting to call is in a
|
||||
// contract that only exists on unconfirmed state (and we set `use_unconfirmed_tip` to false).
|
||||
// contract that only exists on unconfirmed state (and we did not set tip).
|
||||
Err(err_str) => {
|
||||
assert!(err_str.contains("No contract source data found"));
|
||||
}
|
||||
}
|
||||
|
||||
// Set use_latest_tip=1, and ask for the source of the contract defined in the microblock.
|
||||
// Set tip=latest, and ask for the source of the contract defined in the microblock.
|
||||
// This should succeeed.
|
||||
assert!(get_contract_src(
|
||||
&http_origin,
|
||||
@@ -6109,7 +6109,7 @@ fn use_latest_tip_integration_test() {
|
||||
};
|
||||
assert!(!trie_exists);
|
||||
|
||||
// Set use_latest_tip=1, and ask for the source of the contract defined in the previous epoch.
|
||||
// Set tip=latest, and ask for the source of the contract defined in the previous epoch.
|
||||
// The underlying MARF trie for the unconfirmed tip does not exist, so the transaction will be
|
||||
// validated against the confirmed chain tip instead of the unconfirmed tip. This should be valid.
|
||||
assert!(get_contract_src(
|
||||
|
||||
Reference in New Issue
Block a user