private bool IsFinal(Transaction tx, int blockHeight, long blockTime)
{
// no tx lock time specified, transaction is final
if (tx.LockTime == 0)
return true;
// lock time is compared by block height before LOCKTIME_THRESHOLD, block time afterwards
var blockLockTime = (tx.LockTime < LOCKTIME_THRESHOLD ? blockHeight : blockTime);
// if block's time is after tx's lock time, transaction is final
if (blockLockTime >= tx.LockTime)
return true;
// if tx's lock time hasn't yet been reached, the transaction is final if all its inputs are final
return tx.Inputs.All(x => IsFinal(x));
}