Skip to content

Commit

Permalink
Node registry (project-serum#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
armaniferrante authored Oct 2, 2020
1 parent db82618 commit 43d1f8c
Show file tree
Hide file tree
Showing 54 changed files with 3,774 additions and 249 deletions.
22 changes: 8 additions & 14 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,7 @@ language: shell
os: linux

_defaults: &defaults
cache:
directories:
- $TRAVIS_HOME/.cargo
- $TRAVIS_HOME/.rustup
- $TRAVIS_HOME/.cache
- $TRAVIS_BUILD_DIR/crank/target
- $TRAVIS_BUILD_DIR/dex/target
cache: false
services:
- docker
before_install:
Expand All @@ -17,7 +11,6 @@ _defaults: &defaults
- mkdir -p bin && ./bpf-sdk-install.sh bin
before_cache:
- scripts/travis/stop-docker.sh
- rm -rf "$TRAVIS_HOME/.cargo/registry/src"

_localnet: &localnet
language: node_js
Expand All @@ -40,16 +33,17 @@ jobs:
script:
- docker exec dev ./scripts/travis/dex-tests.sh
- <<: *defaults
name: Safe strict build
name: Safe tests
<<: *localnet
script:
- docker exec dev make -C safe build features=strict
- docker exec dev make -C safe init-test features=strict
- <<: *defaults
name: Safe tests
name: Registry tests
<<: *localnet
script:
- docker exec dev make -C safe init-test
- docker exec dev make -C registry init-test
- <<: *defaults
name: Common
name: Fmt and Common Tests
script:
- docker exec dev cargo fmt -- --check
- docker exec -w=/workdir/common dev cargo test --features client
- docker exec -w=/workdir/common dev cargo test --features client,strict
26 changes: 26 additions & 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 Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
members = [
"solana-client-gen",
"common",
"common/tests",
"crank",
"safe",
"registry",
]
exclude = [
"safe/program",
"dex",
"registry/program",
"rewards/constant",
]
100 changes: 100 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# This is the parent Makefile used by Solana program crates. It's expected
# this is included in child Makefiles with commands overriden as desired
# (this is why all the targets here end with % wildcards). In addition to
# override targets, one can customize the behavior, by override following
# variables in a child Makefile. See `registry/Makefile` for an example of
# a child.

#
# Path to your local solana keypair.
#
TEST_PAYER_FILEPATH="$(HOME)/.config/solana/id.json"
#
# The solana cluster to test against. Defaults to local.
#
TEST_CLUSTER=localnet
#
# The url of TEST_CLUSTER.
#
TEST_CLUSTER_URL="http://localhost:8899"
#
# One can optionally set this along with the test-program command
# to avoid redeploying everytime tests are run.
#
TEST_PROGRAM_ID=""
#
# Default options used for the solana cli.
#
SOL_OPTIONS=--url $(TEST_CLUSTER_URL) --keypair $(TEST_PAYER_FILEPATH)
#
# Path to the BPF sdk to build solana programs.
#
BPF_SDK=$(shell pwd)/../bin/bpf-sdk
#
# The name of the directory holding your Solana program, relative to the Makefile.
#
PROGRAM_DIRNAME=program
#
# Parent dir for the Solana program's build target.
#
BUILD_DIR=$(shell pwd)/$(PROGRAM_DIRNAME)/target/bpfel-unknown-unknown/release
#
# The program's crate name.
#
LIB_NAME=<your-solana-program>

.PHONY: buil% \
build-clien% \
build-progra% \
deplo% \
tes% \
test-progra% \
test-integratio% \
test-uni% \
clipp% \
custo%

buil%: build-progra% build-clien%
@ # no-op

build-clien%:
ifdef features
@cargo build --features client,$(features)
else
@cargo build --features client
endif

build-progra%:
@$(BPF_SDK)/rust/build.sh $(PROGRAM_DIRNAME)
@cp $(BUILD_DIR)/$(LIB_NAME).so $(BUILD_DIR)/$(LIB_NAME)_debug.so
@$(BPF_SDK)/dependencies/llvm-native/bin/llvm-objcopy --strip-all $(BUILD_DIR)/$(LIB_NAME).so $(BUILD_DIR)/$(LIB_NAME).so

deplo%: buil%
@$(eval TEST_PROGRAM_ID=$(shell solana deploy $(SOL_OPTIONS) $(BUILD_DIR)/$(LIB_NAME).so | jq .programId -r))
@echo "{\"programId\": \"$(TEST_PROGRAM_ID)\"}"

test-progra%:
RUST_BACKTRACE=1 \
TEST_PROGRAM_ID=$(TEST_PROGRAM_ID) \
TEST_PAYER_FILEPATH=$(TEST_PAYER_FILEPATH) \
TEST_CLUSTER=$(TEST_CLUSTER) \
TEST_REWARDS_PROGRAM_ID=$(TEST_REWARDS_PROGRAM_ID) \
cargo test --features test,client -- --nocapture $(args)

tes%: deplo% test-progra%
@ # no-op

init-tes%:
@make init
@make test

test-uni%:
RUST_BACKTRACE=1 \
@cargo test --lib --features test,client -- --nocapture $(args)

ini%:
@yes | solana-keygen new --outfile $(TEST_PAYER_FILEPATH)
@yes | solana airdrop $(SOL_OPTIONS) 100

clipp%:
@cargo clippy --features client
1 change: 1 addition & 0 deletions common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ edition = "2018"
[features]
program = ["spl-token/program", "solana-sdk/program"]
client = ["spl-token/default", "solana-sdk/default", "solana-client", "anyhow", "rand"]
strict = []

[dependencies]
spl-token = { version = "=2.0.3", default-features = false }
Expand Down
2 changes: 1 addition & 1 deletion common/src/client/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ pub fn account_token_unpacked<T: TokenPack>(client: &RpcClient, addr: &Pubkey) -
T::unpack_from_slice(&account.data).unwrap()
}

