Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 15 additions & 17 deletions service/src/modules/chores.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,18 @@ import { Data, RPC, Eth, Bsc } from "./index.js";
import Transaction from "../models/Transaction.js";
import Transfer from "../models/Transfer.js";
import Conversion from "../models/Conversion.js";
import { resolveStartingNonce, reserveNextNonce } from "../utils/nonce.js";

let ethNonce = 0;
let bscNonce = 0;

function setupNonce(){
if ((ethNonce == 0) && (nonces.eth == 0)) {
ethNonce = Eth.getTransactionCount();
} else if ((nonces.eth > 0) && (nonces.eth > ethNonce)) {
ethNonce = nonces.eth;
}
if ((bscNonce == 0) && (nonces.bsc == 0)) {
bscNonce = Bsc.getTransactionCount();
} else if ((nonces.bsc > 0) && (nonces.bsc > bscNonce)) {
bscNonce = nonces.bsc;
}
async function setupNonce() {
ethNonce = await resolveStartingNonce(ethNonce, nonces.eth, () =>
Eth.getTransactionCount(),
);
bscNonce = await resolveStartingNonce(bscNonce, nonces.bsc, () =>
Bsc.getTransactionCount(),
);
}

const expireDate = () => {
Expand Down Expand Up @@ -71,7 +68,7 @@ async function checkBglTransactions() {
blockHash || undefined,
confirmations.bgl,
);
setupNonce();
await setupNonce();
result.transactions
.filter(
(tx) =>
Expand Down Expand Up @@ -122,20 +119,21 @@ async function checkBglTransactions() {
}

try {
const AssignedNonce = transfer.chain === "bsc" ? Bsc : Eth;
if (transfer.chain === "bsc") {
bscNonce += 1;
const reserved = reserveNextNonce(bscNonce);
bscNonce = reserved.nextNonce;
conversion.txid = await Chain.sendWBGL(
transfer.to,
amount.toString(),
bscNonce
reserved.nonce,
);
} else {
ethNonce += 1;
const reserved = reserveNextNonce(ethNonce);
ethNonce = reserved.nextNonce;
conversion.txid = await Chain.sendWBGL(
transfer.to,
amount.toString(),
ethNonce
reserved.nonce,
);
}
await conversion.save();
Expand Down
59 changes: 59 additions & 0 deletions service/src/tests/nonce.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import assert from "assert";
import {
parseConfiguredNonce,
resolveStartingNonce,
reserveNextNonce,
} from "../utils/nonce.js";

describe("nonce helpers", function () {
describe("#parseConfiguredNonce", function () {
it("uses the first populated positive integer value", function () {
assert.equal(parseConfiguredNonce(undefined, "", "12"), 12);
});

it("returns zero for missing, invalid, or non-positive values", function () {
assert.equal(parseConfiguredNonce(), 0);
assert.equal(parseConfiguredNonce("abc"), 0);
assert.equal(parseConfiguredNonce("-1"), 0);
assert.equal(parseConfiguredNonce("0"), 0);
});
});

describe("#resolveStartingNonce", function () {
it("awaits the chain nonce when no local or configured nonce is available", async function () {
let calls = 0;
const nonce = await resolveStartingNonce(0, 0, async () => {
calls += 1;
return 42;
});

assert.equal(nonce, 42);
assert.equal(calls, 1);
});

it("uses a configured nonce when it is ahead of the local nonce", async function () {
const nonce = await resolveStartingNonce(5, 8, async () => {
throw new Error("chain nonce should not be fetched");
});

assert.equal(nonce, 8);
});

it("keeps the local nonce when it is already ahead", async function () {
const nonce = await resolveStartingNonce(9, 8, async () => {
throw new Error("chain nonce should not be fetched");
});

assert.equal(nonce, 9);
});
});

describe("#reserveNextNonce", function () {
it("returns the nonce to send and the next local counter", function () {
assert.deepEqual(reserveNextNonce(12), {
nonce: 12,
nextNonce: 13,
});
});
});
});
7 changes: 4 additions & 3 deletions service/src/utils/config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import dotenv from 'dotenv';
import dotenv from "dotenv";
import { parseConfiguredNonce } from "./nonce.js";
dotenv.config();

export const env = process.env.NODE_ENV || "development";
Expand Down Expand Up @@ -48,6 +49,6 @@ export const confirmations = {
export const feePercentage = process.env.FEE_PERCENTAGE || 1;

export const nonces = {
bsc: parseInt(process.env.BSC_NONCE) || 0,
eth: parseInt(process.env.ETH__NONCE) || 0,
bsc: parseConfiguredNonce(process.env.BSC_NONCE),
eth: parseConfiguredNonce(process.env.ETH_NONCE, process.env.ETH__NONCE),
};
29 changes: 29 additions & 0 deletions service/src/utils/nonce.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export const parseConfiguredNonce = (...values) => {
for (const value of values) {
if (value === undefined || value === null || value === "") {
continue;
}
const parsed = Number.parseInt(value, 10);
return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
}
return 0;
};

export const resolveStartingNonce = async (
currentNonce,
configuredNonce,
fetchCurrentNonce,
) => {
if (currentNonce === 0 && configuredNonce === 0) {
return await fetchCurrentNonce();
}
if (configuredNonce > 0 && configuredNonce > currentNonce) {
return configuredNonce;
}
return currentNonce;
};

export const reserveNextNonce = (currentNonce) => ({
nonce: currentNonce,
nextNonce: currentNonce + 1,
});