Contract and client library improvements. (#184)

* Added tty check to contract libs.
* Javascript browser-native client.
* Removed hex encoding in user json outputs.
* Updated file contract for new contract library.
This commit is contained in:
Ravin Perera
2020-12-05 09:08:24 +05:30
committed by GitHub
parent a421f13d91
commit b2fd8ae4b5
16 changed files with 2967 additions and 125 deletions

View File

@@ -15,7 +15,7 @@ const echoContract = async (ctx) => {
for (const user of ctx.users.list()) {
// This user's pubkey can be accessed from 'user.pubKey'
for (const input of user.inputs) {
inputHandlers.push(new Promise(async (resolve) => {
@@ -23,10 +23,11 @@ const echoContract = async (ctx) => {
const buf = await ctx.users.read(input);
const msg = buf.toString();
if (msg == "ts")
await user.send(fs.readFileSync("exects.txt"));
else
await user.send("Echoing: " + msg);
const output = (msg == "ts") ? fs.readFileSync("exects.txt").toString() : ("Echoing: " + msg);
// Stringify to escape JSON characters and remove surrounding double quotes.
const stringified = JSON.stringify(output);
await user.send(stringified.substr(1, stringified.length - 2));
resolve();
}));

View File

@@ -3,72 +3,77 @@ const fs = require('fs');
const bson = require('bson');
const fileContract = async (ctx) => {
await ctx.users.onMessage(async (user, buf) => {
const msg = bson.deserialize(buf);
if (msg.type == "upload") {
if (fs.existsSync(msg.fileName)) {
await user.send(bson.serialize({
type: "uploadResult",
status: "already_exists",
fileName: msg.fileName
}));
for (const user of ctx.users.list()) {
for (const input of user.inputs) {
const buf = await ctx.users.read(input);
const msg = bson.deserialize(buf);
if (msg.type == "upload") {
if (fs.existsSync(msg.fileName)) {
await user.send(bson.serialize({
type: "uploadResult",
status: "already_exists",
fileName: msg.fileName
}));
}
else if (msg.content.length > 10 * 1024 * 1024) { // 10MB
await user.send(bson.serialize({
type: "uploadResult",
status: "too_large",
fileName: msg.fileName
}));
}
else {
// Save the file.
fs.writeFileSync(msg.fileName, msg.content.buffer);
await user.send(bson.serialize({
type: "uploadResult",
status: "ok",
fileName: msg.fileName
}));
}
}
else if (msg.content.length > 10 * 1024 * 1024) { // 10MB
await user.send(bson.serialize({
type: "uploadResult",
status: "too_large",
fileName: msg.fileName
}));
else if (msg.type == "delete") {
if (fs.existsSync(msg.fileName)) {
fs.unlinkSync(msg.fileName);
await user.send(bson.serialize({
type: "deleteResult",
status: "ok",
fileName: msg.fileName
}));
}
else {
await user.send(bson.serialize({
type: "deleteResult",
status: "not_found",
fileName: msg.fileName
}));
}
}
else {
// Save the file.
fs.writeFileSync(msg.fileName, msg.content.buffer);
await user.send(bson.serialize({
type: "uploadResult",
status: "ok",
fileName: msg.fileName
}));
else if (msg.type == "download") {
if (fs.existsSync(msg.fileName)) {
const fileContent = fs.readFileSync(msg.fileName);
await user.send(bson.serialize({
type: "downloadResult",
status: "ok",
fileName: msg.fileName,
content: fileContent
}));
}
else {
await user.send(bson.serialize({
type: "downloadResult",
status: "not_found",
fileName: msg.fileName
}));
}
}
}
else if (msg.type == "delete") {
if (fs.existsSync(msg.fileName)) {
fs.unlinkSync(msg.fileName);
await user.send(bson.serialize({
type: "deleteResult",
status: "ok",
fileName: msg.fileName
}));
}
else {
await user.send(bson.serialize({
type: "deleteResult",
status: "not_found",
fileName: msg.fileName
}));
}
}
else if (msg.type == "download") {
if (fs.existsSync(msg.fileName)) {
const fileContent = fs.readFileSync(msg.fileName);
await user.send(bson.serialize({
type: "downloadResult",
status: "ok",
fileName: msg.fileName,
content: fileContent
}));
}
else {
await user.send(bson.serialize({
type: "downloadResult",
status: "not_found",
fileName: msg.fileName
}));
}
}
});
}
};
const hpc = new HotPocketContract();

View File

@@ -1,4 +1,6 @@
const fs = require('fs');
const tty = require('tty');
require('process');
const MAX_SEQ_PACKET_SIZE = 128 * 1024;
const CONTROL_MESSAGE = {
@@ -14,14 +16,20 @@ class HotPocketContract {
init(contractFunc) {
if (this.#controlChannel) // Already initialized.
return;
return false;
if (tty.isatty(process.stdin.fd)) {
console.error("Error: Hot Pocket smart contracts must be executed via Hot Pocket.");
return false;
}
// Parse HotPocket args.
const argsJson = fs.readFileSync(0, 'utf8');
const argsJson = fs.readFileSync(process.stdin.fd, 'utf8');
const hpargs = JSON.parse(argsJson);
this.#controlChannel = new ControlChannel(hpargs.controlfd);
this.#executeContract(hpargs, contractFunc);
return true;
}
#executeContract = (hpargs, contractFunc) => {