Move drone into its own crate

This commit is contained in:
Michael Vines 2018-11-16 08:04:46 -08:00 committed by Grimes
parent cf95708c18
commit d96a6b42a5
67 changed files with 678 additions and 567 deletions

View File

@ -21,10 +21,6 @@ path = "src/bin/bench-streamer.rs"
name = "solana-bench-tps"
path = "src/bin/bench-tps.rs"
[[bin]]
name = "solana-drone"
path = "src/bin/drone.rs"
[[bin]]
required-features = ["chacha"]
name = "solana-replicator"
@ -113,6 +109,7 @@ tokio = "0.1"
tokio-codec = "0.1"
untrusted = "0.6.2"
solana-bpfloader = { path = "programs/native/bpf_loader", version = "0.11.0" }
solana-drone = { path = "drone", version = "0.11.0" }
solana-erc20 = { path = "programs/native/erc20", version = "0.11.0" }
solana-lualoader = { path = "programs/native/lua_loader", version = "0.11.0" }
solana-noop = { path = "programs/native/noop", version = "0.11.0" }
@ -139,6 +136,7 @@ name = "chacha"
[workspace]
members = [
".",
"drone",
"metrics",
"sdk",
"programs/bpf/rust/noop",

View File

@ -2,14 +2,15 @@
extern crate bincode;
extern crate rayon;
extern crate solana;
extern crate solana_sdk;
extern crate test;
use solana::bank::*;
use solana::hash::hash;
use solana::mint::Mint;
use solana::signature::{Keypair, KeypairUtil};
use solana::system_transaction::SystemTransaction;
use solana::transaction::Transaction;
use solana_sdk::hash::hash;
use test::Bencher;
#[bench]

View File

@ -11,12 +11,12 @@ use rayon::prelude::*;
use solana::bank::{Bank, MAX_ENTRY_IDS};
use solana::banking_stage::{BankingStage, NUM_THREADS};
use solana::entry::Entry;
use solana::hash::hash;
use solana::mint::Mint;
use solana::packet::to_packets_chunked;
use solana::signature::{KeypairUtil, Signature};
use solana::system_transaction::SystemTransaction;
use solana::transaction::Transaction;
use solana_sdk::hash::hash;
use solana_sdk::pubkey::Pubkey;
use std::iter;
use std::sync::mpsc::{channel, Receiver};

View File

@ -1,13 +1,14 @@
#![feature(test)]
extern crate solana;
extern crate solana_sdk;
extern crate test;
use solana::entry::reconstruct_entries_from_blobs;
use solana::hash::{hash, Hash};
use solana::ledger::{next_entries, Block};
use solana::signature::{Keypair, KeypairUtil};
use solana::system_transaction::SystemTransaction;
use solana::transaction::Transaction;
use solana_sdk::hash::{hash, Hash};
use test::Bencher;
#[bench]

View File

@ -1 +1,2 @@
cargo-install/
usr/

View File

@ -18,8 +18,11 @@ if [[ -z $CHANNEL ]]; then
fi
rm -rf usr/
../docker-run.sh solanalabs/rust:1.30.0 \
../docker-run.sh solanalabs/rust:1.30.1 bash -c "
set -ex
cargo install --path drone --root ci/docker-solana/usr
cargo install --path . --root ci/docker-solana/usr
"
cp -f entrypoint.sh usr/bin/solana-entrypoint.sh
../../scripts/install-native-programs.sh usr/bin/

View File

@ -19,7 +19,7 @@ if [[ -n $CI ]]; then
fi
# shellcheck disable=2044 # Disable 'For loops over find output are fragile...'
for Cargo_toml in {sdk,metrics,programs/native/{bpf_loader,lua_loader,noop},.}/Cargo.toml; do
for Cargo_toml in {sdk,metrics,drone,programs/native/{bpf_loader,lua_loader,noop},.}/Cargo.toml; do
# TODO: Ensure the published version matches the contents of BUILDKITE_TAG
(
set -x

View File

@ -43,7 +43,8 @@ echo --- Creating tarball
git rev-parse HEAD
) > solana-release/version.txt
cargo install --root solana-release
cargo install --path drone --root solana-release
cargo install --path . --root solana-release
./scripts/install-native-programs.sh solana-release/bin
./fetch-perf-libs.sh

View File

@ -25,6 +25,7 @@ _() {
}
FEATURES=cuda,erasure,chacha
_ cargo build --all --verbose --features="$FEATURES"
_ cargo test --verbose --features="$FEATURES" --lib
# Run integration tests serially

View File

@ -25,7 +25,7 @@ maybe_install() {
}
_ cargo fmt -- --check
_ cargo build --verbose
_ cargo build --all --verbose
_ cargo test --verbose --lib
_ cargo clippy -- --deny=warnings || true

29
drone/Cargo.toml Normal file
View File

@ -0,0 +1,29 @@
[package]
name = "solana-drone"
version = "0.11.0"
description = "Solana Drone"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
[dependencies]
bincode = "1.0.0"
bytes = "0.4"
byteorder = "1.2.1"
clap = "2.31"
log = "0.4.2"
serde = "1.0.27"
serde_derive = "1.0.27"
solana-sdk = { path = "../sdk", version = "0.11.0" }
solana-metrics = { path = "../metrics", version = "0.11.0" }
tokio = "0.1"
tokio-codec = "0.1"
[lib]
name = "solana_drone"
crate-type = ["lib"]
[[bin]]
name = "solana-drone"
path = "src/bin/drone.rs"

View File

@ -4,9 +4,10 @@ extern crate bytes;
#[macro_use]
extern crate clap;
extern crate log;
extern crate serde_json;
extern crate solana;
#[macro_use]
extern crate solana_drone;
extern crate solana_metrics;
extern crate solana_sdk;
extern crate tokio;
extern crate tokio_codec;
@ -14,9 +15,9 @@ use bincode::{deserialize, serialize};
use byteorder::{ByteOrder, LittleEndian};
use bytes::Bytes;
use clap::{App, Arg};
use solana::drone::{Drone, DroneRequest, DRONE_PORT};
use solana::logger;
use solana::signature::read_keypair;
use solana_drone::drone::{Drone, DroneRequest, DRONE_PORT};
//use solana::logger;
use solana_sdk::signature::read_keypair;
use std::error;
use std::io;
use std::net::{Ipv4Addr, SocketAddr};
@ -26,18 +27,8 @@ use tokio::net::TcpListener;
use tokio::prelude::*;
use tokio_codec::{BytesCodec, Decoder};
macro_rules! socketaddr {
($ip:expr, $port:expr) => {
SocketAddr::from((Ipv4Addr::from($ip), $port))
};
($str:expr) => {{
let a: SocketAddr = $str.parse().unwrap();
a
}};
}
fn main() -> Result<(), Box<error::Error>> {
logger::setup();
//logger::setup();
solana_metrics::set_panic_hook("drone");
let matches = App::new("drone")
.version(crate_version!())

View File

@ -7,13 +7,14 @@
use bincode::{deserialize, serialize};
use byteorder::{ByteOrder, LittleEndian};
use bytes::Bytes;
use hash::Hash;
use packet::PACKET_DATA_SIZE;
use signature::Keypair;
use solana_metrics;
use solana_metrics::influxdb;
use solana_sdk::hash::Hash;
use solana_sdk::packet::PACKET_DATA_SIZE;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::Keypair;
use solana_sdk::system_instruction::{SystemInstruction, SYSTEM_PROGRAM_ID};
use solana_sdk::transaction::Transaction;
use std::io;
use std::io::{Error, ErrorKind};
use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpStream};
@ -21,12 +22,21 @@ use std::sync::mpsc::Sender;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
use system_transaction::SystemTransaction;
use tokio;
use tokio::net::TcpListener;
use tokio::prelude::*;
use tokio_codec::{BytesCodec, Decoder};
use transaction::Transaction;
#[macro_export]
macro_rules! socketaddr {
($ip:expr, $port:expr) => {
SocketAddr::from((Ipv4Addr::from($ip), $port))
};
($str:expr) => {{
let a: SocketAddr = $str.parse().unwrap();
a
}};
}
pub const TIME_SLICE: u64 = 60;
pub const REQUEST_CAP: u64 = 500_000_000;
@ -124,9 +134,23 @@ impl Drone {
);
info!("Requesting airdrop of {} to {:?}", tokens, to);
let mut tx = Transaction::system_new(&self.mint_keypair, to, tokens, last_id);
tx.sign(&[&self.mint_keypair], last_id);
Ok(tx)
let create_instruction = SystemInstruction::CreateAccount {
tokens,
space: 0,
program_id: Pubkey::default(),
};
let mut transaction = Transaction::new(
&self.mint_keypair,
&[to],
Pubkey::new(&SYSTEM_PROGRAM_ID),
&create_instruction,
last_id,
0, /*fee*/
);
transaction.sign(&[&self.mint_keypair], last_id);
Ok(transaction)
} else {
Err(Error::new(ErrorKind::Other, "token limit reached"))
}
@ -276,7 +300,7 @@ mod tests {
use logger;
use mint::Mint;
use netutil::get_ip_addr;
use signature::{Keypair, KeypairUtil};
use solana_sdk::signature::{Keypair, KeypairUtil};
use std::fs::remove_dir_all;
use std::net::{SocketAddr, UdpSocket};
use std::sync::{Arc, RwLock};

14
drone/src/lib.rs Normal file
View File

@ -0,0 +1,14 @@
pub mod drone;
extern crate bincode;
extern crate byteorder;
extern crate bytes;
#[macro_use]
extern crate log;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate solana_metrics;
extern crate solana_sdk;
extern crate tokio;
extern crate tokio_codec;

View File

@ -57,10 +57,13 @@ else
program=${BASH_REMATCH[1]}
features="--features=cuda"
fi
if [[ "$program" = drone ]]; then
maybe_package="--package solana-drone"
fi
if [[ -z $DEBUG ]]; then
maybe_release=--release
fi
printf "cargo run $maybe_release --bin solana-%s %s -- " "$program" "$features"
printf "cargo run $maybe_release $maybe_package --bin solana-%s %s -- " "$program" "$features"
}
if [[ -n $SOLANA_CUDA ]]; then
# shellcheck disable=2154 # 'here' is referenced but not assigned

