def test_6_serialize_full_approve_payload(self):

        sc = NotifyEvent(
            SmartContractEvent.RUNTIME_NOTIFY,
            [b'approve', self.addr_to, self.addr_from, b'x\xe0\x01'],
            self.contract_hash, 91349, self.event_tx, True, False)

        stream = StreamManager.GetStream()
        writer = BinaryWriter(stream)
        sc.Serialize(writer)

        out = bytes(stream.getvalue())

        StreamManager.ReleaseStream(stream)
        new_event = SmartContractEvent.FromByteArray(out)

        self.assertEqual(new_event.event_type, sc.event_type)
        self.assertEqual(new_event.contract_hash, sc.contract_hash)
        self.assertEqual(new_event.test_mode, sc.test_mode)
        self.assertEqual(new_event.tx_hash, sc.tx_hash)
        self.assertEqual(new_event.block_number, sc.block_number)

        self.assertEqual(new_event.notify_type, b'approve')
        self.assertEqual(new_event.AddressFrom,
                         'AKZmSGPD7ytJBbxpRPmobYGLNxdWH3Jiqs')
        self.assertEqual(new_event.AddressTo,
                         'ALb8FEhEmtSqv97fuNVuoLmcmrSKckffRf')
        self.assertEqual(new_event.Amount, 123000)
        self.assertEqual(new_event.is_standard_notify, True)
        self.assertEqual(new_event.ShouldPersist, True)
    def test_2_serialize_single_notify_payload(self):

        sc = NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY, [b'hello'],
                         self.contract_hash, 99, self.event_tx, True, False)

        stream = StreamManager.GetStream()
        writer = BinaryWriter(stream)
        sc.Serialize(writer)

        out = bytes(stream.getvalue())

        self.assertEqual(
            out,
            b'\x1cSmartContract.Runtime.Notify\x11\xc4\xd1\xf4\xfb\xa6\x19\xf2b\x88p\xd3n:\x97s\xe8tp[c\x00\x00\x00\x90\xe4\xf1\xbbb\x8e\xf1\x07\xde\xe9\xf0\xd2\x12\xd1w\xbco\x844\x07=\x1b\xa7\x1f\xa7\x94`\x0b\xb4\x88|K\x05hello'
        )

        StreamManager.ReleaseStream(stream)
        new_event = SmartContractEvent.FromByteArray(out)

        self.assertEqual(new_event.event_type, sc.event_type)
        self.assertEqual(new_event.contract_hash, sc.contract_hash)
        self.assertEqual(new_event.test_mode, sc.test_mode)
        self.assertEqual(new_event.tx_hash, sc.tx_hash)
        self.assertEqual(new_event.block_number, sc.block_number)

        self.assertEqual(new_event.notify_type, b'hello')
        self.assertEqual(new_event.AddressFrom, None)
        self.assertEqual(new_event.AddressTo, None)
        self.assertEqual(new_event.Amount, 0)
        self.assertEqual(new_event.is_standard_notify, False)
    def test_3_serialize_single_transfer_notify_payload(self):

        sc = NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY, [b'transfer'],
                         self.contract_hash, 99, self.event_tx, True, False)

        stream = StreamManager.GetStream()
        writer = BinaryWriter(stream)
        sc.Serialize(writer)

        out = bytes(stream.getvalue())

        StreamManager.ReleaseStream(stream)
        new_event = SmartContractEvent.FromByteArray(out)

        self.assertEqual(new_event.event_type, sc.event_type)
        self.assertEqual(new_event.contract_hash, sc.contract_hash)
        self.assertEqual(new_event.test_mode, sc.test_mode)
        self.assertEqual(new_event.tx_hash, sc.tx_hash)
        self.assertEqual(new_event.block_number, sc.block_number)

        self.assertEqual(new_event.notify_type, b'transfer')
        self.assertEqual(new_event.AddressFrom, None)
        self.assertEqual(new_event.AddressTo, None)
        self.assertEqual(new_event.Amount, 0)
        self.assertEqual(new_event.is_standard_notify, False)
        self.assertEqual(new_event.ShouldPersist, False)
    def test_5_serialize_full_refund_payload(self):

        sc = NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY,
                         [b'refund', self.addr_to,
                          BigInteger(123000)], self.contract_hash, 91349,
                         self.event_tx, True, False)

        stream = StreamManager.GetStream()
        writer = BinaryWriter(stream)
        sc.Serialize(writer)

        out = bytes(stream.getvalue())

        StreamManager.ReleaseStream(stream)
        new_event = SmartContractEvent.FromByteArray(out)

        self.assertEqual(new_event.event_type, sc.event_type)
        self.assertEqual(new_event.contract_hash, sc.contract_hash)
        self.assertEqual(new_event.test_mode, sc.test_mode)
        self.assertEqual(new_event.tx_hash, sc.tx_hash)
        self.assertEqual(new_event.block_number, sc.block_number)

        self.assertEqual(new_event.notify_type, b'refund')
        self.assertEqual(new_event.AddressTo,
                         'AKZmSGPD7ytJBbxpRPmobYGLNxdWH3Jiqs')
        self.assertEqual(new_event.addr_from, sc.contract_hash)
        self.assertEqual(new_event.Amount, 123000)
        self.assertEqual(new_event.is_standard_notify, True)
