mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-21 11:31:08 +03:00
bcc8f68f52
* Fix issue where we have no metadata for a block (#938)
when restarting node before initial sync completed
* Avoid double-locking on add eviction. Fixes #936
* Fix 33c5a983
* Add support for DNS Seed (#940)
* Add support for DNS Seed
* Add port
* Add seed.grin-tech.org
* Remove duplicate IPs
* minimal stratum server
* Modifications for review comments. Move stratum test into its own file, move get_block() into its own rust module, use pool and chain only rather than the entire Miner object
* rustfmt
* cleanup
* cleanup
* Introduce extending_readonly to simplify a forcing and cancelling rollbacks (#945)
readonly views of the txhashset
* Add DNS Seed and make DNSSeed default (#942)
* Add dns seed seeding type
* Add grin-seed.owncrypto.de and make DNSSeed default
* Add email address for each DNS Seed
* [WIP] Core PMMR and API updates to support wallet restore (#950)
* update pmmr to get batch of elements by insertion position
* update pmmr to get batch of elements by insertion position
* add api + chain calls to get traversed outputs back out
* add api + chain calls to get traversed outputs back out
* first pass getting wallet restore to work again with updated utxo-walking api
* Update simulation.md
* Fix Bus Error (core dumped) when validating fast sync txhashset (#956)
This PR fixes #953 by introducing a lock for txhashet_write. It's not enough
to synchronize access to in memory data, files also needs to be protected, so
a general txhashset lock was introduced.
* refactor grin crate into separate modules (#955)
* Add total kernel offset to block api (#954)
* minimal stratum server
* Modifications for review comments. Move stratum test into its own file, move get_block() into its own rust module, use pool and chain only rather than the entire Miner object
* rustfmt
* cleanup
* cleanup
* Merge with grin_grin -> servers code reorg
* Merge with grin_grin -> servers code reorg
* add stratum server stats
150 lines
4.9 KiB
Rust
150 lines
4.9 KiB
Rust
// Copyright 2018 The Grin Developers
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
extern crate grin_api as api;
|
|
extern crate grin_chain as chain;
|
|
extern crate grin_core as core;
|
|
extern crate grin_servers as servers;
|
|
extern crate grin_p2p as p2p;
|
|
extern crate grin_pow as pow;
|
|
extern crate grin_util as util;
|
|
extern crate grin_wallet as wallet;
|
|
|
|
extern crate bufstream;
|
|
extern crate serde_json;
|
|
|
|
mod framework;
|
|
|
|
use std::io::prelude::*;
|
|
use std::net::TcpStream;
|
|
use bufstream::BufStream;
|
|
use serde_json::Value;
|
|
|
|
use std::thread;
|
|
use std::time;
|
|
|
|
use core::global;
|
|
use core::global::ChainTypes;
|
|
|
|
use framework::{config, miner_config};
|
|
|
|
// Create a grin server, and a stratum server.
|
|
// Simulate a few JSONRpc requests and verify the results.
|
|
// Validate disconnected workers
|
|
// Validate broadcasting new jobs
|
|
#[test]
|
|
fn basic_stratum_server() {
|
|
util::init_test_logger();
|
|
global::set_mining_mode(ChainTypes::AutomatedTesting);
|
|
|
|
let test_name_dir = "stratum_server";
|
|
framework::clean_all_output(test_name_dir);
|
|
|
|
// Create a server
|
|
let s = servers::Server::new(config(4000, test_name_dir, 0)).unwrap();
|
|
|
|
// Get mining config with stratumserver enabled
|
|
let mut miner_cfg = miner_config();
|
|
miner_cfg.enable_mining = false;
|
|
miner_cfg.attempt_time_per_block = 999;
|
|
miner_cfg.enable_stratum_server = true;
|
|
miner_cfg.stratum_server_addr = Some(String::from("127.0.0.1:11101"));
|
|
|
|
// Start stratum server
|
|
s.start_stratum_server(miner_cfg);
|
|
|
|
// Wait for stratum server to start and
|
|
// Verify stratum server accepts connections
|
|
loop {
|
|
if let Ok(_stream) = TcpStream::connect("127.0.0.1:11101") {
|
|
break;
|
|
} else {
|
|
thread::sleep(time::Duration::from_millis(500));
|
|
}
|
|
// As this stream falls out of scope it will be disconnected
|
|
}
|
|
|
|
// Create a few new worker connections
|
|
let mut workers = vec![];
|
|
for _n in 0..5 {
|
|
let w = TcpStream::connect("127.0.0.1:11101").unwrap();
|
|
w.set_nonblocking(true)
|
|
.expect("Failed to set TcpStream to non-blocking");
|
|
let stream = BufStream::new(w);
|
|
workers.push(stream);
|
|
}
|
|
assert!(workers.len() == 5);
|
|
|
|
// Simulate a worker lost connection
|
|
workers.remove(4);
|
|
|
|
// Swallow the genesis block
|
|
thread::sleep(time::Duration::from_secs(1)); // Wait for the server to broadcast
|
|
let mut response = String::new();
|
|
for n in 0..workers.len() {
|
|
let _result = workers[n].read_line(&mut response);
|
|
}
|
|
|
|
// Verify a few stratum JSONRpc commands
|
|
// getjobtemplate - expected block template result
|
|
let mut response = String::new();
|
|
let job_req = "{\"id\": \"Stratum\", \"jsonrpc\": \"2.0\", \"method\": \"getjobtemplate\"}\n";
|
|
workers[2].write(job_req.as_bytes()).unwrap();
|
|
workers[2].flush().unwrap();
|
|
thread::sleep(time::Duration::from_secs(1)); // Wait for the server to reply
|
|
match workers[2].read_line(&mut response) {
|
|
Ok(_) => {
|
|
let r: Value = serde_json::from_str(&response).unwrap();
|
|
assert_eq!(r["error"], serde_json::Value::Null);
|
|
assert_ne!(r["result"], serde_json::Value::Null);
|
|
}
|
|
Err(_e) => {
|
|
assert!(false);
|
|
}
|
|
}
|
|
|
|
// keepalive - expected "ok" result
|
|
let mut response = String::new();
|
|
let job_req = "{\"id\":\"3\",\"jsonrpc\":\"2.0\",\"method\":\"keepalive\"}\n";
|
|
let ok_resp = "{\"id\":\"3\",\"jsonrpc\":\"2.0\",\"result\":\"ok\",\"error\":null}\n";
|
|
workers[2].write(job_req.as_bytes()).unwrap();
|
|
workers[2].flush().unwrap();
|
|
thread::sleep(time::Duration::from_secs(1)); // Wait for the server to reply
|
|
let _st = workers[2].read_line(&mut response);
|
|
assert_eq!(response.as_str(), ok_resp);
|
|
|
|
// "doesnotexist" - error expected
|
|
let mut response = String::new();
|
|
let job_req = "{\"id\":\"4\",\"jsonrpc\":\"2.0\",\"method\":\"doesnotexist\"}\n";
|
|
let ok_resp = "{\"id\":\"4\",\"jsonrpc\":\"2.0\",\"result\":null,\"error\":{\"code\":-32601,\"message\":\"Method not found\"}}\n";
|
|
workers[3].write(job_req.as_bytes()).unwrap();
|
|
workers[3].flush().unwrap();
|
|
thread::sleep(time::Duration::from_secs(1)); // Wait for the server to reply
|
|
let _st = workers[3].read_line(&mut response);
|
|
assert_eq!(response.as_str(), ok_resp);
|
|
|
|
// Simulate a worker lost connection
|
|
workers.remove(1);
|
|
|
|
// Start mining blocks
|
|
s.start_miner(miner_config());
|
|
|
|
// Verify blocks are being broadcast to workers
|
|
let expected = String::from("job");
|
|
thread::sleep(time::Duration::from_secs(3)); // Wait for a few mined blocks
|
|
let mut jobtemplate = String::new();
|
|
let _st = workers[2].read_line(&mut jobtemplate);
|
|
let job_template: Value = serde_json::from_str(&jobtemplate).unwrap();
|
|
assert_eq!(job_template["method"], expected);
|
|
}
|