View File

@ -136,7 +136,11 @@ build() {
# shellcheck source=/dev/null
source target/perf-libs/env.sh
fi
$MAYBE_DOCKER cargo install --features="$cargoFeatures" --root farf
$MAYBE_DOCKER bash -c "
set -ex
cargo install --path drone --features=$cargoFeatures --root farf
cargo install --path . --features=$cargoFeatures --root farf
"
./scripts/install-native-programs.sh farf/
)
echo "Build took $SECONDS seconds"

View File

@ -11,7 +11,10 @@ bincode = "1.0.0"
bs58 = "0.2.0"
generic-array = { version = "0.12.0", default-features = false, features = ["serde"] }
log = "0.4.2"
ring = "0.13.2"
sha2 = "0.8.0"
serde = "1.0.27"
serde_derive = "1.0.27"
serde_json = "1.0.10"
untrusted = "0.6.2"

View File

@ -1,12 +1,22 @@
pub mod account;
pub mod hash;
pub mod loader_instruction;
pub mod native_program;
pub mod packet;
pub mod pubkey;
pub mod signature;
pub mod system_instruction;
pub mod timing;
pub mod transaction;
extern crate bincode;
extern crate bs58;
extern crate generic_array;
extern crate log;
extern crate ring;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate sha2;
extern crate untrusted;

2
sdk/src/packet.rs Normal file
View File

@ -0,0 +1,2 @@
/// Maximum over-the-wire size of a Transaction
pub const PACKET_DATA_SIZE: usize = 512;

80
sdk/src/signature.rs Normal file
View File

@ -0,0 +1,80 @@
//! The `signature` module provides functionality for public, and private keys.
use bs58;
use generic_array::typenum::U64;
use generic_array::GenericArray;
use pubkey::Pubkey;
use ring::signature::Ed25519KeyPair;
use ring::{rand, signature};
use serde_json;
use std::error;
use std::fmt;
use std::fs::File;
use untrusted::Input;
pub type Keypair = Ed25519KeyPair;
#[derive(Serialize, Deserialize, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Signature(GenericArray<u8, U64>);
impl Signature {
pub fn new(signature_slice: &[u8]) -> Self {
Signature(GenericArray::clone_from_slice(&signature_slice))
}
pub fn verify(&self, pubkey_bytes: &[u8], message_bytes: &[u8]) -> bool {
let pubkey = Input::from(pubkey_bytes);
let message = Input::from(message_bytes);
let signature = Input::from(self.0.as_slice());
signature::verify(&signature::ED25519, pubkey, message, signature).is_ok()
}
}
impl AsRef<[u8]> for Signature {
fn as_ref(&self) -> &[u8] {
&self.0[..]
}
}
impl fmt::Debug for Signature {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", bs58::encode(self.0).into_string())
}
}
impl fmt::Display for Signature {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", bs58::encode(self.0).into_string())
}
}
pub trait KeypairUtil {
fn new() -> Self;
fn pubkey(&self) -> Pubkey;
}
impl KeypairUtil for Ed25519KeyPair {
/// Return a new ED25519 keypair
fn new() -> Self {
let rng = rand::SystemRandom::new();
let pkcs8_bytes = Ed25519KeyPair::generate_pkcs8(&rng).expect("generate_pkcs8");
Ed25519KeyPair::from_pkcs8(Input::from(&pkcs8_bytes)).expect("from_pcks8")
}
/// Return the public key for the given keypair
fn pubkey(&self) -> Pubkey {
Pubkey::new(self.public_key_bytes())
}
}
pub fn read_pkcs8(path: &str) -> Result<Vec<u8>, Box<error::Error>> {
let file = File::open(path.to_string())?;
let pkcs8: Vec<u8> = serde_json::from_reader(file)?;
Ok(pkcs8)
}
pub fn read_keypair(path: &str) -> Result<Keypair, Box<error::Error>> {
let pkcs8 = read_pkcs8(path)?;
let keypair = Ed25519KeyPair::from_pkcs8(Input::from(&pkcs8))?;
Ok(keypair)
}

View File

@ -0,0 +1,28 @@
use pubkey::Pubkey;
pub const SYSTEM_PROGRAM_ID: [u8; 32] = [0u8; 32];
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum SystemInstruction {
/// Create a new account
/// * Transaction::keys[0] - source
/// * Transaction::keys[1] - new account key
/// * tokens - number of tokens to transfer to the new account
/// * space - memory to allocate if greater then zero
/// * program_id - the program id of the new account
CreateAccount {
tokens: u64,
space: u64,
program_id: Pubkey,
},
/// Assign account to a program
/// * Transaction::keys[0] - account to assign
Assign { program_id: Pubkey },
/// Move tokens
/// * Transaction::keys[0] - source
/// * Transaction::keys[1] - destination
Move { tokens: u64 },
/// Spawn a new program from an account
Spawn,
}

334
sdk/src/transaction.rs Normal file
View File