示例#5
0
    def test_4_serialize_full_transfer_notify_payload(self):

        payload = ContractParameter(ContractParameterType.Array, [
            ContractParameter(ContractParameterType.String, b'transfer'),
            ContractParameter(ContractParameterType.ByteArray, self.addr_to),
            ContractParameter(ContractParameterType.ByteArray, self.addr_from),
            ContractParameter(ContractParameterType.Integer, 123000)
        ])

        sc = NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY, payload, self.contract_hash, 91349, self.event_tx, True, False)

        stream = StreamManager.GetStream()
        writer = BinaryWriter(stream)
        sc.Serialize(writer)

        out = bytes(stream.getvalue())

        StreamManager.ReleaseStream(stream)
        new_event = SmartContractEvent.FromByteArray(out)

        self.assertEqual(new_event.event_type, sc.event_type)
        self.assertEqual(new_event.contract_hash, sc.contract_hash)
        self.assertEqual(new_event.test_mode, sc.test_mode)
        self.assertEqual(new_event.tx_hash, sc.tx_hash)
        self.assertEqual(new_event.block_number, sc.block_number)

        self.assertEqual(new_event.notify_type, b'transfer')
        self.assertEqual(new_event.AddressTo, 'ALb8FEhEmtSqv97fuNVuoLmcmrSKckffRf')
        self.assertEqual(new_event.AddressFrom, 'AKZmSGPD7ytJBbxpRPmobYGLNxdWH3Jiqs')
        self.assertEqual(new_event.Amount, 123000)
        self.assertEqual(new_event.is_standard_notify, True)
示例#6
0
    def Runtime_Notify(self, engine):

        state = engine.EvaluationStack.Pop()

        # Build and emit smart contract event
        state_py = stack_item_to_py(state)
        payload = state_py if isinstance(state_py, list) else [
            state_py
        ]  # Runtime.Notify payload must be a list

        args = NotifyEventArgs(
            engine.ScriptContainer,
            UInt160(data=engine.CurrentContext.ScriptHash()), payload)

        message = payload[0] if len(payload) > 0 else payload
        engine.write_log(str(message))

        self.notifications.append(args)

        if settings.emit_notify_events_on_sc_execution_error:
            # emit Notify events even if the SC execution might fail.
            tx_hash = engine.ScriptContainer.Hash
            height = Blockchain.Default().Height + 1
            success = None
            self.events_to_dispatch.append(
                NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY, args.State,
                            args.ScriptHash, height, tx_hash, success,
                            engine.testMode))

        return True
示例#7
0
    def test_1_notify_should_not_persist(self):

        sc = NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY, ContractParameter(ContractParameterType.Array, []), self.contract_hash, 99, self.event_tx, True, False)

        ndb = NotificationDB.instance()
        ndb.on_smart_contract_event(sc)

        self.assertEqual(ndb.current_events, [])
