1

I have a private Ethereum network. The bootnode(main node)'s goal is to watch Events and if a new Event is generated than trigger a contract's function that I want to run. The key point is triggered contract's function should only called and run once. Please note that the bootnode(main node) does not mine and geth runs inside bootnode(main node).

  • watch() should be run on geth's background so when new block is deployed latest should also point new deployed block number, since latest block number keep increases.

For example, I am running following solution on geth.

> var theDAOVotedEvent = theDAO.Voted({}, {fromBlock: 1614771, toBlock: 'latest'});
undefined
theDAOVotedEvent.watch(function(error, result){
  console.log(JSON.stringify(result));
  //call a contract's function. (this should called only one time)
});

As I understand, when a new Event is generated, watch() will be called and it will print out on geth console the following example line and call a contract's function.

{"address":"0xbb9bc244d798123fde783fcc1c72d3bb8c189413","args":{"position":false,"proposalID":"11","voter":"0xebbf5d7d649aedde2c27a8b850a2a3862595eb53"},"blockHash":"0x69be968ce90c7e910c149cc80ab1e5f2ae6bdb45f142ee0e6fa181be9d1e106e","blockNumber":1614812,"event":"Voted","logIndex":0,"transactionHash":"0x6b5cab6f7987d7283fdde051c76ace98c9f080bda6dbdf720689fc0c3958005b","transactionIndex":2}
...

[Q] For example the bootnode (main node) restarted and geth closed and re-opened after 5 minutes. At this point, while geth was closed, assume new 20 blocks and 50 new Events are generated. When I re-start geth inside the bootnode's (main node), how could I continue to watch the Events from the block number that bootnode's (main node) was closed?

This approach is similar to use a pipe ("Whatever bytes are sent into the input of the pipe can be read from the other end of the pipe."). For example, when geth is shut down, Events should queued in pipe and when geth is alive again it should continue reading Events from the pipe.

I have come up with the following solution, but since synchronisation is done right after geth is re-open I was not able to run the following code piece before the synchronisation started.

//I think watch() should start from the latest retrieved block's number on bootnode (main node). 

latestWatched        = eth.blockNumber;     
var theDAOVotedEvent = theDAO.Voted({}, {fromBlock: latestWatched, toBlock: 'latest'});

theDAOVotedEvent.watch(function(error, result){
   console.log(JSON.stringify(result));
   //call a contract's function. (this should called only one time)
});

Thank you for your valuable time and help.

  • I don't get why you need to close geth. Because as you mentioned at the end, geth need to get synch (which is normal, because Transactions happened during geth was stopped). Why just not running geth all the time? – FrenchieiSverige Jan 23 '17 at 15:24
  • You are right and I thought like you as to run geth all the time. But if there is a electricity shut down (which will force geth to shut down for coupe of minutes) or I may need to restart the node (if it is overloaded) there will be missed blocks and missed Events. I just want to rely my system %100 and not to miss any generated Event. @FrenchieiSverige – alper Jan 23 '17 at 15:38
  • 1
    Always remember that each node of the blockchain has a copy of all transactions that has been mined. So when you are going to open your geth, geth will automatically download a copy of all transactions that happened during your offline time. But your smart contract is still on the blockchain, and running thanks to the other nodes. So events will still be fired, even you are offline. Then, you will just need to use web3.eth.filter(address:YourSmartContractAdress, topic:'YourFunction') to see all events. – FrenchieiSverige Jan 23 '17 at 15:44
  • Correct, I just want to continue to watch the Events form the latest block that is seen on the node's geth which is closed. So I have to recall theDAOVotedEvent.watch() with new defined fromBlock: ' ', toBlock: ' ' values. Think it like a pipe. The point is I don't want to see the all Events for efficiency and I just want to continue to watch where it is closed and trigger my contract's function if new Event is already come. – alper Jan 23 '17 at 16:02
  • I'm facing the same issue myself and I think I'm leaning towards keeping the latest 'handled' block in the DB - the block for which I already processed the events. And then when restarting the server (or geth), listen to all events starting from the one I fully processed + 1. There's still a case in which I can receive the same event twice but that I think should be handled by the business logic if it's critical. – nergall Jan 24 '17 at 8:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.