<commit_before>/*
 * Copyright (c) 2013, 2014 Conformal Systems LLC <<EMAIL>>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package tx

import (
	"errors"
	"fmt"
	"sort"
	"time"

	"github.com/conformal/btcchain"
	"github.com/conformal/btcscript"
	"github.com/conformal/btcutil"
	"github.com/conformal/btcwire"
)

var (
	// ErrDuplicateInsert describes the error where an insert was ignored
	// for being a duplicate.
	ErrDuplicateInsert = errors.New("duplicate insert")

	// ErrInconsistentStore describes an error where the transaction store
	// is in an inconsistent state.  This error is unrecoverable, and the
	// transaction store should be regenerated by a rescan.
	ErrInconsistentStore = errors.New("inconsistant transaction store")

	// ErrUnsupportedVersion represents an error where a serialized
	// object is marked with a version that is no longer supported
	// during deserialization.
	ErrUnsupportedVersion = errors.New("version no longer supported")
)

// MissingValueError is a catch-all error interface for any error due to a
// missing value in the transaction store.
type MissingValueError interface {
	Error() string
	MissingValueError() error
}

// MissingBlockError describes an error where a block could not be found in
// the transaction store.  The value is the height of the missing block.
type MissingBlockError int32

// Error implements the error interface.
func (e MissingBlockError) Error() string {
	return fmt.Sprintf("missing record for block %d", e)
}

// MissingValueError implements the MissingValueError interface.
func (e MissingBlockError) MissingValueError() error {
	return e
}

// MissingBlockTxError describes an error where a mined transaction could
// not be found in the transaction store.  The value is the lookup key for
// the mined transaction.
type MissingBlockTxError BlockTxKey

// Error implements the error interface.
func (e MissingBlockTxError) Error() string {
	return fmt.Sprintf("missing record for transaction at block %d index "+
		"%d", e.BlockHeight, e.BlockIndex)
}

// MissingValueError implements the MissingValueError interface.
func (e MissingBlockTxError) MissingValueError() error {
	return e
}

// MissingDebitsError describes an error where a mined transaction does not
// contain any debiting records.  The value is the lookup key for the mined
// transaction.
type MissingDebitsError BlockTxKey

// Error implements the error interface.
func (e MissingDebitsError) Error() string {
	return fmt.Sprintf("missing record for debits at block %d index %d",
		e.BlockHeight, e.BlockIndex)
}

// MissingValueError implements the MissingValueError interface.
func (e MissingDebitsError) MissingValueError() error {
	return e
}

// MissingCreditError describes an error where a mined transaction does not
// contain a credit record at for some output.  The value is the lookup key
// for the mined transaction's output.
type MissingCreditError BlockOutputKey

// Error implements the error interface.
func (e MissingCreditError) Error() string {
	return fmt.Sprintf("missing record for received transaction output at "+
		"block %d index %d output %d", e.BlockHeight, e.BlockIndex,
		e.OutputIndex)
}

// MissingValueError implements the MissingValueError interface.
func (e MissingCreditError) MissingValueError() error {
	return e
}

// TxRecord is the record type for all transactions in the store.  If the
// transaction is mined, BlockTxKey will be the lookup key for the transaction.
// Otherwise, the embedded BlockHeight will be -1.
type TxRecord struct {
	BlockTxKey
	*txRecord
	s *Store
}

// Block holds details about a block that contains wallet transactions.
type Block struct {
	Hash   btcwire.ShaHash
	Time   time.Time
	Height int32
}

// Debits is the type representing any TxRecord which debits from previous
// wallet transaction outputs.
type Debits struct {
	*TxRecord
}

// Credit is the type representing a transaction output which is spendable
// by wallet.<commit_msg>Clarify distinction between a Credit and UTXO.<commit_after>/*
 * Copyright (c) 2013, 2014 Conformal Systems LLC <<EMAIL>>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package tx

import (
	"errors"
	"fmt"
	"sort"
	"time"

	"github.com/conformal/btcchain"
	"github.com/conformal/btcscript"
	"github.com/conformal/btcutil"
	"github.com/conformal/btcwire"
)

var (
	// ErrDuplicateInsert describes the error where an insert was ignored
	// for being a duplicate.
	ErrDuplicateInsert = errors.New("duplicate insert")

	// ErrInconsistentStore describes an error where the transaction store
	// is in an inconsistent state.  This error is unrecoverable, and the
	// transaction store should be regenerated by a rescan.
	ErrInconsistentStore = errors.New("inconsistant transaction store")

	// ErrUnsupportedVersion represents an error where a serialized
	// object is marked with a version that is no longer supported
	// during deserialization.
	ErrUnsupportedVersion = errors.New("version no longer supported")
)

// MissingValueError is a catch-all error interface for any error due to a
// missing value in the transaction store.
type MissingValueError interface {
	Error() string
	MissingValueError() error
}

// MissingBlockError describes an error where a block could not be found in
// the transaction store.  The value is the height of the missing block.
type MissingBlockError int32

// Error implements the error interface.
func (e MissingBlockError) Error() string {
	return fmt.Sprintf("missing record for block %d", e)
}

// MissingValueError implements the MissingValueError interface.
func (e MissingBlockError) MissingValueError() error {
	return e
}

// MissingBlockTxError describes an error where a mined transaction could
// not be found in the transaction store.  The value is the lookup key for
// the mined transaction.
type MissingBlockTxError BlockTxKey

// Error implements the error interface.
func (e MissingBlockTxError) Error() string {
	return fmt.Sprintf("missing record for transaction at block %d index "+
		"%d", e.BlockHeight, e.BlockIndex)
}

// MissingValueError implements the MissingValueError interface.
func (e MissingBlockTxError) MissingValueError() error {
	return e
}

// MissingDebitsError describes an error where a mined transaction does not
// contain any debiting records.  The value is the lookup key for the mined
// transaction.
type MissingDebitsError BlockTxKey

// Error implements the error interface.
func (e MissingDebitsError) Error() string {
	return fmt.Sprintf("missing record for debits at block %d index %d",
		e.BlockHeight, e.BlockIndex)
}

// MissingValueError implements the MissingValueError interface.
func (e MissingDebitsError) MissingValueError() error {
	return e
}

// MissingCreditError describes an error where a mined transaction does not
// contain a credit record at for some output.  The value is the lookup key
// for the mined transaction's output.
type MissingCreditError BlockOutputKey

// Error implements the error interface.
func (e MissingCreditError) Error() string {
	return fmt.Sprintf("missing record for received transaction output at "+
		"block %d index %d output %d", e.BlockHeight, e.BlockIndex,
		e.OutputIndex)
}

// MissingValueError implements the MissingValueError interface.
func (e MissingCreditError) MissingValueError() error {
	return e
}

// TxRecord is the record type for all transactions in the store.  If the
// transaction is mined, BlockTxKey will be the lookup key for the transaction.
// Otherwise, the embedded BlockHeight will be -1.
type TxRecord struct {
	BlockTxKey
	*txRecord
	s *Store
}

// Block holds details about a block that contains wallet transactions.
type Block struct {
	Hash   btcwire.ShaHash
	Time   time.Time
	Height int32
}

// Debits is the type representing any TxRecord which debits from previous
// wallet transaction outputs.
type Debits struct {
	*TxRecord
}

// Credit is the type representing a transaction output which was spent or
// is still spendably by wallet.  A UTXO is an unspent Credit, but not all
// Credits are UTXOs.
{'fraction_non_alphanumeric': 0.06726886291179596, 'fraction_numerical': 0.002763018065887354, 'mean_word_length': 4.266368214885283, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5839904', 'n_tokens_mistral': 2625, 'n_tokens_neox': 2459, 'n_words': 1159}