Skip to content
This repository has been archived by the owner on Nov 15, 2021. It is now read-only.

Commit

Permalink
Merge 6209ccb into dcee198
Browse files Browse the repository at this point in the history
  • Loading branch information
localhuman committed Sep 28, 2018
2 parents dcee198 + 6209ccb commit 97d240f
Show file tree
Hide file tree
Showing 12 changed files with 178 additions and 74 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Expand Up @@ -16,6 +16,7 @@ All notable changes to this project are documented in this file.
- Disable ``prompt.py`` test cases due to high time consumption and unreliable results.
- Migrate the existing test cases, which depend on BlockchainFixtureTestCase and WalletFixtureTestCase, to a privnet. Reduction of the fixtures' size to about 7MB. `#478 <https://github.com/CityOfZion/neo-python/issues/478>`_
- Ensure non-zero send value in prompt.py
- Update block importing and exporting functionality.
- Add send-zero provision and improved test coverage to ``sendtoaddress``


Expand Down
27 changes: 22 additions & 5 deletions neo/Core/Block.py
Expand Up @@ -123,11 +123,6 @@ def Size(self):
return s

def CalculatneNetFee(self, transactions):
# Transaction[] ts = transactions.Where(p= > p.Type != TransactionType.MinerTransaction & & p.Type != TransactionType.ClaimTransaction).ToArray();
# Fixed8 amount_in = ts.SelectMany(p= > p.References.Values.Where(o= > o.AssetId == Blockchain.SystemCoin.Hash)).Sum(p= > p.Value);
# Fixed8 amount_out = ts.SelectMany(p= > p.Outputs.Where(o= > o.AssetId == Blockchain.SystemCoin.Hash)).Sum(p= > p.Value);
# Fixed8 amount_sysfee = ts.Sum(p= > p.SystemFee);
# return amount_in - amount_out - amount_sysfee;
return 0

def TotalFees(self):
Expand All @@ -151,6 +146,25 @@ def LoadTransactions(self):
transactions = self.FullTransactions
return transactions

def DeserializeForImport(self, reader):
"""
Deserialize full object.
Args:
reader (neo.IO.BinaryReader):
"""
super(Block, self).Deserialize(reader)

self.Transactions = []
transaction_length = reader.ReadVarInt()

for i in range(0, transaction_length):
tx = Transaction.DeserializeFrom(reader)
self.Transactions.append(tx)

if len(self.Transactions) < 1:
raise Exception('Invalid format %s ' % self.Index)

def Deserialize(self, reader):
"""
Deserialize full object.
Expand Down Expand Up @@ -220,6 +234,9 @@ def FromTrimmedData(byts):
raise Exception("Could not find transaction!\n Are you running code against a valid Blockchain instance?\n Tests that accesses transactions or size of a block but inherit from NeoTestCase instead of BlockchainFixtureTestCase will not work.")
tx_list.append(tx)

if len(tx_list) < 1:
raise Exception("Invalid block, no transactions found")

block.Transactions = tx_list

StreamManager.ReleaseStream(ms)
Expand Down
23 changes: 22 additions & 1 deletion neo/Core/Helper.py
Expand Up @@ -69,7 +69,7 @@ def ToArray(value):
value (neo.IO.Mixins.SerializableMixin): object extending SerializableMixin.
Returns:
bytes:
bytes: hex formatted bytes
"""
ms = StreamManager.GetStream()
writer = BinaryWriter(ms)
Expand All @@ -81,6 +81,27 @@ def ToArray(value):

return retVal

@staticmethod
def ToStream(value):
"""
Serialize the given `value` to a an array of bytes.
Args:
value (neo.IO.Mixins.SerializableMixin): object extending SerializableMixin.
Returns:
bytes: not hexlified
"""
ms = StreamManager.GetStream()
writer = BinaryWriter(ms)

value.Serialize(writer)

retVal = ms.getvalue()
StreamManager.ReleaseStream(ms)

return retVal

@staticmethod
def AddrStrToScriptHash(address):
"""
Expand Down
Expand Up @@ -39,7 +39,6 @@ def instance():
if not NotificationDB.__instance:
if settings.NOTIFICATION_DB_PATH:
NotificationDB.__instance = NotificationDB(settings.notification_leveldb_path)
# logger.info("Created Notification DB At %s " % settings.NOTIFICATION_DB_PATH)
else:
logger.info("Notification DB Path not configured in settings")
return NotificationDB.__instance
Expand Down
22 changes: 22 additions & 0 deletions neo/Prompt/Commands/Wallet.py
Expand Up @@ -233,6 +233,7 @@ def ShowUnspentCoins(wallet, args):
addr = None
asset_type = None
watch_only = 0
do_count = False
try:
for item in args:
if len(item) == 34:
Expand All @@ -241,6 +242,8 @@ def ShowUnspentCoins(wallet, args):
asset_type = get_asset_id(wallet, item)
if item == '--watch':
watch_only = 64
elif item == '--count':
do_count = True

except Exception as e:
print("Invalid arguments specified")
Expand All @@ -250,6 +253,11 @@ def ShowUnspentCoins(wallet, args):
else:
unspents = wallet.FindUnspentCoins(from_addr=addr, watch_only_val=watch_only)

if do_count:
print('\n-----------------------------------------------')
print('Total Unspent: %s' % len(unspents))
return unspents

for unspent in unspents:
print('\n-----------------------------------------------')
print(json.dumps(unspent.ToJson(), indent=4))
Expand All @@ -268,11 +276,18 @@ def SplitUnspentCoin(wallet, args, prompt_passwd=True):
:return: bool
"""

