keppel / lotion Goto Github PK
View Code? Open in Web Editor NEW✨ Smooth, easy blockchain apps ✨
Home Page: https://lotionjs.com
✨ Smooth, easy blockchain apps ✨
Home Page: https://lotionjs.com
I have an application with a genesis.json and a keys.json which holds the keys for the validator. I can repeatedly delete the folder from my .lotion directory and it spins up perfectly each time.
However, if I add a second validator to the list it creates the data folder, but no requests to Tendermint on port 3000 from my web browser go through, they all fail to connect.
There is no debug message in my terminal, and logTendermint is on. localhost:3000/state gives me nothing, just fails to load.
I do not know how to begin debugging this issue.
Interested in testing the functionality of an experimental app with multiple Tendermint nodes with running lotion node processes on a single computer. Is this possible?
need that content-addressability from ipfs
Hi everybody. So far I have been using lotion locally to develop my application. I recently deployed it to two EC2 instances and found out two things:
The express tx-server is run with 'localhost' as host and therefore only available on the host itself. Now that I need to have clients sending transactions and not being full validator nodes I have two options:
I have tried to run a lite node but have not been successful. It seems that the supercop module is crashing. Is there a step that I have to include other than running lotion as lite and giving it the GCI as a target?
As I actually have all the information (genesis etc.) from the chain - is there a way to run a light client without utilising the GCI and the bittorrent magic behind it?
Is opening a tx-server to the 'public' and using it as an end-point for my clients a wrong pattern?
Thank you very much.
Hello,
I have created some tests with Lotion, and I would like to know the process to finally use a production Blockchain instead of the "test-*" generated one.
(it's not to pass in production right now, jsute to understand how to do it)
I have no idea how to do this.
Thanks for the answers!
Best regards,
AlexMog.
I'm trying to run a simple example but I get the following error:
"UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: ENOENT: no such file or directory, open 'C:\Users\lucas.vieira.lotion\networks\583c7041c2ce21ac5778207c08c3f4a755397364552927bea49218eb475f13e9412962989\priv_validator.json'
(node:6944) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js
process with a non-zero exit code."
here is my code:
options = {
initialState: {
count: 0
},
genesis: 'genesis.json',
keys: 'keys2.json',
peers: ['localhost:46661'],
p2pPort: 46660,
devMode: true
}
let app = require('lotion')(options)
app.use((state, tx) => {
state.count++
})
app.listen(3001)
I'm using windows 10. Already tried to run rm -rf ~/.lotion
After updating my version of lotion I found empty items getting pushed into state arrays.
I just altered the base example from the README and yield null
valued elements in my array.
app.js:
let lotion = require('lotion')
let app = lotion({
initialState: {
count: 0,
elements: []
}
})
app.use(function (state, tx) {
if(state.count === tx.nonce) {
state.count++;
state.elements.push(tx.nonce);
}
})
app.listen(3000)
localhost:3000/state
after 2 transactions with increasing nonces:
{"count":2,"elements":[null,0,null,1]}
So far I have not been able to make out what and where the causing changes are - @keppel: Do you have any clue what it could be?
best,
arne
errors during a (state, tx)
pair will be common and shouldn't cause the process to exit
Logo Revision
I would like to propose some modifications to the logo and branding for lotion to set it forward as a professional-quality framework that companies can feel comfortable using - at least at first glance visually.
I've attached some logos that we (Devslopes) have created for Lotion. Created by our VP of Product Evan Leong. I'd love to get your thoughts about the variants and look into possibly picking one 😄
Open Source LotionJS.com
I would also like to propose open-sourcing lotionjs.com so we can actively develop on it. It would be the place where traffic gets directed and have documentation, tutorials etc. Me, and some other web developers on my team would LOVE to help build it out. Take it to the level you see on https://electronjs.org/ and other websites.
Might be cool to consider something more open-sourcey like lotionjs.io , lotion.io or something similar if that makes sense.
state machines can accept an optional third info
parameter. right now I just need a way to know the current block height, but it seems likely there'll be other blockchain info apps might need.
let handler = (state, tx, info) => {
console.log(info.height) // 52
}
Can you somehow use browserify to build a in-webpage light client?
let app = lotion({
onSyncProgress: function (progress) {
// progress is a number from 0 - 1, estimated from block timestamps.
}
})
perhaps?
When running the code on the ReadMe I get:
C:\Users\Yousif\Documents\Dev\my-block-chain-app>node app.js
(node:5824) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: ENOENT: no such file or directory, open 'C:\Users\Yousif.lotion\networks\f0de10af52caa20754575a42899e005c7cb48f461219042bc43cffd614934863\genesis.json'
(node:5824) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Running Node 8.7.0. Windows 8 64-bit
There is no .lotion directory under my home directory.
I tried this in Git Bash and my Command Prompt, and I also tried my command prompt under admin privileges.
/dial_peers endpoint requires unsafe mode for rpc. since only the lotion transaction and abci servers talk to the tendermint node, it's ok to run in unsafe mode as long as the tendermint node isn't exposed to the outside world.
ed25519-supercop
uses incompatible private key format)Sorry if this isn't the right place to discuss this, but I'm sure it's a question more "noobs" like myself have.
Tendermint is great because it allows us to achieve consensus without mining. However lets say I want to reward validators by a "currency".
So one way I can do this can be seen in my lotion-example/index.js:
app.useBlock((state, chainInfo) => {
console.log({state, chainInfo})
Object.keys(chainInfo.validators)
.forEach(validator => {
state.ledger.push({
to: validator,
from: '_network',
at: chainInfo.height,
amount: 0.0001
})
})
})
So this will, for every block, add a transaction of 0.0001. I'm aware that the transaction log itself could keep a track of this, meaning I could just have a key value pair for each address, but just for my learning I'm putting the transactions into the state itself. I guess I should be doing:
app.useBlock((state, chainInfo) => {
console.log({state, chainInfo})
Object.keys(chainInfo.validators)
.forEach(validator => {
state.accounts[validator] = state.accounts[validator] + 0.0001 || 0
})
})
So, the above works great. However it always adds 0.0001 for every validator for every block.
Ideally I only want to reward a validator if they are online and have validated the block.
Maybe something like:
app.useBlock((state, chainInfo) => {
console.log({state, chainInfo})
Object.keys(chainInfo.validators)
.forEach(validator => {
if (chainInfo.activeValidator[validator]) {
state.accounts[validator] = state.accounts[validator] + 0.0001 || 0
} else {
state.accounts[validator] = state.accounts[validator] - 0.001 || 0
}
})
})
tl;dr; I guess the brief question is: Is there any way to verify if a validator is active or not?
Thanks again
If i change the app logic on all the peers.And restart all the peers.The chain is starting from Block 0.
what's happening seems correct but,
Its bad if i have to start from the beginning.
Is there any solution for this?
alternate way to initialize a bit of state:
module.exports = [
{ type: 'initializer', middleware: function(state) { state.partINeed = {} }
]
Currently, the state is only held in memory, so a full chain replay is done every time a node starts up. It's possible to persist the state in a way that doesn't break the synchronous app handler APIs, we just need to flush the changes to disk in between each block.
this is important for a few reasons:
lotion
to be the glue between tendermint and a program written in any other language. this is the sort of thing where Node shines.transactions will still be handled serially, they just don't have to mutate the state synchronously.
After read code, I found that txs store in a nother database (txCache)which will not sync by Tendermint. So that means when I query a tx information in one peer, I can get it. If I query this information in another peer, I can’t get it, right? Emmmm, I have another question : how to let one lotion peer connect another one? I can’t find this way in document 😅😅😅
I copied the counter.js file to counter2, counter3 and so on to listen on a few different ports. When I started counter.js on port 3000 and then started counter2.js on port 3001 I received this error:
/tmp/lotion/example/counter/node_modules/lotion/lib/tendermint.js:48
throw new Error('Tendermint node crashed')
^
Error: Tendermint node crashed
at ChildProcess.tendermintProcess.on /tmp/lotion/example/counter/node_modules/lotion/lib/tendermint.js:48:11)
at emitTwo (events.js:125:13)
at ChildProcess.emit (events.js:213:7)
at maybeClose (internal/child_process.js:927:16)
at Socket.stream.socket.on (internal/child_process.js:348:11)
at emitOne (events.js:115:13)
at Socket.emit (events.js:210:7)
at Pipe._handle.close [as _onclose] (net.js:547:12)
Once this issue gets solved, all I need to do is /dial_seeds to get them linked up right?
The goal is to move away from one big JSON blob of state towards some sort of merkle structure. Would be nice to preserve the API of state being just an object (using ES6 proxies) so that app code doesn't have to change.
Benefits:
I cannot GET /state, /info nor /txs from a JavaScript client webpage. However, I can get all /tendermint passthrough endpoints.
Recommended fix: Add CORS headers to these endpoints. I will look into doing this.
currently log is empty. just say "a tx must mutate the state to be valid"
Currently from reading the docs I can see you can change the voting power dynamically by mutating the chainInfo.validators
object.
However is there a way to add/remove a validator?
I was thinking maybe this is possible using the tendermint rest api? If so, we could add an app.validators
object.
app.validators.push({
"pub_key": {
"type": "ed25519",
"data": "BAA8FE961773E916FBE5DC4AB195F3DEB22FC9330D44880F1FC558EE71B8A47B"
},
"power": 10,
"name": ""
})
Maybe this could encompass some of my findings from issue #73 too by adding a "blockLastSeen".
app.validators === [..., {
"pub_key": {
"type": "ed25519",
"data": "BAA8FE961773E916FBE5DC4AB195F3DEB22FC9330D44880F1FC558EE71B8A47B"
},
"power": 10,
"name": "",
"blockLastSeen": 100
}]
If it's just not implemented yet, I'd be more than happy to if you can point me in the right direction.
The lotion port can not be accessed
link : https://github.com/SaifRehman/tendermint-chat-app/blob/master/blockchain/Dockerfile
project: https://github.com/SaifRehman/tendermint-chat-app
Lotion apps should have a global chain identifier (GCI) which will simply be the IPFS hash of the underlying Tendermint node's genesis.json
.
For full nodes, peers can be discovered via DHTs, multicast DNS, etc using the GCI as the rendezvous point. Light clients can also discover full nodes to connect to this way.
Eventually, all Lotion apps should, by convention, checkpoint recent block hashes into a single proof-of-work chain. The GCI will be used to identify checkpoints on that chain.
The GCI can also be used to as the prefix to a single immutable global address space. For instance, if coins supports IBC, you could create an output prefixed with the chain ID that should handle that output.
Lotion apps with on-chain client code should be connected to using their GCI.
Light client API once GCI's are implemented:
const GCI = 'QmT4AeWE9Q9EaoyLJiqaZuYQ8mJeq4ZBncjjFH9dQ9uDVA'
let { connect } = require('lotion')
let { state, send } = connect(GCI)
// query for part of the state. does all the merkle proof verification:
let myBalance = await state.accounts[myPubKey]
console.log(myBalance) // 42
// send a transaction
let { height, ok } = await send({ foo: 'bar' })
console.log(height) // 10
Note the lack of hardcoded full node addresses. Full nodes are discovered using the GCI and connections to multiple nodes are automatically managed for you. Developers should not ever have to think about the host:port
of individual nodes.
currently the promise returned from lotion()
resolves once the tx server and tendermint node are running. instead, the promise should be resolved when the tendermint node has finished syncing.
So I had app.js running and peer.js running in another term:
I tried curl http://localhost:3000/state in another term window and this is what showed up in the first window:
node app.js
(node:15154) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 5): Error: Request failed with status code 500
(node:15154) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Using the connect()
api I am having trouble when the websocket to the full node disconnects.
Now that in v0.1.17 the event-emitter bus
is also returned by the connect()
method, I am listening on errors and try to catch the ones that are "websocket disconnected" type. I then rerun the connect()
method to yield a new client and work with that one but it seems to have deeper troubles in the pumpify/duplexify modules...
Where could this problem lie? Any plans on handling disconnects and maybe autoreconnect in the connect()
api?
My code to handle disconnect:
let client = await lotion.connect(null, {genesis, nodes})
if (client.bus != undefined) {
client.bus.on('error', async(err)=>{
if (err.toString().indexOf("websocket disconnected") > -1) {
console.log("Reconnecting...")
client = await lotion.connect(null, {genesis, nodes})
txServer.lc = client
}
})
}
Lotion apps can now be easily deployed in any cloud premise. Most importantly cloud supporting cloud foundry. It is just matter of cf push to deploy a whole blockchain with sexy frontend.
Read more about it in readme.
link: https://github.com/SaifRehman/tendermint-chat-app
I will be soon writting a blog and hosting meetup in dubai regarding this. I have googled the entire internet, nobody was able to host a blockchain on cloud foundry, this is possible now with lotion/tendermint. Great job guys, i loved the tech!
@keppel
...instead of doing peer discovery before starting tendermint
let lotion = require("lotion")({
port: 3000,
initialState: { txCount: 0, blockCount: 0 }
});
function txHandler(state, tx, chainInfo) {
state.txCount++
}
function blockHandler(state, chainInfo) {
state.blockCount++
}
let app = lotion(txHandler, blockHandler)
txHandler is required, blockHandler is optional. usually apps can do everything they need to with just a txHandler (for example, all of lotion coin is written with just a txHandler).
but sometimes you need state to change several blocks later in response to a tx. that's where you'd use a blockHandler.
I cannot figure out how to specify a config.toml for a lotion app. I've tried placing the file in both ~/.lotion and the /bin directory containing Tendermint, but both seem to have been ignored.
Hello
It is entirely possible I'm using this completely wrong so I apologise if I'm doing something stupid here.
I have made an example app (based of your example) but split it out a bit.
https://github.com/markwylde/lotion-example
It's working perfectly, and I can add transaction which increase the blocks while running the app and peer.
But if you look in the app/index.js file I have commented out the following code:
// app.useBlock((state, chainInfo) => {
// state.blocks++
// })
What I believe this should do is every time a block is created add 1 to the blocks property in state.
But the act of uncommenting this code stop's me being able to post new transactions. When I run the command below it simply hangs, but when it's commented it works fine.
curl -s http://localhost:3000/txs -d '{ "nonce": 0 }' | jq
I've added to the README.md file exactly how I'm running my "environment" if that helps.
Thanks for any help you can spare.
Node version: v9.4.0
OS: macOS High Sierra 10.13.2
Cannot close immediatly lotion instance after still pending promise object
for example:
let nodeListener = lotion(........); nodeListener.listen(3000); nodeListener.close();
the line of code:
TypeError: Cannot read property 'close' of undefined
at Object.close (node_modules/lotion/index.js:236:17)
There should probably be an app.exit()
method so that nodes can gracefully shutdown. This can be useful for scripts that dynamically start/stop nodes at runtime, and is also needed for tests (we currently use process.exit()
at the end of the tests, which is ghetto).
Referenced on https://lotionjs.com/
Are they set to private?
if initialState
isn't provided in the lotion configuration object, lotion should try to read the initial state from initial-state.json
in the lotion home directory.
this allows connecting to networks running the same state machine but with a different initial validator set and state by just changing the genesis key.
it's too hard to remember not to read from the app state after mutating it.
I recently heard about this project and wanted to show a friend. So I searched github for lotionjs but this repo does not appear in the results. I suggest adding the string lotionjs
in a tag or repo description.
There is a mention of 'lotion-stake' on the lotionjs.com website but it seems like the repository has been taken down. Are there any updates on this repository?
Hello,
When generating a new genesis & keys file by Lotion, everything works perfectly.
After copying the genesis & privkey file to the root of the Lotion project, and setting the genesis to be loaded from the genesis.json file and keys such as loaded by the privkey file, after setting to true the logs, I got this:
E[01-21|17:28:18.153] Error signing vote module=consensus height=1 round=0 vote="Vote{0:12DCDF9D24F2 1/00/1(Prevote) 000000000000 {<nil>} @ 2018-01-21T17:28:18.153Z}" err="Error signing vote: Height regression"
The height seems to be defined to 1 (see the log above), but it's 478 in my priv_validator.json
Is it a bug or am I doing it wrong?
Thanks for the help!
Best regards,
AlexMog.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.