Skip to content
This repository has been archived by the owner on Mar 11, 2021. It is now read-only.

Commit

Permalink
Initial release (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
adrianbrink authored Jun 16, 2017
1 parent 167d771 commit 1eddd55
Show file tree
Hide file tree
Showing 4 changed files with 293 additions and 3 deletions.
56 changes: 56 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# The Tendermint Code of Conduct
This code of conduct applies to all projects run by the Tendermint/COSMOS team and hence to rust-abci.


----


# Conduct
## Contact: adrian@tendermint.com

* We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic.

* On Slack, please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and welcoming environment for all.

* Please be kind and courteous. There’s no need to be mean or rude.

* Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer.

* Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works.

* We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behaviour. We interpret the term “harassment” as including the definition in the [Citizen Code of Conduct](http://citizencodeofconduct.org/); if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don’t tolerate behavior that excludes people in socially marginalized groups.

* Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel admins or the person mentioned above immediately. Whether you’re a regular contributor or a newcomer, we care about making this community a safe place for you and we’ve got your back.

* Likewise any spamming, trolling, flaming, baiting or other attention-stealing behaviour is not welcome.


----


# Moderation
These are the policies for upholding our community’s standards of conduct. If you feel that a thread needs moderation, please contact the above mentioned person.

1. Remarks that violate the Tendermint/COSMOS standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.)

2. Remarks that moderators find inappropriate, whether listed in the code of conduct or not, are also not allowed.

3. Moderators will first respond to such remarks with a warning.

4. If the warning is unheeded, the user will be “kicked,” i.e., kicked out of the communication channel to cool off.

5. If the user comes back and continues to make trouble, they will be banned, i.e., indefinitely excluded.

6. Moderators may choose at their discretion to un-ban the user if it was a first offense and they offer the offended party a genuine apology.

7. If a moderator bans someone and you think it was unjustified, please take it up with that moderator, or with a different moderator, in private. Complaints about bans in-channel are not allowed.

8. Moderators are held to a higher standard than other community members. If a moderator creates an inappropriate situation, they should expect less leeway than others.

In the Tendermint/COSMOS community we strive to go the extra step to look out for each other. Don’t just aim to be technically unimpeachable, try to be your best self. In particular, avoid flirting with offensive or sensitive issues, particularly if they’re off-topic; this all too often leads to unnecessary fights, hurt feelings, and damaged trust; worse, it can drive people away from the community entirely.

And if someone takes issue with something you said or did, resist the urge to be defensive. Just stop doing what it was they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good there was something you could’ve communicated better — remember that it’s your responsibility to make your fellow Cosmonauts comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their trust.

The enforcement policies listed above apply to all official Tendermint/COSMOS venues.For other projects adopting the Tendermint/COSMOS Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion.

*Adapted from the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling), the [Contributor Covenant v1.3.0](http://contributor-covenant.org/version/1/3/0/) and the [Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html).
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ version = "0.1.0"
authors = ["Adrian Brink <adrian@brink-holdings.com>"]

[dependencies]
byteorder = "1.0.0"
futures = "0.1"
futures-cpupool = "0.1"
grpc = "0.*"
Expand Down
70 changes: 67 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,84 @@
# Rust ABCI
A rust implementation of the ABCI protocol for Tendermint.

[![](https://tokei.rs/b1/github/tendermint/rust-abci)](https://github.com/tendermint/rust-abci)

### Join the chat!
[![](https://img.shields.io/badge/slack-join%20chat-brightgreen.svg)](http://forum.tendermint.com:3000/)

We have a friendly community of like-minded people which are always eager to help someone in need of advice or just
looking for casual banter.

### Code of Conduct
Please read, understand and adhere to our [code of conduct](https://github.com/tendermint/rust-abci/blob/develop/CODE_OF_CONDUCT.md).


----


## About rust-abci
This library implements the ABCI protocol and can be used to write ABCI applications for Tendermint in rust.
Here you can find more information about [Tendermint](https://github.com/tendermint/tendermint) and [ABCI application](https://github.com/tendermint/abci).

For a real life example of an ABCI application you can checkout [Ethermint](https://github.com/tendermint/ethermint) or [Basecoin](https://github.com/tendermint/basecoin).


----


## Dependencies
Make sure that you have Rust installed. The easiest way is to follow the instructions on [rustup](https://rustup.rs/).


## Installation
// TODO - explain how to use this library in writing your own ABCI app
// TODO - publish to crates.io
To test the examples, please clone this repository.
```bash
git clone git@github.com:tendermint/rust-abci.git
```
Please have a look at the dummy or counter app inside `src/bin` to get a feeling for how this server works.

To use this library to build your own ABCI apps in rust you have to include the following in your `Cargo.toml` file.
```bash
[dependencies]
rust-abci = { git = "git@github.com:tendermint/rust-abci.git" }
```
----
## Running the examples
### Tendermint
To run either of the example apps you have to have Tendermint installed and initialised. Please install it according to these [instructions](https://github.com/tendermint/tendermint). You can also check out [Ethermint](https://github.com/tendermint/ethermint/tree/develop) for an in-depth explanation of how ABCI apps work.
Rememeber to run tendermint with the `--abci grpc` flag like so.
```bash
tendermint node --abci grpc
```
### Examples
Once the Tendermint instance is up and running you can start either of the examples like this. Of course, please rememeber to
switch into the rust-abci folder.
```bash
cargo run --bin dummy

cargo run --bin counter
```
----
## Documentation
// TODO - publish to rust docs
// TODO - give quick examples
## Dependencies
----
## Optional Dependencies
The message types for the ABCI protocol are defined in a protobuf file, which can be copied from [here](https://github.com/tendermint/abci/blob/master/types/types.proto).
We use [rust-protobuf](https://github.com/stepancheg/rust-protobuf) to generate compatible rust files from the protobuf
Expand All @@ -26,6 +89,7 @@ Install these two tools.
cargo install protobuf
cargo install grpc-compiler
```
```bash
protoc --rust_out src/ types.proto
protoc --rust-grpc_out src/ types.proto
Expand Down
169 changes: 169 additions & 0 deletions src/bin/counter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
extern crate byteorder;
extern crate grpc;
extern crate rust_abci;


use rust_abci::new_server;
use rust_abci::types::*;
use rust_abci::types_grpc::*;


use std::sync::Mutex;
use std::thread;


use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};


struct CounterApp {
serial: Mutex<bool>,
txCount: Mutex<u64>,
hashCount: Mutex<u64>,
}

impl CounterApp {
fn new(serial: bool) -> CounterApp {
CounterApp {
serial: Mutex::new(serial),
txCount: Mutex::new(0),
hashCount: Mutex::new(0),
}
}
}

impl ABCIApplication for CounterApp {
fn echo(&self, o: ::grpc::RequestOptions, p: RequestEcho) -> ::grpc::SingleResponse<ResponseEcho> {
let echo = p.get_message();
let mut response = ResponseEcho::new();
response.set_message(echo.to_owned());
::grpc::SingleResponse::completed(response)
}

fn flush(&self, o: ::grpc::RequestOptions, p: RequestFlush) -> ::grpc::SingleResponse<ResponseFlush> {
unimplemented!();
}

fn info(&self, o: ::grpc::RequestOptions, p: RequestInfo) -> ::grpc::SingleResponse<ResponseInfo> {
let mut response = ResponseInfo::new();
response.set_data("CounterApp".to_owned());
response.set_version("0.1.0".to_owned());
::grpc::SingleResponse::completed(response)
}

fn set_option(&self, o: ::grpc::RequestOptions, p: RequestSetOption) -> ::grpc::SingleResponse<ResponseSetOption> {
let mut response = ResponseSetOption::new();
if p.get_key() == "serial" && p.get_value() == "on" {
let mut serial = self.serial.lock().unwrap();
*serial = true;
response.set_log("Serial set to ON".to_owned());
}
::grpc::SingleResponse::completed(response)
}

fn deliver_tx(&self, o: ::grpc::RequestOptions, p: RequestDeliverTx) -> ::grpc::SingleResponse<ResponseDeliverTx> {
let mut response = ResponseDeliverTx::new();
if *self.serial.lock().unwrap() {
if p.get_tx().len() > 8 {
response.set_code(CodeType::EncodingError);
response.set_log("Max tx size is 8 bytes".to_owned());
return ::grpc::SingleResponse::completed(response);
}
}
let nonce = p.get_tx().read_uint::<BigEndian>(p.get_tx().len()).unwrap();
if *self.txCount.lock().unwrap() != nonce {
response.set_code(CodeType::BadNonce);
response.set_log("Invalid nonce.".to_owned());
return ::grpc::SingleResponse::completed(response);
}
let mut txCount = self.txCount.lock().unwrap();
*txCount += 1;
response.set_code(CodeType::OK);
::grpc::SingleResponse::completed(response)
}

fn check_tx(&self, o: ::grpc::RequestOptions, p: RequestCheckTx) -> ::grpc::SingleResponse<ResponseCheckTx> {
let mut response = ResponseCheckTx::new();
if *self.serial.lock().unwrap() {
if p.get_tx().len() > 8 {
response.set_code(CodeType::EncodingError);
response.set_log("Max tx size is 8 bytes".to_owned());
return ::grpc::SingleResponse::completed(response);
}
}
let nonce = p.get_tx().read_uint::<BigEndian>(p.get_tx().len()).unwrap();
if *self.txCount.lock().unwrap() != nonce {
response.set_code(CodeType::BadNonce);
response.set_log("Invalid nonce.".to_owned());
return ::grpc::SingleResponse::completed(response);
}
response.set_code(CodeType::OK);
::grpc::SingleResponse::completed(response)
}

fn query(&self, o: ::grpc::RequestOptions, p: RequestQuery) -> ::grpc::SingleResponse<ResponseQuery> {
let mut response = ResponseQuery::new();
match p.get_path() {
"hash" => {
let mut data = vec![];
data.write_uint::<BigEndian>(*self.hashCount.lock().unwrap(), 8);
response.set_value(data);
return ::grpc::SingleResponse::completed(response);
},
"tx" => {
let mut data = vec![];
data.write_uint::<BigEndian>(*self.txCount.lock().unwrap(), 8);
response.set_value(data);
return ::grpc::SingleResponse::completed(response);
},
_ => {
response.set_log("Invalid query path. Expected hash or tx.".to_owned());
return ::grpc::SingleResponse::completed(response);
},
}
}

fn commit(&self, o: ::grpc::RequestOptions, p: RequestCommit) -> ::grpc::SingleResponse<ResponseCommit> {
let mut response = ResponseCommit::new();

let mut hashCount = self.hashCount.lock().unwrap();
*hashCount += 1;

if *self.txCount.lock().unwrap() == 0 {
response.set_code(CodeType::OK);
return ::grpc::SingleResponse::completed(response);
}

let mut data = vec![];
data.write_uint::<BigEndian>(*self.txCount.lock().unwrap(), 8);
response.set_data(data);
::grpc::SingleResponse::completed(response)
}

fn init_chain(&self, o: ::grpc::RequestOptions, p: RequestInitChain) -> ::grpc::SingleResponse<ResponseInitChain> {
let response = ResponseInitChain::new();
::grpc::SingleResponse::completed(response)
}

fn begin_block(&self, o: ::grpc::RequestOptions, p: RequestBeginBlock) -> ::grpc::SingleResponse<ResponseBeginBlock> {
let response = ResponseBeginBlock::new();
::grpc::SingleResponse::completed(response)
}

fn end_block(&self, o: ::grpc::RequestOptions, p: RequestEndBlock) -> ::grpc::SingleResponse<ResponseEndBlock> {
let response = ResponseEndBlock::new();
::grpc::SingleResponse::completed(response)
}
}

fn main() {
let listen_addr = "0.0.0.0:46658";
let connection_type = "grpc";

let app = CounterApp::new(true);

let _server = new_server(listen_addr, connection_type, app);

loop {
thread::park();
}
}

0 comments on commit 1eddd55

Please sign in to comment.