When working with decentralized platforms like Steem, it’s important to expect occasional hiccups — network issues, API rate limits, or temporary downtimes. That’s why any integration, bot, or tool you build should be able to fail gracefully and recover smartly.
In this post, I’ll walk you through a simple yet robust vote-checking utility for the Steem blockchain that:
First Version: Check a Witness voted by
Here’s a handy Node.js function that checks if a Steem user has voted for a specific witness — either directly or via a proxy.
function is_voted_by(witness, id) {
return new Promise((resolve, reject) => {
steem.api.getAccounts([id], function(err, response) {
if (err) reject(err);
if (typeof response == "undefined") reject("undefined");
const data = response[0];
resolve((data.proxy === witness) || data.witness_votes.includes(witness));
});
});
}
It fetches the account data for the given id. Then it checks if the user has set a voting proxy matching the target witness, or if the witness is in their direct vote list.
Retry-Enabled Witness Vote Checker for Steem
Here’s the updated version of the function with a simple retry mechanism (up to 3 attempts with a 1-second delay between retries). Here’s a more robust version of the vote check function with retry logic built-in:
function is_voted_by(witness, id, retries = 3) {
return new Promise((resolve, reject) => {
const attempt = (remaining) => {
steem.api.getAccounts([id], function(err, response) {
if (err || typeof response === "undefined") {
if (remaining > 0) {
setTimeout(() => attempt(remaining - 1), 1000); // Retry after 1 second
} else {
reject(err || "undefined response");
}
return;
}
const data = response[0];
resolve((data.proxy === witness) || data.witness_votes.includes(witness));
});
};
attempt(retries);
});
}
This version implements up to 3 retries if the Steem API fails or returns undefined. It helps handle unreliable network conditions or temporary API hiccups. Same functionality: checks direct witness votes or proxy delegation.
Retry exponential backoff
Uses exponential backoff to avoid hammering the API and log each attempt for better debugging and visibility.
module.exports.is_voted_by = function(witness, id, retries = 3, delay = 1000) {
return new Promise((resolve, reject) => {
const attempt = (remaining, currentDelay) => {
console.log(`Checking vote for "${id}" against witness "${witness}"... (${retries - remaining + 1}/${retries})`);
steem.api.getAccounts([id], function(err, response) {
if (err || typeof response === "undefined") {
console.warn(`Attempt failed: ${err || 'undefined response'}`);
if (remaining > 0) {
console.log(`Retrying in ${currentDelay}ms...`);
setTimeout(() => attempt(remaining - 1, currentDelay * 2), currentDelay); // Exponential backoff
} else {
reject(err || "undefined response after retries");
}
return;
}
const data = response[0];
const voted = (data.proxy === witness) || data.witness_votes.includes(witness);
console.log(`Vote check result: ${voted}`);
resolve(voted);
});
};
attempt(retries, delay);
});
};
This:
- Calls the Steem API to get account info for a given id.
- Checks if the user voted for a specific witness, either: Directly (i.e., in witness_votes), or Indirectly via a proxy (i.e., if proxy === witness).
If the API call fails or returns undefined, it: Waits, Retries (up to retries times), And increases the wait time exponentially (1s, 2s, 4s, etc.).
🔧 Why Use Exponential Backoff?
Exponential backoff is a classic strategy in network programming — if a service is down or struggling, hitting it again quickly is more likely to make things worse. Slowing down between retries gives the system time to recover, and is kinder to APIs.
🧪 Example Usage
is_voted_by('witness-name', 'username')
.then(voted => {
if (voted) {
console.log("User supports the witness!");
} else {
console.log("User has not voted for the witness.");
}
})
.catch(err => {
console.error("Error checking vote:", err);
});
🏁 Final Thoughts
When building tools that interact with blockchains, resilience is key. A little retry logic can go a long way in keeping your apps functional and user-friendly — even when the underlying infrastructure hits a rough patch.
Steem Programming
- Building a Reliable Witness Vote Checker for the Steem Blockchain (with Retry & Exponential Backoff)
- Javascript (NodeJS) Function to Check if a Witness Has been Voted by or Proxied By on Steem Blockchain
–EOF (The Ultimate Computing & Technology Blog) —
776 wordsLast Post: AI Transforms Photos into Ghibli Style? ChatGPT-4o Costs Money, But Here's a Free Method!
Next Post: Teaching Kids Programming - Compute the Range Sum with Update: A Deep Dive into Segment Tree, SQRT Decomposition, Brute Force & Prefix Sum