pub fn account_unpacked<'a, T: Pack<'a>>(client: &RpcClient, addr: &Pubkey) -> T {
pub fn account_unpacked<T: Pack>(client: &RpcClient, addr: &Pubkey) -> T {
let account = client
.get_account_with_commitment(addr, CommitmentConfig::recent())
.unwrap()
Expand Down
2 changes: 2 additions & 0 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![cfg_attr(feature = "strict", deny(warnings))]

#[cfg(feature = "client")]
pub mod client;
#[macro_use]
Expand Down
4 changes: 2 additions & 2 deletions common/src/pack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub use solana_sdk::program_error::ProgramError;
/// The Pack trait defines Account serialization for Solana programs.
///
/// If possible, don't use `*_unchecked` methods.
pub trait Pack<'a>: serde::Serialize + serde::Deserialize<'a> {
pub trait Pack: std::marker::Sized {
/// Serializes `src` into `dst`. The size of the serialization and
/// dst must be equal.
fn pack(src: Self, dst: &mut [u8]) -> Result<(), ProgramError>;
Expand Down Expand Up @@ -70,7 +70,7 @@ pub trait Pack<'a>: serde::Serialize + serde::Deserialize<'a> {
#[macro_export]
macro_rules! packable {
($my_struct:ty) => {
impl<'a> Pack<'a> for $my_struct {
impl Pack for $my_struct {
fn pack(src: $my_struct, dst: &mut [u8]) -> Result<(), ProgramError> {
if src.size()? != dst.len() as u64 {
return Err(ProgramError::InvalidAccountData);
Expand Down
13 changes: 13 additions & 0 deletions common/tests/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "serum-common-tests"
version = "0.1.0"
description = "Serum common test utilities"
repository = "https://github.com/project-serum/serum-dex"
edition = "2018"

[features]
strict = []

[dependencies]
solana-client-gen = { path = "../../solana-client-gen", features = ["client"] }
serum-common = { path = "../", features = ["client"] }
119 changes: 119 additions & 0 deletions common/tests/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#![cfg_attr(feature = "strict", deny(warnings))]

use serum_common::client::Cluster;
use solana_client_gen::prelude::ClientGen;
use solana_client_gen::prelude::*;
use solana_client_gen::solana_client::rpc_config::RpcSendTransactionConfig;
use solana_client_gen::solana_sdk::commitment_config::CommitmentConfig;

// Creates
//
// * Mint authority (shared between SRM and MSRM)
// * SRM mint
// * SRM god account (funded wallet)
// * MSRM mint
// * MSRM god account (funded wallet)
// * RPC client.
//
pub fn genesis<T: ClientGen>() -> Genesis<T> {
let client = client::<T>();

let spl_mint_decimals = 3;

// Initialize the SPL token representing SRM.
let mint_authority = Keypair::from_bytes(&Keypair::to_bytes(client.payer().clone())).unwrap();
let srm_mint = Keypair::generate(&mut OsRng);
let _ = serum_common::client::rpc::create_and_init_mint(
client.rpc(),
client.payer(),
&srm_mint,
&mint_authority.pubkey(),
spl_mint_decimals,
)
.unwrap();

// Initialize the SPL token representing MSRM.
let mint_authority = Keypair::from_bytes(&Keypair::to_bytes(client.payer().clone())).unwrap();
let msrm_mint = Keypair::generate(&mut OsRng);
let _ = serum_common::client::rpc::create_and_init_mint(
client.rpc(),
client.payer(),
&msrm_mint,
&mint_authority.pubkey(),
spl_mint_decimals,
);

// Create a funded SRM account.
let god_balance_before = 1_000_000;
let god = serum_common::client::rpc::mint_to_new_account(
client.rpc(),
client.payer(),
&mint_authority,
&srm_mint.pubkey(),
god_balance_before,
)
.unwrap();
// Create a funded MSRM account.
let god_msrm_balance_before = 1_000_000;
let god_msrm = serum_common::client::rpc::mint_to_new_account(
client.rpc(),
client.payer(),
&mint_authority,
&msrm_mint.pubkey(),
god_balance_before,
)
.unwrap();

let god_owner = Keypair::from_bytes(&Keypair::to_bytes(client.payer().clone())).unwrap();

Genesis {
client,
mint_authority,
srm_mint,
msrm_mint,
god,
god_msrm,
god_balance_before,
god_msrm_balance_before,
god_owner,
}
}

// Genesis defines the initial state of the world.
pub struct Genesis<T: ClientGen> {
// RPC client.
pub client: T,
// SRM mint authority.
pub mint_authority: Keypair,
// SRM.
pub srm_mint: Keypair,
// MSRM.
pub msrm_mint: Keypair,
// Account funded with a ton of SRM.
pub god: Keypair,
// Account funded with a ton of MSRM.
pub god_msrm: Keypair,
// Balance of the god account to start.
pub god_balance_before: u64,
// Balance of the god_msrm account to start.
pub god_msrm_balance_before: u64,
// Owner of both god accounts.
pub god_owner: Keypair,
}

// Returns a solana-client-gen generated client from the environment.
pub fn client<T: ClientGen>() -> T {
let program_id = std::env::var("TEST_PROGRAM_ID").unwrap().parse().unwrap();
let payer_filepath = std::env::var("TEST_PAYER_FILEPATH").unwrap().clone();
let cluster: Cluster = std::env::var("TEST_CLUSTER").unwrap().parse().unwrap();

T::from_keypair_file(program_id, &payer_filepath, cluster.url())
.expect("invalid keypair file")
.with_options(RequestOptions {
commitment: CommitmentConfig::single(),
tx: RpcSendTransactionConfig {
skip_preflight: true,
preflight_commitment: None,
},
})
}
Loading

0 comments on commit 43d1f8c

Please sign in to comment.