@ -0,0 +1,334 @@
//! The `transaction` module provides functionality for creating log transactions.
use bincode::serialize;
use hash::{Hash, Hasher};
use pubkey::Pubkey;
use serde::Serialize;
use signature::{Keypair, KeypairUtil, Signature};
use std::mem::size_of;
pub const SIG_OFFSET: usize = size_of::<u64>();
/// An instruction to execute a program under the `program_id` of `program_ids_index` with the
/// specified accounts and userdata
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct Instruction {
/// The program code that executes this transaction is identified by the program_id.
/// this is an offset into the Transaction::program_ids field
pub program_ids_index: u8,
/// Indices into the keys array of which accounts to load
pub accounts: Vec<u8>,
/// Userdata to be stored in the account
pub userdata: Vec<u8>,
}
impl Instruction {
pub fn new<T: Serialize>(program_ids_index: u8, userdata: &T, accounts: Vec<u8>) -> Self {
let userdata = serialize(userdata).unwrap();
Instruction {
program_ids_index,
userdata,
accounts,
}
}
}
/// An atomic transaction
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct Transaction {
/// A set of digital signature of `account_keys`, `program_ids`, `last_id`, `fee` and `instructions`, signed by the first
/// signatures.len() keys of account_keys
pub signatures: Vec<Signature>,
/// The `Pubkeys` that are executing this transaction userdata. The meaning of each key is
/// program-specific.
/// * account_keys[0] - Typically this is the `caller` public key. `signature` is verified with account_keys[0].
/// In the future which key pays the fee and which keys have signatures would be configurable.
/// * account_keys[1] - Typically this is the program context or the recipient of the tokens
pub account_keys: Vec<Pubkey>,
/// The ID of a recent ledger entry.
pub last_id: Hash,
/// The number of tokens paid for processing and storage of this transaction.
pub fee: u64,
/// Keys identifying programs in the instructions vector.
pub program_ids: Vec<Pubkey>,
/// Programs that will be executed in sequence and commited in one atomic transaction if all
/// succeed.
pub instructions: Vec<Instruction>,
}
impl Transaction {
pub fn new<T: Serialize>(
from_keypair: &Keypair,
transaction_keys: &[Pubkey],
program_id: Pubkey,
userdata: &T,
last_id: Hash,
fee: u64,
) -> Self {
let program_ids = vec![program_id];
let accounts = (0..=transaction_keys.len() as u8).collect();
let instructions = vec![Instruction::new(0, userdata, accounts)];
Self::new_with_instructions(
&[from_keypair],
transaction_keys,
last_id,
fee,
program_ids,
instructions,
)
}
/// Create a signed transaction
/// * `from_keypair` - The key used to sign the transaction. This key is stored as keys[0]
/// * `account_keys` - The keys for the transaction. These are the program state
/// instances or token recipient keys.
/// * `last_id` - The PoH hash.
/// * `fee` - The transaction fee.
/// * `program_ids` - The keys that identify programs used in the `instruction` vector.
/// * `instructions` - The programs and their arguments that the transaction will execute atomically
pub fn new_with_instructions(
from_keypairs: &[&Keypair],
keys: &[Pubkey],
last_id: Hash,
fee: u64,
program_ids: Vec<Pubkey>,
instructions: Vec<Instruction>,
) -> Self {
let mut account_keys: Vec<_> = from_keypairs
.iter()
.map(|keypair| keypair.pubkey())
.collect();
account_keys.extend_from_slice(keys);
let mut tx = Transaction {
signatures: vec![],
account_keys,
last_id: Hash::default(),
fee,
program_ids,
instructions,
};
tx.sign(from_keypairs, last_id);
tx
}
pub fn userdata(&self, instruction_index: usize) -> &[u8] {
&self.instructions[instruction_index].userdata
}
fn key_index(&self, instruction_index: usize, accounts_index: usize) -> Option<usize> {
self.instructions
.get(instruction_index)
.and_then(|instruction| instruction.accounts.get(accounts_index))
.map(|&account_keys_index| account_keys_index as usize)
}
pub fn key(&self, instruction_index: usize, accounts_index: usize) -> Option<&Pubkey> {
self.key_index(instruction_index, accounts_index)
.and_then(|account_keys_index| self.account_keys.get(account_keys_index))
}
pub fn signed_key(&self, instruction_index: usize, accounts_index: usize) -> Option<&Pubkey> {
match self.key_index(instruction_index, accounts_index) {
None => None,
Some(signature_index) => {
if signature_index >= self.signatures.len() {
return None;
}
self.account_keys.get(signature_index)
}
}
}
pub fn program_id(&self, instruction_index: usize) -> &Pubkey {
let program_ids_index = self.instructions[instruction_index].program_ids_index;
&self.program_ids[program_ids_index as usize]
}
/// Get the transaction data to sign.
pub fn get_sign_data(&self) -> Vec<u8> {
let mut data = serialize(&self.account_keys).expect("serialize account_keys");
let last_id_data = serialize(&self.last_id).expect("serialize last_id");
data.extend_from_slice(&last_id_data);
let fee_data = serialize(&self.fee).expect("serialize fee");
data.extend_from_slice(&fee_data);
let program_ids = serialize(&self.program_ids).expect("serialize program_ids");
data.extend_from_slice(&program_ids);
let instructions = serialize(&self.instructions).expect("serialize instructions");
data.extend_from_slice(&instructions);
data
}
/// Sign this transaction.
pub fn sign(&mut self, keypairs: &[&Keypair], last_id: Hash) {
self.last_id = last_id;
let sign_data = self.get_sign_data();
self.signatures = keypairs
.iter()
.map(|keypair| Signature::new(&keypair.sign(&sign_data).as_ref()))
.collect();
}
/// Verify only the transaction signature.
pub fn verify_signature(&self) -> bool {
self.signatures
.iter()
.all(|s| s.verify(&self.from().as_ref(), &self.get_sign_data()))
}
/// Verify that references in the instructions are valid
pub fn verify_refs(&self) -> bool {
for instruction in &self.instructions {
if (instruction.program_ids_index as usize) >= self.program_ids.len() {
return false;
}
for account_index in &instruction.accounts {
if (*account_index as usize) >= self.account_keys.len() {
return false;
}
}
}
true
}
pub fn from(&self) -> &Pubkey {
&self.account_keys[0]
}
// a hash of a slice of transactions only needs to hash the signatures
pub fn hash(transactions: &[Transaction]) -> Hash {
let mut hasher = Hasher::default();
transactions
.iter()
.for_each(|tx| hasher.hash(&tx.signatures[0].as_ref()));
hasher.result()
}
}
#[cfg(test)]
mod tests {
use super::*;
use bincode::serialize;
#[test]
fn test_refs() {
let key = Keypair::new();
let key1 = Keypair::new().pubkey();
let key2 = Keypair::new().pubkey();
let prog1 = Keypair::new().pubkey();
let prog2 = Keypair::new().pubkey();
let instructions = vec![
Instruction::new(0, &(), vec![0, 1]),
Instruction::new(1, &(), vec![0, 2]),
];
let tx = Transaction::new_with_instructions(
&[&key],
&[key1, key2],
Default::default(),
0,
vec![prog1, prog2],
instructions,
);
assert!(tx.verify_refs());
assert_eq!(tx.key(0, 0), Some(&key.pubkey()));
assert_eq!(tx.signed_key(0, 0), Some(&key.pubkey()));
assert_eq!(tx.key(1, 0), Some(&key.pubkey()));
assert_eq!(tx.signed_key(1, 0), Some(&key.pubkey()));
assert_eq!(tx.key(0, 1), Some(&key1));
assert_eq!(tx.signed_key(0, 1), None);
assert_eq!(tx.key(1, 1), Some(&key2));
assert_eq!(tx.signed_key(1, 1), None);
assert_eq!(tx.key(2, 0), None);
assert_eq!(tx.signed_key(2, 0), None);
assert_eq!(tx.key(0, 2), None);
assert_eq!(tx.signed_key(0, 2), None);
assert_eq!(*tx.program_id(0), prog1);
assert_eq!(*tx.program_id(1), prog2);
}
#[test]
fn test_refs_invalid_program_id() {
let key = Keypair::new();
let instructions = vec![Instruction::new(1, &(), vec![])];
let tx = Transaction::new_with_instructions(
&[&key],
&[],
Default::default(),
0,
vec![],
instructions,
);
assert!(!tx.verify_refs());
}
#[test]
fn test_refs_invalid_account() {
let key = Keypair::new();
let instructions = vec![Instruction::new(0, &(), vec![1])];
let tx = Transaction::new_with_instructions(
&[&key],
&[],
Default::default(),
0,
vec![Default::default()],
instructions,
);
assert_eq!(*tx.program_id(0), Default::default());
assert!(!tx.verify_refs());
}
/// Detect binary changes in the serialized contract userdata, which could have a downstream
/// affect on SDKs and DApps
#[test]
fn test_sdk_serialize() {
use untrusted::Input;
let keypair = Keypair::from_pkcs8(Input::from(&[
48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32, 255, 101, 36, 24, 124, 23,
167, 21, 132, 204, 155, 5, 185, 58, 121, 75, 156, 227, 116, 193, 215, 38, 142, 22, 8,
14, 229, 239, 119, 93, 5, 218, 161, 35, 3, 33, 0, 36, 100, 158, 252, 33, 161, 97, 185,
62, 89, 99, 195, 250, 249, 187, 189, 171, 118, 241, 90, 248, 14, 68, 219, 231, 62, 157,
5, 142, 27, 210, 117,
])).expect("fu");
let to = Pubkey::new(&[
1, 1, 1, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 7, 6, 5, 4,
1, 1, 1,
]);
let program_id = Pubkey::new(&[
2, 2, 2, 4, 5, 6, 7, 8, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 8, 7, 6, 5, 4,
2, 2, 2,
]);
let tx = Transaction::new(
&keypair,
&[keypair.pubkey(), to],
program_id,
&(1u8, 2u8, 3u8),
Hash::default(),
99,
);
assert_eq!(
serialize(&tx).unwrap(),
vec![
1, 0, 0, 0, 0, 0, 0, 0, 213, 248, 255, 179, 219, 217, 130, 31, 27, 85, 33, 217, 62,
28, 180, 204, 186, 141, 178, 150, 153, 184, 205, 87, 123, 128, 101, 254, 222, 111,
152, 17, 153, 210, 169, 1, 81, 208, 254, 64, 229, 205, 145, 10, 213, 241, 255, 31,
184, 52, 242, 148, 213, 131, 241, 165, 144, 181, 18, 4, 58, 171, 44, 11, 3, 0, 0,
0, 0, 0, 0, 0, 36, 100, 158, 252, 33, 161, 97, 185, 62, 89, 99, 195, 250, 249, 187,
189, 171, 118, 241, 90, 248, 14, 68, 219, 231, 62, 157, 5, 142, 27, 210, 117, 36,
100, 158, 252, 33, 161, 97, 185, 62, 89, 99, 195, 250, 249, 187, 189, 171, 118,
241, 90, 248, 14, 68, 219, 231, 62, 157, 5, 142, 27, 210, 117, 1, 1, 1, 4, 5, 6, 7,
8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 7, 6, 5, 4, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 99, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 4, 5, 6, 7, 8, 9, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 8, 7, 6, 5, 4, 2, 2, 2, 1, 0, 0, 0, 0, 0,
0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3
],
);
}
}

View File