fee = Fixed8.Zero()

try:
addr = wallet.ToScriptHash(args[0])
asset = get_asset_id(wallet, args[1])
index = int(args[2])
divisions = int(args[3])

if len(args) == 5:
fee = Fixed8.TryParse(args[4])

except Exception as e:
logger.info("Invalid arguments specified: %s " % e)
return None
Expand All @@ -285,7 +300,14 @@ def SplitUnspentCoin(wallet, args, prompt_passwd=True):

outputs = split_to_vouts(asset, addr, unspentItem.Output.Value, divisions)

# subtract a fee from the first vout
if outputs[0].Value > fee:
outputs[0].Value -= fee
else:
raise Exception("Fee could not be subtracted from outputs.")

contract_tx = ContractTransaction(outputs=outputs, inputs=[unspentItem.Reference])

ctx = ContractParametersContext(contract_tx)
wallet.Sign(ctx)

Expand Down
3 changes: 1 addition & 2 deletions neo/SmartContract/ApplicationEngine.py
Expand Up @@ -22,10 +22,9 @@
from neo.Core.State.AccountState import AccountState
from neo.Core.State.ValidatorState import ValidatorState
from neo.Core.State.StorageItem import StorageItem

from neo.Core.State.ContractState import ContractPropertyState
from neo.SmartContract import TriggerType

from neo.VM.InteropService import Array
from neocore.UInt160 import UInt160
import datetime
from neo.Settings import settings
Expand Down
5 changes: 4 additions & 1 deletion neo/SmartContract/SmartContractEvent.py
Expand Up @@ -266,7 +266,10 @@ def SerializePayload(self, writer):
writer.WriteUInt160(self.addr_from)
writer.WriteUInt160(self.addr_to)

if self.Amount < 0xffffffffffffffff:
if self.Amount < 0:
logger.warn("Transfer Amount less than 0")
writer.WriteVarInt(0)
elif self.Amount < 0xffffffffffffffff:
writer.WriteVarInt(self.amount)
else:
logger.warn("Writing Payload value amount greater than ulong long is not allowed. Setting to ulong long max")
Expand Down
27 changes: 0 additions & 27 deletions neo/VM/ExecutionEngine.py
Expand Up @@ -235,7 +235,6 @@ def ExecuteOp(self, opcode, context: ExecutionContext):
script = self._Table.GetScript(UInt160(data=script_hash).ToBytes())

if script is None:
logger.error("Could not find script from script table: %s " % script_hash)
return self.VM_FAULT_and_report(VMFault.INVALID_CONTRACT, script_hash)

context_new = self.LoadScript(script)
Expand Down Expand Up @@ -1011,32 +1010,6 @@ def StepInto(self):

if self._exit_on_error:
self._VMState |= VMState.FAULT
else:
logger.error(error_msg)
logger.exception(e)

def StepOut(self):
self._VMState &= ~VMState.BREAK
count = self._InvocationStack.Count

while self._VMState & VMState.HALT == 0 and \
self._VMState & VMState.FAULT == 0 and \
self._VMState & VMState.BREAK == 0 and \
self._InvocationStack.Count > count:
self.StepInto()

def StepOver(self):
if self._VMState & VMState.HALT > 0 or self._VMState & VMState.FAULT > 0:
return

self._VMState &= ~VMState.BREAK
count = self._InvocationStack.Count

while self._VMState & VMState.HALT == 0 and \
self._VMState & VMState.FAULT == 0 and \
self._VMState & VMState.BREAK == 0 and \
self._InvocationStack.Count > count:
self.StepInto()

def VM_FAULT_and_report(self, id, *args):
self._VMState |= VMState.FAULT
Expand Down
7 changes: 1 addition & 6 deletions neo/VM/InteropService.py
Expand Up @@ -534,12 +534,7 @@ def Register(self, method, func):

def Invoke(self, method, engine):
if method not in self._dictionary.keys():

logger.info("method %s not found in ->" % method)
for k, v in self._dictionary.items():
logger.info("%s -> %s " % (k, v))
return False

logger.warn("method %s not found" % method)
func = self._dictionary[method]
# logger.info("[InteropService Method] %s " % func)
return func(engine)
Expand Down
10 changes: 9 additions & 1 deletion neo/bin/export_blocks.py
Expand Up @@ -6,6 +6,7 @@
import argparse
from tqdm import trange
import binascii
from neo.Core.Helper import Helper


def main():
Expand Down Expand Up @@ -67,7 +68,14 @@ def main():

block = chain.GetBlockByHeight(index)
block.LoadTransactions()
output = binascii.unhexlify(block.ToArray())

# make sure this block has transactions
# otherwise we will have a bad import
if len(block.Transactions) < 1:
raise Exception("Block %s has no transactions %s " % block.Index)

output = Helper.ToStream(block)

output_length = len(output).to_bytes(4, 'little')
file_out.write(output_length)
file_out.write(output)
Expand Down

0 comments on commit 97d240f

Please sign in to comment.