Skip to content

Add RegTest RPC methods for Genesis values #1040

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion node-lib/src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,10 @@ async fn initialize(
// RPC Functions for tests
let rpc_test_functions = if chain_config.chain_type() == &ChainType::Regtest {
// We add the test rpc functions only if we are in regtest mode
manager.add_subsystem("rpc_test_functions", make_rpc_test_functions())
manager.add_subsystem(
"rpc_test_functions",
make_rpc_test_functions(Arc::clone(&chain_config)),
)
} else {
// Otherwise we add empty rpc functions
manager.add_subsystem("rpc_test_functions", make_empty_rpc_test_functions())
Expand Down
1 change: 1 addition & 0 deletions test-rpc-functions/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ edition = "2021"

[dependencies]
chainstate-types = { path = "../chainstate/types" }
chainstate = { path = "../chainstate/" }
common = { path = "../common/" }
crypto = { path = "../crypto/" }
rpc = { path = "../rpc/" }
Expand Down
9 changes: 8 additions & 1 deletion test-rpc-functions/src/empty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use std::sync::Arc;

use crate::interface::rpc_test_interface::RpcTestFunctionsInterface;
use common::chain::ChainConfig;

// Empty implementation to exclude test functions under certain conditions, such as mainnet
pub struct EmptyRpcTestFunctionsRpc;
Expand All @@ -34,4 +37,8 @@ pub fn make_empty_rpc_test_functions() -> Box<dyn RpcTestFunctionsInterface> {
Box::new(EmptyRpcTestFunctionsRpc::new())
}

impl RpcTestFunctionsInterface for EmptyRpcTestFunctionsRpc {}
impl RpcTestFunctionsInterface for EmptyRpcTestFunctionsRpc {
fn get_chain_config(&self) -> Option<Arc<ChainConfig>> {
None
}
}
8 changes: 7 additions & 1 deletion test-rpc-functions/src/interface/rpc_test_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use std::sync::Arc;

use common::chain::ChainConfig;

#[async_trait::async_trait]
pub trait RpcTestFunctionsInterface: Send {}
pub trait RpcTestFunctionsInterface: Send {
fn get_chain_config(&self) -> Option<Arc<ChainConfig>>;
}
19 changes: 18 additions & 1 deletion test-rpc-functions/src/interface/rpc_test_interface_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,26 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use std::sync::Arc;

use crate::RpcTestFunctions;
use common::chain::ChainConfig;

use super::rpc_test_interface::RpcTestFunctionsInterface;

pub struct RpcTestFunctionsImpl {
rpc_test_functions: RpcTestFunctions,
}

impl RpcTestFunctionsImpl {
pub fn new(rpc_test_functions: RpcTestFunctions) -> Self {
Self { rpc_test_functions }
}
}

#[async_trait::async_trait]
impl RpcTestFunctionsInterface for RpcTestFunctions {}
impl RpcTestFunctionsInterface for RpcTestFunctionsImpl {
fn get_chain_config(&self) -> Option<Arc<ChainConfig>> {
Some(Arc::clone(&self.rpc_test_functions.chain_config))
}
}
23 changes: 17 additions & 6 deletions test-rpc-functions/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use std::sync::Arc;

use chainstate_types::vrf_tools::ProofOfStakeVRFError;
use common::chain::ChainConfig;
use crypto::key::SignatureError;
use interface::rpc_test_interface::RpcTestFunctionsInterface;
use interface::{
rpc_test_interface::RpcTestFunctionsInterface, rpc_test_interface_impl::RpcTestFunctionsImpl,
};
use subsystem::subsystem::CallError;

pub mod empty;
Expand All @@ -32,18 +37,24 @@ pub enum RpcTestFunctionsError {
ProofOfStakeVRFError(#[from] ProofOfStakeVRFError),
}

pub struct RpcTestFunctions {}
pub struct RpcTestFunctions {
chain_config: Arc<ChainConfig>,
}

impl RpcTestFunctions {
pub fn new() -> Self {
Self {}
pub fn new(chain_config: Arc<ChainConfig>) -> Self {
Self { chain_config }
}
}

pub type RpcTestFunctionsHandle = subsystem::Handle<Box<dyn RpcTestFunctionsInterface>>;

impl subsystem::Subsystem for Box<dyn RpcTestFunctionsInterface> {}

pub fn make_rpc_test_functions() -> Box<dyn RpcTestFunctionsInterface> {
Box::new(RpcTestFunctions::new())
pub fn make_rpc_test_functions(
chain_config: Arc<ChainConfig>,
) -> Box<dyn RpcTestFunctionsInterface> {
let rpc_test_functions = RpcTestFunctions::new(chain_config);
let rpc_test_functions_interface = RpcTestFunctionsImpl::new(rpc_test_functions);
Box::new(rpc_test_functions_interface)
}
102 changes: 100 additions & 2 deletions test-rpc-functions/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,35 @@

use chainstate_types::vrf_tools::{construct_transcript, verify_vrf_and_get_vrf_output};
use common::{
chain::{block::timestamp::BlockTimestamp, config::EpochIndex},
chain::config::regtest_genesis_values,
chain::{
block::timestamp::BlockTimestamp, config::EpochIndex, stakelock::StakePoolData, PoolId,
TxOutput,
},
primitives::H256,
};
use crypto::key::Signature;
use serialization::{hex::HexDecode, hex::HexEncode};

use crate::RpcTestFunctionsError;
use crate::{RpcTestFunctionsError, RpcTestFunctionsHandle};

#[rpc::rpc(server, namespace = "test_functions")]
trait RpcTestFunctionsRpc {
#[method(name = "genesis_pool_id")]
async fn genesis_pool_id(&self) -> rpc::Result<Option<String>>;

#[method(name = "genesis_private_key")]
async fn genesis_private_key(&self) -> rpc::Result<Option<String>>;

#[method(name = "genesis_public_key")]
async fn genesis_public_key(&self) -> rpc::Result<Option<String>>;

#[method(name = "genesis_vrf_private_key")]
async fn genesis_vrf_private_key(&self) -> rpc::Result<Option<String>>;

#[method(name = "genesis_vrf_public_key")]
async fn genesis_vrf_public_key(&self) -> rpc::Result<Option<String>>;

#[method(name = "new_private_key")]
async fn new_private_key(&self) -> rpc::Result<String>;

Expand Down Expand Up @@ -77,6 +96,60 @@ trait RpcTestFunctionsRpc {

#[async_trait::async_trait]
impl RpcTestFunctionsRpcServer for super::RpcTestFunctionsHandle {
async fn genesis_pool_id(&self) -> rpc::Result<Option<String>> {
let (genesis_pool_id, genesis_stake_pool_data, _, _, _, _) = regtest_genesis_values();

Ok(
assert_genesis_values(self, genesis_pool_id, genesis_stake_pool_data)
.await
.then_some(genesis_pool_id.hex_encode()),
)
}

async fn genesis_private_key(&self) -> rpc::Result<Option<String>> {
let (genesis_pool_id, genesis_stake_pool_data, genesis_stake_private_key, _, _, _) =
regtest_genesis_values();

Ok(
assert_genesis_values(self, genesis_pool_id, genesis_stake_pool_data)
.await
.then_some(genesis_stake_private_key.hex_encode()),
)
}

async fn genesis_public_key(&self) -> rpc::Result<Option<String>> {
let (genesis_pool_id, genesis_stake_pool_data, _, genesis_stake_public_key, _, _) =
regtest_genesis_values();

Ok(
assert_genesis_values(self, genesis_pool_id, genesis_stake_pool_data)
.await
.then_some(genesis_stake_public_key.hex_encode()),
)
}

async fn genesis_vrf_private_key(&self) -> rpc::Result<Option<String>> {
let (genesis_pool_id, genesis_stake_pool_data, _, _, genesis_vrf_private_key, _) =
regtest_genesis_values();

Ok(
assert_genesis_values(self, genesis_pool_id, genesis_stake_pool_data)
.await
.then_some(genesis_vrf_private_key.hex_encode()),
)
}

async fn genesis_vrf_public_key(&self) -> rpc::Result<Option<String>> {
let (genesis_pool_id, genesis_stake_pool_data, _, _, _, genesis_vrf_public_key) =
regtest_genesis_values();

Ok(
assert_genesis_values(self, genesis_pool_id, genesis_stake_pool_data)
.await
.then_some(genesis_vrf_public_key.hex_encode()),
)
}

async fn new_private_key(&self) -> rpc::Result<String> {
let keys =
crypto::key::PrivateKey::new_from_entropy(crypto::key::KeyKind::Secp256k1Schnorr);
Expand Down Expand Up @@ -194,3 +267,28 @@ impl RpcTestFunctionsRpcServer for super::RpcTestFunctionsHandle {
Ok(vrf_output.hex_encode())
}
}

async fn assert_genesis_values(
handle: &RpcTestFunctionsHandle,
genesis_pool_id: PoolId,
genesis_stake_pool_data: Box<StakePoolData>,
) -> bool {
let expected_genesis_pool_txoutput =
TxOutput::CreateStakePool(genesis_pool_id, genesis_stake_pool_data);

let current_create_genesis_pool_txoutput = handle
.call(|this| {
this.get_chain_config()
.and_then(|chain| chain.genesis_block().utxos().get(1).map(|u| u.hex_encode()))
})
.await
.expect("Subsystem call ok");

match current_create_genesis_pool_txoutput {
None => false,
Some(txoutput) => {
assert!(txoutput == expected_genesis_pool_txoutput.hex_encode());
true
}
}
}