image source: pixabay.com
As I mentioned in my last update, my next focus for the Post Promoter voting bot software was implementing a number of features to help curb spam and abuse on the Steem blockchain - or at least prevent it from buying upvotes.
The majority of the features that have been implemented were suggested by @themarkymark who, along with @patrice, does a lot of great work on the spam and abuse fighting front. I would like to make sure they get the recognition they deserve for that. I don't have the time to do what they do, but I try to contribute what I can through my development efforts to support them.
Anyway, let's get right down to it...
Local / Remote Blacklist File Support
There is now a configuration setting called "blacklist_location" in the config.json file which allows the bot owner to specify the location of the blacklist file that the bot should use. The location can be either a file location on the local server, or a URL of a remotely hosted blacklist file. This will allow bot owners to set up a global blacklist file that can be easily used by all bots running the Post Promoter software.
The blacklist file (whether local or remote) should simply be a text file with one Steem account name per line. You can see an example global blacklist file here: http://steembottracker.com/blacklist.txt and set up in the Post Promoter software to use it like so:
"blacklist_location": "http://steembottracker.com/blacklist.txt"
Refund Options for Blacklisted Bids
There is now an option for whether or not blacklisted users' bids should be refunded to them. In all cases that I'm aware of bot owners do not refund bids from blacklisted users, however I believe that users of the software should still have the option to do so if they wish.
"refund_blacklist": true/false,
Additionally, bot owners now also have the option to automatically donate bids from blacklisted users to an account of their choice. The idea being that such bids can be automatically donated to a spam/abuse fighting service such as @steemcleaners, @spaminator, @cheetah, etc.
"blacklist_donation_account": "steemcleaners"
Finally, the bot now replies to blacklisted users with a 0.001 STEEM or SBD transfer (whichever currency the bid was in) informing them that their account has been blacklisted from using the bot.
Spam/Abuse Flag Signal Accounts List
The third change that was added to help fight spam and abuse was to add a list of accounts that act as signals for spam/abuse posts. This means that when a bid comes in for a post, the software will check if any of the accounts on the list have flagged that post, and if so it will consider the post blacklisted and handle the bid amount based on the blacklist settings mentioned above.
"flag_signal_accounts": ["spaminator", "cheetah", "steemcleaners", "mack-bot", "blacklist-a"]
So for example if a bid comes in for a post that @steemcleaners has flagged, then based on the above list the software will consider that an invalid bid, send the sender a 0.001 STEEM/SBD transfer informing them their bid is invalid because the post has been flagged as spam or abuse, and donate the bid amount to the specified spam/abuse fighting service.
Fixed Issues with Auto-Failover
This is unrelated to fighting spam and abuse, but since the previous update where the auto RPC node failover feature was implemented a few issues have cropped up with it. Namely that sometimes a transaction actually fails for a legitimate reason not caused by an issue with the RPC node but that still triggered a failover. Then the transaction was re-tried, failed again, and triggered another failover. If for any reason there were a couple transactions that failed in a short period of time a whole bunch of failovers were triggered which caused "mayhem" as it was kindly put in the reported issue :-)
Luckily the fix was pretty simple - the code now checks if a failed transaction was due to an "assert_exception", meaning there was an error with the transaction itself, not with the RPC node, and if so it doesn't include that failure in the error count for triggering a failover.
Show Some Code!
It was suggested in my last post that I take some time to show the code behind some of these changes - which is a great idea since this is a development-focused site and all! Let me know what you think of this and if it's received well I'll continue to do this in all my posts going forward.
Here is the snippet of code that checks if an account on the "flag_signal_accounts" list has flagged/downvoted the post:
steem.api.getContent(author, permLink, function (err, result) {
if (!err && result && result.id > 0) {
// Check if this post has been flagged by any flag signal accounts
if(config.flag_signal_accounts){
var flags = result.active_votes.filter(function(v) { return v.percent < 0 && config.flag_signal_accounts.indexOf(v.voter) >= 0; });
if(flags.length > 0) {
handleFlag(sender, amount, currency);
return;
}
}
}
});
Got it? Don't worry - I'll break it down a bit! The first step is to load the post content which is also necessary to check that it's a valid post in the first place. That is done using the steem.api.getContent() call in the Steem JS library.
I check to make sure it doesn't return an error and that the "result", which is an object containing the post data, has an "id" that is greater than 0 - meaning it is a valid post. Then I check if there is a "flag_signal_accounts" property set in the config.json file using "config.flag_signal_accounts".
The next line is the actual meat of the code:
var flags = result.active_votes.filter(function(v) { return v.percent < 0 && config.flag_signal_accounts.indexOf(v.voter) >= 0; });
Let's take that one piece at a time. First, if you remember, "result" is an object containing all of the data about the post. "result.active_votes" is an array of all of the votes data (including upvotes and downvotes/flags) that have been submitted for the post so far.
I call the filter() function on the list of active votes for the post which filters out only the votes in the list which return "true" when passed through the function supplied as the first argument. The function is as follows:
function(v) {
return v.percent < 0 &&
config.flag_signal_accounts.indexOf(v.voter) >= 0;
}
The "v" parameter represents an individual vote object. Here we check if the "percent" property of the vote is less than 0. This means that the vote is a downvote or flag. The "percent" property indicates the weight of the vote, so if you give a 20% upvote on a post then the "percent" property for your vote will be 2000 (Steem multiplies all percents by 100). Similarly if you give a 20% downvote on a post then the "percent" property will be -2000.
So we check simply if the "percent" property is less than 0 to indicate a downvote of any weight, and then next we check to see if the list of "flag_signal_accounts" in the config.json settings contains the name of the "voter" property in the vote object. If it does then that means one of the accounts in the list downvoted the post and the function will return the value "true".
Finally we check the "length" of the result of the filter call to see if one or more of the votes in the active_votes list for the post returned "true" from our function. If so then that means the post has been flagged by an account on the list and should be treated as blacklisted.
If that happens then the handleFlag() function is called which handles notifying the sender that their post has been flagged and their bid is invalid, and optionally donating the bid amount to the specified spam/abuse service. Then a "return" statement is executed which exits the current function call so nothing else happens with that particular bid.
Thanks for your support!
Wow that was much longer than most of my contribution posts! If you've made it this far then thank you very much for reading...I hope this has helped you learn a bit about how these things are developed! As always I want to thank everyone who has helped and supported me in creating this software. Please stay tuned for more updates in the coming weeks!
Links to relevant commits:
- Added flag signal accounts list
- Allow loading blacklist from a URL
- Fixed issues with multiple errors causing "mayhem"
- Added new blacklist options
Posted on Utopian.io - Rewarding Open Source Contributors