From a517b5ff71c1019eb12b80f05b61e81fce88f4b5 Mon Sep 17 00:00:00 2001 From: Brian Lenz Date: Wed, 16 May 2018 22:42:13 -0400 Subject: [PATCH 1/4] High Volume GAS Claim Improvement * Added chunking to the GAS claim process so that at most 200 UTXOs will be claimed at a time. This allows addresses with thousands of UTXOs to claim gas through a series of transactions. A single transaction with thousands of UTXOs wasn't succeeding otherwise. --- neo/Prompt/Commands/Wallet.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/neo/Prompt/Commands/Wallet.py b/neo/Prompt/Commands/Wallet.py index 8cd17597e..a7988d61b 100644 --- a/neo/Prompt/Commands/Wallet.py +++ b/neo/Prompt/Commands/Wallet.py @@ -11,6 +11,7 @@ from prompt_toolkit import prompt import binascii import json +import math def DeleteAddress(prompter, wallet, addr): @@ -108,12 +109,18 @@ def AddAlias(wallet, addr, title): def ClaimGas(wallet, require_password=True, args=None): unclaimed_coins = wallet.GetUnclaimedCoins() - unclaimed_coin_refs = [coin.Reference for coin in unclaimed_coins] - if len(unclaimed_coin_refs) == 0: + unclaimed_count = len(unclaimed_coins) + if unclaimed_count == 0: print("no claims to process") return False + max_coins_per_claim = 200 + if unclaimed_count > max_coins_per_claim: + unclaimed_coins = unclaimed_coins[:max_coins_per_claim] + + unclaimed_coin_refs = [coin.Reference for coin in unclaimed_coins] + available_bonus = Blockchain.Default().CalculateBonusIgnoreClaimed(unclaimed_coin_refs) if available_bonus == Fixed8.Zero(): @@ -146,6 +153,8 @@ def ClaimGas(wallet, require_password=True, args=None): print("\n---------------------------------------------------------------") print("Will make claim for %s GAS" % available_bonus.ToString()) + if unclaimed_count > max_coins_per_claim: + print("NOTE: There is a transaction limit on GAS claims. %s additional claim transactions will be required to claim all available GAS." % math.floor(unclaimed_count / max_coins_per_claim)) print("------------------------------------------------------------------\n") if require_password: From eec6e380f7b249e94c53e2fbc51d2004fe79dcbe Mon Sep 17 00:00:00 2001 From: Brian Lenz Date: Wed, 16 May 2018 23:26:10 -0400 Subject: [PATCH 2/4] Add Changelog --- CHANGELOG.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5dfba4036..a8aa8fefb 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -9,6 +9,7 @@ All notable changes to this project are documented in this file. - fix ``StateMachine.Contract_Migrate`` and add tests - add ability to attach tx attrs to build command and testinvoke. altered tx attr parsing - updated the install instructions present on ``docs`` +- added support for chunking through GAS claims 200 UTXOs at a time `#419 `_ [0.6.9] 2018-04-30 From 4db134afcc397dd39f4cb58ffa9d4b206fa3a9fa Mon Sep 17 00:00:00 2001 From: Brian Lenz Date: Sat, 19 May 2018 15:56:45 -0400 Subject: [PATCH 3/4] Chunking through GAS claims via prompt is now optional --- CHANGELOG.rst | 2 +- neo/Prompt/Commands/Wallet.py | 36 +++++++++++++++++++++++------------ neo/bin/prompt.py | 2 +- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a8aa8fefb..99634a6ab 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -9,7 +9,7 @@ All notable changes to this project are documented in this file. - fix ``StateMachine.Contract_Migrate`` and add tests - add ability to attach tx attrs to build command and testinvoke. altered tx attr parsing - updated the install instructions present on ``docs`` -- added support for chunking through GAS claims 200 UTXOs at a time `#419 `_ +- added support for optionally chunking through GAS claims in prompt `#419 `_ [0.6.9] 2018-04-30 diff --git a/neo/Prompt/Commands/Wallet.py b/neo/Prompt/Commands/Wallet.py index a7988d61b..260387e02 100644 --- a/neo/Prompt/Commands/Wallet.py +++ b/neo/Prompt/Commands/Wallet.py @@ -5,7 +5,7 @@ from neo.Core.TX.TransactionAttribute import TransactionAttribute, TransactionAttributeUsage from neo.SmartContract.ContractParameterContext import ContractParametersContext from neo.Network.NodeLeader import NodeLeader -from neo.Prompt.Utils import get_asset_id, get_from_addr +from neo.Prompt.Utils import get_asset_id, get_from_addr, get_arg from neocore.Fixed8 import Fixed8 from neocore.UInt160 import UInt160 from prompt_toolkit import prompt @@ -108,6 +108,12 @@ def AddAlias(wallet, addr, title): def ClaimGas(wallet, require_password=True, args=None): + if args: + params, from_addr_str = get_from_addr(args) + else: + params = None + from_addr_str = None + unclaimed_coins = wallet.GetUnclaimedCoins() unclaimed_count = len(unclaimed_coins) @@ -115,8 +121,16 @@ def ClaimGas(wallet, require_password=True, args=None): print("no claims to process") return False - max_coins_per_claim = 200 - if unclaimed_count > max_coins_per_claim: + max_coins_per_claim = None + if params: + max_coins_per_claim = get_arg(params, 0, convert_to_int=True) + if not max_coins_per_claim: + print("max_coins_to_claim must be an integer") + return False + if max_coins_per_claim <= 0: + print("max_coins_to_claim must be greater than zero") + return False + if max_coins_per_claim and unclaimed_count > max_coins_per_claim: unclaimed_coins = unclaimed_coins[:max_coins_per_claim] unclaimed_coin_refs = [coin.Reference for coin in unclaimed_coins] @@ -136,13 +150,11 @@ def ClaimGas(wallet, require_password=True, args=None): # the following can be used to claim gas that is in an imported contract_addr # example, wallet claim --from-addr={smart contract addr} - if args: - params, from_addr_str = get_from_addr(args) - if from_addr_str: - script_hash = wallet.ToScriptHash(from_addr_str) - standard_contract = wallet.GetStandardAddress() - claim_tx.Attributes = [TransactionAttribute(usage=TransactionAttributeUsage.Script, - data=standard_contract.Data)] + if from_addr_str: + script_hash = wallet.ToScriptHash(from_addr_str) + standard_contract = wallet.GetStandardAddress() + claim_tx.Attributes = [TransactionAttribute(usage=TransactionAttributeUsage.Script, + data=standard_contract.Data)] claim_tx.outputs = [ TransactionOutput(AssetId=Blockchain.SystemCoin().Hash, Value=available_bonus, script_hash=script_hash) @@ -153,8 +165,8 @@ def ClaimGas(wallet, require_password=True, args=None): print("\n---------------------------------------------------------------") print("Will make claim for %s GAS" % available_bonus.ToString()) - if unclaimed_count > max_coins_per_claim: - print("NOTE: There is a transaction limit on GAS claims. %s additional claim transactions will be required to claim all available GAS." % math.floor(unclaimed_count / max_coins_per_claim)) + if max_coins_per_claim and unclaimed_count > max_coins_per_claim: + print("NOTE: You are claiming GAS on %s unclaimed coins. %s additional claim transactions will be required to claim all available GAS." % (max_coins_per_claim, math.floor(unclaimed_count / max_coins_per_claim))) print("------------------------------------------------------------------\n") if require_password: diff --git a/neo/bin/prompt.py b/neo/bin/prompt.py index 7a6008a18..723a8667b 100755 --- a/neo/bin/prompt.py +++ b/neo/bin/prompt.py @@ -127,7 +127,7 @@ class PromptInterface: 'open wallet {path}', 'create wallet {path}', 'wallet {verbose}', - 'wallet claim', + 'wallet claim (max_coins_to_claim)', 'wallet migrate', 'wallet rebuild {start block}', 'wallet delete_addr {addr}', From 533011d1204ba47e7d277ab4c34933503415b1b4 Mon Sep 17 00:00:00 2001 From: Brian Lenz Date: Sat, 19 May 2018 16:08:19 -0400 Subject: [PATCH 4/4] Added test of partial GAS claim --- neo/Prompt/Commands/tests/test_claim_command.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/neo/Prompt/Commands/tests/test_claim_command.py b/neo/Prompt/Commands/tests/test_claim_command.py index 22d608de8..7bfe68137 100644 --- a/neo/Prompt/Commands/tests/test_claim_command.py +++ b/neo/Prompt/Commands/tests/test_claim_command.py @@ -97,10 +97,19 @@ def test_4_wallet_claim_ok(self): wallet = self.GetWallet3() + claim = ClaimGas(wallet, require_password=False, args=['1']) + + self.assertTrue(claim) + + def test_5_wallet_claim_ok(self): + + wallet = self.GetWallet3() + claim = ClaimGas(wallet, require_password=False) self.assertTrue(claim) + def test_block_150000_sysfee(self): fee = Blockchain.Default().GetSysFeeAmountByHeight(150000)