/// <inheritdoc />
        public void SetStatus(CrossChainTransferStatus status, uint256 blockHash = null, int?blockHeight = null)
        {
            this.status = status;

            if (this.status == CrossChainTransferStatus.SeenInBlock)
            {
                this.blockHash   = blockHash;
                this.blockHeight = blockHeight;
            }

            Guard.Assert(IsValid());
        }
        /// <summary>
        /// Constructs this object from passed parameters.
        /// </summary>
        /// <param name="status">The status of the cross chain transfer transaction.</param>
        /// <param name="depositTransactionId">The transaction id of the deposit transaction.</param>
        /// <param name="depositTargetAddress">The target address of the deposit transaction.</param>
        /// <param name="depositAmount">The amount (in satoshis) of the deposit transaction.</param>
        /// <param name="depositHeight">The chain A height at which the deposit was made (if known).</param>
        /// <param name="partialTransaction">The unsigned partial transaction containing a full set of available UTXO's.</param>
        /// <param name="blockHash">The hash of the block where the transaction resides.</param>
        /// <param name="blockHeight">The height (in our chain) of the block where the transaction resides.</param>
        public CrossChainTransfer(CrossChainTransferStatus status, uint256 depositTransactionId, Script depositTargetAddress, Money depositAmount,
                                  int?depositHeight, Transaction partialTransaction, uint256 blockHash = null, int?blockHeight = null)
        {
            this.status = status;
            this.depositTransactionId = depositTransactionId;
            this.depositTargetAddress = depositTargetAddress;
            this.depositAmount        = depositAmount;
            this.depositHeight        = depositHeight;
            this.partialTransaction   = partialTransaction;
            this.blockHash            = blockHash;
            this.blockHeight          = blockHeight;

            Guard.Assert(this.IsValid());
        }
        /// <summary>
        /// (De)serializes this object.
        /// </summary>
        /// <param name="stream">Stream to use for (de)serialization.</param>
        public void ReadWrite(BitcoinStream stream)
        {
            if (stream.Serializing)
            {
                Guard.Assert(this.IsValid());
            }

            byte status = (byte)this.status;

            stream.ReadWrite(ref status);
            this.status = (CrossChainTransferStatus)status;

            stream.ReadWrite(ref this.depositTransactionId);
            stream.ReadWrite(ref this.depositTargetAddress);
            stream.ReadWrite(ref this.depositAmount);

            int depositHeight = this.DepositHeight ?? -1;

            stream.ReadWrite(ref depositHeight);
            this.depositHeight = (depositHeight < 0) ? (int?)null : depositHeight;

            stream.ReadWrite(ref this.partialTransaction);

            if (!stream.Serializing && this.partialTransaction.Inputs.Count == 0 && this.partialTransaction.Outputs.Count == 0)
            {
                this.partialTransaction = null;
            }

            if (this.status == CrossChainTransferStatus.SeenInBlock)
            {
                uint256 blockHash = this.blockHash ?? 0;
                stream.ReadWrite(ref blockHash);
                this.blockHash = (blockHash == 0) ? null : blockHash;

                int blockHeight = this.BlockHeight ?? -1;
                stream.ReadWrite(ref blockHeight);
                this.blockHeight = (blockHeight < 0) ? (int?)null : blockHeight;
            }
        }