示例#8
0
    def ExecutionCompleted(self, engine, success, error=None):

        height = Blockchain.Default().Height
        tx_hash = engine.ScriptContainer.Hash

        entry_script = None
        try:
            # get the first script that was executed
            # this is usually the script that sets up the script to be executed
            entry_script = UInt160(data=engine.ExecutedScriptHashes[0])

            # ExecutedScriptHashes[1] will usually be the first contract executed
            if len(engine.ExecutedScriptHashes) > 1:
                entry_script = UInt160(data=engine.ExecutedScriptHashes[1])
        except Exception as e:
            logger.error("Could not get entry script: %s " % e)

        payload = []
        for item in engine.EvaluationStack.Items:
            payload_item = stack_item_to_py(item)
            payload.append(payload_item)

        if success:

            # dispatch all notify events, along with the success of the contract execution
            for notify_event_args in self.notifications:
                self.events_to_dispatch.append(
                    NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY,
                                notify_event_args.State,
                                notify_event_args.ScriptHash, height, tx_hash,
                                success, engine.testMode))

            if engine.Trigger == Application:
                self.events_to_dispatch.append(
                    SmartContractEvent(SmartContractEvent.EXECUTION_SUCCESS,
                                       payload, entry_script, height, tx_hash,
                                       success, engine.testMode))
            else:
                self.events_to_dispatch.append(
                    SmartContractEvent(SmartContractEvent.VERIFICATION_SUCCESS,
                                       payload, entry_script, height, tx_hash,
                                       success, engine.testMode))

        else:
            if engine.Trigger == Application:
                self.events_to_dispatch.append(
                    SmartContractEvent(SmartContractEvent.EXECUTION_FAIL,
                                       [payload, error, engine._VMState],
                                       entry_script, height, tx_hash, success,
                                       engine.testMode))
            else:
                self.events_to_dispatch.append(
                    SmartContractEvent(SmartContractEvent.VERIFICATION_FAIL,
                                       [payload, error, engine._VMState],
                                       entry_script, height, tx_hash, success,
                                       engine.testMode))

        self.notifications = []
示例#9
0
def dispatch_smart_contract_notify(event_type,
                                   event_payload,
                                   contract_hash,
                                   block_number,
                                   tx_hash,
                                   execution_success=False,
                                   test_mode=False):
    notify_event = NotifyEvent(event_type, event_payload, contract_hash, block_number, tx_hash, execution_success, test_mode)
    events.emit(event_type, notify_event)
示例#10
0
    def test_should_persist_mint_event(self):
        sc = NotifyEvent(
            SmartContractEvent.RUNTIME_NOTIFY,
            [b'mint', self.addr_to, BigInteger(123000)], self.contract_hash,
            91349, self.event_tx, True, False)

        ndb = NotificationDB.instance()
        ndb.on_smart_contract_event(sc)

        self.assertEqual(len(ndb.current_events), 1)
        ndb.on_persist_completed(None)
    def test_4_should_persist(self):

        ndb = NotificationDB.instance()

        self.assertEqual(len(ndb.current_events), 0)
        sc = NotifyEvent(
            SmartContractEvent.RUNTIME_NOTIFY,
            [b'transfer', self.addr_to, self.addr_from,
             BigInteger(123000)], self.contract_hash, 91349, self.event_tx,
            True, True)

        ndb.on_smart_contract_event(sc)

        self.assertEqual(len(ndb.current_events), 0)
示例#12
0
    def test_3_should_persist(self):
        payload = ContractParameter(ContractParameterType.Array, [
            ContractParameter(ContractParameterType.String, b'transfer'),
            ContractParameter(ContractParameterType.ByteArray, self.addr_to),
            ContractParameter(ContractParameterType.ByteArray, self.addr_from),
            ContractParameter(ContractParameterType.Integer, 123000)
        ])
        sc = NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY, payload, self.contract_hash, 91349, self.event_tx, True, False)

        ndb = NotificationDB.instance()
        ndb.on_smart_contract_event(sc)

        self.assertEqual(len(ndb.current_events), 1)
        ndb.on_persist_completed(None)
示例#13
0
    def Runtime_Notify(self, engine: ExecutionEngine):
        state = engine.CurrentContext.EvaluationStack.Pop()

        payload = ContractParameter.ToParameter(state)

        args = NotifyEventArgs(
            engine.ScriptContainer,
            UInt160(data=engine.CurrentContext.ScriptHash()), payload)

        self.notifications.append(args)

        if settings.emit_notify_events_on_sc_execution_error:
            # emit Notify events even if the SC execution might fail.
            tx_hash = engine.ScriptContainer.Hash
            height = GetBlockchain().Height + 1
            success = None
            self.events_to_dispatch.append(
                NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY, payload,
                            args.ScriptHash, height, tx_hash, success,
                            engine.testMode))

        return True
