mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-26 19:21:44 +00:00
Move js example to js-tmsp/example
This commit is contained in:
1
example/js/README.md
Normal file
1
example/js/README.md
Normal file
@ -0,0 +1 @@
|
||||
This example has been moved here: https://github.com/tendermint/js-tmsp/tree/master/example
|
@ -1,75 +0,0 @@
|
||||
var server = require("./server");
|
||||
var wire = require("js-wire");
|
||||
var util = require("util");
|
||||
var msg = require("./msgs");
|
||||
var types = require("./types");
|
||||
|
||||
|
||||
function CounterApp(){
|
||||
this.hashCount = 0;
|
||||
this.txCount = 0;
|
||||
this.serial = false;
|
||||
};
|
||||
|
||||
CounterApp.prototype.info = function(cb) {
|
||||
return cb(util.format("hashes:%d, txs:%d", this.hashCount, this.txCount));
|
||||
}
|
||||
|
||||
CounterApp.prototype.set_option = function(cb, key, value) {
|
||||
if (key == "serial" && value == "on") {
|
||||
this.serial = true;
|
||||
}
|
||||
return cb("");
|
||||
}
|
||||
|
||||
CounterApp.prototype.append_tx = function(cb, txBytes) {
|
||||
if (this.serial) {
|
||||
if (txBytes.length >= 2 && txBytes.slice(0, 2) == "0x") {
|
||||
var hexString = txBytes.toString("ascii", 2);
|
||||
var hexBytes = new Buffer(hexString, "hex");
|
||||
txBytes = hexBytes;
|
||||
}
|
||||
var txValue = txBytes.readIntBE(0, txBytes.length);
|
||||
if (txValue != this.txCount){
|
||||
return cb(types.RetCodeInvalidNonce, "", "Nonce is invalid");
|
||||
}
|
||||
}
|
||||
this.txCount += 1;
|
||||
return cb(types.RetCodeOK, "", "");
|
||||
}
|
||||
|
||||
CounterApp.prototype.check_tx = function(cb, txBytes) {
|
||||
if (this.serial) {
|
||||
if (txBytes.length >= 2 && txBytes.slice(0, 2) == "0x") {
|
||||
var hexString = txBytes.toString("ascii", 2);
|
||||
var hexBytes = new Buffer(hexString, "hex");
|
||||
txBytes = hexBytes;
|
||||
}
|
||||
var txValue = txBytes.readIntBE(0, txBytes.length);
|
||||
if (txValue < this.txCount){
|
||||
return cb(types.RetCodeInvalidNonce, "", "Nonce is too low");
|
||||
}
|
||||
}
|
||||
this.txCount += 1;
|
||||
return cb(types.RetCodeOK, "", "");
|
||||
}
|
||||
|
||||
CounterApp.prototype.get_hash = function(cb) {
|
||||
this.hashCount += 1;
|
||||
if (this.txCount == 0){
|
||||
return cb("", "Zero tx count; hash is empth");
|
||||
}
|
||||
var buf = new Buffer(8);
|
||||
buf.writeIntBE(this.txCount, 0, 8);
|
||||
cb(buf, "");
|
||||
}
|
||||
|
||||
CounterApp.prototype.query = function(cb) {
|
||||
return cb("", "Query not yet supporrted");
|
||||
}
|
||||
|
||||
console.log("Counter app in Javascript");
|
||||
|
||||
var app = new CounterApp();
|
||||
var appServer = new server.AppServer(app);
|
||||
appServer.server.listen(46658);
|
@ -1,88 +0,0 @@
|
||||
var wire = require("js-wire");
|
||||
var types = require("./types");
|
||||
|
||||
var readRequestInfo = function(r) { return []; };
|
||||
var readRequestSetOption = function(r) { return [r.readString(), r.readString()]; };
|
||||
var readRequestAppendTx = function(r) { return [r.readByteArray()]; };
|
||||
var readRequestCheckTx = function(r) { return [r.readByteArray()]; };
|
||||
var readRequestGetHash = function(r) { return []; };
|
||||
var readRequestQuery = function(r) { return [r.readByteArray()]; };
|
||||
|
||||
var runOnce = function(name, f) {
|
||||
var ran = false;
|
||||
return function() {
|
||||
if (ran) {
|
||||
console.log("Error: response was already written for "+name);
|
||||
return
|
||||
} else {
|
||||
ran = true;
|
||||
}
|
||||
return f.apply(this, arguments);
|
||||
};
|
||||
};
|
||||
|
||||
var makeWriteResponseInfo = function(w, cb) { return runOnce("info", function(info) {
|
||||
w.writeUint8(types.ResponseTypeInfo);
|
||||
w.writeString(info);
|
||||
cb(w);
|
||||
});};
|
||||
var makeWriteResponseSetOption = function(w, cb) { return runOnce("set_option", function(log) {
|
||||
w.writeUint8(types.ResponseTypeSetOption);
|
||||
w.writeString(log);
|
||||
cb(w);
|
||||
});};
|
||||
var makeWriteResponseAppendTx = function(w, cb) { return runOnce("append_tx", function(code, result, log) {
|
||||
w.writeUint8(types.ResponseTypeAppendTx);
|
||||
w.writeUint8(code);
|
||||
w.writeByteArray(result);
|
||||
w.writeString(log);
|
||||
cb(w);
|
||||
});};
|
||||
var makeWriteResponseCheckTx = function(w, cb) { return runOnce("check_tx", function(code, result, log) {
|
||||
w.writeUint8(types.ResponseTypeCheckTx);
|
||||
w.writeUint8(code);
|
||||
w.writeByteArray(result);
|
||||
w.writeString(log);
|
||||
cb(w);
|
||||
});};
|
||||
var makeWriteResponseGetHash = function(w, cb) { return runOnce("get_hash", function(hash, log) {
|
||||
w.writeUint8(types.ResponseTypeGetHash);
|
||||
w.writeByteArray(hash);
|
||||
w.writeString(log);
|
||||
cb(w);
|
||||
});};
|
||||
var makeWriteResponseQuery = function(w, cb) { return runOnce("query", function(result, log) {
|
||||
w.writeUint8(types.ResponseTypeQuery);
|
||||
w.writeByteArray(result);
|
||||
w.writeString(log);
|
||||
cb(w);
|
||||
});};
|
||||
|
||||
module.exports = {
|
||||
types : {
|
||||
0x01 : "echo",
|
||||
0x02 : "flush",
|
||||
0x03 : "info",
|
||||
0x04 : "set_option",
|
||||
0x21 : "append_tx",
|
||||
0x22 : "check_tx",
|
||||
0x23 : "get_hash",
|
||||
0x24 : "query",
|
||||
},
|
||||
readers : {
|
||||
"info": readRequestInfo,
|
||||
"set_option": readRequestSetOption,
|
||||
"append_tx": readRequestAppendTx,
|
||||
"check_tx": readRequestCheckTx,
|
||||
"get_hash": readRequestGetHash,
|
||||
"query": readRequestQuery,
|
||||
},
|
||||
writerGenerators: {
|
||||
"info": makeWriteResponseInfo,
|
||||
"set_option": makeWriteResponseSetOption,
|
||||
"append_tx": makeWriteResponseAppendTx,
|
||||
"check_tx": makeWriteResponseCheckTx,
|
||||
"get_hash": makeWriteResponseGetHash,
|
||||
"query": makeWriteResponseQuery,
|
||||
},
|
||||
};
|
@ -1,10 +0,0 @@
|
||||
{
|
||||
"name": "example",
|
||||
"version": "0.0.1",
|
||||
"description": "Example javascript TMSP application",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"js-wire": "0.0.2"
|
||||
}
|
||||
}
|
||||
|
@ -1,141 +0,0 @@
|
||||
var net = require("net");
|
||||
var wire = require("js-wire");
|
||||
var msg = require("./msgs");
|
||||
var types = require("./types");
|
||||
|
||||
var maxWriteBufferLength = 4096; // Any more and flush
|
||||
|
||||
// Takes an application and handles TMSP connection
|
||||
// which invoke methods on the app
|
||||
function AppServer(app){
|
||||
// set the app for the socket handler
|
||||
this.app = app;
|
||||
|
||||
// create a server by providing callback for
|
||||
// accepting new connection and callbacks for
|
||||
// connection events ('data', 'end', etc.)
|
||||
this.createServer();
|
||||
}
|
||||
|
||||
AppServer.prototype.createServer = function() {
|
||||
var app = this.app;
|
||||
|
||||
// Define the socket handler
|
||||
this.server = net.createServer(function(socket) {
|
||||
socket.name = socket.remoteAddress + ":" + socket.remotePort;
|
||||
console.log("new connection from", socket.name);
|
||||
|
||||
var conn = new Connection(socket, function(msgBytes, cb) {
|
||||
var r = new wire.Reader(msgBytes);
|
||||
|
||||
// Now we can decode
|
||||
var typeByte = r.readByte();
|
||||
var reqType = msg.types[typeByte];
|
||||
|
||||
// Special messages.
|
||||
// NOTE: msgs are length prefixed
|
||||
if (reqType == "flush") {
|
||||
var w = new wire.Writer();
|
||||
w.writeByte(types.ResponseTypeFlush);
|
||||
conn.writeMessage(w.getBuffer());
|
||||
conn.flush();
|
||||
return cb();
|
||||
} else if (reqType == "echo") {
|
||||
var message = r.readString();
|
||||
var w = new wire.Writer();
|
||||
w.writeByte(types.ResponseTypeEcho);
|
||||
w.writeString(message);
|
||||
conn.writeMessage(w.getBuffer());
|
||||
return cb();
|
||||
}
|
||||
|
||||
// Make callback by wrapping cp
|
||||
var resCb = msg.writerGenerators[reqType](new wire.Writer(), function(w) {
|
||||
conn.writeMessage(w.getBuffer());
|
||||
return cb();
|
||||
});
|
||||
|
||||
// Decode arguments
|
||||
var args = msg.readers[reqType](r);
|
||||
args.unshift(resCb);
|
||||
|
||||
// Call function
|
||||
var res = app[reqType].apply(app, args);
|
||||
if (res != undefined) {
|
||||
console.log("Message handler shouldn't return anything!");
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
function Connection(socket, msgCb) {
|
||||
this.socket = socket;
|
||||
this.recvBuf = new Buffer(0);
|
||||
this.sendBuf = new Buffer(0);
|
||||
this.msgCb = msgCb;
|
||||
this.waitingResult = false;
|
||||
var conn = this;
|
||||
|
||||
// Handle TMSP requests.
|
||||
socket.on('data', function(data) {
|
||||
conn.appendData(data);
|
||||
});
|
||||
socket.on('end', function() {
|
||||
console.log("connection ended");
|
||||
});
|
||||
}
|
||||
|
||||
Connection.prototype.appendData = function(bytes) {
|
||||
var conn = this;
|
||||
if (bytes.length > 0) {
|
||||
this.recvBuf = Buffer.concat([this.recvBuf, new Buffer(bytes)]);
|
||||
}
|
||||
if (this.waitingResult) {
|
||||
return;
|
||||
}
|
||||
var r = new wire.Reader(this.recvBuf);
|
||||
var msg;
|
||||
try {
|
||||
msg = r.readByteArray();
|
||||
} catch(e) {
|
||||
return;
|
||||
}
|
||||
this.recvBuf = r.buf.slice(r.offset);
|
||||
this.waitingResult = true;
|
||||
this.socket.pause();
|
||||
//try {
|
||||
this.msgCb(msg, function() {
|
||||
// This gets called after msg handler is finished with response.
|
||||
conn.waitingResult = false;
|
||||
conn.socket.resume();
|
||||
if (conn.recvBuf.length > 0) {
|
||||
conn.appendData("");
|
||||
}
|
||||
});
|
||||
//} catch(e) {
|
||||
// console.log("FATAL ERROR: ", e);
|
||||
//}
|
||||
};
|
||||
|
||||
Connection.prototype.writeMessage = function(msgBytes) {
|
||||
var msgLength = wire.uvarintSize(msgBytes.length);
|
||||
var buf = new Buffer(1+msgLength+msgBytes.length);
|
||||
var w = new wire.Writer(buf);
|
||||
w.writeByteArray(msgBytes); // TODO technically should be writeVarint
|
||||
this.sendBuf = Buffer.concat([this.sendBuf, w.getBuffer()]);
|
||||
if (this.sendBuf.length >= maxWriteBufferLength) {
|
||||
this.flush();
|
||||
}
|
||||
};
|
||||
|
||||
Connection.prototype.flush = function() {
|
||||
var n = this.socket.write(this.sendBuf);
|
||||
this.sendBuf = new Buffer(0);
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
module.exports = { AppServer: AppServer };
|
@ -1,27 +0,0 @@
|
||||
module.exports = {
|
||||
RetCodeOK: 0,
|
||||
RetCodeInternalError: 1,
|
||||
RetCodeUnauthorized: 2,
|
||||
RetCodeInsufficientFees: 3,
|
||||
RetCodeUnknownRequest: 4,
|
||||
RetCodeEncodingError: 5,
|
||||
RetCodeNonce: 6,
|
||||
|
||||
RequestTypeEcho: 0x01,
|
||||
RequestTypeFlush: 0x02,
|
||||
RequestTypeInfo: 0x03,
|
||||
RequestTypeSetOption: 0x04,
|
||||
RequestTypeAppendTx: 0x21,
|
||||
RequestTypeCheckTx: 0x22,
|
||||
RequestTypeGetHash: 0x23,
|
||||
RequestTypeQuery: 0x24,
|
||||
|
||||
ResponseTypeEcho: 0x11,
|
||||
ResponseTypeFlush: 0x12,
|
||||
ResponseTypeInfo: 0x13,
|
||||
ResponseTypeSetOption: 0x14,
|
||||
ResponseTypeAppendTx: 0x31,
|
||||
ResponseTypeCheckTx: 0x32,
|
||||
ResponseTypeGetHash: 0x33,
|
||||
ResponseTypeQuery: 0x34,
|
||||
};
|
Reference in New Issue
Block a user