Skip to content

Commit

Permalink
Refactoring "state_get_auction_info" and "state_get_auction_info_v2" … (
Browse files Browse the repository at this point in the history
#393)

* Refactoring "state_get_auction_info" and "state_get_auction_info_v2" to make less binary port requests

---------

Co-authored-by: Jakub Zajkowski <[email protected]>
  • Loading branch information
zajko and Jakub Zajkowski authored Jan 17, 2025
1 parent b28ca20 commit de43fbc
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 164 deletions.
88 changes: 14 additions & 74 deletions rpc_sidecar/src/rpcs/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use super::{
};
use auction_state::AuctionState;
use casper_binary_port::{
DictionaryItemIdentifier, EntityIdentifier as PortEntityIdentifier, GlobalStateQueryResult,
DictionaryItemIdentifier, EntityIdentifier as PortEntityIdentifier,
PackageIdentifier as PortPackageIdentifier, PurseIdentifier as PortPurseIdentifier,
};
#[cfg(test)]
Expand All @@ -36,7 +36,6 @@ use casper_types::{
auction::{
BidKind, EraValidators, SeigniorageRecipientsV1, SeigniorageRecipientsV2,
ValidatorWeights, SEIGNIORAGE_RECIPIENTS_SNAPSHOT_KEY,
SEIGNIORAGE_RECIPIENTS_SNAPSHOT_VERSION_KEY,
},
AUCTION,
},
Expand Down Expand Up @@ -381,8 +380,8 @@ impl RpcWithOptionalParams for GetAuctionInfo {
let state_identifier =
state_identifier.unwrap_or(GlobalStateIdentifier::BlockHeight(block_header.height()));

let is_not_condor = block_header.protocol_version().value().major == 1;
let bids = fetch_bid_kinds(node_client.clone(), state_identifier, is_not_condor).await?;
let is_1x = block_header.protocol_version().value().major == 1;
let bids = fetch_bid_kinds(node_client.clone(), state_identifier, is_1x).await?;

// always retrieve the latest system contract registry, old versions of the node
// did not write it to the global state
Expand All @@ -398,12 +397,7 @@ impl RpcWithOptionalParams for GetAuctionInfo {
.into_t()
.map_err(|_| Error::InvalidAuctionState)?;
let &auction_hash = registry.get(AUCTION).ok_or(Error::InvalidAuctionState)?;
let maybe_version = get_seigniorage_recipients_version(
Arc::clone(&node_client),
Some(state_identifier),
auction_hash,
)
.await?;

let (snapshot_value, _) = if let Some(result) = node_client
.query_global_state(
Some(state_identifier),
Expand All @@ -430,7 +424,7 @@ impl RpcWithOptionalParams for GetAuctionInfo {
.into_cl_value()
.ok_or(Error::InvalidAuctionState)?;

let validators = era_validators_from_snapshot(snapshot, maybe_version)?;
let validators = era_validators_from_snapshot(snapshot, is_1x)?;
let auction_state = AuctionState::new(
*block_header.state_root_hash(),
block_header.height(),
Expand All @@ -445,42 +439,18 @@ impl RpcWithOptionalParams for GetAuctionInfo {
}
}

pub(crate) async fn get_seigniorage_recipients_version(
node_client: Arc<dyn NodeClient>,
state_identifier: Option<GlobalStateIdentifier>,
auction_hash: AddressableEntityHash,
) -> Result<Option<u8>, Error> {
let key = Key::addressable_entity_key(EntityKindTag::System, auction_hash);
if let Some(result) = fetch_seigniorage_recipients_snapshot_version_key(
Arc::clone(&node_client),
key,
state_identifier,
)
.await?
{
Ok(Some(result))
} else {
let key = Key::Hash(auction_hash.value());
fetch_seigniorage_recipients_snapshot_version_key(node_client, key, state_identifier).await
}
}

pub(crate) async fn fetch_bid_kinds(
node_client: Arc<dyn NodeClient>,
state_identifier: GlobalStateIdentifier,
is_not_condor: bool,
is_1x: bool,
) -> Result<Vec<BidKind>, RpcError> {
let key_tag = if is_not_condor {
KeyTag::Bid
} else {
KeyTag::BidAddr
};
let key_tag = if is_1x { KeyTag::Bid } else { KeyTag::BidAddr };
let stored_values = node_client
.query_global_state_by_tag(Some(state_identifier), key_tag)
.await
.map_err(|err| Error::NodeRequest("auction bids", err))?
.into_iter();
let res: Result<Vec<BidKind>, Error> = if is_not_condor {
let res: Result<Vec<BidKind>, Error> = if is_1x {
stored_values
.map(|v| v.into_bid().ok_or(Error::InvalidAuctionState))
.map(|bid_res| bid_res.map(|bid| BidKind::Unified(bid.into())))
Expand All @@ -493,36 +463,6 @@ pub(crate) async fn fetch_bid_kinds(
res.map_err(|e| e.into())
}

pub(crate) async fn fetch_seigniorage_recipients_snapshot_version_key(
node_client: Arc<dyn NodeClient>,
base_key: Key,
state_identifier: Option<GlobalStateIdentifier>,
) -> Result<Option<u8>, Error> {
node_client
.query_global_state(
state_identifier,
base_key,
vec![SEIGNIORAGE_RECIPIENTS_SNAPSHOT_VERSION_KEY.to_owned()],
)
.await
.map(|result| result.and_then(unwrap_seigniorage_recipients_result))
.map_err(|err| Error::NodeRequest("auction snapshot", err))
}

pub(crate) fn unwrap_seigniorage_recipients_result(
query_result: GlobalStateQueryResult,
) -> Option<u8> {
let (version_value, _) = query_result.into_inner();
let maybe_cl_value = version_value.into_cl_value();
match maybe_cl_value {
Some(cl_value) => {
let a = cl_value.into_t();
Some(a.unwrap())
}
None => None,
}
}

/// Identifier of an account.
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema)]
#[serde(deny_unknown_fields, untagged)]
Expand Down Expand Up @@ -1370,12 +1310,12 @@ impl RpcWithParams for GetTrie {

pub(crate) fn era_validators_from_snapshot(
snapshot: CLValue,
maybe_version: Option<u8>,
is_1x: bool,
) -> Result<EraValidators, RpcError> {
if maybe_version.is_some() {
//handle as condor
if is_1x {
//handle as pre-condor
//TODO add some context to the error
let seigniorage: BTreeMap<EraId, SeigniorageRecipientsV2> =
let seigniorage: BTreeMap<EraId, SeigniorageRecipientsV1> =
snapshot.into_t().map_err(|_| Error::InvalidAuctionState)?;
Ok(seigniorage
.into_iter()
Expand All @@ -1390,9 +1330,9 @@ pub(crate) fn era_validators_from_snapshot(
})
.collect())
} else {
//handle as pre-condor
//handle as condor
//TODO add some context to the error
let seigniorage: BTreeMap<EraId, SeigniorageRecipientsV1> =
let seigniorage: BTreeMap<EraId, SeigniorageRecipientsV2> =
snapshot.into_t().map_err(|_| Error::InvalidAuctionState)?;
Ok(seigniorage
.into_iter()
Expand Down
44 changes: 6 additions & 38 deletions rpc_sidecar/src/rpcs/state_get_auction_info_v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use serde::{Deserialize, Serialize};

use super::common;
use super::state::{
era_validators_from_snapshot, fetch_bid_kinds, get_seigniorage_recipients_version,
GetAuctionInfoParams, JsonEraValidators, JsonValidatorWeight,
era_validators_from_snapshot, fetch_bid_kinds, GetAuctionInfoParams, JsonEraValidators,
JsonValidatorWeight,
};
use super::{
docs::{DocExample, DOCS_EXAMPLE_API_VERSION},
Expand Down Expand Up @@ -105,8 +105,8 @@ impl RpcWithOptionalParams for GetAuctionInfo {
let state_identifier =
state_identifier.unwrap_or(GlobalStateIdentifier::BlockHeight(block_header.height()));

let is_not_condor = block_header.protocol_version().value().major == 1;
let bids = fetch_bid_kinds(node_client.clone(), state_identifier, is_not_condor).await?;
let is_1x = block_header.protocol_version().value().major == 1;
let bids = fetch_bid_kinds(node_client.clone(), state_identifier, is_1x).await?;

// always retrieve the latest system contract registry, old versions of the node
// did not write it to the global state
Expand All @@ -122,12 +122,7 @@ impl RpcWithOptionalParams for GetAuctionInfo {
.into_t()
.map_err(|_| Error::InvalidAuctionState)?;
let &auction_hash = registry.get(AUCTION).ok_or(Error::InvalidAuctionState)?;
let maybe_version = get_seigniorage_recipients_version(
Arc::clone(&node_client),
Some(state_identifier),
auction_hash,
)
.await?;

let (snapshot_value, _) = if let Some(result) = node_client
.query_global_state(
Some(state_identifier),
Expand All @@ -154,7 +149,7 @@ impl RpcWithOptionalParams for GetAuctionInfo {
.into_cl_value()
.ok_or(Error::InvalidAuctionState)?;

let validators = era_validators_from_snapshot(snapshot, maybe_version)?;
let validators = era_validators_from_snapshot(snapshot, is_1x)?;
let auction_state = AuctionState::new(
*block_header.state_root_hash(),
block_header.height(),
Expand Down Expand Up @@ -300,16 +295,6 @@ mod tests {
binary_port_mock
.add_system_registry(state_identifier, registry)
.await;
binary_port_mock
.add_seigniorage_recipients_version_addressable_entity(
None,
state_identifier,
auction_hash,
)
.await;
binary_port_mock
.add_seigniorage_recipients_version_key_hash(None, state_identifier, auction_hash)
.await;
binary_port_mock
.add_seigniorage_snapshot_under_addressable_entity(state_identifier, auction_hash, None)
.await;
Expand Down Expand Up @@ -388,16 +373,6 @@ mod tests {
binary_port_mock
.add_system_registry(state_identifier, registry)
.await;
binary_port_mock
.add_seigniorage_recipients_version_addressable_entity(
None,
state_identifier,
auction_hash,
)
.await;
binary_port_mock
.add_seigniorage_recipients_version_key_hash(Some(2), state_identifier, auction_hash)
.await;
binary_port_mock
.add_seigniorage_snapshot_under_addressable_entity(state_identifier, auction_hash, None)
.await;
Expand Down Expand Up @@ -471,13 +446,6 @@ mod tests {
binary_port_mock
.add_system_registry(state_identifier, registry)
.await;
binary_port_mock
.add_seigniorage_recipients_version_addressable_entity(
Some(2),
state_identifier,
auction_hash,
)
.await;
binary_port_mock
.add_seigniorage_snapshot_under_addressable_entity(
state_identifier,
Expand Down
53 changes: 1 addition & 52 deletions rpc_sidecar/src/rpcs/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ use casper_binary_port::{
use casper_types::{
addressable_entity::EntityKindTag,
bytesrepr::ToBytes,
system::auction::{
Bid, BidKind, SEIGNIORAGE_RECIPIENTS_SNAPSHOT_KEY,
SEIGNIORAGE_RECIPIENTS_SNAPSHOT_VERSION_KEY,
},
system::auction::{Bid, BidKind, SEIGNIORAGE_RECIPIENTS_SNAPSHOT_KEY},
AddressableEntityHash, BlockHeader, CLValue, GlobalStateIdentifier, Key, KeyTag,
ProtocolVersion, SemVer, StoredValue,
};
Expand Down Expand Up @@ -102,54 +99,6 @@ impl BinaryPortMock {
self.when_then(BinaryRequest::Get(req), res).await;
}

pub async fn add_seigniorage_recipients_version_addressable_entity(
&mut self,
maybe_seigniorage_recipients_version: Option<u8>,
state_identifier: Option<GlobalStateIdentifier>,
auction_hash: AddressableEntityHash,
) {
let base_key = Key::addressable_entity_key(EntityKindTag::System, auction_hash);
let req = GetRequest::State(Box::new(GlobalStateRequest::new(
state_identifier,
GlobalStateEntityQualifier::Item {
base_key,
path: vec![SEIGNIORAGE_RECIPIENTS_SNAPSHOT_VERSION_KEY.to_owned()],
},
)));
let res = BinaryResponse::from_option(
maybe_seigniorage_recipients_version.map(|v| {
let cl_value = CLValue::from_t(v).unwrap();
GlobalStateQueryResult::new(StoredValue::CLValue(cl_value), vec![])
}),
*PROTOCOL_VERSION,
);
self.when_then(BinaryRequest::Get(req), res).await;
}

pub async fn add_seigniorage_recipients_version_key_hash(
&mut self,
maybe_seigniorage_recipients_version: Option<u8>,
state_identifier: Option<GlobalStateIdentifier>,
auction_hash: AddressableEntityHash,
) {
let base_key = Key::Hash(auction_hash.value());
let req = GetRequest::State(Box::new(GlobalStateRequest::new(
state_identifier,
GlobalStateEntityQualifier::Item {
base_key,
path: vec![SEIGNIORAGE_RECIPIENTS_SNAPSHOT_VERSION_KEY.to_owned()],
},
)));
let res = BinaryResponse::from_option(
maybe_seigniorage_recipients_version.map(|v| {
let cl_value = CLValue::from_t(v).unwrap();
GlobalStateQueryResult::new(StoredValue::CLValue(cl_value), vec![])
}),
*PROTOCOL_VERSION,
);
self.when_then(BinaryRequest::Get(req), res).await;
}

pub async fn add_seigniorage_snapshot_under_addressable_entity(
&mut self,
state_identifier: Option<GlobalStateIdentifier>,
Expand Down

0 comments on commit de43fbc

Please sign in to comment.