示例#14
0
    def ExecutionCompleted(self, engine, success, error=None):
        height = Blockchain.Default().Height + 1
        tx_hash = None

        if engine.ScriptContainer:
            tx_hash = engine.ScriptContainer.Hash

        if not tx_hash:
            tx_hash = UInt256(data=bytearray(32))

        entry_script = None
        try:
            # get the first script that was executed
            # this is usually the script that sets up the script to be executed
            entry_script = UInt160(data=engine.ExecutedScriptHashes[0])

            # ExecutedScriptHashes[1] will usually be the first contract executed
            if len(engine.ExecutedScriptHashes) > 1:
                entry_script = UInt160(data=engine.ExecutedScriptHashes[1])
        except Exception as e:
            logger.error("Could not get entry script: %s " % e)

        payload = ContractParameter(ContractParameterType.Array, value=[])
        for item in engine.ResultStack.Items:
            payload.Value.append(ContractParameter.ToParameter(item))

        if success:

            # dispatch all notify events, along with the success of the contract execution
            for notify_event_args in self.notifications:
                self.events_to_dispatch.append(NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY, notify_event_args.State,
                                                           notify_event_args.ScriptHash, height, tx_hash,
                                                           success, engine.testMode))

            if engine.Trigger == Application:
                self.events_to_dispatch.append(SmartContractEvent(SmartContractEvent.EXECUTION_SUCCESS, payload, entry_script,
                                                                  height, tx_hash, success, engine.testMode))
            else:
                self.events_to_dispatch.append(SmartContractEvent(SmartContractEvent.VERIFICATION_SUCCESS, payload, entry_script,
                                                                  height, tx_hash, success, engine.testMode))

        else:
            # when a contract exits in a faulted state
            # we should display that in the notification
            if not error:
                error = 'Execution exited in a faulted state. Any payload besides this message contained in this event is the contents of the EvaluationStack of the current script context.'

            payload.Value.append(ContractParameter(ContractParameterType.String, error))

            # If we do not add the eval stack, then exceptions that are raised in a contract
            # are not displayed to the event consumer
            [payload.Value.append(ContractParameter.ToParameter(item)) for item in engine.CurrentContext.EvaluationStack.Items]

            if engine.Trigger == Application:
                self.events_to_dispatch.append(
                    SmartContractEvent(SmartContractEvent.EXECUTION_FAIL, payload,
                                       entry_script, height, tx_hash, success, engine.testMode))
            else:
                self.events_to_dispatch.append(
                    SmartContractEvent(SmartContractEvent.VERIFICATION_FAIL, payload,
                                       entry_script, height, tx_hash, success, engine.testMode))

        self.notifications = []
示例#15
0
    def ExecutionCompleted(self, engine, success, error=None):
        height = Blockchain.Default().Height + 1
        tx_hash = None

        if engine.ScriptContainer:
            tx_hash = engine.ScriptContainer.Hash

        if not tx_hash:
            tx_hash = UInt256(data=bytearray(32))

        entry_script = None
        try:
            # get the first script that was executed
            # this is usually the script that sets up the script to be executed
            entry_script = UInt160(data=engine.ExecutedScriptHashes[0])

            # ExecutedScriptHashes[1] will usually be the first contract executed
            if len(engine.ExecutedScriptHashes) > 1:
                entry_script = UInt160(data=engine.ExecutedScriptHashes[1])
        except Exception as e:
            logger.error("Could not get entry script: %s " % e)

        payload = ContractParameter(ContractParameterType.Array, value=[])
        for item in engine.ResultStack.Items:
            payload.Value.append(ContractParameter.ToParameter(item))

        if success:

            # dispatch all notify events, along with the success of the contract execution
            for notify_event_args in self.notifications:
                self.events_to_dispatch.append(
                    NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY,
                                notify_event_args.State,
                                notify_event_args.ScriptHash, height, tx_hash,
                                success, engine.testMode))

            if engine.Trigger == Application:
                self.events_to_dispatch.append(
                    SmartContractEvent(SmartContractEvent.EXECUTION_SUCCESS,
                                       payload, entry_script, height, tx_hash,
                                       success, engine.testMode))
            else:
                self.events_to_dispatch.append(
                    SmartContractEvent(SmartContractEvent.VERIFICATION_SUCCESS,
                                       payload, entry_script, height, tx_hash,
                                       success, engine.testMode))

        else:
            payload.Value.append(
                ContractParameter(ContractParameterType.String, error))
            payload.Value.append(
                ContractParameter(ContractParameterType.String,
                                  engine._VMState))
            if engine.Trigger == Application:
                self.events_to_dispatch.append(
                    SmartContractEvent(SmartContractEvent.EXECUTION_FAIL,
                                       payload, entry_script, height, tx_hash,
                                       success, engine.testMode))
            else:
                self.events_to_dispatch.append(
                    SmartContractEvent(SmartContractEvent.VERIFICATION_FAIL,
                                       payload, entry_script, height, tx_hash,
                                       success, engine.testMode))

        self.notifications = []