The Magic Frog: Improve Bot Stability (Task Response)
Repository
https://github.com/mktcode/the-magic-story-machine
Work Done
The work here was 2-fold.
- Voting queue to force votes to be made in sequence and synchronously
- Force vote after
commentOptions
to be synchronous to ensure best possible outcome
Voting Queue
It's just a list using push
and shift
to add details to a queue about how to vote and what to vote on. The queue is using first-in-last-out (FILO) to ensure votes are handled in order. Promises were used to avoid asynchronous collisions.
Forcing Vote after commentOptions
This isn't so much about forcing a vote as it is about ensuring the vote happens in a certain order. The request was originally sent after commentOptions
which led to actions sometimes happening out of order. The queue is used in this case to prevent actions from happening out of order.
Details
diff --git a/helper.js b/helper.js
index e24aa52..84904e5 100644
--- a/helper.js
+++ b/helper.js
@@ -1,5 +1,20 @@
const steem = require('steem');
const locales = require('./locales');
+const EventEmitter = require('events')
+
+const voting_queue = [];
+const FIVE_SECONDS = 5000
+const TEN_MINUTES = 600000
+const THIRTY_MINUTES = 1800000
+
+const voting = {
+ length: () => { return voting_queue.length },
+ push: (obj) => { return voting_queue.push(obj) },
+ pop: () => { return voting_queue.pop() },
+ shift: () => { return voting_queue.shift() },
+ unshift: (obj) => { return voting_queue.unshift(obj) }
+}
+
Above is the actual structure for the voting queue.
module.exports = {
BOT_ACCOUNT_NAME: process.env.BOT_ACCOUNT_NAME,
@@ -232,35 +247,14 @@ module.exports = {
});
// vote
- steem.broadcast.vote(this.BOT_KEY, this.BOT_ACCOUNT_NAME, this.BOT_ACCOUNT_NAME, permlink, 10000);
+ this.upvote({ author: this.BOT_ACCOUNT_NAME, permlink: permlink }, 10000)
} else {
console.log(err);
}
});
},
upvote(comment, weight) {
- steem.api.getActiveVotes(comment.author, comment.permlink, (err, result) => {
- if (err) {
- console.log(err);
- } else {
- // check if already voted
- let voted = false;
- result.forEach((vote) => {
- if (vote.voter === this.BOT_ACCOUNT_NAME && vote.percent > 0) {
- voted = true;
- }
- });
-
- // vote
- if (!voted) {
- steem.broadcast.vote(this.BOT_KEY, this.BOT_ACCOUNT_NAME, comment.author, comment.permlink, weight, (err) => {
- if (err) {
- console.log(err);
- }
- });
- }
- }
- });
+ upvote_queue.push({ comment: comment, weight: weight, key: this.BOT_KEY, bot_account_name: this.BOT_ACCOUNT_NAME})
},
transfer(to, amount, memo) {
steem.broadcast.transfer(this.BOT_KEY, this.BOT_ACCOUNT_NAME, to, amount.toFixed(3) + ' SBD', memo, function(err) {
@@ -269,4 +263,36 @@ module.exports = {
}
});
}
-};
Above is replacing the existing function with a new function that appends the queue with memento data for voting.
+};
+
+setInterval(() => {
+ const options = voting_queue.pop()
+ if (options) {
+ real_upvote(options)
+ .catch((err) => {
+ // If there's an error, just push it back on the stack and retry it
+ // Really, we want to just do this if it's because it was inside
+ // the voting threshold. TODO: There should be a check to verify first
+ voting_queue.push(options)
+ })
+ }
+}, FIVE_SECONDS)
+
+function real_upvote(options) {
+ const {comment, weight, key, bot_account_name } = options
+ return steem.api.getActiveVotesAsync(comment.author, comment.permlink)
+ .filter((vote) => vote.voter === bot_account_name && vote.percent > 0)
+ .then((votes) => {
+ if (votes.length > 0) { // Already voted?
+ return votes
+ }
+
+ return steem.broadcast.voteAsync(key, bot_account_name, comment.author, comment.permlink, weight)
+ .then((results) => {
+ // Handle results
+ })
+ .catch((error) => {
+ // Handle voting error
+ })
+ })
+}
Above is the actual queue and voting implementation that shifts voting data off the front of the queue, then handles it.
Thank you very much! Just one thing... you used the tag
task-development
but it should actually be justdevelopment
. ;)Oh and @emrebeyler said it's possible to post and set beneficiaries with one transaction. If you want, you can try to implement this too. Would be even better I guess.
Dang it! I guess I can change the
development
tag still. Also, now that I think about itsteem.broadcast.send
will allowextensions
. We can give that a shot.I revised the PR so that the
comment
,comment_options
, andvote
happen in a single transaction.:kiss: I love you! :)
I commented a bit on the code in the PR. I have some questions. If you could have a second look at the PR, would be nice! :)
Nice Development!
Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.
To view those questions and the relevant answers related to your post, click here.
Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]
Wow! That's weird that this came after the upvote. I'm not used to that. That upvote was so tasty. I'm assuming if I add more comments that's one way to get an even better upvote, so I'll definitely do that. I can't wait for v2
The voting bot is sometimes very fast. You’re welcome. And bon appétit! ;-)
Hey @r351574nc3
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!
Contributing on Utopian
Learn how to contribute on our website or by watching this tutorial on Youtube.
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!
Woohoo! Thanks much!