@ -9,7 +9,6 @@ use bpf_loader;
use budget_program::BudgetState;
use counter::Counter;
use entry::Entry;
use hash::{hash, Hash};
use itertools::Itertools;
use jsonrpc_macros::pubsub::Sink;
use leader_scheduler::LeaderScheduler;
@ -25,7 +24,9 @@ use rpc::RpcSignatureStatus;
use signature::Keypair;
use signature::Signature;
use solana_sdk::account::{create_keyed_accounts, Account, KeyedAccount};
use solana_sdk::hash::{hash, Hash};
use solana_sdk::pubkey::Pubkey;
use solana_sdk::system_instruction::SystemInstruction;
use solana_sdk::timing::{duration_as_us, timestamp};
use std;
use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};
@ -1229,15 +1230,15 @@ impl Bank {
let tx = &entry1.transactions[0];
assert!(SystemProgram::check_id(tx.program_id(0)), "Invalid ledger");
assert!(SystemProgram::check_id(tx.program_id(1)), "Invalid ledger");
let mut instruction: SystemProgram = deserialize(tx.userdata(0)).unwrap();
let mint_deposit = if let SystemProgram::Move { tokens } = instruction {
let mut instruction: SystemInstruction = deserialize(tx.userdata(0)).unwrap();
let mint_deposit = if let SystemInstruction::Move { tokens } = instruction {
Some(tokens)
} else {
None
}.expect("invalid ledger, needs to start with mint deposit");
instruction = deserialize(tx.userdata(1)).unwrap();
let leader_payment = if let SystemProgram::Move { tokens } = instruction {
let leader_payment = if let SystemInstruction::Move { tokens } = instruction {
Some(tokens)
} else {
None
@ -1495,11 +1496,11 @@ mod tests {
use budget_program::BudgetState;
use entry::next_entry;
use entry::Entry;
use hash::hash;
use jsonrpc_macros::pubsub::{Subscriber, SubscriptionId};
use ledger;
use signature::Keypair;
use signature::{GenKeys, KeypairUtil};
use solana_sdk::hash::hash;
use std;
use system_transaction::SystemTransaction;
use tokio::prelude::{Async, Stream};
@ -1573,7 +1574,7 @@ mod tests {
let key1 = Keypair::new().pubkey();
let key2 = Keypair::new().pubkey();
let bank = Bank::new(&mint);
let spend = SystemProgram::Move { tokens: 1 };
let spend = SystemInstruction::Move { tokens: 1 };
let instructions = vec![
Instruction {
program_ids_index: 0,

View File

@ -7,7 +7,6 @@ use bincode::deserialize;
use compute_leader_finality_service::ComputeLeaderFinalityService;
use counter::Counter;
use entry::Entry;
use hash::Hash;
use log::Level;
use packet::Packets;
use poh_recorder::{PohRecorder, PohRecorderError};
@ -15,6 +14,7 @@ use poh_service::{Config, PohService};
use result::{Error, Result};
use service::Service;
use sigverify_stage::VerifiedPackets;
use solana_sdk::hash::Hash;
use solana_sdk::timing;
use std::net::SocketAddr;
use std::sync::atomic::{AtomicUsize, Ordering};

View File

@ -8,6 +8,7 @@ extern crate log;
extern crate serde_json;
#[macro_use]
extern crate solana;
extern crate solana_drone;
extern crate solana_metrics;
extern crate solana_sdk;
@ -17,8 +18,6 @@ use rand::{thread_rng, Rng};
use rayon::prelude::*;
use solana::client::mk_client;
use solana::cluster_info::{ClusterInfo, NodeInfo};
use solana::drone::{request_airdrop_transaction, DRONE_PORT};
use solana::hash::Hash;
use solana::logger;
use solana::ncp::Ncp;
use solana::service::Service;
@ -27,7 +26,9 @@ use solana::system_transaction::SystemTransaction;
use solana::thin_client::{poll_gossip_for_leader, ThinClient};
use solana::transaction::Transaction;
use solana::window::default_window;
use solana_drone::drone::{request_airdrop_transaction, DRONE_PORT};
use solana_metrics::influxdb;
use solana_sdk::hash::Hash;
use solana_sdk::timing::timestamp;
use solana_sdk::timing::{duration_as_ms, duration_as_s};
use std::cmp;

View File

@ -4,12 +4,12 @@ extern crate getopts;
extern crate serde_json;
#[macro_use]
extern crate solana;
extern crate solana_drone;
use clap::{App, Arg};
use solana::chacha::{chacha_cbc_encrypt_file, CHACHA_BLOCK_SIZE};
use solana::client::mk_client;
use solana::cluster_info::Node;
use solana::drone::{request_airdrop_transaction, DRONE_PORT};
use solana::fullnode::Config;
use solana::ledger::LEDGER_DATA_FILE;
use solana::logger;
@ -17,6 +17,7 @@ use solana::replicator::{sample_file, Replicator};
use solana::signature::{Keypair, KeypairUtil};
use solana::storage_transaction::StorageTransaction;
use solana::transaction::Transaction;
use solana_drone::drone::{request_airdrop_transaction, DRONE_PORT};
use std::fs::File;
use std::net::{Ipv4Addr, SocketAddr};
use std::path::Path;

View File

@ -59,7 +59,7 @@ impl<T: BloomHashIndex> Bloom<T> {
#[cfg(test)]
mod test {
use super::*;
use hash::{hash, Hash};
use solana_sdk::hash::{hash, Hash};
#[test]
fn test_bloom_filter() {

View File

@ -254,9 +254,9 @@ mod test {
use budget_program::{BudgetError, BudgetState};
use budget_transaction::BudgetTransaction;
use chrono::prelude::{DateTime, NaiveDate, Utc};
use hash::Hash;
use signature::{GenKeys, Keypair, KeypairUtil};
use solana_sdk::account::Account;
use solana_sdk::hash::Hash;
use solana_sdk::pubkey::Pubkey;
use transaction::Transaction;

View File

@ -5,11 +5,11 @@ use budget_expr::{BudgetExpr, Condition};
use budget_instruction::Instruction;
use budget_program::BudgetState;
use chrono::prelude::*;
use hash::Hash;
use payment_plan::Payment;
use signature::{Keypair, KeypairUtil};
use solana_sdk::hash::Hash;
use solana_sdk::pubkey::Pubkey;
use system_program::SystemProgram;
use solana_sdk::system_instruction::{SystemInstruction, SYSTEM_PROGRAM_ID};
use transaction::{self, Transaction};
pub trait BudgetTransaction {
@ -60,7 +60,7 @@ pub trait BudgetTransaction {
) -> Self;
fn instruction(&self, program_index: usize) -> Option<Instruction>;
fn system_instruction(&self, program_index: usize) -> Option<SystemProgram>;
fn system_instruction(&self, program_index: usize) -> Option<SystemInstruction>;
fn verify_plan(&self) -> bool;
}
@ -77,7 +77,7 @@ impl BudgetTransaction for Transaction {
let contract = Keypair::new().pubkey();
let keys = vec![from_keypair.pubkey(), contract];
let system_instruction = SystemProgram::Move { tokens };
let system_instruction = SystemInstruction::Move { tokens };
let payment = Payment {
tokens: tokens - fee,
@ -85,7 +85,7 @@ impl BudgetTransaction for Transaction {
};
let budget_instruction = Instruction::NewBudget(BudgetExpr::Pay(payment));
let program_ids = vec![SystemProgram::id(), BudgetState::id()];
let program_ids = vec![Pubkey::new(&SYSTEM_PROGRAM_ID), BudgetState::id()];
let instructions = vec![
transaction::Instruction::new(0, &system_instruction, vec![0, 1]),
@ -206,13 +206,13 @@ impl BudgetTransaction for Transaction {
deserialize(&self.userdata(instruction_index)).ok()
}
fn system_instruction(&self, instruction_index: usize) -> Option<SystemProgram> {
fn system_instruction(&self, instruction_index: usize) -> Option<SystemInstruction> {
deserialize(&self.userdata(instruction_index)).ok()
}
/// Verify only the payment plan.
fn verify_plan(&self) -> bool {
if let Some(SystemProgram::Move { tokens }) = self.system_instruction(0) {
if let Some(SystemInstruction::Move { tokens }) = self.system_instruction(0) {
if let Some(Instruction::NewBudget(expr)) = self.instruction(1) {
if !(self.fee <= tokens && expr.verify(tokens - self.fee)) {
return false;
@ -284,7 +284,7 @@ mod tests {
let pubkey = keypair.pubkey();
let mut tx = Transaction::budget_new(&keypair, pubkey, 42, zero);
let mut system_instruction = tx.system_instruction(0).unwrap();
if let SystemProgram::Move { ref mut tokens } = system_instruction {
if let SystemInstruction::Move { ref mut tokens } = system_instruction {
*tokens = 1_000_000; // <-- attack, part 1!
let mut instruction = tx.instruction(1).unwrap();
if let Instruction::NewBudget(ref mut expr) = instruction {

View File

@ -1,7 +1,7 @@
use chacha::{CHACHA_BLOCK_SIZE, CHACHA_KEY_SIZE};
use hash::Hash;
use ledger::LedgerWindow;
use sigverify::{chacha_cbc_encrypt_many_sample, chacha_end_sha_state, chacha_init_sha_state};
use solana_sdk::hash::Hash;
use std::io;
use std::mem::size_of;
@ -102,10 +102,10 @@ pub fn chacha_cbc_encrypt_file_many_keys(
mod tests {
use chacha::chacha_cbc_encrypt_file;
use chacha_cuda::chacha_cbc_encrypt_file_many_keys;
use hash::Hash;
use ledger::LedgerWriter;
use ledger::{get_tmp_ledger_path, make_tiny_test_entries, LEDGER_DATA_FILE};
use replicator::sample_file;
use solana_sdk::hash::Hash;
use std::fs::{remove_dir_all, remove_file};
use std::path::Path;

View File

@ -19,7 +19,6 @@ use counter::Counter;
use crds_gossip::CrdsGossip;
use crds_gossip_pull::CRDS_GOSSIP_PULL_CRDS_TIMEOUT_MS;
use crds_value::{CrdsValue, CrdsValueLabel, LeaderId};
use hash::Hash;
use ledger::LedgerWindow;
use log::Level;
use netutil::{bind_in_range, bind_to, find_available_port_in_range, multi_bind_in_range};
@ -29,6 +28,7 @@ use rayon::prelude::*;
use result::Result;
use rpc::RPC_PORT;
use signature::{Keypair, KeypairUtil};
use solana_sdk::hash::Hash;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::timing::{duration_as_ms, timestamp};
use std::collections::HashMap;
@ -1046,12 +1046,12 @@ mod tests {
use super::*;
use crds_value::CrdsValueLabel;
use entry::Entry;
use hash::{hash, Hash};
use ledger::{get_tmp_ledger_path, LedgerWindow, LedgerWriter};
use logger;
use packet::SharedBlob;
use result::Error;
use signature::{Keypair, KeypairUtil};
use solana_sdk::hash::{hash, Hash};
use std::fs::remove_dir_all;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::sync::{Arc, RwLock};

View File

@ -136,10 +136,10 @@ pub mod tests {
use bank::Bank;
use bincode::serialize;
use compute_leader_finality_service::ComputeLeaderFinalityService;
use hash::hash;
use logger;
use mint::Mint;
use signature::{Keypair, KeypairUtil};
use solana_sdk::hash::hash;
use std::sync::Arc;
use std::thread::sleep;
use std::time::Duration;

View File

@ -26,8 +26,8 @@
use bincode::serialize;
use crds_value::{CrdsValue, CrdsValueLabel};
use hash::{hash, Hash};
use indexmap::map::IndexMap;
use solana_sdk::hash::{hash, Hash};
use solana_sdk::pubkey::Pubkey;
use std::cmp;

View File

@ -9,7 +9,7 @@ use crds_gossip_error::CrdsGossipError;
use crds_gossip_pull::CrdsGossipPull;
use crds_gossip_push::{CrdsGossipPush, CRDS_GOSSIP_NUM_ACTIVE};
use crds_value::CrdsValue;
use hash::Hash;
use solana_sdk::hash::Hash;
use solana_sdk::pubkey::Pubkey;
pub struct CrdsGossip {

View File

@ -14,10 +14,10 @@ use bloom::Bloom;
use crds::Crds;
use crds_gossip_error::CrdsGossipError;
use crds_value::{CrdsValue, CrdsValueLabel};
use hash::Hash;
use packet::BLOB_DATA_SIZE;
use rand;
use rand::distributions::{Distribution, Weighted, WeightedChoice};
use solana_sdk::hash::Hash;
use solana_sdk::pubkey::Pubkey;
use std::cmp;
use std::collections::HashMap;

View File

@ -13,10 +13,10 @@ use bloom::Bloom;
use crds::{Crds, VersionedCrdsValue};
use crds_gossip_error::CrdsGossipError;
use crds_value::{CrdsValue, CrdsValueLabel};
use hash::Hash;
use indexmap::map::IndexMap;
use packet::BLOB_DATA_SIZE;
use rand::{self, Rng};
use solana_sdk::hash::Hash;
use solana_sdk::pubkey::Pubkey;
use std::cmp;
use std::collections::HashMap;

View File

@ -1,5 +1,5 @@
use bloom::BloomHashIndex;
use hash::Hash;
use solana_sdk::hash::Hash;
use solana_sdk::pubkey::Pubkey;
fn slice_hash(slice: &[u8], hash_index: u64) -> u64 {

View File

@ -3,10 +3,10 @@
//! transactions within it. Entries cannot be reordered, and its field `num_hashes`
//! represents an approximate amount of time since the last Entry was created.
use bincode::{deserialize, serialize_into, serialized_size};
use hash::Hash;
use packet::{SharedBlob, BLOB_DATA_SIZE};
use poh::Poh;
use result::Result;
use solana_sdk::hash::Hash;
use solana_sdk::pubkey::Pubkey;
use std::io::Cursor;
use std::mem::size_of;
@ -275,8 +275,8 @@ mod tests {
use budget_transaction::BudgetTransaction;
use chrono::prelude::*;
use entry::Entry;
use hash::hash;
use signature::{Keypair, KeypairUtil};
use solana_sdk::hash::hash;
use system_transaction::SystemTransaction;
use transaction::Transaction;

View File

@ -3,7 +3,6 @@
use bank::Bank;
use broadcast_stage::BroadcastStage;
use cluster_info::{ClusterInfo, Node, NodeInfo};
use hash::Hash;
use leader_scheduler::LeaderScheduler;
use ledger::read_ledger;
use ncp::Ncp;
@ -11,6 +10,7 @@ use rpc::JsonRpcService;
use rpc_pubsub::PubSubService;
use service::Service;
use signature::{Keypair, KeypairUtil};
use solana_sdk::hash::Hash;
use solana_sdk::timing::timestamp;
use std::net::UdpSocket;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};

View File

@ -6,9 +6,9 @@ use bank::Bank;
use bincode::serialize;
use byteorder::{LittleEndian, ReadBytesExt};
use entry::Entry;
use hash::{hash, Hash};
use ledger::create_ticks;
use signature::{Keypair, KeypairUtil};
use solana_sdk::hash::{hash, Hash};
use solana_sdk::pubkey::Pubkey;
use std::collections::HashSet;
use std::io::Cursor;
@ -493,13 +493,13 @@ pub fn make_active_set_entries(
#[cfg(test)]
mod tests {
use bank::Bank;
use hash::Hash;
use leader_scheduler::{
LeaderScheduler, LeaderSchedulerConfig, DEFAULT_BOOTSTRAP_HEIGHT,
DEFAULT_LEADER_ROTATION_INTERVAL, DEFAULT_SEED_ROTATION_INTERVAL,
};
use mint::Mint;
use signature::{Keypair, KeypairUtil};
use solana_sdk::hash::Hash;
use solana_sdk::pubkey::Pubkey;
use std::collections::HashSet;
use std::hash::Hash as StdHash;

View File

@ -8,14 +8,14 @@ use budget_transaction::BudgetTransaction;
#[cfg(test)]
use chrono::prelude::Utc;
use entry::Entry;
#[cfg(test)]
use hash::hash;
use hash::Hash;
use log::Level::Trace;
use mint::Mint;
use packet::{SharedBlob, BLOB_DATA_SIZE};
use rayon::prelude::*;
use signature::{Keypair, KeypairUtil};
#[cfg(test)]
use solana_sdk::hash::hash;
use solana_sdk::hash::Hash;
use solana_sdk::pubkey::Pubkey;
use std::fs::{create_dir_all, remove_dir_all, File, OpenOptions};
use std::io::prelude::*;
@ -672,9 +672,9 @@ mod tests {
use bincode::{deserialize, serialized_size};
use budget_transaction::BudgetTransaction;
use entry::{next_entry, reconstruct_entries_from_blobs, Entry};
use hash::hash;
use packet::{to_blobs, BLOB_DATA_SIZE, PACKET_DATA_SIZE};
use signature::{Keypair, KeypairUtil};
use solana_sdk::hash::hash;
use std;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use transaction::Transaction;

View File

@ -36,13 +36,11 @@ pub mod budget_program;
pub mod cluster_info;
pub mod compute_leader_finality_service;
pub mod db_ledger;
pub mod drone;
pub mod entry;
#[cfg(feature = "erasure")]
pub mod erasure;
pub mod fetch_stage;
pub mod fullnode;
pub mod hash;
pub mod leader_scheduler;
pub mod ledger;
pub mod ledger_write_stage;
@ -122,6 +120,7 @@ extern crate serde_json;
extern crate serde_cbor;
extern crate sha2;
extern crate socket2;
extern crate solana_drone;
extern crate solana_jsonrpc_core as jsonrpc_core;
extern crate solana_jsonrpc_http_server as jsonrpc_http_server;
#[macro_use]

View File

@ -1,7 +1,7 @@
//! The `dynamic_transaction` module provides functionality for loading and calling a program
use hash::Hash;
use signature::{Keypair, KeypairUtil};
use solana_sdk::hash::Hash;
use solana_sdk::loader_instruction::LoaderInstruction;
use solana_sdk::pubkey::Pubkey;
use transaction::Transaction;

View File

@ -1,9 +1,9 @@
//! The `mint` module is a library for generating the chain's genesis block.
use entry::Entry;
use hash::{hash, Hash};
use ring::rand::SystemRandom;
use signature::{Keypair, KeypairUtil};
use solana_sdk::hash::{hash, Hash};
use solana_sdk::pubkey::Pubkey;
use system_transaction::SystemTransaction;
use transaction::Transaction;
@ -108,6 +108,7 @@ mod tests {
use super::*;
use bincode::deserialize;
use ledger::Block;
use solana_sdk::system_instruction::SystemInstruction;
use system_program::SystemProgram;
#[test]
@ -116,8 +117,8 @@ mod tests {
let tx = transactions.next().unwrap();
assert_eq!(tx.instructions.len(), 1);
assert!(SystemProgram::check_id(tx.program_id(0)));
let instruction: SystemProgram = deserialize(tx.userdata(0)).unwrap();
if let SystemProgram::Move { tokens } = instruction {
let instruction: SystemInstruction = deserialize(tx.userdata(0)).unwrap();
if let SystemInstruction::Move { tokens } = instruction {
assert_eq!(tokens, 100);
}
assert_eq!(transactions.next(), None);
@ -134,12 +135,12 @@ mod tests {
assert_eq!(tx.instructions.len(), 2);
assert!(SystemProgram::check_id(tx.program_id(0)));
assert!(SystemProgram::check_id(tx.program_id(1)));
let instruction: SystemProgram = deserialize(tx.userdata(0)).unwrap();
if let SystemProgram::Move { tokens } = instruction {
let instruction: SystemInstruction = deserialize(tx.userdata(0)).unwrap();
if let SystemInstruction::Move { tokens } = instruction {
assert_eq!(tokens, 100);
}
let instruction: SystemProgram = deserialize(tx.userdata(1)).unwrap();
if let SystemProgram::Move { tokens } = instruction {
let instruction: SystemInstruction = deserialize(tx.userdata(1)).unwrap();
if let SystemInstruction::Move { tokens } = instruction {
assert_eq!(tokens, 1);
}
assert_eq!(transactions.next(), None);

View File

@ -5,13 +5,14 @@ use counter::Counter;
#[cfg(test)]
use entry::Entry;
#[cfg(test)]
use hash::Hash;
#[cfg(test)]
use ledger::Block;
use log::Level;
use recvmmsg::{recv_mmsg, NUM_RCVMMSGS};
use result::{Error, Result};
use serde::Serialize;
#[cfg(test)]
use solana_sdk::hash::Hash;
pub use solana_sdk::packet::PACKET_DATA_SIZE;
use solana_sdk::pubkey::Pubkey;
use std::fmt;
use std::io;
@ -27,7 +28,6 @@ pub type SharedBlobs = Vec<SharedBlob>;
pub const NUM_PACKETS: usize = 1024 * 8;
pub const BLOB_SIZE: usize = (64 * 1024 - 128); // wikipedia says there should be 20b for ipv4 headers
pub const BLOB_DATA_SIZE: usize = BLOB_SIZE - (BLOB_HEADER_SIZE * 2);
pub const PACKET_DATA_SIZE: usize = 512;
pub const NUM_BLOBS: usize = (NUM_PACKETS * PACKET_DATA_SIZE) / BLOB_SIZE;
#[derive(Clone, Default, Debug, PartialEq)]
@ -457,12 +457,12 @@ pub fn make_consecutive_blobs(
#[cfg(test)]
mod tests {
use hash::Hash;
use packet::{
to_packets, Blob, Meta, Packet, Packets, SharedBlob, SharedPackets, NUM_PACKETS,
PACKET_DATA_SIZE,
};
use signature::{Keypair, KeypairUtil};
use solana_sdk::hash::Hash;
use std::io;
use std::io::Write;
use std::net::UdpSocket;

View File

@ -1,6 +1,6 @@
//! The `Poh` module provides an object for generating a Proof of History.
//! It records Hashes items on behalf of its users.
use hash::{hash, hashv, Hash};
use solana_sdk::hash::{hash, hashv, Hash};
pub struct Poh {
prev_id: Hash,
@ -96,8 +96,8 @@ pub fn verify(initial: Hash, entries: &[PohEntry]) -> bool {
#[cfg(test)]
mod tests {
use hash::Hash;
use poh::{self, PohEntry};
use solana_sdk::hash::Hash;
#[test]
#[should_panic]

View File

@ -3,9 +3,9 @@
//!
use bank::Bank;
use entry::Entry;
use hash::Hash;
use poh::Poh;
use result::{Error, Result};
use solana_sdk::hash::Hash;
use std::sync::mpsc::Sender;
use std::sync::{Arc, Mutex};
use transaction::Transaction;
@ -118,8 +118,8 @@ impl PohRecorder {
#[cfg(test)]
mod tests {
use super::*;
use hash::hash;
use mint::Mint;
use solana_sdk::hash::hash;
use std::sync::mpsc::channel;
use std::sync::Arc;
use system_transaction::test_tx;

View File

@ -4,7 +4,7 @@ use bank::Bank;
use cluster_info::ClusterInfo;
use counter::Counter;
use entry::{EntryReceiver, EntrySender};
use hash::Hash;
use solana_sdk::hash::Hash;
use ledger::Block;
use log::Level;
@ -246,7 +246,6 @@ mod test {
use cluster_info::{ClusterInfo, Node};
use entry::Entry;
use fullnode::Fullnode;
use hash::Hash;
use leader_scheduler::{make_active_set_entries, LeaderScheduler, LeaderSchedulerConfig};
use ledger::{create_ticks, create_tmp_sample_ledger, LedgerWriter};
use logger;
@ -255,6 +254,7 @@ mod test {
use result::Error;
use service::Service;
use signature::{Keypair, KeypairUtil};
use solana_sdk::hash::Hash;
use std::fs::remove_dir_all;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::channel;

View File

@ -1,9 +1,9 @@
use blob_fetch_stage::BlobFetchStage;
use cluster_info::{ClusterInfo, Node, NodeInfo};
use hash::{Hash, Hasher};
use leader_scheduler::LeaderScheduler;
use ncp::Ncp;
use service::Service;
use solana_sdk::hash::{Hash, Hasher};
use std::fs::File;
use std::io;
use std::io::BufReader;
@ -168,13 +168,13 @@ mod tests {
use client::mk_client;
use cluster_info::Node;
use fullnode::Fullnode;
use hash::Hash;
use leader_scheduler::LeaderScheduler;
use ledger::{create_tmp_genesis, get_tmp_ledger_path, read_ledger};
use logger;
use replicator::sample_file;
use replicator::Replicator;
use signature::{Keypair, KeypairUtil};
use solana_sdk::hash::Hash;
use std::fs::File;
use std::fs::{create_dir_all, remove_dir_all, remove_file};
use std::io::Write;

View File

@ -4,12 +4,12 @@ use bank::{Bank, BankError};
use bincode::{deserialize, serialize};
use bs58;
use cluster_info::ClusterInfo;
use drone::{request_airdrop_transaction, DRONE_PORT};
use jsonrpc_core::*;
use jsonrpc_http_server::*;
use packet::PACKET_DATA_SIZE;
use service::Service;
use signature::Signature;
use solana_drone::drone::{request_airdrop_transaction, DRONE_PORT};
use solana_sdk::account::Account;
use solana_sdk::pubkey::Pubkey;
use std::mem;
@ -363,7 +363,6 @@ mod tests {
use bincode::serialize;
use cluster_info::{Node, NodeInfo};
use fullnode::Fullnode;
use hash::{hash, Hash};
use jsonrpc_core::Response;
use leader_scheduler::LeaderScheduler;
use ledger::create_tmp_ledger_with_mint;
@ -371,6 +370,7 @@ mod tests {
use reqwest;
use reqwest::header::CONTENT_TYPE;
use signature::{Keypair, KeypairUtil};
use solana_sdk::hash::{hash, Hash};
use std::fs::remove_dir_all;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use system_transaction::SystemTransaction;

View File

@ -1,72 +1,10 @@
//! The `signature` module provides functionality for public, and private keys.
use bs58;
use generic_array::typenum::U64;
use generic_array::GenericArray;
use rand::{ChaChaRng, Rng, SeedableRng};
use rayon::prelude::*;
use ring::signature::Ed25519KeyPair;
use ring::{rand, signature};
use serde_json;
use solana_sdk::pubkey::Pubkey;
use std::error;
use std::fmt;
use std::fs::File;
use untrusted::Input;
pub type Keypair = Ed25519KeyPair;
#[derive(Serialize, Deserialize, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Signature(GenericArray<u8, U64>);
impl Signature {
pub fn new(signature_slice: &[u8]) -> Self {
Signature(GenericArray::clone_from_slice(&signature_slice))
}
pub fn verify(&self, pubkey_bytes: &[u8], message_bytes: &[u8]) -> bool {
let pubkey = Input::from(pubkey_bytes);
let message = Input::from(message_bytes);
let signature = Input::from(self.0.as_slice());
signature::verify(&signature::ED25519, pubkey, message, signature).is_ok()
}
}
impl AsRef<[u8]> for Signature {
fn as_ref(&self) -> &[u8] {
&self.0[..]
}
}
impl fmt::Debug for Signature {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", bs58::encode(self.0).into_string())
}
}
impl fmt::Display for Signature {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", bs58::encode(self.0).into_string())
}
}
pub trait KeypairUtil {
fn new() -> Self;
fn pubkey(&self) -> Pubkey;
}
impl KeypairUtil for Ed25519KeyPair {
/// Return a new ED25519 keypair
fn new() -> Self {
let rng = rand::SystemRandom::new();
let pkcs8_bytes = Ed25519KeyPair::generate_pkcs8(&rng).expect("generate_pkcs8");
Ed25519KeyPair::from_pkcs8(Input::from(&pkcs8_bytes)).expect("from_pcks8")
}
/// Return the public key for the given keypair
fn pubkey(&self) -> Pubkey {
Pubkey::new(self.public_key_bytes())
}
}
pub use solana_sdk::signature::*;
pub struct GenKeys {
generator: ChaChaRng,
@ -96,21 +34,10 @@ impl GenKeys {
}
}
pub fn read_pkcs8(path: &str) -> Result<Vec<u8>, Box<error::Error>> {
let file = File::open(path.to_string())?;
let pkcs8: Vec<u8> = serde_json::from_reader(file)?;
Ok(pkcs8)
}
pub fn read_keypair(path: &str) -> Result<Keypair, Box<error::Error>> {
let pkcs8 = read_pkcs8(path)?;
let keypair = Ed25519KeyPair::from_pkcs8(Input::from(&pkcs8))?;
Ok(keypair)
}
#[cfg(test)]
mod tests {
use super::*;
pub use solana_sdk::pubkey::Pubkey;
use std::collections::HashSet;
#[test]

View File

@ -324,10 +324,11 @@ pub fn make_packet_from_transaction(tx: Transaction) -> Packet {
mod tests {
use bincode::serialize;
use budget_program::BudgetState;
use hash::Hash;
use packet::{Packet, SharedPackets};
use signature::{Keypair, KeypairUtil};
use sigverify;
use solana_sdk::hash::Hash;
use solana_sdk::system_instruction::SystemInstruction;
use system_program::SystemProgram;
use system_transaction::{memfind, test_tx};
use transaction;
@ -426,7 +427,7 @@ mod tests {
let keys = vec![keypair0.pubkey(), keypair1.pubkey()];
let system_instruction = SystemProgram::Move { tokens };
let system_instruction = SystemInstruction::Move { tokens };
let program_ids = vec![SystemProgram::id(), BudgetState::id()];

View File

@ -3,8 +3,8 @@
//! and give reward for good proofs.
use bincode::deserialize;
use hash::Hash;
use solana_sdk::account::Account;
use solana_sdk::hash::Hash;
use solana_sdk::pubkey::Pubkey;
use transaction::Transaction;

View File

@ -5,12 +5,12 @@
#[cfg(all(feature = "chacha", feature = "cuda"))]
use chacha_cuda::chacha_cbc_encrypt_file_many_keys;
use entry::EntryReceiver;
use hash::Hash;
use rand::{ChaChaRng, Rng, SeedableRng};
use result::{Error, Result};
use service::Service;
use signature::Keypair;
use signature::Signature;
use solana_sdk::hash::Hash;
use solana_sdk::pubkey::Pubkey;
use std::mem::size_of;
use std::sync::atomic::{AtomicBool, Ordering};
@ -260,12 +260,12 @@ impl Service for StorageStage {
#[cfg(test)]
mod tests {
use entry::Entry;
use hash::Hash;
use ledger::make_tiny_test_entries;
use ledger::{create_tmp_sample_ledger, LedgerWriter};
use logger;
use service::Service;
use signature::{Keypair, KeypairUtil};
use solana_sdk::hash::Hash;
use std::cmp::{max, min};
use std::fs::remove_dir_all;
use std::sync::atomic::{AtomicBool, Ordering};

View File

@ -1,5 +1,5 @@
use hash::Hash;
use signature::{Keypair, KeypairUtil};
use solana_sdk::hash::Hash;
use storage_program::StorageProgram;
use transaction::Transaction;

View File

@ -3,6 +3,7 @@
use bincode::deserialize;
use solana_sdk::account::Account;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::system_instruction::SystemInstruction;
use std;
use transaction::Transaction;
@ -22,30 +23,7 @@ impl std::error::Error for Error {}
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum SystemProgram {
/// Create a new account
/// * Transaction::keys[0] - source
/// * Transaction::keys[1] - new account key
/// * tokens - number of tokens to transfer to the new account
/// * space - memory to allocate if greater then zero
/// * program_id - the program id of the new account
CreateAccount {
tokens: u64,
space: u64,
program_id: Pubkey,
},
/// Assign account to a program
/// * Transaction::keys[0] - account to assign
Assign { program_id: Pubkey },
/// Move tokens
/// * Transaction::keys[0] - source
/// * Transaction::keys[1] - destination
Move { tokens: u64 },
/// Spawn a new program from an account
Spawn,
}
pub struct SystemProgram {}
pub const SYSTEM_PROGRAM_ID: [u8; 32] = [0u8; 32];
@ -68,7 +46,7 @@ impl SystemProgram {
if let Ok(syscall) = deserialize(tx.userdata(pix)) {
trace!("process_transaction: {:?}", syscall);
match syscall {
SystemProgram::CreateAccount {
SystemInstruction::CreateAccount {
tokens,
space,
program_id,
@ -95,13 +73,13 @@ impl SystemProgram {
accounts[1].executable = false;
accounts[1].loader = Pubkey::default();
}
SystemProgram::Assign { program_id } => {
SystemInstruction::Assign { program_id } => {
if !Self::check_id(&accounts[0].owner) {
Err(Error::AssignOfUnownedAccount)?;
}
accounts[0].owner = program_id;
}
SystemProgram::Move { tokens } => {
SystemInstruction::Move { tokens } => {
//bank should be verifying correctness
if tokens > accounts[0].tokens {
info!("Insufficient tokens in account[0]");
@ -110,7 +88,7 @@ impl SystemProgram {
accounts[0].tokens -= tokens;
accounts[1].tokens += tokens;
}
SystemProgram::Spawn => {
SystemInstruction::Spawn => {
if !accounts[0].executable || accounts[0].loader != Pubkey::default() {
Err(Error::AccountNotFinalized)?;
}
@ -128,9 +106,9 @@ impl SystemProgram {
#[cfg(test)]
mod test {
use super::*;
use hash::Hash;
use signature::{Keypair, KeypairUtil};
use solana_sdk::account::Account;
use solana_sdk::hash::Hash;
use solana_sdk::pubkey::Pubkey;
use system_program::SystemProgram;
use system_transaction::SystemTransaction;

View File

@ -1,9 +1,11 @@
//! The `system_transaction` module provides functionality for creating system transactions.
use hash::Hash;
use signature::{Keypair, KeypairUtil};
use solana_sdk::hash::Hash;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::system_instruction::SystemInstruction;
use system_program::SystemProgram;
use transaction::{Instruction, Transaction};
pub trait SystemTransaction {
@ -40,7 +42,7 @@ pub trait SystemTransaction {
}
impl SystemTransaction for Transaction {
/// Create and sign new SystemProgram::CreateAccount transaction
/// Create and sign new SystemInstruction::CreateAccount transaction
fn system_create(
from_keypair: &Keypair,
to: Pubkey,
@ -50,7 +52,7 @@ impl SystemTransaction for Transaction {
program_id: Pubkey,
fee: u64,
) -> Self {
let create = SystemProgram::CreateAccount {
let create = SystemInstruction::CreateAccount {
tokens, //TODO, the tokens to allocate might need to be higher then 0 in the future
space,
program_id,
@ -64,9 +66,9 @@ impl SystemTransaction for Transaction {
fee,
)
}
/// Create and sign new SystemProgram::Assign transaction
/// Create and sign new SystemInstruction::Assign transaction
fn system_assign(from_keypair: &Keypair, last_id: Hash, program_id: Pubkey, fee: u64) -> Self {
let assign = SystemProgram::Assign { program_id };
let assign = SystemInstruction::Assign { program_id };
Transaction::new(
from_keypair,
&[],
@ -76,11 +78,11 @@ impl SystemTransaction for Transaction {
fee,
)
}
/// Create and sign new SystemProgram::CreateAccount transaction with some defaults
/// Create and sign new SystemInstruction::CreateAccount transaction with some defaults
fn system_new(from_keypair: &Keypair, to: Pubkey, tokens: u64, last_id: Hash) -> Self {
Transaction::system_create(from_keypair, to, last_id, tokens, 0, Pubkey::default(), 0)
}
/// Create and sign new SystemProgram::Move transaction
/// Create and sign new SystemInstruction::Move transaction
fn system_move(
from_keypair: &Keypair,
to: Pubkey,
@ -88,7 +90,7 @@ impl SystemTransaction for Transaction {
last_id: Hash,
fee: u64,
) -> Self {
let move_tokens = SystemProgram::Move { tokens };
let move_tokens = SystemInstruction::Move { tokens };
Transaction::new(
from_keypair,
&[to],
@ -98,13 +100,13 @@ impl SystemTransaction for Transaction {
fee,
)
}
/// Create and sign new SystemProgram::Move transaction to many destinations
/// Create and sign new SystemInstruction::Move transaction to many destinations
fn system_move_many(from: &Keypair, moves: &[(Pubkey, u64)], last_id: Hash, fee: u64) -> Self {
let instructions: Vec<_> = moves
.iter()
.enumerate()
.map(|(i, (_, amount))| {
let spend = SystemProgram::Move { tokens: *amount };
let spend = SystemInstruction::Move { tokens: *amount };
Instruction::new(0, &spend, vec![0, i as u8 + 1])
}).collect();
let to_keys: Vec<_> = moves.iter().map(|(to_key, _)| *to_key).collect();
@ -118,9 +120,9 @@ impl SystemTransaction for Transaction {
instructions,
)
}
/// Create and sign new SystemProgram::Spawn transaction
/// Create and sign new SystemInstruction::Spawn transaction
fn system_spawn(from_keypair: &Keypair, last_id: Hash, fee: u64) -> Self {
let spawn = SystemProgram::Spawn;
let spawn = SystemInstruction::Spawn;
Transaction::new(from_keypair, &[], SystemProgram::id(), &spawn, last_id, fee)
}
}

View File

@ -7,7 +7,6 @@ use bank::Bank;
use bincode::serialize;
use bs58;
use cluster_info::{ClusterInfo, ClusterInfoError, NodeInfo};
use hash::Hash;
use log::Level;
use ncp::Ncp;
use packet::PACKET_DATA_SIZE;
@ -18,6 +17,7 @@ use signature::{Keypair, Signature};
use solana_metrics;
use solana_metrics::influxdb;
use solana_sdk::account::Account;
use solana_sdk::hash::Hash;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::timing;
use std;
@ -417,8 +417,8 @@ mod tests {
use logger;
use mint::Mint;
use signature::{Keypair, KeypairUtil};
use solana_sdk::system_instruction::SystemInstruction;
use std::fs::remove_dir_all;
use system_program::SystemProgram;
use vote_program::VoteProgram;
use vote_transaction::VoteTransaction;
@ -520,7 +520,7 @@ mod tests {
let mut tr2 = Transaction::system_new(&alice.keypair(), bob_pubkey, 501, last_id);
let mut instruction2 = deserialize(tr2.userdata(0)).unwrap();
if let SystemProgram::Move { ref mut tokens } = instruction2 {
if let SystemInstruction::Move { ref mut tokens } = instruction2 {
*tokens = 502;
}
tr2.instructions[0].userdata = serialize(&instruction2).unwrap();

View File

@ -5,11 +5,11 @@ use bank::Bank;
use banking_stage::{BankingStage, BankingStageReturnType};
use entry::Entry;
use fetch_stage::FetchStage;
use hash::Hash;
use ledger_write_stage::LedgerWriteStage;
use poh_service::Config;
use service::Service;
use sigverify_stage::SigVerifyStage;
use solana_sdk::hash::Hash;
use std::net::UdpSocket;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::Receiver;

View File

@ -1,329 +1 @@
//! The `transaction` module provides functionality for creating log transactions.
use bincode::serialize;
use hash::{Hash, Hasher};
use serde::Serialize;
use signature::{Keypair, KeypairUtil, Signature};
use solana_sdk::pubkey::Pubkey;
use std::mem::size_of;
pub const SIG_OFFSET: usize = size_of::<u64>();
/// An instruction to execute a program under the `program_id` of `program_ids_index` with the
/// specified accounts and userdata
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct Instruction {
/// The program code that executes this transaction is identified by the program_id.
/// this is an offset into the Transaction::program_ids field
pub program_ids_index: u8,
/// Indices into the keys array of which accounts to load
pub accounts: Vec<u8>,
/// Userdata to be stored in the account
pub userdata: Vec<u8>,
}
impl Instruction {
pub fn new<T: Serialize>(program_ids_index: u8, userdata: &T, accounts: Vec<u8>) -> Self {
let userdata = serialize(userdata).unwrap();
Instruction {
program_ids_index,
userdata,
accounts,
}
}
}
/// An atomic transaction
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct Transaction {
/// A set of digital signature of `account_keys`, `program_ids`, `last_id`, `fee` and `instructions`, signed by the first
/// signatures.len() keys of account_keys
pub signatures: Vec<Signature>,
/// The `Pubkeys` that are executing this transaction userdata. The meaning of each key is
/// program-specific.
/// * account_keys[0] - Typically this is the `caller` public key. `signature` is verified with account_keys[0].
/// In the future which key pays the fee and which keys have signatures would be configurable.
/// * account_keys[1] - Typically this is the program context or the recipient of the tokens
pub account_keys: Vec<Pubkey>,
/// The ID of a recent ledger entry.
pub last_id: Hash,
/// The number of tokens paid for processing and storage of this transaction.
pub fee: u64,
/// Keys identifying programs in the instructions vector.
pub program_ids: Vec<Pubkey>,
/// Programs that will be executed in sequence and commited in one atomic transaction if all
/// succeed.
pub instructions: Vec<Instruction>,
}
impl Transaction {
pub fn new<T: Serialize>(
from_keypair: &Keypair,
transaction_keys: &[Pubkey],
program_id: Pubkey,
userdata: &T,
last_id: Hash,
fee: u64,
) -> Self {
let program_ids = vec![program_id];
let accounts = (0..=transaction_keys.len() as u8).collect();
let instructions = vec![Instruction::new(0, userdata, accounts)];
Self::new_with_instructions(
&[from_keypair],
transaction_keys,
last_id,
fee,
program_ids,
instructions,
)
}
/// Create a signed transaction
/// * `from_keypair` - The key used to sign the transaction. This key is stored as keys[0]
/// * `account_keys` - The keys for the transaction. These are the program state
/// instances or token recipient keys.
/// * `last_id` - The PoH hash.
/// * `fee` - The transaction fee.
/// * `program_ids` - The keys that identify programs used in the `instruction` vector.
/// * `instructions` - The programs and their arguments that the transaction will execute atomically
pub fn new_with_instructions(
from_keypairs: &[&Keypair],
keys: &[Pubkey],
last_id: Hash,
fee: u64,
program_ids: Vec<Pubkey>,
instructions: Vec<Instruction>,
) -> Self {
let mut account_keys: Vec<_> = from_keypairs
.iter()
.map(|keypair| keypair.pubkey())
.collect();
account_keys.extend_from_slice(keys);
let mut tx = Transaction {
signatures: vec![],
account_keys,
last_id: Hash::default(),
fee,
program_ids,
instructions,
};
tx.sign(from_keypairs, last_id);
tx
}
pub fn userdata(&self, instruction_index: usize) -> &[u8] {
&self.instructions[instruction_index].userdata
}
fn key_index(&self, instruction_index: usize, accounts_index: usize) -> Option<usize> {
self.instructions
.get(instruction_index)
.and_then(|instruction| instruction.accounts.get(accounts_index))
.map(|&account_keys_index| account_keys_index as usize)
}
pub fn key(&self, instruction_index: usize, accounts_index: usize) -> Option<&Pubkey> {
self.key_index(instruction_index, accounts_index)
.and_then(|account_keys_index| self.account_keys.get(account_keys_index))
}
pub fn signed_key(&self, instruction_index: usize, accounts_index: usize) -> Option<&Pubkey> {
match self.key_index(instruction_index, accounts_index) {
None => None,
Some(signature_index) => {
if signature_index >= self.signatures.len() {
return None;
}
self.account_keys.get(signature_index)
}
}
}
pub fn program_id(&self, instruction_index: usize) -> &Pubkey {
let program_ids_index = self.instructions[instruction_index].program_ids_index;
&self.program_ids[program_ids_index as usize]
}
/// Get the transaction data to sign.
pub fn get_sign_data(&self) -> Vec<u8> {
let mut data = serialize(&self.account_keys).expect("serialize account_keys");
let last_id_data = serialize(&self.last_id).expect("serialize last_id");
data.extend_from_slice(&last_id_data);
let fee_data = serialize(&self.fee).expect("serialize fee");
data.extend_from_slice(&fee_data);
let program_ids = serialize(&self.program_ids).expect("serialize program_ids");
data.extend_from_slice(&program_ids);
let instructions = serialize(&self.instructions).expect("serialize instructions");
data.extend_from_slice(&instructions);
data
}
/// Sign this transaction.
pub fn sign(&mut self, keypairs: &[&Keypair], last_id: Hash) {
self.last_id = last_id;
let sign_data = self.get_sign_data();
self.signatures = keypairs
.iter()
.map(|keypair| Signature::new(&keypair.sign(&sign_data).as_ref()))
.collect();
}
/// Verify only the transaction signature.
pub fn verify_signature(&self) -> bool {
warn!("transaction signature verification called");
self.signatures
.iter()
.all(|s| s.verify(&self.from().as_ref(), &self.get_sign_data()))
}
/// Verify that references in the instructions are valid
pub fn verify_refs(&self) -> bool {
for instruction in &self.instructions {
if (instruction.program_ids_index as usize) >= self.program_ids.len() {
return false;
}
for account_index in &instruction.accounts {
if (*account_index as usize) >= self.account_keys.len() {
return false;
}
}
}
true
}
pub fn from(&self) -> &Pubkey {
&self.account_keys[0]
}
// a hash of a slice of transactions only needs to hash the signatures
pub fn hash(transactions: &[Transaction]) -> Hash {
let mut hasher = Hasher::default();
transactions
.iter()
.for_each(|tx| hasher.hash(&tx.signatures[0].as_ref()));
hasher.result()
}
}
#[cfg(test)]
mod tests {
use super::*;
use bincode::serialize;
use signature::GenKeys;
#[test]
fn test_refs() {
let key = Keypair::new();
let key1 = Keypair::new().pubkey();
let key2 = Keypair::new().pubkey();
let prog1 = Keypair::new().pubkey();
let prog2 = Keypair::new().pubkey();
let instructions = vec![
Instruction::new(0, &(), vec![0, 1]),
Instruction::new(1, &(), vec![0, 2]),
];
let tx = Transaction::new_with_instructions(
&[&key],
&[key1, key2],
Default::default(),
0,
vec![prog1, prog2],
instructions,
);
assert!(tx.verify_refs());
assert_eq!(tx.key(0, 0), Some(&key.pubkey()));
assert_eq!(tx.signed_key(0, 0), Some(&key.pubkey()));
assert_eq!(tx.key(1, 0), Some(&key.pubkey()));
assert_eq!(tx.signed_key(1, 0), Some(&key.pubkey()));
assert_eq!(tx.key(0, 1), Some(&key1));
assert_eq!(tx.signed_key(0, 1), None);
assert_eq!(tx.key(1, 1), Some(&key2));
assert_eq!(tx.signed_key(1, 1), None);
assert_eq!(tx.key(2, 0), None);
assert_eq!(tx.signed_key(2, 0), None);
assert_eq!(tx.key(0, 2), None);
assert_eq!(tx.signed_key(0, 2), None);
assert_eq!(*tx.program_id(0), prog1);
assert_eq!(*tx.program_id(1), prog2);
}
#[test]
fn test_refs_invalid_program_id() {
let key = Keypair::new();
let instructions = vec![Instruction::new(1, &(), vec![])];
let tx = Transaction::new_with_instructions(
&[&key],
&[],
Default::default(),
0,
vec![],
instructions,
);
assert!(!tx.verify_refs());
}
#[test]
fn test_refs_invalid_account() {
let key = Keypair::new();
let instructions = vec![Instruction::new(0, &(), vec![1])];
let tx = Transaction::new_with_instructions(
&[&key],
&[],
Default::default(),
0,
vec![Default::default()],
instructions,
);
assert_eq!(*tx.program_id(0), Default::default());
assert!(!tx.verify_refs());
}
/// Detect binary changes in the serialized contract userdata, which could have a downstream
/// affect on SDKs and DApps
#[test]
fn test_sdk_serialize() {
let keypair = &GenKeys::new([0u8; 32]).gen_n_keypairs(1)[0];
let to = Pubkey::new(&[
1, 1, 1, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 7, 6, 5, 4,
1, 1, 1,
]);
let program_id = Pubkey::new(&[
2, 2, 2, 4, 5, 6, 7, 8, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 8, 7, 6, 5, 4,
2, 2, 2,
]);
let tx = Transaction::new(
keypair,
&[keypair.pubkey(), to],
program_id,
&(1u8, 2u8, 3u8),
Hash::default(),
99,
);
assert_eq!(
serialize(&tx).unwrap(),
vec![
1, 0, 0, 0, 0, 0, 0, 0, 234, 139, 34, 5, 120, 28, 107, 203, 69, 25, 236, 200, 164,
1, 12, 47, 147, 53, 41, 143, 23, 116, 230, 203, 59, 228, 153, 14, 22, 241, 103,
226, 186, 169, 181, 65, 49, 215, 44, 2, 61, 214, 113, 216, 184, 206, 147, 104, 140,
225, 138, 21, 172, 135, 211, 80, 103, 80, 216, 106, 249, 86, 194, 1, 3, 0, 0, 0, 0,
0, 0, 0, 32, 253, 186, 201, 177, 11, 117, 135, 187, 167, 181, 188, 22, 59, 206,
105, 231, 150, 215, 30, 78, 212, 76, 16, 252, 180, 72, 134, 137, 247, 161, 68, 32,
253, 186, 201, 177, 11, 117, 135, 187, 167, 181, 188, 22, 59, 206, 105, 231, 150,
215, 30, 78, 212, 76, 16, 252, 180, 72, 134, 137, 247, 161, 68, 1, 1, 1, 4, 5, 6,
7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 7, 6, 5, 4, 1, 1, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 4, 5, 6, 7, 8, 9,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 8, 7, 6, 5, 4, 2, 2, 2, 1, 0, 0, 0, 0,
0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3
],
);
}
}
pub use solana_sdk::transaction::*;

View File

@ -13,12 +13,12 @@
use bank::Bank;
use blob_fetch_stage::BlobFetchStage;
use cluster_info::ClusterInfo;
use hash::Hash;
use ledger_write_stage::LedgerWriteStage;
use replicate_stage::{ReplicateStage, ReplicateStageReturnType};
use retransmit_stage::RetransmitStage;
use service::Service;
use signature::Keypair;
use solana_sdk::hash::Hash;
use std::net::UdpSocket;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, RwLock};
@ -167,7 +167,6 @@ pub mod tests {
use bincode::serialize;
use cluster_info::{ClusterInfo, Node};
use entry::Entry;
use hash::Hash;
use leader_scheduler::LeaderScheduler;
use logger;
use mint::Mint;
@ -175,6 +174,7 @@ pub mod tests {
use packet::SharedBlob;
use service::Service;
use signature::{Keypair, KeypairUtil};
use solana_sdk::hash::Hash;
use std::net::UdpSocket;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::channel;

View File

@ -4,11 +4,11 @@ use bank::Bank;
use bincode::serialize;
use cluster_info::ClusterInfo;
use counter::Counter;
use hash::Hash;
use log::Level;
use packet::SharedBlob;
use result::{Error, Result};
use signature::Keypair;
use solana_sdk::hash::Hash;
use std::net::SocketAddr;
use std::sync::atomic::AtomicUsize;
use std::sync::{Arc, RwLock};

View File

@ -3,12 +3,12 @@
#[cfg(test)]
use bank::Bank;
use bincode::deserialize;
use hash::Hash;
#[cfg(test)]
use result::Result;
use signature::Keypair;
#[cfg(test)]
use signature::KeypairUtil;
use solana_sdk::hash::Hash;
use solana_sdk::pubkey::Pubkey;
use system_transaction::SystemTransaction;
use transaction::Transaction;

View File

@ -5,10 +5,8 @@ use budget_program::BudgetState;
use budget_transaction::BudgetTransaction;
use chrono::prelude::*;
use clap::ArgMatches;
use drone::{request_airdrop_transaction, DRONE_PORT};
use elf;
use fullnode::Config;
use hash::Hash;
use loader_transaction::LoaderTransaction;
use ring::rand::SystemRandom;
use ring::signature::Ed25519KeyPair;
@ -16,6 +14,8 @@ use rpc::RpcSignatureStatus;
use rpc_request::RpcRequest;
use serde_json;
use signature::{Keypair, KeypairUtil, Signature};
use solana_drone::drone::{request_airdrop_transaction, DRONE_PORT};
use solana_sdk::hash::Hash;
use solana_sdk::pubkey::Pubkey;
use std::fs::{self, File};
use std::io::Write;
@ -759,12 +759,12 @@ mod tests {
use bank::Bank;
use clap::{App, Arg, SubCommand};
use cluster_info::Node;
use drone::run_local_drone;
use fullnode::Fullnode;
use leader_scheduler::LeaderScheduler;
use ledger::create_tmp_genesis;
use serde_json::Value;
use signature::{read_keypair, read_pkcs8, Keypair, KeypairUtil};
use solana_drone::drone::run_local_drone;
use std::fs::remove_dir_all;
use std::sync::mpsc::channel;
use std::sync::{Arc, RwLock};

View File

@ -354,10 +354,10 @@ pub fn window_service(
mod test {
use cluster_info::{ClusterInfo, Node};
use entry::Entry;
use hash::Hash;
use leader_scheduler::LeaderScheduler;
use logger;
use packet::{make_consecutive_blobs, SharedBlob, PACKET_DATA_SIZE};
use solana_sdk::hash::Hash;
use std::net::UdpSocket;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{channel, Receiver};

View File

@ -10,7 +10,6 @@ use solana::blob_fetch_stage::BlobFetchStage;
use solana::cluster_info::{ClusterInfo, Node, NodeInfo};
use solana::entry::{reconstruct_entries_from_blobs, Entry};
use solana::fullnode::{Fullnode, FullnodeReturnType};
use solana::hash::Hash;
use solana::leader_scheduler::{make_active_set_entries, LeaderScheduler, LeaderSchedulerConfig};
use solana::ledger::{
create_tmp_genesis, create_tmp_sample_ledger, get_tmp_ledger_path, read_ledger, LedgerWindow,
@ -28,6 +27,7 @@ use solana::system_transaction::SystemTransaction;
use solana::thin_client::{retry_get_balance, ThinClient};
use solana::transaction::Transaction;
use solana::window::default_window;
use solana_sdk::hash::Hash;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::timing::{duration_as_ms, duration_as_s};
use std::collections::{HashSet, VecDeque};