peatio
peatio copied to clipboard
Issues regarding multiple ETH withdrawals and their validity with wallet balance
If we create 100 ETH Withdrawals, each is 1 ETH, and hotwallet has 50 ETH now we process them all
while we process it, we call eth_getBalance which returns the whole balance of the wallet.
however, after we send 50 Transactions, (and thats goes very fast), on n=51 the wallet should be empty already, so we need to raise exception that the wallet is empty. however, because we call eth_getBalance
and all TXs pending it still returns 50
the only thing i can imagine to fix that
current_balance = eth_getBalance
txs.each do |tx|
if tx.amount > current_balance
tx.state = :waiting_for_funds
else
.... send tx out
current_balance -= amount+fee
end
means that sending payments has to be always "batched"
yet i wonder, how is the nonce handled? if nonce is 12 and we send payment which is pending, then the next TX needs to be nonce 13, but if we call for transactions it's still 12 because it's pending. bit tricky if lot of people wanna withdraw ethereuem
tried it out for a different project and that seems to work now
the implementation looks something like this. i keep track of address balance an nonce myself and now i can send out 20 transactions at the same time, untill my balance gets empty
nonce = $ethereum_rpc.request(:eth_getTransactionCount, ["0xb613a7c3c274f736cbaba8f4c59550cf272b17df"]).hex
balance = service.balance
withdrawals.map do |withdrawal|
@logger.tagged "ID: #{withdrawal.id}" do
if balance < withdrawal.withdrawal_amount
withdrawal.put_on_hold!
next
else
begin
withdrawal.sending!
transaction = service.create_transaction!( withdrawal.to_transaction_hash.merge(nonce: nonce) )
balance -= withdrawal.amount
nonce += 1
edit: if we use personal_sendTransaction
we don't need to count the nonce since the node is doing it for us. but we still need to keep track of the balances
tried sending via node personal_sendTransaction
and yes, as i expected, the balance is always wrong
or better to say not updated
.
in order to have a good working, solid codebase, we really need to keep track of our own balance
[261] pry(main)> $rpc.request(:personal_sendTransaction, [tx, ""]) && (p $rpc.request(:eth_getBalance, [address]).hex)
50000000000000000
[262] pry(main)> $rpc.request(:personal_sendTransaction, [tx, ""]) && (p $rpc.request(:eth_getBalance, [address]).hex)
50000000000000000
[263] pry(main)> $rpc.request(:personal_sendTransaction, [tx, ""]) && (p $rpc.request(:eth_getBalance, [address]).hex)
50000000000000000